Skip to content
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 34 additions & 13 deletions docs/specs/AST-017/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ affects_consumer_docs: [release-process, templates]
"DEC-17",
"DEC-18",
"DEC-20",
"DEC-21",
"FR3",
"FR4",
"FR5",
Expand Down Expand Up @@ -650,15 +651,19 @@ one removal merged ahead of the decision to allow it.
or lowers the next plan. Merge-back preserves main's current declaration. When it
equals or falls below the released version, FR46's canary publication check emits no
prerelease at equality and fails below it.
- **FR51 — The next plan is an owner change separate from merge-back.** After FR50
lands, a separate pull request changes every fixed-group package version, every
generated exact internal pin, the lockfile, and version-stamped compatibility assets
to the next planned version. The default is the patch successor of the released
version. The minor successor is used only when Cindy explicitly names that minor as
the next plan; pending `[breaking]` Changesets are not that decision. Other main work
need not wait for this bookkeeping change, but FR46 suppresses canary publication
until the declaration is strictly above stable. If main already carries a newer
owner plan, FR50 preserves it and no duplicate bump is required. The plan remains
- **FR51 — The next plan is prepared at the cut and remains separate from merge-back.**
When a release cut succeeds, release tooling prepares one pull request from current
main that changes every fixed-group package version, every generated exact internal
pin, the lockfile, and version-stamped compatibility asset to the successor plan. The
default is the cut version's patch successor. The minor successor is used only when
Cindy explicitly names that minor as the next plan; pending `[breaking]` Changesets
are not that decision. The plan MUST NOT merge before an immutable tag or stable
package publication makes the cut version non-reusable. After that point it may land
through normal gates before or after FR50; merge-back preserves an already-landed
newer plan. A terminal cut with no immutable public identity closes its prepared plan
unmerged. If main already carries a newer owner plan, the prepared change closes or
refreshes instead of duplicating or lowering it. Other main work need not wait, and
FR46 remains the independent canary-publication safety boundary. The plan remains
malleable under FR46 until the next cut.
- **FR53 — Accessibility behavior fixes are not breaking.** A change whose purpose is
to make a released component conform to its accessibility target — a WCAG 2.2 Level
Expand Down Expand Up @@ -772,9 +777,10 @@ time: strictly above stable publishes, equality skips, and lower or split declar
fail closed. A release branch releases the cut's declaration unchanged and admits
incompatible work only when it is a minor; the Changeset cannot choose that version
itself. Published branch bytes squash back into current main without regeneration,
post-cut consumption, or plan changes. A separate owner change declares the next plan—
patch successor by default, minor only when Cindy names it—without holding unrelated
main work.
post-cut consumption, or plan changes. Release tooling prepares the separate successor
plan at cut time—patch by default, minor only when Cindy names it—and holds it until the
cut version becomes non-reusable. It may then land before or after merge-back without
holding unrelated main work; an unpublished terminal cut closes it unmerged.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This closes the plan for any unpublished terminal cut, but FR51 (lines 665–666) and DEC-21 close it only for a terminal cut with no immutable public identity, and FR51 lets the plan merge as soon as an immutable tag exists. For a cut that is tagged but never published the two rules disagree, and closing the plan there would leave main declaring an already-tagged version that FR49 refuses to release.

Suggested wording: "…; a terminal cut with neither an immutable tag nor stable package publication closes it unmerged."


These requirements alter no published package by themselves and need no Changeset.
Authoring helpers, validators, metadata projections, compatibility snapshots, release
Expand Down Expand Up @@ -805,7 +811,7 @@ lands, maintainers apply its requirement in review and release approval.
| FR48 | Category and classification admission under each declared tier | patch release with `[breaking]`, patch release with a deprecation, minor release with `[breaking]` | Incompatible work passes in a patch release, or a deprecation is refused in one |
| FR49 | Malformed and inconsistent declaration fixtures | disagreeing group versions, canary identifier, release version unlike the cut manifest, already-released version, skipped version, no stable tag | An untrustworthy or mismatched declaration is released |
| FR50 | Three-way squash merge-back fixtures bound to the immutable tag, branch head, and plan digest | exact branch outputs, frozen deletion, branch-only marker exclusion, post-cut Changeset/manifest edit, newer main declaration, merge conflict, regenerated output | Merge-back differs from release bytes, lands lifecycle files, consumes post-cut work, overwrites a newer main declaration or unrelated field, or chooses a version |
| FR51 | Separate next-plan manifest/pin/lockfile/compatibility-asset fixtures plus canary routing assertions | default patch successor, explicitly named minor, pre-advanced main plan, unrelated main work during equality | Equality publishes a canary, the default skips a patch, pending Changesets choose a minor, exact pins or compatibility assets split, or merge-back requires a duplicate bump for an existing newer plan |
| FR51 | Cut-time successor-plan preparation plus manifest/pin/lockfile/compatibility-asset and lifecycle fixtures | default patch successor, explicitly named minor, no-publication abort, immutable tag before merge-back, pre-advanced main plan, unrelated main work during equality | The plan merges before the cut version is non-reusable, survives an unpublished terminal cut, skips the default patch, derives a minor from pending Changesets, splits pins/assets, or merge-back lowers or duplicates an existing newer plan |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: this row lists pre-advanced main plan, but its only matching failure is "merge-back lowers or duplicates an existing newer plan", while FR51 now gives that duty to the prepared change ("the prepared change closes or refreshes instead of duplicating or lowering it"). unrelated main work during equality also lost its expectation when "Equality publishes a canary" was dropped (FR46's row still covers canary equality).

A minimal fix: end the failure cell with "…, or the prepared plan or merge-back lowers or duplicates an existing newer plan", and either drop the equality state or pair it with "unrelated main work waits for the plan".

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same mismatch here: the no-publication abort state and the "survives an unpublished terminal cut" failure would require closing a tagged-but-unpublished plan that FR51 lets merge. Suggested: the state "abort before any tag or publication" and the failure "survives a terminal cut with neither an immutable tag nor stable publication".

Optionally, the pre-advanced main plan failure could also name the prepared plan ("…, or the prepared plan or merge-back lowers or duplicates an existing newer plan"), since FR51 now gives that duty to the prepared change.

| FR53 | Changeset classification review against the governing component record's accessibility evidence | a fix that replaces documented keyboard or focus behavior to meet an adopted APG pattern's required parts; a fix that changes a role, state, or accessible name to meet WCAG 2.2 A/AA; a fix that adds an optional prop | An accessibility fix is held for a minor, given a coexistence path, or classified `[breaking]`; or a change that needs an app-layer code edit, or that removes, renames, or narrows public surface, ships as an accessibility `[fix]` |

## Decision log
Expand Down Expand Up @@ -1185,6 +1191,21 @@ or keyboard behavior. The boundary is the public surface: the fix needs no app-l
Rejected: classifying accessibility corrections as breaking whenever a released
caller observes the old behavior, which delays every conformance fix to a minor.

### DEC-21 — The cut prepares but does not authorize the successor plan

**Reference:** `spec:AST-017/DEC-21`
**Decider:** `cixzhang`, 2026-10-14

The cut knows the default successor and every file that must move together, so it
prepares the separate plan change immediately. That change cannot merge until an
immutable tag or stable package publication makes the cut version non-reusable. It may
then land before or after merge-back because FR50 preserves a newer main declaration.
A terminal cut with no immutable public identity closes the prepared change unmerged.

Rejected: merging the successor before the cut version becomes non-reusable, which
strands an unpublished terminal cut on a skipped plan; and waiting until merge-back to
prepare information already fixed at the cut.

## Open questions

None.
Loading