chore: write the release version literals from one command - #47
Merged
Merged
Conversation
A release moves one approved version string through eight literals in six files. Seven of the eight are transcription — the four host manifests and the two `plugin list` samples in each README — and hand-editing them is the step that drifts. `hooks/release-version X.Y.Z` writes them in one call and checks before it writes, so a refusal leaves every file byte-identical. It refuses until the `CHANGELOG.md` section exists. That is the ordering rule `RELEASE.md` now states: the tag is the immutable artifact the marketplace `sha` pins, so the commit it names has to carry the release notes itself. `hooks/release-check` gains two checks that were measured missing: - Every README sample line is compared, not the first one per file. Reading only the first left two literals a release has to move compared by nothing — setting `README.md:261` to the previous version still printed `STATUS: pass`. - The range from the tagged commit to the commit that recorded the pin may contain only the two marketplace catalogs. Anything else would ship under the pin without being in the release commit the tag names. Paths under `TaskFlowDocs/` are exempt: task documents are not distributed. Two claims in the Todo entry did not survive measurement and are corrected in the PRD rather than implemented: the tagged commits for v1.0.7 and v1.0.8 already carry their `CHANGELOG.md` sections, so "the tag lacks the release body" was not a defect — what was missing was the stated ordering. The literal count was eight in six files, not six in seven. Verified: `bash hooks/smoke-test` ALL SMOKE PASSED; `bash hooks/release-check .` pass on the unmodified repository; `git diff --check` clean. Five mutations, one per new check, each caught by the suite.
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.
Summary
Cut the mechanical overhead out of a release: write the eight version literals a release has to move from one command, state the ordering rule that keeps the release notes inside the tagged commit, and fail CI on the two release records that could go stale unnoticed.
The literals are one approved version string transcribed into six files — the four host manifests and the two
plugin listsamples in each README. Seven of the eight are mechanical, and hand-editing them is where a release drifts. The eighth is theCHANGELOG.mdsection, which stays with the author.Changes
hooks/release-version <x.y.z> [root](new) — writes every mechanical literal in a single call: four manifests, and both README samples in both READMEs. It checks before it writes, so a refusal leaves all six files byte-identical, and each staged rewrite is read back with the same readerrelease-checkuses before anything is moved. The Codex and CodeBuddy cachebuster dates come from the run's own date.It refuses until the
CHANGELOG.mdsection exists. That is deliberate: it is what binds the prose to the same commit as the literals. It never tags, pushes, publishes, or records an approval —RELEASE.md's manual, approved tag step is untouched.hooks/release-check— two checks that were measured missing:… | head -1, so only the first of its two literals was comparedREADME.md:261to1.0.7printedSTATUS: passEvery sample line is now compared, each named by position when it is not the first, and the output lists each literal so a second sample disagreeing with the first is visible rather than averaged away. The pin-window rule allows only the two marketplace catalogs, and exempts
TaskFlowDocs/because task documents are not distributed with the release.RELEASE.md— states why theCHANGELOG.mdsection is written before the tag (the tag is what the marketplaceshapins, so the commit it names must carry the notes itself), names the new command in the scope list, and records the pin-window rule in the validation checklist.hooks/README.md— the hook tree gainsrelease-version.TaskFlow traceability
TaskFlowDocs/achieved/2026-09-21-release-overhead/(archived in this PR)TF-20260919-c41f8ahooks/release-version,hooks/release-check,hooks/smoke-test,RELEASE.md,hooks/README.md, and the task documentsmainhkwuks/TaskFlow(origin)Verification
bash hooks/smoke-test— ALL SMOKE PASSEDgit diff --check— cleanbash -nclean on all three changed hooks; the new hook and both changed checks are covered by the smoke suite; no skill or manifest file is touched, so no Skill validation is applicableTaskFlowDocs/achieved/2026-09-21-release-overhead/plan.md,## Verification / ReviewBeyond the suite:
bash hooks/release-check .reportsSTATUS: passon the unmodified repository and lists all nine literal lines;bash hooks/release-versionwas refused in four ways (noCHANGELOGsection, malformed version, no increase, already at target) with the tree verified byte-identical afterwards.Five mutations, one per new check, each caught by the suite:
readme_versionsrestricted to the first match, as the old code didFAIL stale second README sample acceptedFAIL a stray file in the pin window was acceptedFAIL a manifest with two version keys was rewrittenCHANGELOG-section precondition removedFAIL release-version ran without a CHANGELOG sectionFAIL a file already at the target version was overwritten silentlyTwo claims from the Todo entry that measurement did not support
Recorded in the PRD's
## Background / Confirmed Factsand the Plan's## Change Log, because both changed what was built:c3c536d) and v1.0.8 (620c6a7) both already carry theirCHANGELOG.mdsections. Thegit tag -aannotation is a second copy on the tag object, not a replacement for the first. So there was no procedure change to make — what was missing wasRELEASE.mdstating the ordering, which is now R4.CHANGELOG.mdis the seventh file and stays prose, which the item had right.Review boundaries
origin(hkwuks/TaskFlow), targetingmainKnown limitations
HEAD. Work landing onmainafter the release is not part of the release, so comparing againstHEADwould report every commit since as a stray. A release that writes the catalogs in more than one commit is still covered — the range spans all of them.release-versiontranscribes and never decides. It refuses a version that is not greater than the current one, so a deliberate re-release of the same number is not expressible; that has not occurred and would need a decision about what it means for the tag.README.zh-CN.mdfixture is a copy of the English one in the smoke suite, so a sample line that exists only in the Chinese README would not be caught by the assertions — the check itself reads both files, so this is a fixture limitation, not a check limitation.