From a19a1e5ea7a220478f0c14149c4d4046dadace9e Mon Sep 17 00:00:00 2001 From: Cindy Zhang Date: Mon, 12 Oct 2026 21:46:08 -0700 Subject: [PATCH 1/3] spec(release): prepare successor plan at cut time --- docs/specs/AST-017/spec.md | 47 +++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/docs/specs/AST-017/spec.md b/docs/specs/AST-017/spec.md index 6025d873effa2..67855bf791dd1 100644 --- a/docs/specs/AST-017/spec.md +++ b/docs/specs/AST-017/spec.md @@ -48,6 +48,7 @@ affects_consumer_docs: [release-process, templates] "DEC-14", "DEC-17", "DEC-18", + "DEC-19", "FR3", "FR4", "FR5", @@ -641,15 +642,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. ### Platform support @@ -747,9 +752,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. These requirements alter no published package by themselves and need no Changeset. Authoring helpers, validators, metadata projections, compatibility snapshots, release @@ -780,7 +786,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 | ## Decision log @@ -1143,6 +1149,21 @@ before merging, which duplicated the Changeset and made bookkeeping the blocker; per-record transition requirement and waiver, which the patch rule already expresses; and dropping the manifest, which would lose the minor's migration inventory. +### DEC-19 — The cut prepares but does not authorize the successor plan + +**Reference:** `spec:AST-017/DEC-19` +**Decider:** pending owner review + +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. From 525d2d5602efebae9996e9003af2b8089623ef4e Mon Sep 17 00:00:00 2001 From: Cindy Zhang Date: Wed, 14 Oct 2026 20:41:01 -0700 Subject: [PATCH 2/3] spec(AST-017): record cixzhang as DEC-21's decider --- docs/specs/AST-017/spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/specs/AST-017/spec.md b/docs/specs/AST-017/spec.md index 4cb033c810b86..05f2c5ed9d12c 100644 --- a/docs/specs/AST-017/spec.md +++ b/docs/specs/AST-017/spec.md @@ -1194,7 +1194,7 @@ 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:** pending owner review +**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 From 6eaab961e3d37a614071c1089abd2f8e66882c94 Mon Sep 17 00:00:00 2001 From: Cindy Zhang Date: Thu, 15 Oct 2026 04:41:48 -0700 Subject: [PATCH 3/3] spec(AST-017): one close condition for the prepared plan in FR51, DEC-21, impact, and verification --- docs/specs/AST-017/spec.md | 62 ++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/docs/specs/AST-017/spec.md b/docs/specs/AST-017/spec.md index 88d52f8d174d6..94a90a0e06ef3 100644 --- a/docs/specs/AST-017/spec.md +++ b/docs/specs/AST-017/spec.md @@ -662,8 +662,8 @@ one removal merged ahead of the decision to allow it. 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 + newer plan. A terminal cut with neither an immutable tag nor stable package + publication 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. @@ -793,7 +793,8 @@ itself. Published branch bytes squash back into current main without regeneratio 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. +holding unrelated main work; a terminal cut with neither an immutable tag nor stable +package publication closes it unmerged. Codemod promotion relocates staged transform source into the immutable release folder. Repository evidence that reads a transform follows that lifecycle location and treats a @@ -806,31 +807,31 @@ lands, maintainers apply its requirement in review and release approval. ## Verification -| Contract | Verification | Representative states | Mutation or failure expectation | -| --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FR1–FR3 | PR compatibility statement plus latest stable package inspection | released export, narrowed type, changed interaction default; unreleased and private surface; visual-only spacing, typography, layout styling, or default appearance | A change is labeled from diff size or possibility alone, a functional contract loss is hidden as visual-only, or a pixel-only change is tagged `[breaking]` even though callers need no source or configuration change | -| FR4–FR6 | Old-usage type/runtime/CLI regression test | alias retained, deprecation warning, broad rewrite, low-adoption caller | Contractual old usage fails despite a nonbreaking label, or risk is substituted for compatibility | -| FR7–FR8 | `pnpm check:changesets` (tag, bump, contributors, declared tier) plus FR8 migration review of `[breaking]` text | existing `[fix]`, `[feat]`, `[breaking]`, and `[experimental]` tags paired with compatible, deprecation, planned-removal, or incompatible-fix metadata | A new lifecycle replaces an established tag, tag/metadata/bump diverge, an incompatible correction uses bare `[fix]`, or migration is unusable | -| FR9–FR13 | CLI contract tests, response-schema/type snapshots, text projections, generated consumer docs, and template catalog/output tests | slug rename, metadata edit, source rebuild, optional field addition, command or schema change | Catalog data is frozen as API, a command/schema incompatibility is mislabeled as catalog-only, or a response field lacks a complete projection | -| FR12 | Minimum and representative supported-version tests plus manifest and release-note review | retained range, narrowed range, adapter, coordinated upgrade | An in-range combination breaks under a nonbreaking label, or release coordination hides the affected package or migration | -| FR14 | Help/manifest snapshots, public API and consumer docs, and focused contract tests | command, option, API/config, private rollout/test hook | Supported behavior is hidden, an environment variable changes behavior, or automation lacks a documented API | -| FR15 | Full manifest-derived command matrix, supported-consumer evidence, and scope-specific contract tests | global invariant, scoped command group, single command, programmatic API | A global control is a no-op for any command, has different meanings, or replaces a narrower owning surface | -| FR16–FR18 | Boundary inventory, hostile side-effect probes, response snapshots, and concurrent API tests | known and new extension, partial result, text/JSON/API parity, independent concurrent calls | A route bypasses the guarantee, omitted work looks complete, or one invocation changes another | -| FR19–FR20 | Proposal evidence with a regression fixture for the detection failure, plus composition and provenance tests | convention covers the case, detection fails, app plus two integrations, refusal, failing contribution, repeated load | A key ships without a reproduced detection failure, a contribution displaces the app or applies twice, a part of the effective value has no inspectable source, or a failure silently weakens protection | -| FR21–FR24 | Published-surface comparison, declaration/doc metadata checks, import-boundary checks, and Changeset classification review | experimental prop object, experimental subpath, patch evolution, promotion, unpublished adjacent field, stable warning behavior, integration theme | A prose-only marker excludes a stable API, adjacency falsely publishes a new field, an experimental export leaks through a stable path, a patch changes stable behavior, or a promoted API remains unprotected | -| FR25–FR27 | Stable-surface inventory and experimental-boundary matrix | package/API, CSS/token, CLI/config, persistence, build tooling, docs, whole Lab component | An unmarked experiment changes stable defaults or a stable surface bypasses compatibility review | -| FR28–FR31 | Declared-tier check: on a minor, the `[breaking]` Changeset describes the change (old usage, replacement, migration); on a patch, a breaking Changeset is refused and the deprecation ships instead; declaration/doc/build/CLI warning projections; old/new fixtures; dry-run/idempotence/migration tests; maintained-source and latest-stable upgrade evidence | whole component, prop/value, theme field/helper/token/target/source, CLI command, CLI option; old-only, new-only, both, static/dynamic/uncertain migration, text/JSON, development/production | A warning has no usable modernization route, production runtime changes for deprecation, maintained guidance teaches the old surface, a migration guesses, old behavior degrades early, cadence invents a wait, or one cleanup id covers multiple incompatible deltas | -| FR32–FR35 | Latest-stable victim fixture, pre-existing authority named in the Changeset or pull request, owner review, declared-tier check, and emergency attestation | victim-free `[fix]`, `[fix]` plus incompatible-fix metadata, coexistence, cleanup transition, critical-harm emergency | A released victim uses bare `[fix]`, a new Changeset tag replaces metadata, a correction record disagrees with its public-surface state, or urgency bypasses migration | -| FR36–FR40 | Owner-declared target, locked final-patch receipt, three-way delta classification against the merged `[breaking]` Changesets, and separated release notes | ordinary cadence, immediate pair, cleanup, release metadata, pre/post-lock compatible fix | Cadence becomes eligibility, the final patch is recut for bookkeeping, a feature or incompatible fix enters the incidental-fix lane, or release notes merge cleanup with fixes | -| FR41–FR44 | Schema validation, PR declaration, semantic stable/base/head comparisons, exact-main gate, and immutable publish/rollback receipt | duplicate ids, missing evidence, route/schema removal, old-client metadata, partial publish, safe rollback | A label passes without semantics, a delta maps zero or multiple times, fixed-group membership drifts, or a release rebuilds under one identity | -| FR45 | Docs route inventory, repository-reference checks, and Changeset review | catalog entry rename, former-route miss, stable command and JSON schema | Catalog routing is frozen as API, or a rename silently changes the contractual command or response schema | -| FR46–FR47 | Declared-tier Changeset admission, canary publication ordering, and release-versioning fixtures | owner increase/decrease, above/equal/below stable, split group, `[breaking]` on patch and minor plans | Pending Changesets derive the plan, `[breaking]` passes on a patch or fails on a minor, equality publishes a canary, or a lower/split declaration publishes instead of failing | -| 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 | 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 | -| FR52 | Promotion fixtures plus every checked-in source consumer run before and after codemod promotion | staged transform, promoted transform, missing source, ambiguous candidates, changed entry identity | Evidence hardcodes only `next/`, keeps a duplicate source, silently chooses among candidates, or passes when the promoted transform no longer exposes the same identity and entries | -| 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]` | +| Contract | Verification | Representative states | Mutation or failure expectation | +| --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FR1–FR3 | PR compatibility statement plus latest stable package inspection | released export, narrowed type, changed interaction default; unreleased and private surface; visual-only spacing, typography, layout styling, or default appearance | A change is labeled from diff size or possibility alone, a functional contract loss is hidden as visual-only, or a pixel-only change is tagged `[breaking]` even though callers need no source or configuration change | +| FR4–FR6 | Old-usage type/runtime/CLI regression test | alias retained, deprecation warning, broad rewrite, low-adoption caller | Contractual old usage fails despite a nonbreaking label, or risk is substituted for compatibility | +| FR7–FR8 | `pnpm check:changesets` (tag, bump, contributors, declared tier) plus FR8 migration review of `[breaking]` text | existing `[fix]`, `[feat]`, `[breaking]`, and `[experimental]` tags paired with compatible, deprecation, planned-removal, or incompatible-fix metadata | A new lifecycle replaces an established tag, tag/metadata/bump diverge, an incompatible correction uses bare `[fix]`, or migration is unusable | +| FR9–FR13 | CLI contract tests, response-schema/type snapshots, text projections, generated consumer docs, and template catalog/output tests | slug rename, metadata edit, source rebuild, optional field addition, command or schema change | Catalog data is frozen as API, a command/schema incompatibility is mislabeled as catalog-only, or a response field lacks a complete projection | +| FR12 | Minimum and representative supported-version tests plus manifest and release-note review | retained range, narrowed range, adapter, coordinated upgrade | An in-range combination breaks under a nonbreaking label, or release coordination hides the affected package or migration | +| FR14 | Help/manifest snapshots, public API and consumer docs, and focused contract tests | command, option, API/config, private rollout/test hook | Supported behavior is hidden, an environment variable changes behavior, or automation lacks a documented API | +| FR15 | Full manifest-derived command matrix, supported-consumer evidence, and scope-specific contract tests | global invariant, scoped command group, single command, programmatic API | A global control is a no-op for any command, has different meanings, or replaces a narrower owning surface | +| FR16–FR18 | Boundary inventory, hostile side-effect probes, response snapshots, and concurrent API tests | known and new extension, partial result, text/JSON/API parity, independent concurrent calls | A route bypasses the guarantee, omitted work looks complete, or one invocation changes another | +| FR19–FR20 | Proposal evidence with a regression fixture for the detection failure, plus composition and provenance tests | convention covers the case, detection fails, app plus two integrations, refusal, failing contribution, repeated load | A key ships without a reproduced detection failure, a contribution displaces the app or applies twice, a part of the effective value has no inspectable source, or a failure silently weakens protection | +| FR21–FR24 | Published-surface comparison, declaration/doc metadata checks, import-boundary checks, and Changeset classification review | experimental prop object, experimental subpath, patch evolution, promotion, unpublished adjacent field, stable warning behavior, integration theme | A prose-only marker excludes a stable API, adjacency falsely publishes a new field, an experimental export leaks through a stable path, a patch changes stable behavior, or a promoted API remains unprotected | +| FR25–FR27 | Stable-surface inventory and experimental-boundary matrix | package/API, CSS/token, CLI/config, persistence, build tooling, docs, whole Lab component | An unmarked experiment changes stable defaults or a stable surface bypasses compatibility review | +| FR28–FR31 | Declared-tier check: on a minor, the `[breaking]` Changeset describes the change (old usage, replacement, migration); on a patch, a breaking Changeset is refused and the deprecation ships instead; declaration/doc/build/CLI warning projections; old/new fixtures; dry-run/idempotence/migration tests; maintained-source and latest-stable upgrade evidence | whole component, prop/value, theme field/helper/token/target/source, CLI command, CLI option; old-only, new-only, both, static/dynamic/uncertain migration, text/JSON, development/production | A warning has no usable modernization route, production runtime changes for deprecation, maintained guidance teaches the old surface, a migration guesses, old behavior degrades early, cadence invents a wait, or one cleanup id covers multiple incompatible deltas | +| FR32–FR35 | Latest-stable victim fixture, pre-existing authority named in the Changeset or pull request, owner review, declared-tier check, and emergency attestation | victim-free `[fix]`, `[fix]` plus incompatible-fix metadata, coexistence, cleanup transition, critical-harm emergency | A released victim uses bare `[fix]`, a new Changeset tag replaces metadata, a correction record disagrees with its public-surface state, or urgency bypasses migration | +| FR36–FR40 | Owner-declared target, locked final-patch receipt, three-way delta classification against the merged `[breaking]` Changesets, and separated release notes | ordinary cadence, immediate pair, cleanup, release metadata, pre/post-lock compatible fix | Cadence becomes eligibility, the final patch is recut for bookkeeping, a feature or incompatible fix enters the incidental-fix lane, or release notes merge cleanup with fixes | +| FR41–FR44 | Schema validation, PR declaration, semantic stable/base/head comparisons, exact-main gate, and immutable publish/rollback receipt | duplicate ids, missing evidence, route/schema removal, old-client metadata, partial publish, safe rollback | A label passes without semantics, a delta maps zero or multiple times, fixed-group membership drifts, or a release rebuilds under one identity | +| FR45 | Docs route inventory, repository-reference checks, and Changeset review | catalog entry rename, former-route miss, stable command and JSON schema | Catalog routing is frozen as API, or a rename silently changes the contractual command or response schema | +| FR46–FR47 | Declared-tier Changeset admission, canary publication ordering, and release-versioning fixtures | owner increase/decrease, above/equal/below stable, split group, `[breaking]` on patch and minor plans | Pending Changesets derive the plan, `[breaking]` passes on a patch or fails on a minor, equality publishes a canary, or a lower/split declaration publishes instead of failing | +| 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 | Cut-time successor-plan preparation plus manifest/pin/lockfile/compatibility-asset and lifecycle fixtures | default patch successor, explicitly named minor, abort before any tag or publication, 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 a terminal cut with neither an immutable tag nor stable publication, skips the default patch, derives a minor from pending Changesets, splits pins/assets, or the prepared plan or merge-back lowers or duplicates an existing newer plan | +| FR52 | Promotion fixtures plus every checked-in source consumer run before and after codemod promotion | staged transform, promoted transform, missing source, ambiguous candidates, changed entry identity | Evidence hardcodes only `next/`, keeps a duplicate source, silently chooses among candidates, or passes when the promoted transform no longer exposes the same identity and entries | +| 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 @@ -1232,10 +1233,11 @@ The cut knows the default successor and every file that must move together, so i 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. +A terminal cut with neither an immutable tag nor stable package publication 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 +strands a terminal cut with neither a tag nor a publication on a skipped plan; and waiting until merge-back to prepare information already fixed at the cut. ## Open questions