From 20fef44cd31bc8a9097aa4e298fac284dc16e1bc Mon Sep 17 00:00:00 2001 From: Benjamin Borbe Date: Wed, 26 Aug 2026 21:44:54 +0200 Subject: [PATCH] fix(commit): verify branch base is current before writing CHANGELOG Adds Step A.0 to Workflow A, run before composing any changelog entry: git fetch git diff origin/master -- CHANGELOG.md | grep -E '^[-+]## ' Only '+## Unreleased' is acceptable. A '-## vX.Y.Z' line means a release was cut after the branch point -- '## Unreleased' was renamed upstream, so the branch's bullets merge INTO the released section. Git resolves that cleanly with no conflict marker, so nothing warns anyone. Two silent consequences: the tag and the CHANGELOG disagree about what shipped, and with no '## Unreleased' block left the release watcher has nothing to cut, so the branch's work never gets released at all. On autoRelease repos the trigger is usually your OWN merge -- merging PR-1 cuts a release that stales the base for PR-2 minutes later, no second contributor needed. So the check belongs before every commit, not once per session. The guard already existed in operator memory; nothing ran it. The command that actually writes CHANGELOG now does. Observed 2026-08-26 on bborbe/nuke: missed once and needed a repair PR to unfold a released section, then caught on the next two commits the same afternoon. Excludes unrelated dirty bench/reports/ files via explicit pathspec. --- CHANGELOG.md | 4 ++++ commands/commit.md | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c607953..bd40c64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ Please choose versions by [Semantic Versioning](http://semver.org/). * MINOR version when you add functionality in a backwards-compatible manner, and * PATCH version when you make backwards-compatible bug fixes. +## Unreleased + +- fix(commit): add Step A.0 to Workflow A — verify the branch base is current before composing a changelog entry. On `autoRelease: true` repos your own merge cuts a release that renames `## Unreleased`, so a branch created minutes earlier is already stale and its bullets merge INTO the released section with no conflict marker. Two silent consequences: the tag and CHANGELOG disagree about what shipped, and with no `## Unreleased` left the release watcher has nothing to cut, so the work never gets released. The guard was documented in memory but nothing ran it; the command that writes CHANGELOG now does. + ## v0.50.1 - fix: flip the `tts-mcp#13` conventional-prefix entry from `accepted` to `rejected` in the golden set (`golden-curated-3` → `golden-curated-4`; 158 entries unchanged, 138/20 → 137/21). Verified against the PR head `59f9fe8`: `tts-mcp` declares no conventional-prefix requirement (absent from both `CLAUDE.md` and `AGENTS.md`) and its own released `v0.2.0`/`v0.1.0` CHANGELOG sections use the same prose-bullet style — a correct observation that names no defect, which the golden set's own rule rejects. It was promoted on 2026-08-18 on the strength of three-model agreement (m3+m2.7+deepseek); that reasoning was wrong because all three share a conventional-commit training prior, so agreement amplified a shared bias rather than triangulating truth. **Model agreement is not independent evidence when the models share priors** — verification has to run against the repository, not a vote. Scores computed against `golden-curated-3` credited models for reproducing a non-defect and penalised them for missing it; the entry now works as a precision probe instead diff --git a/commands/commit.md b/commands/commit.md index 9182278..a422319 100644 --- a/commands/commit.md +++ b/commands/commit.md @@ -288,6 +288,37 @@ Triggered for: - Any feature branch with `CHANGELOG.md` - **Any branch (including master) when `.maintainer.yaml: release.autoRelease: true`** — `github-releaser-agent` will rename `## Unreleased` → `## vX.Y.Z` and tag within ~10 min of push. +**Step A.0: Verify the branch base is current** + +Do this BEFORE composing any changelog entry. + +```bash +cd $PROJECT_DIR && git fetch +cd $PROJECT_DIR && git diff origin/master -- CHANGELOG.md | grep -E '^[-+]## ' +``` + +Must print **only** `+## Unreleased`. A `-## vX.Y.Z` line means a release was cut +after your branch point: `## Unreleased` was renamed to that version upstream, so +your bullets will merge INTO the released section instead of a new Unreleased +block. Git resolves this cleanly with no conflict marker — nothing warns you. + +Two consequences, both silent: the tag and the CHANGELOG disagree about what +shipped, and with no `## Unreleased` left the release watcher has nothing to cut, +so this PR's work never gets released at all. + +Recover by refreshing the base, then re-applying the entry: + +```bash +cd $PROJECT_DIR && git reset --hard origin/master # save your non-CHANGELOG edits first +# re-apply the entry, then re-run the check above +``` + +**On `autoRelease: true` repos, run this before EVERY commit, not once per +session.** The cut is triggered by your own merges, so merging PR-1 stales your +base for PR-2 minutes later — no second contributor required. Observed 2026-08-26 +on `bborbe/nuke`: missed once (needed a repair PR), then caught on the next two +commits the same afternoon by running it. + **Step A.1: Pre-commit validation** ```bash make precommit # Skip if target doesn't exist