feat(release-cut): auto-re-pin on cut for single-click release UX (v1.0.0 must-fix) #445

Closed
opened 2026-07-07 09:36:38 +02:00 by bosun · 0 comments
Owner

Motivation

The check-self-bootstrap workflow is designed to fail-loud on pin-drift as a discipline-enforcer (per #124: "make sure you re-pin so future cuts use the fix"). In practice, this means every release-toolkit-internal substrate cut fires check-self-bootstrap RED.

Why: any compose-script edit (register-check.sh, changelog-body-check.sh, release-decide.sh, release-prep.sh, etc.) creates drift between main and the pinned ref in release.yml. The cut fires from the pinned ref (older code); check-self-bootstrap notices main has moved forward → RED.

Empirical anchor (2026-07-06 through 2026-07-07 CEST substrate sprint):

  • PR#438 (v0.28.0 substrate arc) → check-self-bootstrap RED on push:main
  • PR#443 (v0.28.1/v0.29.0 Bundle 1) → check-self-bootstrap RED on push:main
  • v0.29.0 rolling PR merge → check-self-bootstrap RED on push:main

Every single toolkit-self substrate cut in this sprint fired the check red. Adopters (other projects using release-toolkit) never see it — they don't ship the toolkit code itself; only release-toolkit-self-development shows this pattern.

Operator ideal: single-click release = single rolling PR merge fires cut + re-pin + green. No manual second cycle. Currently the flow requires:

  1. Substrate fix → rolling PR → merge → cut (RED on check-self-bootstrap)
  2. Operator manually: tag new RC at main HEAD + update release.yml + commit + push
  3. Next cut runs green

The two-cut cadence is manual, easy to forget, and creates noise on every legitimate substrate cut.

Scope

Substrate design + implementation work spanning:

  • The cut mechanic (release.yml / release-decide.sh / release-prep.sh) — decide whether/how to auto-update the pinned ref as part of the cut
  • The release.yml pin declaration itself — restructure if beneficial (config file, tag pointer, computed default, etc.)
  • The check-self-bootstrap workflow — reconsider trigger scope, severity, or gating behavior in light of the new cadence
  • Documentation of the new UX + migration notes for adopters

Design options (starting points, not committed)

A. Cut workflow auto-updates release.yml pin as part of cut — preferred per operator's single-click framing:

  • After cut composes tag + release, workflow updates release.yml to reference the new tag
  • Commit + push happens in same workflow run (or via a bookkeeping commit at end of cut)
  • Next check-self-bootstrap run is green by construction
  • Tradeoff: cut workflow now has substrate-write authority; needs careful commit-authorship + push-safety

B. Skip check-self-bootstrap on release-prep merge commits — scope-by-trigger:

  • Recognize when push:main is a release-prep merge (subject pattern already used by PREP_SUBJECT_RE)
  • Skip pin-drift check on that push
  • Fires normally on any other compose-script edit
  • Tradeoff: skips signal on the exact push where compose-script changes are most likely; loses coverage

C. Warn-instead-of-red — severity change:

  • Pin-drift becomes informational output, not a failure
  • Still surfaces the "you should re-pin" reminder
  • Doesn't create red-noise on legitimate cuts
  • Tradeoff: reminder is easier to ignore; discipline-enforcer weakens

D. Restructure pinned-ref mechanism:

  • Move the pinned ref out of release.yml (into a config file, or computed from tag list)
  • Restructure so cut naturally uses fresh code without needing an explicit pin update
  • Tradeoff: larger scope; may reshape adopter integration too

Not exhaustive — the tracker frames the design question, doesn't pre-commit to a fix.

Verification AC

  • A cut from a substrate-modifying rolling PR merge completes with all workflow checks green (or explicit warnings that don't require a follow-up manual action)
  • Operator can achieve a release by merging a single rolling PR without a follow-up re-pin commit
  • Check-self-bootstrap continues to fire loudly on genuine pin-drift scenarios (accidental hand-edits to release.yml, orphaned tags, etc.) — the discipline value is preserved for its actual failure modes
  • Documentation + integration.md updated to reflect the new cadence
  • Adopter integration continues to work unchanged (this is a toolkit-self UX fix, not a consumer-visible change)
  • #124 — check-self-bootstrap origin design + the "operator re-pins after cut" cadence assumption
  • #432 — check-self-bootstrap header sharpening ("pin-drift detection, NOT content validation") — this tracker questions whether the current implementation of that scope is the right UX
  • #417 / #427 / #421 / #424 / #440 / #441 / #442 — all substrate PRs from the 2026-07-06/07 sprint that fired check-self-bootstrap RED as expected-red per QM's pre-emptive naming; every one is empirical evidence for this tracker
  • #439 (Bundle 2 pending) — workflow_dispatch compose-path unification; shares substrate design lane

Anchor

Operator directive 2026-07-07 during v0.29.0 draft creation (this session):

"The ideal for me is still a single click release: a single rolling PR merge."

Priority/high + v1.0.0 must-fix framing per operator explicit statement in that exchange. Empirical evidence accumulated across every toolkit-self substrate cut since substrate sprint began 2026-07-06.

## Motivation The `check-self-bootstrap` workflow is designed to fail-loud on pin-drift as a discipline-enforcer (per #124: "make sure you re-pin so future cuts use the fix"). In practice, this means **every release-toolkit-internal substrate cut fires check-self-bootstrap RED**. **Why**: any compose-script edit (`register-check.sh`, `changelog-body-check.sh`, `release-decide.sh`, `release-prep.sh`, etc.) creates drift between `main` and the pinned ref in `release.yml`. The cut fires from the pinned ref (older code); check-self-bootstrap notices main has moved forward → RED. **Empirical anchor** (2026-07-06 through 2026-07-07 CEST substrate sprint): - PR#438 (v0.28.0 substrate arc) → check-self-bootstrap RED on push:main - PR#443 (v0.28.1/v0.29.0 Bundle 1) → check-self-bootstrap RED on push:main - v0.29.0 rolling PR merge → check-self-bootstrap RED on push:main Every single toolkit-self substrate cut in this sprint fired the check red. Adopters (other projects using release-toolkit) never see it — they don't ship the toolkit code itself; only release-toolkit-self-development shows this pattern. **Operator ideal**: single-click release = single rolling PR merge fires cut + re-pin + green. No manual second cycle. Currently the flow requires: 1. Substrate fix → rolling PR → merge → cut (RED on check-self-bootstrap) 2. Operator manually: tag new RC at main HEAD + update `release.yml` + commit + push 3. Next cut runs green The two-cut cadence is manual, easy to forget, and creates noise on every legitimate substrate cut. ## Scope Substrate design + implementation work spanning: - The cut mechanic (`release.yml` / `release-decide.sh` / `release-prep.sh`) — decide whether/how to auto-update the pinned ref as part of the cut - The `release.yml` pin declaration itself — restructure if beneficial (config file, tag pointer, computed default, etc.) - The `check-self-bootstrap` workflow — reconsider trigger scope, severity, or gating behavior in light of the new cadence - Documentation of the new UX + migration notes for adopters ## Design options (starting points, not committed) **A. Cut workflow auto-updates `release.yml` pin as part of cut** — preferred per operator's single-click framing: - After cut composes tag + release, workflow updates `release.yml` to reference the new tag - Commit + push happens in same workflow run (or via a bookkeeping commit at end of cut) - Next check-self-bootstrap run is green by construction - Tradeoff: cut workflow now has substrate-write authority; needs careful commit-authorship + push-safety **B. Skip check-self-bootstrap on release-prep merge commits** — scope-by-trigger: - Recognize when push:main is a release-prep merge (subject pattern already used by `PREP_SUBJECT_RE`) - Skip pin-drift check on that push - Fires normally on any other compose-script edit - Tradeoff: skips signal on the exact push where compose-script changes are most likely; loses coverage **C. Warn-instead-of-red** — severity change: - Pin-drift becomes informational output, not a failure - Still surfaces the "you should re-pin" reminder - Doesn't create red-noise on legitimate cuts - Tradeoff: reminder is easier to ignore; discipline-enforcer weakens **D. Restructure pinned-ref mechanism**: - Move the pinned ref out of `release.yml` (into a config file, or computed from tag list) - Restructure so cut naturally uses fresh code without needing an explicit pin update - Tradeoff: larger scope; may reshape adopter integration too Not exhaustive — the tracker frames the design question, doesn't pre-commit to a fix. ## Verification AC - A cut from a substrate-modifying rolling PR merge completes with all workflow checks green (or explicit warnings that don't require a follow-up manual action) - Operator can achieve a release by merging a single rolling PR without a follow-up re-pin commit - Check-self-bootstrap continues to fire loudly on genuine pin-drift scenarios (accidental hand-edits to `release.yml`, orphaned tags, etc.) — the discipline value is preserved for its actual failure modes - Documentation + integration.md updated to reflect the new cadence - Adopter integration continues to work unchanged (this is a toolkit-self UX fix, not a consumer-visible change) ## Related - **#124** — check-self-bootstrap origin design + the "operator re-pins after cut" cadence assumption - **#432** — check-self-bootstrap header sharpening ("pin-drift detection, NOT content validation") — this tracker questions whether the current implementation of that scope is the right UX - **#417 / #427 / #421 / #424 / #440 / #441 / #442** — all substrate PRs from the 2026-07-06/07 sprint that fired check-self-bootstrap RED as expected-red per QM's pre-emptive naming; every one is empirical evidence for this tracker - **#439** (Bundle 2 pending) — workflow_dispatch compose-path unification; shares substrate design lane ## Anchor Operator directive 2026-07-07 during v0.29.0 draft creation (this session): > *"The ideal for me is still a single click release: a single rolling PR merge."* Priority/high + v1.0.0 must-fix framing per operator explicit statement in that exchange. Empirical evidence accumulated across every toolkit-self substrate cut since substrate sprint began 2026-07-06.
bosun closed this issue 2026-07-07 11:13:42 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
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#445
No description provided.