guard: regenerating a screen touches the ones that changed, and a version stays linkable - #50
Merged
Merged
Conversation
…sion stays linkable Two things that went wrong while closing 0.3.0-rc1, neither of them broken code, both found by reading a diff rather than by anything red. Regenerating the stored screens rewrote all twenty five whether or not any had changed. Only About had: it draws the version. The other twenty four came back with byte identical pixels and files 12.6% to 28.9% larger, because Go 1.27 encodes PNG less tightly than 1.26.7, which wrote them - measured by re-encoding a committed file with today's compiler and getting the regenerated size exactly, while About, already written under 1.27, round trips byte for byte. So 402 kB of pure encoder churn across twenty four binary files went into the release commit, where `git diff --stat` says only "Bin". The writer now asks the guard's own question - does the stored reference still stand - rather than whether the bytes match. Byte equality was written here first and measured wrong on the spot: it rewrites every picture once on the first regeneration after a compiler update, which is the churn it was meant to stop. One judgement now serves both the comparison and the writing, so the two cannot drift apart about what changed. Measured after: twenty five of twenty five left alone, nothing written, and a reference replaced by another picture is still the one and only file rewritten. And the changelog's link definitions had nothing holding them. A "## [0.3.0-rc1]" heading went in without its definition, so it rendered as literal brackets, and Unreleased still compared from v0.2.0 - showing the release's own changes as if they were still coming. Keep a Changelog is declared in the file's own header and in GIT.md, so the convention was written down and unguarded. Same class as O178. Six mutations, all caught. Two of them are the two faults themselves. Co-Authored-By: Claude Opus 5 <noreply@anthropic.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.
Two things that went wrong while closing
0.3.0-rc1. Neither was broken code, and both were found by reading a diff rather than by anything red.Regenerating the stored screens rewrote all twenty five
Only one had changed - About, because it draws the version. The other twenty four came back with byte identical pixels and files 12.6% to 28.9% larger.
The cause is the compiler, and it was measured rather than inferred:
generate.pngpreset.pngrecipe-refused.pngRe-encoding a committed file with today's compiler produces exactly the regenerated size.
about.png, already written under 1.27, round trips byte for byte - one file under the new toolchain and twenty four under the old, in one run on one machine, so the measurement carries its own control.So 402 kB of pure encoder churn across twenty four binary files went into the release commit, where
git diff --statsays onlyBin. What took it back out was somebody reading.The writer now asks the guard's own question - does the stored reference still stand - rather than whether the bytes match. Byte equality was written here first and measured wrong on the spot: it rewrites every picture once on the first regeneration after a compiler update, which is the churn it was meant to stop. One judgement (
judgePicture) now serves both the comparison and the writing, so the two cannot drift apart about what changed.Measured after: twenty five of twenty five left alone and nothing written, while a reference replaced by a different picture is still the one and only file rewritten.
The changelog's link definitions had nothing holding them
A
## [0.3.0-rc1]heading went in without its definition, so it rendered as literal square brackets, and[Unreleased]still compared fromv0.2.0- showing the release's own changes as if they were still coming. A wrong target is worse than a missing one, because the link works.Keep a Changelog is declared in the file's own header and in the project's git conventions, so this was a written convention with nothing behind it. Same class as the README table guard closed the same day. The guard also catches the drift running the other way, a definition left behind with no section.
Proof
Six mutations, all caught. Two of them are the two faults themselves. Full suite green,
preflight --quickgreen on all twelve checks including staticcheck, lint and govulncheck.🤖 Generated with Claude Code