chore(repin): extend WRAPPER_GLOB to cover all consumer wrappers dynamically #295

Closed
opened 2026-07-02 17:38:20 +02:00 by quartermaster · 2 comments

Scope

scripts/repin.sh hardcodes WRAPPER_GLOB=(.forgejo/workflows/release.yml .forgejo/workflows/manifest-check.yml) — the two wrappers that existed when the script was written (release-toolkit#172 / #222).

Newer wrappers added post-script:

  • fragment-check.yml (release-toolkit#278, v0.20.0)
  • Future: changelog-body-check.yml (release-toolkit#290 will add the toolkit-self dogfood)

repin.sh silently skips these — the operator has to know to bump them manually, or the re-pin is incomplete and check-self-bootstrap reds on the manually-omitted wrapper.

Empirical anchor

release-toolkit#294 (v0.21.0-rc.1 bootstrap re-pin) — repin.sh produced an initial commit that only bumped release.yml + manifest-check.yml; fragment-check.yml needed a manual follow-up commit on the same branch (7f41c79) to close the gap.

Plan

Two options:

  1. Static list keyed on check-self-bootstrap's DEFAULT_COMPOSE_SCRIPTS — reuse the same list the check already maintains for its diff-vs-pin logic. Single source of truth, both scripts always stay in lockstep.

  2. Dynamic discovery — grep .forgejo/workflows/*.yml for uses: frankenbit/release-toolkit/...@ lines + bump every match. More robust to future additions but harder to reason about.

(1) is probably right — the two lists conceptually describe the same set (toolkit-self consumer wrappers).

Tests: tests/repin.bats regression guard that walks discovered wrapper set + asserts each has been bumped.

Sibling substrate footgun

Same shape as release-toolkit#293 (CC-bullet dedup scope-as-issue-ref shape) — a mechanism that only covers its original scope silently missing newer additions. Both are "scoped-mechanism-vs-open-substrate" class.

Refs

## Scope `scripts/repin.sh` hardcodes `WRAPPER_GLOB=(.forgejo/workflows/release.yml .forgejo/workflows/manifest-check.yml)` — the two wrappers that existed when the script was written (release-toolkit#172 / #222). Newer wrappers added post-script: - `fragment-check.yml` (release-toolkit#278, v0.20.0) - Future: `changelog-body-check.yml` (release-toolkit#290 will add the toolkit-self dogfood) `repin.sh` silently skips these — the operator has to know to bump them manually, or the re-pin is incomplete and `check-self-bootstrap` reds on the manually-omitted wrapper. ## Empirical anchor release-toolkit#294 (v0.21.0-rc.1 bootstrap re-pin) — `repin.sh` produced an initial commit that only bumped release.yml + manifest-check.yml; `fragment-check.yml` needed a manual follow-up commit on the same branch (`7f41c79`) to close the gap. ## Plan Two options: 1. **Static list keyed on check-self-bootstrap's `DEFAULT_COMPOSE_SCRIPTS`** — reuse the same list the check already maintains for its diff-vs-pin logic. Single source of truth, both scripts always stay in lockstep. 2. **Dynamic discovery** — grep `.forgejo/workflows/*.yml` for `uses: frankenbit/release-toolkit/...@` lines + bump every match. More robust to future additions but harder to reason about. (1) is probably right — the two lists conceptually describe the same set (toolkit-self consumer wrappers). Tests: `tests/repin.bats` regression guard that walks discovered wrapper set + asserts each has been bumped. ## Sibling substrate footgun Same shape as [release-toolkit#293](https://git.frankenbit.de/frankenbit/release-toolkit/issues/293) (CC-bullet dedup scope-as-issue-ref shape) — a mechanism that only covers its original scope silently missing newer additions. Both are "scoped-mechanism-vs-open-substrate" class. ## Refs - Empirical anchor: [release-toolkit#294](https://git.frankenbit.de/frankenbit/release-toolkit/pulls/294) v0.21.0-rc.1 bootstrap re-pin - Related: [release-toolkit#293](https://git.frankenbit.de/frankenbit/release-toolkit/issues/293) (sibling scope-gap footgun) - Milestone: Set F candidate
Author
Owner

Severity recalibration per Surveyor 2acd on release-toolkit#294:

The WRAPPER_GLOB gap is bounded by the detector, not silent: had you forgotten the fragment-check fold, it'd sit at @v0.20.0 → UNIQUE_REFS=2 → single-ref-alignment fails loud in CI. So #295 is ergonomics (kill the manual fold), not a safety hole — substrate already blocks a mismatched re-pin from shipping.

Reclassifying this from "footgun" to "ergonomics" — the substrate has a fail-loud backstop (check-self-bootstrap catches any wrapper-glob omission at PR CI time). The manual fold cost is annoyance, not risk. #163 alignment-enforcement is the load-bearing safety mechanism.

Still worth fixing (kill the manual fold + prevent recurrence with a new wrapper add) but priority stays low — the safety-hole framing in the original scope was overstated. Option 1 (reuse check-self-bootstrap's DEFAULT_COMPOSE_SCRIPTS as single source of truth) remains the right implementation lean.

Sibling n=2 with release-toolkit#293: "scoped-mechanism-vs-open-substrate" ergonomics class (both are annoyance-when-missed, not risk-when-missed).

Severity recalibration per Surveyor `2acd` on [release-toolkit#294](https://git.frankenbit.de/frankenbit/release-toolkit/pulls/294): > The WRAPPER_GLOB gap is bounded by the detector, not silent: had you forgotten the fragment-check fold, it'd sit at @v0.20.0 → UNIQUE_REFS=2 → single-ref-alignment fails loud in CI. So #295 is ergonomics (kill the manual fold), not a safety hole — substrate already blocks a mismatched re-pin from shipping. Reclassifying this from "footgun" to "ergonomics" — the substrate has a fail-loud backstop (`check-self-bootstrap` catches any wrapper-glob omission at PR CI time). The manual fold cost is annoyance, not risk. `#163` alignment-enforcement is the load-bearing safety mechanism. Still worth fixing (kill the manual fold + prevent recurrence with a new wrapper add) but priority stays `low` — the safety-hole framing in the original scope was overstated. Option 1 (reuse `check-self-bootstrap`'s DEFAULT_COMPOSE_SCRIPTS as single source of truth) remains the right implementation lean. Sibling n=2 with [release-toolkit#293](https://git.frankenbit.de/frankenbit/release-toolkit/issues/293): "scoped-mechanism-vs-open-substrate" ergonomics class (both are annoyance-when-missed, not risk-when-missed).
Author
Owner

Scope widening per Surveyor 16b3 forward-looking finding on release-toolkit#298

Surveyor caught that the scoped-mechanism-vs-open-substrate class has more sites than repin.sh alone. Full inventory:

  1. scripts/repin.sh WRAPPER_GLOB (originally scoped): hardcoded .forgejo/workflows/release.yml + manifest-check.yml. Misses fragment-check.yml (v0.20.0/#278) + changelog-body-check.yml (v0.21.0/#290).

  2. reusable-release.yml auto-re-pin loops (NEW site per Surveyor): both path-α (~line 513) and path-γ (~line 562) for f in release.yml manifest-check.yml fragment-check.yml. changelog-body-check.yml is missing from both.

  3. tests/workflows.bats regression guards (guard-gap per Surveyor): the #278 guard covers reusable bake-lists but NOT consumer re-pin loops. A companion guard "every consumer wrapper in both auto-re-pin loops" closes it.

Immediate v0.22.0 cut-time consequence

v0.22.0's cut will run reusable-release.yml @v0.21.0-rc.1 (bootstrap-lag) — those runtime loops list only 3 wrappers. Post-cut auto-re-pin bumps 3 wrappers to @v0.22.0; changelog-body-check.yml stays at @v0.21.0-rc.1 (silent single-ref-alignment breakage the next PR-CI will red on).

Two paths for v0.22.0:

  • (A) Fix substrate before v0.22.0 cut — add changelog-body-check.yml to loops 513/562 + repin.sh WRAPPER_GLOB + companion guard. Then re-pin to v0.21.0-rc.2 so the cut runs with the widened loops. v0.22.0 cut goes clean.
  • (B) Accept manual fold at v0.22.0 cut-time — someone (Bosun/operator) manually re-pins changelog-body-check.yml after the cut, before merge-to-main. Same class fold as #294's fragment-check bump.

Path (A) closes the loop preemptively; path (B) treats this as "expected-cut-time manual step" per the #294 precedent. Routing the choice to Bosun (5f4c follow-up territory).

Severity re-recalibration

Bumping this from priority/lowpriority/medium because v0.22.0 cut is imminent + the guard-gap is a real repeat-recurrence risk. Still ergonomics-class (detector bounds it fail-loud in CI post-cut), but "wait for CI to catch it and manually recover" is worse ergonomics than "widen the mechanism to prevent the class."

Class n-count: n=3 confirmed instances (fragment-check missed at v0.21.0 via #294, changelog-body-check now, plus the #293 CC-bullet dedup as sibling shape). Meta-pattern surfacing.

## Scope widening per Surveyor `16b3` forward-looking finding on [release-toolkit#298](https://git.frankenbit.de/frankenbit/release-toolkit/pulls/298) Surveyor caught that the scoped-mechanism-vs-open-substrate class has **more sites than repin.sh alone**. Full inventory: 1. **`scripts/repin.sh` WRAPPER_GLOB** (originally scoped): hardcoded `.forgejo/workflows/release.yml` + `manifest-check.yml`. Misses `fragment-check.yml` (v0.20.0/#278) + `changelog-body-check.yml` (v0.21.0/#290). 2. **`reusable-release.yml` auto-re-pin loops** (NEW site per Surveyor): both path-α (~line 513) and path-γ (~line 562) `for f in release.yml manifest-check.yml fragment-check.yml`. **`changelog-body-check.yml` is missing from both.** 3. **`tests/workflows.bats` regression guards** (guard-gap per Surveyor): the #278 guard covers reusable bake-lists but NOT consumer re-pin loops. A companion guard "every consumer wrapper in both auto-re-pin loops" closes it. ## Immediate v0.22.0 cut-time consequence v0.22.0's cut will run reusable-release.yml @v0.21.0-rc.1 (bootstrap-lag) — those runtime loops list only 3 wrappers. Post-cut auto-re-pin bumps 3 wrappers to `@v0.22.0`; `changelog-body-check.yml` stays at `@v0.21.0-rc.1` (silent single-ref-alignment breakage the next PR-CI will red on). **Two paths for v0.22.0**: - (A) **Fix substrate before v0.22.0 cut** — add `changelog-body-check.yml` to loops 513/562 + repin.sh WRAPPER_GLOB + companion guard. Then re-pin to `v0.21.0-rc.2` so the cut runs with the widened loops. v0.22.0 cut goes clean. - (B) **Accept manual fold at v0.22.0 cut-time** — someone (Bosun/operator) manually re-pins `changelog-body-check.yml` after the cut, before merge-to-main. Same class fold as #294's fragment-check bump. Path (A) closes the loop preemptively; path (B) treats this as "expected-cut-time manual step" per the #294 precedent. Routing the choice to Bosun (`5f4c` follow-up territory). ## Severity re-recalibration Bumping this from `priority/low` → **`priority/medium`** because v0.22.0 cut is imminent + the guard-gap is a real repeat-recurrence risk. Still ergonomics-class (detector bounds it fail-loud in CI post-cut), but "wait for CI to catch it and manually recover" is worse ergonomics than "widen the mechanism to prevent the class." Class n-count: n=3 confirmed instances (fragment-check missed at v0.21.0 via #294, changelog-body-check now, plus the #293 CC-bullet dedup as sibling shape). Meta-pattern surfacing.
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#295
No description provided.