Skip to content

docs(releases): the versioning policy states the 17.x launch-window rule and the v18 prerelease regime - #22963

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-22933-versioning-policy-v18
Oct 12, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-22933-versioning-policy-v18

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #22933
Clause-②: no

Release-owned channel 2: a factual error in content/docs/releases/index.mdx, fixed in a dedicated docs-only PR, as triage graded it (comment 6118040748). One file, one section ("Versioning policy"), +15 / -7 lines. No gate script is edited and no release action is taken.

What was false

On main at 51b43a8dc the section said a launch-window override is "in force today" and that scripts/check-changeset-no-major.mjs "fails any pull request that declares a major bump". On that same commit, .changeset/pre.json reads {"mode": "pre", "tag": "next"}, and the guard's judge() returns its exempt verdict (exit 0) for any major a diff introduces while pre.mode === 'pre'.

Each changed sentence, before and after, and the main fact it rests on

1. Opening sentence

  • Before: "ObjectStack follows Semantic Versioning, with one override that is in force today: while the launch window is open, a breaking change ships as a minor release."
  • After: "ObjectStack follows Semantic Versioning."
  • Rests on: the deleted clause is the false claim. The override is not what governs a release cut from main today (see 5 and 6).

2. Lockstep sentence

  • Before: "All @objectstack/* packages version in lockstep, so a single major bump would promote the whole platform; instead a breaking change lands in a minor ..."
  • After: "All @objectstack/* packages version in lockstep, so a single major bump promotes the whole platform, and which version a breaking change ships in depends on the line."
  • Rests on: the fixed group in .changeset/config.json. The guard's own header (WHY THIS EXISTS) says Changesets applies the highest bump in the group to every package in it.

3. The 17.x rule, now history (new bold lead)

  • After: "The 17.x minors ran under a launch-window override: a breaking change shipped as a minor release."
  • Rests on: .changeset/pre.json was created by a87d8be29 ("enter Changesets pre mode (next) with one major marker", 2026-10-08). It is absent at a87d8be29^ and at dc1b98680 (2026-09-23, inside the 17.x minors). Control: .changeset/config.json is present at dc1b98680. So the guard was in its enforcing branch through the 17.x minors. The v17 page's banner says 17.1.0 through 17.7.0 are "minors by version number, not by blast radius".

4. How the 17.x rule was enforced

  • Before: "... alongside a changeset entry marked **BREAKING**, and scripts/check-changeset-no-major.mjs fails any pull request that declares a major bump."
  • After: "It landed in a minor alongside a changeset entry marked **BREAKING**, and scripts/check-changeset-no-major.mjs failed a pull request that declared a major bump."
  • Rests on: judge() returns enforce (exit 1) when pre.json is absent. The sentence is now past tense. "any" became "a" because the script's header documents an allow-major label escape hatch outside pre mode.

5. The v18 regime (new bold lead)

  • After: "The v18 line is a major in prerelease."
  • Rests on: a87d8be29 opened the line in pre mode with a major marker. The v18 page (content/docs/releases/v18/index.mdx) has the release-status banner.

6. The guard in pre mode (new)

  • After: "Changesets is in pre mode with the tag next, and check-changeset-no-major.mjs stands aside in pre mode, so a pull request may declare a major bump."
  • Rests on: .changeset/pre.json; judge() line 673 (if (pre?.mode === 'pre') return { verdict: 'exempt', ... }); the RC EXEMPTION paragraph at :105. The exemption has no package condition and no pending-marker condition; those belong only to the separate protocol-lockstep verdict. 21 pending changesets on main declare a major.

7. What publishes (new)

  • After: "Every release cut from main is the next 18.0.0-next.N on npm's next tag, while latest stays on 17.x."
  • Rests on: the v18 page, which says this in the same words (:6-:8, :27-:29). release.yml triggers on pushes to main only.

8. Link (new)

  • After: "See how a breaking stage lands on the v18 line."
  • Rests on: that heading exists on the v18 page, and check:doc-anchors resolves the link. The link points at the v18 page and does not restate its next-before-latest paragraphs (ADR-0087 D6), so the two pages cannot drift apart on them.

Where this departs from the card's direction (measured)

  • I did not write "breaking changes land as major changesets." Of the 113 pending changesets carrying **BREAKING**, 93 declare no major at all. At least four of them were added after pre mode was entered: d1dbe70eb, ffb31fca3, 7518ee397 and 9ad3d2470 each have a87d8be29 as an ancestor (merge-base --is-ancestor exit 0, which holds in a shallow clone). What main supports is narrower: the guard admits a major in pre mode, and every cut from main is the next 18.0.0-next.N. The section says exactly that.
  • I did not write "it still holds for any 17.x release." release.yml publishes only on a push to main, and main is in pre mode on next, so the current pipeline cannot cut a 17.x release. The section states the 17.x rule in the past tense, as what the 17.x minors ran under, and makes no claim about a future 17.x release.
  • No date and no version beyond 18.0.0-next.N (triage's bound). The section says nothing about what happens when pre mode exits.

Measured hypotheses

  • The section spans :46-:72, not :46-:54. The later paragraphs (the major/minor/patch bullets and the warning paragraph) do not restate the "in force today" rule. The minor bullet's examples are released history and stay true. They are unchanged.
  • The sync script is untouched by this edit. node scripts/sync-release-index-currency.mjs printed "every in-scope entry ... (v16, v17) already names the newest GA release of its major ... nothing rewritten", exit 0. The file's git hash-object is the same before and after the run, and equal to the HEAD blob (b2df87d2a). Its --self-test printed "42 cases pass", exit 0. indexEntryLine() takes the first line containing ](/docs/releases/vN). The new link ends v18#how-...), so that needle cannot match it.

Tests: all at 83a041d35 (HEAD of this branch)

  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 47 commands at 83a041d35, identical to the dispatch's lead list. I ran all 47 with each exit code captured before any pipe. The --ran reconciliation printed: "47 derived famil(ies) accounted for — 47 run, 0 NOT-MEASURED (a DERIVED zero — all 47 recorded an exit code and none of them is 3)."
  • Five gates first refused with exit 3 on missing builds (check:doc-formula-expressions, check:doc-security-posture, check:docs, check:skill-examples, check:docs-transcript-drift). Those were prerequisite refusals, not findings. I built spec, formula, lint, client and client-react with their closures under the verify lock (VERDICT command-exit 0 twice) and re-ran them. All five gates now exit 0, for example "262 prose examples type-check across 3 surface(s)".
  • check:doc-anchors: "485 internal #fragment link(s) across 419 source file(s) all resolve to a real heading". A probe through its own extractFragmentLinks() shows the new link is extracted from this file and its target id exists on the v18 page.
  • Lint, a proven narrowing rather than a skipped run. ① The population comes from eslint's own config: eslint.config.mjs files globs are **/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs} and narrower TypeScript globs, with no .mdx glob. ② npx eslint --no-inline-config --format json content/docs/releases/index.mdx returned 1 file, 0 errors, and one warning: "File ignored because no matching configuration was supplied." ③ The diff changes only this file, which no config object matches, so no linted file's verdict can move.
  • No package is touched, so no package test or typecheck is owed. CI runs the Build Docs and Test Core jobs; they were not measured locally.

Acceptance notes

  • Not filed here; reported to the seat: content/docs/protocol/backward-compatibility.mdx:18 still says "While the launch window is open, a breaking change ships as a MINOR release — not a MAJOR one. ... This rule is in force today". The table and the Deprecation Timeline repeat the same claim. This section links that page "for the full policy", so after this lands the two pages disagree. The page is outside this card's file surface.
  • The warning paragraph's "Read the release note for the version you are moving to" has no curated note to point at for an 18.0.0-next.N prerelease. The new v18 link leads to that page's "read the CHANGELOG of every prerelease you move to", so I did not edit the paragraph further.
  • skip-changeset: no published package lists content/, docs or releases in files[] (control: @objectstack/spec's files[] reads back).

Generated by Claude Code

…ule and the v18 prerelease regime

The releases index said a launch-window override was "in force today" and that
check-changeset-no-major.mjs fails any pull request declaring a major. On main,
.changeset/pre.json reads "mode": "pre" with the tag "next", and the guard's
judge() returns its exempt verdict for any introduced major in pre mode. The
section now records the override as the regime the 17.x minors ran under, and
the v18 line as a major in prerelease publishing 18.0.0-next.N on next while
latest stays on 17.x, linking the v18 page rather than restating it.

Claude-Session: https://claude.ai/code/session_012yK1ddAdAqfzwigRHZq3r2
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Oct 12, 2026
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 12, 2026
@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 12, 2026 05:56
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 12, 2026 05:56
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 12, 2026
Merged via the queue into main with commit 246edf5 Oct 12, 2026
37 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-22933-versioning-policy-v18 branch October 12, 2026 06:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants