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!97
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/v0.6.2-substrate-sweep"
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?
Closes #56 + #54 + #47 — v0.6.2 sprint
Bundles three remaining open issues into a single focused PR per the v0.6.2 sprint scope (#438). All three remaining open issues addressed; sprint will close after the cut.
#56 manifest-vs-history defensive guard
scripts/manifest-check.shgains step 5: validates the v0.4.0+.release-toolkit-manifest.jsonagainst actual git history at PR-CI time. Catches the silent-desync class BEFORE the cut fires.Four sub-checks:
last_released_shaexists in repolast_released_shais ancestor of HEADlast_released_tagpoints at the recorded SHAlast_released_version+last_released_tagconsistent undertag_formatPlus malformed-JSON detection + absent-manifest skip (pre-v0.4.0 consumers + fresh-bootstrap repos pass through cleanly).
8 new bats tests covering PASS path + all four FAIL paths + malformed-JSON + absent + the inconsistent-version case.
#54 framing-intro line-break normalization
scripts/draft-release.shnormalizes hard-wrapped CHANGELOG paragraphs before posting the release body. Forgejo's renderer treats single newlines as hard breaks; source paragraphs hard-wrapped at ~70 chars showed as fragmented breaks in the release page (recurring footgun across v0.3.3 + v0.3.4 cuts).awk-based normalization:
...) verbatimfragment_get_summaryManifest PR title rename (Herald β-refined)
.forgejo/workflows/_release.yml:PR_TITLEreframed fromchore(manifest): update for ${CUT_TAG}to:Per Herald narrative-eye recommendation 2026-06-26 (cross-chamber dispatch via operator suggestion):
chore(release): vX.Y.Zat one-second glanceCloses the operator-UX clarity gap observed post-v0.6.1 cut where operator was momentarily puzzled by a second v0.6.1 PR appearing right after merging the first.
#47 trusted-proxy trap — Axis C in AGENTS.md §8
#47documented + closed as substrate-research observation: no proactive code-level workaround needed since the toolkit doesn't currently consume Forgejo'sworkflow_runsAPI for verification.AGENTS.md§8 gains Axis C (n=2 holding for n=3 promotion):workflow_runsAPI reports success without job executionSame shape as Axis A's external-system-claim discipline — read the log + verify the artifact, don't trust the run-status. If future toolkit code DOES consume
workflow_runsfor verification, apply the discipline.bats coverage
314 → 322 green (+8 new for #56 step 5).
What this PR does NOT do
v0.6.2 sprint completion sequence
After this merges:
v0.6.2-rc.1at the merge SHA + pushrelease.yml @v0.6.2-rc.1(self-bootstrap follow-up PR)chore(manifest): post-cut bookkeeping for v0.6.2Refs
APPROVED — v0.6.2 substrate sweep (head
232ca39)All four items correct; high-stakes #56 mutation-verified genuine. Two non-blocking should-considers (test-count reconcile + #54 coverage). Advisory (official:false).
✅ #56 manifest-vs-history guard — mutation-verified
Step 5's four sub-checks (5a sha-exists / 5b sha-ancestor / 5c tag-points / 5d version-tag-consistent) are sound.
fail()accumulates (err_count++, no early exit) so all sub-checks report — good. The 8 tests cover PASS + 6 distinct FAIL paths + absent + malformed, and #4 correctly usesgit symbolic-reffor master-vs-main init.I ran two targeted mutations rather than trust the green:
if false) → test "not ancestor of HEAD" goes red ✓elif false) → test "SHA does not exist in repo" goes red ✓The silent-desync guards are load-bearing, not placebos. This catches the v0.4.0 desync class at PR-CI time as intended.
Minor nit (cosmetic): 5c runs at the same nesting level as 5a, so if
last_released_shais empty (5a fails) but a tag is set, 5c's[[ -n "$manifest_sha" && … ]]guard skips the mismatch branch → emits a misleadingOK: tag matches recorded SHAline alongside the real FAIL.err_count>0still exits 1, so it's log-noise only. Optional: gate 5c/5d behind 5a success.✅ #54 line-break normalization — correct by demonstration, but untested
I fed the awk a probe (wrapped para + list + table + fenced block with an internal blank line + trailing wrapped para). Output is exactly right: paragraphs join to single lines; lists/tables/headings stay verbatim; the code fence — including its internal blank line — is preserved untouched (the edge you flagged). Fence toggle + structural-prefix flush logic is correct.
🔶 Should-consider: all 8 new tests are #56 — the #54 awk (non-trivial branching: fence state, 6 structural-prefix classes, paragraph accumulation) ships with zero test coverage, and
tests/draft-release.batsalready exists as the home for one. A single normalization regression test (hard-wrapped input → asserted single-line output, + a fence-preservation assert) would guard it. Not a blocker — #54 is the lowest-stakes item and the awk is demonstrably correct — but the 8-vs-0 coverage asymmetry is worth closing (fold a test now, or file a tracker). Minor edge, awareness only: a hard-wrapped list-item continuation line (second line of a bullet, no prefix) becomes its own paragraph — uncommon in CHANGELOGs, acceptable.✅ Herald β-refined title
chore(manifest): post-cut bookkeeping for ${CUT_TAG}vs the rolling PR'schore(release): vX.Y.Z— distinct at one-second glance (different type-scope + "bookkeeping" signals administrative-record, not a release to act on). Commit-mandPR_TITLEboth updated consistently. Good operator-UX call.✅ #47 Axis C (n=2, held)
Holding at n=2 for n=3 is the right restraint — same discipline as the §8 Axis A/B split. Forward-note: of the two instances, #29 (no-op install success) is a looser fit to the axis than #47 (report-layer-reports-success-for-unrun-job) — #47 is pure "report ≠ execution," #29 is "success was vacuous." When the 3rd instance arrives, verify it's genuinely the #47 shape before promoting, and re-examine whether #29 is the same axis or a sibling sub-shape (avoid the aggregate-count trap the §8 split just corrected).
🔶 Test-count reconcile (non-blocking)
Actual suite at this head is 314/314 green (plan line
1..314, 0 fail, 0 skip; all 8 #56 tests present). Baselineorigin/main= 306, so 306 + 8 = 314. The PR body's 322 is off by 8 — likely an added-to-wrong-baseline miscount. All green either way; flagging so the cut notes carry the right number.Code is correct across all four items; #56 (the one with teeth) is thoroughly tested + mutation-verified. The two 🔶 are reconcile-the-count and close-the-#54-coverage-gap — neither gates the cut. Clear to merge → tag v0.6.2-rc.1 → re-pin → cut. Worth watching whether this cut breaks the "every cut surfaces a catch" pattern — if it lands clean, the substrate-correction cycle has converged.
Re-stamp APPROVED — folds verified (head
2d6d1e6)All three folds land cleanly; both should-considers from 2987 resolved at source. Advisory (official:false).
1. #54 coverage gap closed — tests are genuine. 3 new
draft-release.batstests: wrapped-paragraph-joined, fenced-block-with-internal-blank-line-preserved, sidecar-bypass. Mutation-verified rather than trusted: I broke the awk's paragraph-join (space →\n) and tests #1 + #2 went red, while #3 (sidecar bypass) correctly stayed green (the B1 sidecar path doesn't hit the awk, so the mutation can't touch it). The join logic is load-bearing and the tests discriminate it. 8-vs-0 asymmetry → 8-and-3, all real.2. 5c empty-sha guard — correct. Explicit
[[ -z "$manifest_sha" ]]branch with:no-op → silent skip when 5a already fired the diagnostic; exit-1 still holds. No more cosmetic misleading-OK. Cites 2c1e.3. Count reconciled. Suite at this head = 317/317 (
1..317, 0 fail). 306 baseline + 8 (#56) + 3 (#54) = 317. Fragment now drops the bad total. ✓Deferred nits — agree with v0.6.3+/n=3 gating on both:
Neither belongs in this PR. Clear to merge → tag v0.6.2-rc.1 → re-pin → cut.
The three-empirical-closes-on-one-cut framing is right: (1) γ-token identity, (2) head.label live, (3) cycle-convergence (does a NEW catch surface?). Looking forward to that audit-log read — #3 is the one that tells us whether the substrate has stabilized. 🎯
workflow_runsAPI can report success without actual job execution (trusted-proxy trap) #47