release: breaking/* labels become enforced version policy; tear guard; cut notes - #223
Merged
Conversation
…; cut notes
Breaking changes are now declared by PR label — breaking/{runtime,
translator,wasi,ct-runner,protocol}, one per package whose published
surface the PR breaks; no label means caret-compatible. Labels are
mutable and read LIVE everywhere they are consulted, so retroactively
correcting a merged PR's labels is a supported workflow: the cut re-reads
the whole window.
tools/version-guard/check.ts enforces the policy at three points:
- pr (gha::core, first step; no-op without PR_NUMBER): lockstep
agreement, monotonicity against the last cut, breaking-label <->
minor-bump agreement in both directions, and the protocol-tear early
warning. Advisory by design — label edits do not re-trigger CI.
- publish (release.yml, both modes, before deno publish): the
authoritative tear guard. When protocol's manifest version is already
on JSR, the in-tree protocol must be byte-identical to the published
files (both directions, via the version _meta.json checksums) —
otherwise this run would skip protocol as already-published and ship
every dependent against the registry's older copy. That is the #219
tear (published protocol@0.2.0 was missing the A20 exports
runtime@0.4.0-pre.* imported; repaired by #221), and it lands here
rather than at PR time because PR checks race publish-on-green-main:
#219's last CI run predated the prerelease that burned 0.2.0. Exact
identity is deliberate; softer canonicalizations are parked in #222.
- cut (release=true): the window's PRs since the last cut tag, with
their labels as they exist AT CUT TIME, become the minor-bump
requirement — and the notes fragment (Breaking / Changes, PR titles,
direct commits) that replaces the boilerplate-only release notes.
AGENTS.md gains the labeling policy and a six-step cutting-a-release
runbook; the sanity pass over the window's titles and diffs is first,
because a MISSING breaking label is the one failure mode every
mechanical check here is blind to.
30 unit tests over injected effects (no network); live smokes: publish
mode PASSes against the published protocol@0.2.1 and reproduces the
exact #219 failure shape against 0.2.0 (--protocol-version override);
cut mode against the real v0.3.1..HEAD window finds #216's labels and
renders the fragment.
lannbot
enabled auto-merge
August 22, 2026 21:24
lann
disabled auto-merge
August 22, 2026 21:26
…side Every green main still gets its pre-<shorthash> GitHub release with the full artifact set (translator shim wasm, embedder bundle, SHA256SUMS) — the cut guard's green-pipeline proof keeps working — but nothing is published to JSR or npm between cuts anymore: - release.yml: the JSR publish and the npm dispatch are release-mode only; the prerelease version-stamping loop is gone (with it, the g-prefix leading-zero machinery); prerelease notes say what a prerelease now is — artifacts for a green commit. The protocol identity guard stays in BOTH modes: authoritative at the cut, pure early detection on the prerelease path (red = the next cut would tear). - ci.yml: the release job's permissions trim to contents:write — the prerelease path needs neither JSR OIDC nor the npm dispatch; cuts enter release.yml via workflow_dispatch under its own block. - npm-publish.yml: pre-* tags are refused rather than computed, which gives the release:published backstop teeth — a hand-made GitHub prerelease can start the workflow but cannot publish. All surviving versions are bare cuts, so the loop publishes --tag latest unconditionally; the npm pre dist-tag is retired and frozen wherever it last pointed. - version-guard: logic untouched (30 tests green); comments rewritten off the publish-on-green-main race framing — publishes now happen only at explicit cuts, and publish mode stays authoritative there because PR-time verdicts still miss post-run label edits, direct pushes, and their own staleness. The tear check's merged-PR-replay note corrected: a merged protocol bump now stays unpublished until the cut, so replays pass. - README §Consuming, docs/consumers.md, AGENTS.md: tracking main between cuts = GitHub release assets or git refs; the -pre.g* versions on JSR and npm's pre dist-tag are frozen leftovers of the earlier flow. A side benefit worth naming: version burning at every green main was the mechanism behind the #219 tear (a 'pending' version published out from under a concurrent branch); with cut-only publishing that entire race class is gone.
lannbot
enabled auto-merge
August 22, 2026 21:34
…ired The #223 trim to contents:write failed the whole CI workflow at startup: a reusable-workflow call is validated against the CALLED workflow's permissions block, and the caller must grant everything it requests — if-skipped steps included. The tokens are inert on the prerelease path (the spending steps are if: inputs.release, which workflow_call cannot set); the comment now records the rule so the trim is not re-attempted.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the label-tracked breaking-change policy discussed for the upcoming cut, plus the guards that make it enforced rather than remembered.
Policy. Breaking changes are declared by PR label —
breaking/{runtime,translator,wasi,ct-runner,protocol}(already created), one per package whose published surface breaks; no label = caret-compatible. Labels are read live everywhere they're consulted, so retroactive label fixes on merged PRs are supported and feed enforcement at cut time.Guards (
tools/version-guard/check.ts, 30 unit tests over injected effects):pr— first step ofgha::core, no-op outside PR runs: lockstep agreement, monotonicity vs the last cut, label ↔ minor-bump agreement both directions, protocol-tear early warning. Advisory (label edits don't re-trigger CI; a re-run picks up fixes).publish— release.yml, both modes, beforedeno publish: the authoritative tear guard. If protocol's manifest version is already on JSR, in-tree protocol must be byte-identical to the published files (bidirectional, via the_meta.jsonchecksums). This is the embedder: structured-clone-safe boundary forms (A20, #131) #219 tear (repaired by protocol: 0.2.1 — republish the A20 exports burned out of 0.2.0 #221) made loudly red at the only point that doesn't race publish-on-green-main. Exact identity by design; softer canonicalizations parked in version-guard: softer canonicalizations for the protocol tear guard (parked alternatives) #222.cut— release=true only: re-reads the window's PR labels as of cut time, requires the matching minor bumps, and renders Breaking/Changes release-notes sections from PR titles (direct pushes listed by commit) — cut releases stop having boilerplate-only notes.Runbook. AGENTS.md gains the labeling policy and a six-step cutting-a-release runbook; step 1 is the human sanity pass over the window's titles/diffs vs labels, because a missing breaking label is the one failure mode the mechanical checks are blind to.
Live smokes:
publishPASSes against the published protocol@0.2.1 and reproduces the exact #219 failure shape when pointed at 0.2.0;cutagainst the real v0.3.1..HEAD window finds #216's labels and renders the fragment. This PR's own CI exercisesprmode for real (no labels, no bumps — all checks should pass).No breaking labels: nothing here touches any published package surface.