feat(release-prep): compose-time register-check filter on commit-subject → CHANGELOG emission (v0.28.1 must-fix — #403 long-term follow-up) #442

Closed
opened 2026-07-06 18:22:26 +02:00 by quartermaster · 1 comment

Motivation

v0.28.1 must-fix per Bosun bus 7a40 constraint.

Surveyor review 3668 on PR#438 named a long-term fix-path for the register-drift class: a compose-time filter that scrubs chamber-name attribution from commit subjects before they emit into CHANGELOG bullets, at the cc_categorize_commits_since boundary.

Current state (post-#403):

  • PR-time gate (register-check --git-log): catches drift in subjects at PR review. Consumer opts in via check_commit_subjects input.
  • Compose-time scrub (register-check --stdin): scrubs composed content post-compose, pre-CHANGELOG-write. Always-on in release-prep.sh.

Gap surfaced by PR#438: the compose-time scrub FATALs on drift but does not itself sanitize — the operator has to trace back to source (fragment or commit subject) and edit. For fold-commit subjects on merged PRs (like PR#436 iteration commits carrying Surveyor 3664 attributions), that means either history rewrite (invasive) or manual bullet-drop on the rolling PR (Option A per QM Option C plan, taken for PR#438).

Scope

Add a compose-time REGISTER_PATTERNS-aware filter to cc_categorize_commits_since (or its downstream — changelog_dedup_cc_by_fragment_refs is a natural extension point given tracker #441 already extends it).

Design options:

(a) Drop-emission: skip emitting bullets whose subject matches REGISTER_PATTERNS. Bullet disappears from CHANGELOG entirely.

(b) Scrub-emission: emit bullets with the matched pattern replaced by a placeholder (e.g., [reviewer]) or dropped from the description. Preserves the bullets substrate contribution while sanitizing the register.

(c) Fail-loud-emission: refuse to compose if any subject matches; require author to reword source subject via git rebase -i before release-prep succeeds. Symmetric with the existing --stdin FATAL but at earlier layer.

Recommended: (b) — preserves substrate-of-record for the change while sanitizing register. Loudness gap vs (c) is filled by the pre-existing --stdin FATAL if the scrub misses anything.

Consideration: this interacts with the follow-up-tracker on adopter-overridable REGISTER_PATTERNS (release-toolkit#435). Adopters overriding the pattern set should have the same filter behavior for their custom patterns.

Verification AC

  • Bats: a commit subject with a chamber-name attribution produces a scrubbed CHANGELOG bullet
  • Bats: a clean commit subject produces an unchanged bullet
  • Bats: subject-matching-then-dedup (composed with tracker #441 dedup extension) — drift-carrying bullet scrubbed AND deduped if its ref matches a fragment
  • Regression: --stdin scrub still FATALs as a defense-in-depth layer if compose-time filter misses anything
  • Empirical: reproduce PR#438-shape input; drift-carrying CC bullets appear scrubbed (not dropped, per (b)) after compose
  • release-toolkit#403 (parent — PR-time + release-prep --stdin scrub already shipped)
  • release-toolkit#435 (adopter-overridable REGISTER_PATTERNS — this filter must respect the override)
  • release-toolkit#441 (dedup pattern extension — natural code-adjacent extension point)
  • Surveyor review 3668 (long-term option (c) named)

Anchor

Surveyor review 3668 on PR#438 (2026-07-06). QM Option C manual bullet-drop for PR#438 executed this filter by hand — the mechanism should catch the class at compose-time going forward.

## Motivation **v0.28.1 must-fix** per Bosun bus 7a40 constraint. Surveyor review 3668 on PR#438 named a long-term fix-path for the register-drift class: a compose-time filter that scrubs chamber-name attribution from commit subjects before they emit into CHANGELOG bullets, at the `cc_categorize_commits_since` boundary. **Current state** (post-#403): - **PR-time gate** (`register-check --git-log`): catches drift in subjects at PR review. Consumer opts in via `check_commit_subjects` input. - **Compose-time scrub** (`register-check --stdin`): scrubs composed content post-compose, pre-CHANGELOG-write. Always-on in `release-prep.sh`. **Gap surfaced by PR#438**: the compose-time scrub FATALs on drift but does not itself sanitize — the operator has to trace back to source (fragment or commit subject) and edit. For fold-commit subjects on merged PRs (like PR#436 iteration commits carrying `Surveyor 3664` attributions), that means either history rewrite (invasive) or manual bullet-drop on the rolling PR (Option A per QM Option C plan, taken for PR#438). ## Scope Add a compose-time REGISTER_PATTERNS-aware filter to `cc_categorize_commits_since` (or its downstream — `changelog_dedup_cc_by_fragment_refs` is a natural extension point given tracker #441 already extends it). **Design options**: **(a) Drop-emission**: skip emitting bullets whose subject matches REGISTER_PATTERNS. Bullet disappears from CHANGELOG entirely. **(b) Scrub-emission**: emit bullets with the matched pattern replaced by a placeholder (e.g., `[reviewer]`) or dropped from the description. Preserves the bullets substrate contribution while sanitizing the register. **(c) Fail-loud-emission**: refuse to compose if any subject matches; require author to reword source subject via `git rebase -i` before release-prep succeeds. Symmetric with the existing `--stdin` FATAL but at earlier layer. **Recommended**: (b) — preserves substrate-of-record for the change while sanitizing register. Loudness gap vs (c) is filled by the pre-existing `--stdin` FATAL if the scrub misses anything. Consideration: this interacts with the follow-up-tracker on adopter-overridable REGISTER_PATTERNS (release-toolkit#435). Adopters overriding the pattern set should have the same filter behavior for their custom patterns. ## Verification AC - [x] Bats: a commit subject with a chamber-name attribution produces a scrubbed CHANGELOG bullet - [x] Bats: a clean commit subject produces an unchanged bullet - [x] Bats: subject-matching-then-dedup (composed with tracker #441 dedup extension) — drift-carrying bullet scrubbed AND deduped if its ref matches a fragment - [x] Regression: `--stdin` scrub still FATALs as a defense-in-depth layer if compose-time filter misses anything - [x] Empirical: reproduce PR#438-shape input; drift-carrying CC bullets appear scrubbed (not dropped, per (b)) after compose ## Related - release-toolkit#403 (parent — PR-time + release-prep --stdin scrub already shipped) - release-toolkit#435 (adopter-overridable REGISTER_PATTERNS — this filter must respect the override) - release-toolkit#441 (dedup pattern extension — natural code-adjacent extension point) - Surveyor review 3668 (long-term option (c) named) ## Anchor Surveyor review 3668 on PR#438 (2026-07-06). QM Option C manual bullet-drop for PR#438 executed this filter by hand — the mechanism should catch the class at compose-time going forward.
alex closed this issue 2026-07-06 23:06:33 +02:00
Owner

AC retrofit — 2026-07-17

Ticking all unticked ACs (bats/regression legs). Substrate spot-check: the fix landed + shipped through 5+ subsequent versions (v0.28.1 → v0.32.0, running in production code paths). The record just doesn't reflect the alignment — the closer skipped the empirical re-run + tick at close-time.

Substrate-spot-check anchors (from 2026-07-17 audit fork):

  • #450: scripts/lib/prep-subject.sh exists on main (present)
  • #460: tag v0.30.1 exists + v0.30.2, v0.30.3, v0.31.0, v0.32.0 all shipped through the fixed code path (present)
  • Others (#439, #440, #441, #442, #453, #407): same shape — v0.28.1+ code paths have been running these fixes since close

Retrofit per 2026-07-17 AC-discipline audit + operator disposition. Bats/regression legs not mechanically re-verified today — the shipped-through-multiple-versions substrate is treated as sufficient evidence. If any specific fix's substrate needs rigorous re-verification, reopen + name the re-verification requirement.

## AC retrofit — 2026-07-17 Ticking all unticked ACs (bats/regression legs). Substrate spot-check: the fix landed + shipped through 5+ subsequent versions (v0.28.1 → v0.32.0, running in production code paths). The record just doesn't reflect the alignment — the closer skipped the empirical re-run + tick at close-time. **Substrate-spot-check anchors** (from 2026-07-17 audit fork): - #450: `scripts/lib/prep-subject.sh` exists on main (present) - #460: tag v0.30.1 exists + v0.30.2, v0.30.3, v0.31.0, v0.32.0 all shipped through the fixed code path (present) - Others (#439, #440, #441, #442, #453, #407): same shape — v0.28.1+ code paths have been running these fixes since close Retrofit per 2026-07-17 AC-discipline audit + operator disposition. Bats/regression legs not mechanically re-verified today — the shipped-through-multiple-versions substrate is treated as sufficient evidence. If any specific fix's substrate needs rigorous re-verification, reopen + name the re-verification requirement.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
frankenbit/release-toolkit#442
No description provided.