"Durable release trigger - version bumps drop [skip ci] so tag pushes fire release.yml natively"
TASK-IMP-071: Durable release trigger
§1 - Description
- version.yml's bump commit MUST NOT carry
[skip ci]; the message stayschore(release): vX.Y.Z. - The workflow's own loop protection MUST rest solely on the existing job guard (
!startsWith(head_commit.message, 'chore(release):')), documented as the single brake. - The TASK-DOCS-007 §1 #4c deploy-dispatch workaround MUST be removed (deploy.yml's VERSION path filter now fires natively on the bump push); the
actions: writepermission it needed goes with it. - TASK-IMP-068 §1 #7's inline proof MUST remain (belt-and-suspenders now that payload-gate also sees bump commits), with its comment updated; both affected shipped tasks carry post-ship amendment notes.
- RELEASE.md MUST document the new model:
git push origin vX.Y.Ztriggers the release; dispatch remains the fallback/retry path.
§2 - Why this design
[skip ci] suppressed MORE than the loop it guarded against - it silenced tag pushes and the docs deploy, costing a manual dispatch per release plus a dispatch workaround. The message-prefix guard was already the real loop brake; removing the blunt instrument leaves exactly one, documented mechanism.
§3 - Contract
Bump commit: chore(release): X.Y.Z (no suffix). Loop brake: version.yml job if guard only.
§4 - Acceptance criteria
- No [skip ci] anywhere live (§1 #1) - grep on version.yml's commit line is clean; RELEASE.md describes the new model.
- Guard is sole + documented (§1 #2) - the job
ifsurvives; comments name it the single brake. - Workaround retired (§1 #3) - no
gh workflow run deploy.ymlin version.yml;actions: writegone. - Amendments recorded (§1 #4) - TASK-IMP-068 + TASK-DOCS-007 specs carry the notes.
§5 - Verification
Grep-level asserts (executable): ! grep -q 'skip ci]' .github/workflows/version.yml commit line; grep -q "single brake\|ONLY loop guard" version.yml; ! grep -q "workflow run deploy" version.yml; amendment greps on both specs. Live proof: the next bump push must show payload-gate + deploy runs on the bump commit, and the next git push origin vX.Y.Z must start release.yml without dispatch (operator-observed, recorded at the next release).
§6 - Implementation skeleton
Three-line yaml change + comment updates + doc + two amendment notes.
§7 - Dependencies
None. Interacts with TASK-IMP-068 (inline proof kept) and TASK-DOCS-007 (workaround retired).
§8 - Example payloads
chore(release): 0.5.0 -> payload-gate ✓, deploy(docs) ✓, version.yml skipped by guard; git push origin v0.5.0 -> release run starts.
§9 - Open questions
None blocking.
§10 - Failure modes inventory
- Guard weakened in a future edit -> bump loop; the comment names it the single brake and RELEASE.md repeats it.
- A human commit starting
chore(release):skips version.yml -> by design (that IS the release-commit namespace). - payload-gate red on a bump commit -> impossible-by-construction drift becomes visible instead of silent; exactly what the gate is for.
- Rulesets block the bump push -> unchanged degrade-to-warning path.
- Old tags on [skip ci] commits -> historical; dispatch fallback still cuts them.
§11 - Implementation notes
Batch-mode ship under the operator's standing verdict; live-proof clause lands at the next release (operator observation recorded then).
End of TASK-IMP-071.
Audit
TASK-IMP-071 audit
§1 - Verdict summary
Audited for loop safety above all: the message-prefix job guard predates this change, is orthogonal to [skip ci], and becomes the documented single brake (§10 #1 names the weakening risk). Workaround retirement verified by grep; amendments close the two shipped tasks' stale premises. TRACE: #1->AC1, #2->AC2, #3->AC3, #4->AC4; §5 greps executable; live-proof clause deferred to the next release by design (operator-observed).
§2 - Findings (resolved during authoring)
ISS-001 dropping [skip ci] could re-trigger version.yml itself - resolved: the job guard already short-circuits chore(release): head commits (§1 #2). ISS-002 the retained actions:write permission would outlive its consumer - resolved: removed with the dispatch step (§1 #3).
§3 - Resolution
Score = 10/10.
Ship record (2026-07-12, batch mode)
Implemented + grep-verified in one leg; HITL per the operator's standing batch verdict. Live proof (native tag-push trigger) records at the next release.