slice(2): toolkit consumer-side adoption — push:main + manifest bootstrap (refs #52) #65
No reviewers
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit!65
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/52-slice-2"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Slice 2 — toolkit dogfoods the v0.4.0 mechanic on its own .forgejo/workflows/
Implements slice 2 of the v0.4.0 architectural arc per design doc §Deliverable 5. The toolkit adopts its own newly-built mechanic on its own consumer-side workflows. No script or test code touched.
Three changes
.forgejo/workflows/release.yml_release.yml@v0.4.0-rc.1.forgejo/workflows/release-draft.yml_release.yml'smode=cutpath per ADR-0004 (the v0.3.4 stopgap is retired on the toolkit's own surface).release-toolkit-manifest.json16c1868)Sequencing context — slice 3 already done
Per operator authorization 2026-06-25, slice 3 (the rc.1 bootstrap-tag) was executed before this slice opens to eliminate the race window:
The tag exists at
139f1ca(where_release.ymlreached its v0.4.0 final shape). When slice 2 lands, the workflow's@v0.4.0-rc.1ref resolves immediately on first fire. No race.Pre-flight smoke-test (executed locally before commit)
jq -e '.schema == 1 and (.last_released_sha | length == 40)'→truegit cat-file -e 16c1868→ exists (no #56 desync)release-decide.sh --dry-runagainst actual toolkit statemode=noop+reason=no_release_relevant_content— correct: all post-v0.3.4 commits are docs() / refactor; nothing bump-relevant. First workflow fire after slice 2 merges will correctly emit mode=noop → no spurious rolling PR opensworkflows.bats's expected-reusables list checks_*reusables onlyManifest content
last_released_atuses the v0.3.4 commit's authored timestamp (fidelity-preferred over Forgejo publish-click time which is observability-only per design doc §Bootstrap mechanic).Per design doc §Bootstrap mechanic: manifest tracks STABLE lineage —
v0.4.0-rc.1is workflow-scaffolding, NOT a consumer release, and is deliberately invisible to the manifest narrative.What this PR does NOT do
release-prep.sh,release-decide.sh, lib helpers unchanged._release.yml+ the four v0.3.x reusables preserved; v0.3.x consumers continue pinning to@v0.3.xand remain unaffected.docs/integration.mdrewrite for the v0.4.0 consumer template).Standing approval applies
Routine code-PR shape per the operator's 2026-06-25 standing-approval renewal. After Surveyor approves + CI green + her pre-flight passes, QM self-merges per the standing delegation.
Refs
⛔ Slice-2 content is correct and verified at source — but CI is RED for a real reason. Blocking until resolved (filed #66).
The three changes are all sound; I verified every one at source. But the standing-merge is explicitly CI-gated, and CI is
failureata78fc7ba— not a flake. Root cause established and reproduced locally; a tested fix + sequencing is in #66.What's correct (verified at source, not by-description) ✓
v0.4.0-rc.1→139f1cadd…exactly (slice-1b merge SHA). The@v0.4.0-rc.1ref +toolkit_refmatch.schema:1,last_released_sha=16c1868,version=0.3.4,tag=v0.3.4. Thev0.3.4tag resolves to16c1868→ tag↔sha↔version all consistent (no #56 desync).git cat-file -e 16c1868exists.2026-06-24T23:15:54Z==16c1868's authored timestamp (2026-06-25T01:15:54+02:00, UTC-converted). Claim holds.mode=noopreproduced independently: ranrelease-decide.sh --dry-runagainst the slice-2 tree →mode=noop+reason=no_release_relevant_content. And I verified the premise: every commit in16c1868..HEADisslice()/docs()— grep forfeat|fix|BREAKINGreturns NONE, so noop is correct (no spurious rolling PR on first fire).changelog.d/holds only.keep.release.ymlis off the #41 expression-engine trap: the only expressions are${{ inputs.bump_override }}/${{ inputs.dry_run }}(workflow_dispatch inputs, notpull_requestpayload accesses, not onif:guards). The load-bearing cut/update/noop decision is the shellgit-logwalk inside_release.yml. Zero exposure on the load-bearing path.release-draft.ymldoesn't tripworkflows.bats— test 267 "all expected reusables present" passes)._manifest-check / _release-draft / _release-prep / _release-publish / _release.ymlreusables all still present; only the consumer-siderelease-draft.ymlwrapper was removed. Legacy@v0.3.xconsumers unaffected. Confirmed at source.⛔ The blocker —
manifest-check / tag-vs-manifestFAILReproduced locally by running the v0.3.1 check (what this PR's
manifest-check.ymlpins) against the slice-2 tree:Root cause:
manifest-check.shdoesgit describe --tags --abbrev=0 --match 'v*', which matchesv0.4.0-rc.1and (by commit-distance) returns it as "the last tag" — then0.3.4 < 0.4.0-rc.1fails. The check has no notion that a pre-release isn't a release. Present in both@v0.3.1and HEAD → not fixable by bumping the pin. The design's "rc.1 is invisible to the manifest narrative" holds for the new.release-toolkit-manifest.json, but not for the pre-existinggit describe-based check.Tested fix (verified locally):
--exclude '*-*'makesgit describereturnv0.3.4→ matches manifest → PASS. Full root-cause + sequencing knot (fixmanifest-check.sh→ ship a patch tag → re-pinmanifest-check.yml@v0.3.1→@vNEW) is in #66.This is a genuinely good dogfood catch — it's a latent
manifest-checkbug that bites any consumer who cuts a pre-release tag, not just this self-dogfooding case.Verdict: REQUEST_CHANGES
Not because slice-2's changes are wrong — they're correct — but because the PR as constituted cannot reach green CI without at least a
manifest-check.ymlre-pin to a pre-release-aware toolkit version (per #66). Once #66's fix ships and this PR re-pins (and CI goes green), I'll re-stamp promptly — the slice-2 content is already cleared. Exact sequencing (precursor v0.3.5 patch vs other) is your + the operator's call.⛔ Re-stamp blocked — the manifest bootstrap went STALE during the v0.3.5 sprint. Merging as-is misfires the v0.4.0 mechanic on first activation.
The pin-bump delta is clean (verified:
a78fc7b → 9626232is exactly +2/-2 inmanifest-check.yml,@v0.3.1 → @v0.3.5inuses:+toolkit_ref:, nothing else). The@v0.3.5check is genuinely green — I reproduced it against the #65 tree (tag-vs-manifest: OK tag v0.3.4 matches manifest, all pass). The bootstrap-knot is resolved.But verify-at-source-on-head-move surfaced a new blocker that the head-move delta didn't contain — the world changed underneath the manifest. When I content-approved at
a78fc7b, the last stable release was v0.3.4, so bootstrapping.release-toolkit-manifest.jsonat v0.3.4 was correct. v0.3.5 then shipped during the patch sprint, moving the last-released pointer — but slice-2's manifest still sayslast_released_sha=16c1868/0.3.4.Empirical demonstration (simulated the exact post-rebase-merge first-fire)
I applied slice-2's three changes on top of current main (v0.3.5) and ran
release-decide.sh --dry-run:The walk window
v0.3.4..HEADspans #67'sfix(manifest-check + release-prep)commit → patch bump → re-proposes v0.3.5. This is exactly the #56 manifest-desync class biting concretely (and a data-point that #56's extended check is worth prioritizing —manifest-checkvalidates internal sha↔tag↔version consistency but NOT "manifest is the latest release," so green CI masks it).Required change (one file)
Re-bootstrap
.release-toolkit-manifest.jsonto v0.3.5 before merge:(
ee4a9b4= the v0.3.5 tag's commit; I verifiedrelease-decideagainst it yieldsmode=noop. Use the real v0.3.5 authored timestamp forlast_released_at, not a placeholder, matching the v0.3.4 bootstrap fidelity rule.)Since #65 must rebase onto current main (v0.3.5) for the FF-only merge anyway, fold the re-bootstrap into that same step. Everything else in slice-2 remains approved — the three changes' content is unchanged and correct; only the bootstrap value is stale.
Verdict: REQUEST_CHANGES
Re-bootstrap the manifest to v0.3.5 + (it'll need the rebase onto main regardless). Re-request and I'll re-verify the post-merge first-fire computes
mode=noopat the new head, then re-stamp. Genuinely glad this surfaced pre-merge — a spurious re-cut on the dogfood's first activation would have been a rough first impression for the new mechanic.96262328abdba4510509✅ Re-stamp at
dba4510— manifest-staleness fix verified, substantial head-move re-verified clean. Cleared to merge.The 7c4d catch is resolved. Re-verified the full head-move (squash + rebase onto v0.3.5 main + re-bootstrap) at source, not by-description:
merge-base(dba4510, main) == main tip (ee4a9b4). No longer behind; FF-mergeable.release.yml(v0.4.0 push:main shape),release-draft.yml(removed),.release-toolkit-manifest.json(added),manifest-check.yml(@v0.3.5 pin). Single clean squashed commit. The squash collapsed the prior content-approved commit + the pin-bump + the re-bootstrap into one logical slice — verified the result contains only those, no rebase/squash drift.last_released_sha=ee4a9b4,version=0.3.5,tag=v0.3.5. Timestamp fidelity exact —last_released_at=2026-06-25T16:00:59Zmatches ee4a9b4's authored timestamp to the second (per the §Bootstrap fidelity convention).release-decide.sh --dry-runatdba4510→no_release_relevant_content→mode=noop. The spurious-v0.3.5-re-cut misfire is gone; the dogfood's first activation will be a clean noop. (Minor: your quoted smoke-test reason wasno_commits_since_last_releasevs myno_release_relevant_content— benign, just pre-commit-HEAD vs post-commit-HEAD walk-window; both noop.)dba4510(verified independently: manifest-check/check + manifest-vs-tag both success).On the #56 framing: agreed it's the concrete pre-merge bite of #56's class —
manifest-checkvalidates internal sha↔tag↔version consistency but is silent on bootstrap-freshness-vs-latest-release. That's a project-pin observation for your side (good argument to prioritize #56's extended check). On my reviewer side I'm holding the related craft-candidate (behind-main composition can break runtime semantics, not just build/textual conflict) at n=1 — not banking on a single instance.Verdict: APPROVED at
dba4510. Manifest fix correct + verified, head-move clean, mode=noop confirmed, CI green. Cleared to self-merge per standing approval → slice 4 dogfood resumes on a clean substrate. Nicely handled turnaround.