Skip to content

Commit f7d6f5b

Browse files
marchtianclaude
andauthored
docs(releases): the 18.1.0 notes, and the 18.x level rule on every page that still promised strict SemVer after GA (#25460)
<!-- claude-projects-attribution: {"github_login":"marchtian"} --> _Requested by **田騏** · [project thread](https://claude.ai/code/project/chan_01VmuUhXU9SSUzqJYyXSmYSi?thread=cmsg_01VmuUhXU9SSUzqJYyXSmYSiRwWtsarkLPmw9fMYiFZ3LY)_ Clause-②: no Metadata-protocol: none A docs-only PR (`content/docs/**` plus the docs-audit list). It publishes nothing from any released package, so it carries no changeset. It does not touch the Version Packages PR #24876, and it performs no release act. ## Why I audited the 18.0 and 18.1 release docs against what shipped and what is pending: - **18.0.0.** `releases/v18/18-0.mdx` is still accurate. `npm view` on 2026-10-23 reads `latest` = 18.0.0 and `next` = 18.0.0-next.5. Two pages around it had drifted: - **Upgrading → "Upgrading to 18.0"** describes three behaviours that only exist on `main` and gives them no version: #25155 (`--no-server` is no longer a way round the auth refusal), #25231 (a plugin-auth load failure is refused) and #25179 (`os migrate plan` lists nullable tenant columns). A reader on 18.0.0 is told about refusals that 18.0.0 does not make. - **Versioning policy.** Backward Compatibility says "the window closes at GA, and strict SemVer resumes from that point", and that a PATCH has "no behavior changes". The releases index says "A patch release fixes bugs." Ruling A (#25105, 2026-10-21) keeps the no-major guard and grades by the metadata protocol, so after 18.0.0 a non-protocol breaking change ships as `patch`. 18.1.0 is a minor that carries 82 changesets declared breaking, 37 of them graded `patch`, #25399 among them. A `^18.0.0` range takes it unattended. - **18.1.0.** No page existed. I rehearsed `pnpm run version` in a throwaway clone of `main` (`2581efb`). It produces 18.1.0 across 73 packages with 227 distinct CHANGELOG entries. Every content gate the publish lane runs is green on that tree. The one exception is `check-release-section-coverage`, which is advisory: "NO heading on this page names the 18.1 series". - **ADR-0087.** The registry is complete. `check-adr-0087-registration --list` shows 82 declared-breaking changesets, all 82 with a disposition and 0 residue: 9 `registered`, 7 `already-registered`, 61 `no-migration-prescription`, 4 `runtime-export-retired` and 1 `runtime-interface-only`. `check:upgrade-guide` and `check:spec-changes` both generate cleanly. ## What changes - **`releases/v18/18-1.mdx` (new).** The 18.1.0 notes, compiled from the changesets, with the entries grouped by `classifyReleaseBullet` as the GitHub Release body groups them: - 73 entries need action from the reader, 9 are converted, 41 are new capabilities, 0 are semantic and 104 are fixes. - The page adds a Console section (pin `616df6598b42` → `1d178e06ac5e`, six refreshes, 91 objectui entries) and an upgrade checklist from 18.0.0. - Two callouts say the page was compiled before the cut and has not been walked. - The cloud-managed break (#25399) gets its own section, which says self-hosted deployments are unchanged. - **`upgrading.mdx`.** - The three post-18.0.0 behaviours now say "from 18.1.0". - The per-release table gains a 18.1.0 row. - The sentence "a minor has nothing for `os migrate meta` to replay" now notes the nine step-18 conversions that 18.1.0 adds. - **`protocol/backward-compatibility.mdx`, `releases/index.mdx`, `releases/v18/index.mdx`.** These now state the post-GA level rule. The v18 index also links 18.1.0 and notes the 18.1.0 tightening of the auth-secret refusal. - **`releases/v18/18-0.mdx`.** It now says that a caret range takes later 18.x releases, which can break, and section 4 points at the 18.1.0 notes. - **`scripts/docs-audit/handwritten-docs.json`.** This regenerates with `--write` for the new page. The "current series" field on the releases index is left to `sync-release-index-currency.mjs`. On the rehearsed post-version tree it stamps `18.1.0`, and `check:release-notes`, `check:release-page-status`, `check:doc-anchors` and the section-coverage check are all green. ## Follow-up after the publish These are not in this PR: - A "Release facts, as measured" section, filled in with `npm view` after the publish. - A walked 18.0.0 → 18.1.0 checklist, which replaces the "not walked" callouts. ## Verified locally - `check:doc-anchors`, `check:docs-single-h1`, `check:docs-redirects`, `check:docs-audit-scope`, `check:release-notes`, `check:release-page-status`, `check:release-index-currency-sync`, `check:published-readme-links` and `check:nul-bytes` are all green. - An MDX 3 + GFM compile of the six edited pages passes. --- _Generated by [Claude Code](https://claude.ai/code/session_01At7xrR4rgknXtej5ZkMJHd)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2a80904 commit f7d6f5b

8 files changed

Lines changed: 610 additions & 29 deletions

File tree

‎content/docs/protocol/backward-compatibility.mdx‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@ ObjectStack follows strict backward compatibility guarantees to ensure predictab
1818
**The 17.x minors ran under a launch-window override: a breaking change shipped as a MINOR release, not a MAJOR one.** Every published `@objectstack/*` package versions in lockstep, so the version number alone is not an upgrade-safety signal; read [Launch Window](#launch-window-minor-releases-can-contain-breaking-changes) at the end of this page before you upgrade across 17.x.
1919

2020
**The v18 line has exited prerelease mode.** While Changesets was in pre mode with the tag `next`, every release cut from `main` was the next `18.0.0-next.N` on npm's `next` tag, and `scripts/check-changeset-no-major.mjs` stood aside in pre mode, so a pull request could declare a major bump. Changesets has exited pre mode, so the line's GA version is `18.0.0`, which publishes to npm's `latest` tag, and the guard again fails a pull request that declares a `major` bump. See [how a breaking stage lands on the v18 line](/docs/releases/v18#how-a-breaking-stage-lands-on-this-line).
21+
22+
**After 18.0.0, a breaking change ships in a MINOR or a PATCH release.** The maintainer's 2026-10-21 ruling ([#25105](https://github.com/objectstack-ai/objectstack/issues/25105)) keeps the no-major guard and grades each change by the metadata protocol: a key, value or metadata type added, narrowed or given a new meaning takes MINOR, and every other change takes PATCH, breaking or not. A non-protocol breaking change (a REST response, a boot refusal, a CLI exit status, a removed runtime export) keeps its `**BREAKING**` banner and ships as a PATCH. 18.1.0, the first release under the rule, is a MINOR that carries 82 changesets declared breaking.
2123
</Callout>
2224

2325
ObjectStack follows [Semantic Versioning 2.0.0](https://semver.org/) (`MAJOR.MINOR.PATCH`). The table below describes what each component means; which version a breaking change ships in depends on the line, as the callout above says.
2426

2527
| Version Component | When Incremented | Guarantee |
2628
|:---|:---|:---|
2729
| **MAJOR** (X.0.0) | Incompatible API changes | May contain breaking changes |
28-
| **MINOR** (0.X.0) | New features — and, in the 17.x minors, breaking changes | Existing code may require migration; the [release notes](/docs/releases) lead with what broke |
29-
| **PATCH** (0.0.X) | Bug fixes, backward-compatible | No behavior changes, only fixes |
30+
| **MINOR** (0.X.0) | New features — and, in the 17.x minors, breaking changes; after 18.0.0, any change to the metadata protocol (added, narrowed or semantic) | Existing code may require migration; the [release notes](/docs/releases) lead with what broke |
31+
| **PATCH** (0.0.X) | Bug fixes — and, after 18.0.0, every change that is not to the metadata protocol, breaking ones included | Before 18.0.0, no behavior changes. After it, a PATCH can break a REST client, a boot or a script: read its release notes |
3032

3133
### SemVer Guarantees
3234

@@ -201,14 +203,14 @@ The convention was enforced rather than informal — `scripts/check-changeset-no
201203
### What this means for an upgrade
202204

203205
- **Do not read a MINOR bump as safe to take unattended.** Read the [release notes](/docs/releases) for the version you are moving to: they lead with breaking changes and carry the migration steps.
204-
- **Pin exact versions** instead of caret ranges if you cannot review each MINOR before it lands.
206+
- **Pin exact versions** instead of caret ranges if you cannot review each MINOR before it lands, and after 18.0.0 each PATCH as well.
205207
- **Diff your own metadata** across the upgrade with `os diff <before> <after> --breaking-only`.
206208

207209
MAJOR releases do still happen — 17.0.0 was cut precisely because its breaking density was too high to carry `^16.x` consumers across on a caret range, and the v18 line is the next one — but in the 17.x minors an individual breaking change did not, on its own, force one.
208210

209211
### When it stops applying
210212

211-
The tables and deprecation timeline above state this rule for the 17.x minors directly, beside what the v18 prerelease did. Classic SemVer — where a breaking change once again requires a MAJOR — is the settled form the project returns to once the launch window closes: the window closes at GA, and strict SemVer resumes from that point. **For the 17.x minors, this section was the operative rule wherever any part of this page disagreed.** For the `18.0.0-next.N` prereleases, the operative rule is [how a breaking stage lands on the v18 line](/docs/releases/v18#how-a-breaking-stage-lands-on-this-line).
213+
The tables and deprecation timeline above state this rule for the 17.x minors directly, beside what the v18 prerelease did. Classic SemVer — where a breaking change once again requires a MAJOR — is the settled form the project returns to once the launch window closes. **It did not close at the 18.0.0 GA.** The 2026-10-21 ruling ([#25105](https://github.com/objectstack-ai/objectstack/issues/25105)) keeps the no-major guard on the v18 line and grades each change by the metadata protocol instead, so after 18.0.0 a breaking change ships in a MINOR when it narrows the metadata protocol and in a PATCH when it does not. **For the 17.x minors, this section was the operative rule wherever any part of this page disagreed.** For the `18.0.0-next.N` prereleases, the operative rule is [how a breaking stage lands on the v18 line](/docs/releases/v18#how-a-breaking-stage-lands-on-this-line). For the releases after 18.0.0, it is that ruling: read every release's notes, PATCH releases included, and pin exact versions.
212214

213215
---
214216

‎content/docs/releases/index.mdx‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,16 @@ publishes to npm's `latest` tag, and the guard again fails a pull request that
6464
declares a major bump. See
6565
[how a breaking stage lands on the v18 line](/docs/releases/v18#how-a-breaking-stage-lands-on-this-line).
6666

67+
**After 18.0.0, the level follows the metadata protocol.** The maintainer's
68+
2026-10-21 ruling ([#25105](https://github.com/objectstack-ai/objectstack/issues/25105))
69+
keeps the no-major guard and grades every changeset by what it does to the
70+
metadata protocol: a key, value or metadata type added, narrowed or given a new
71+
meaning takes `minor`, and every other change takes `patch` — a REST door, a
72+
driver, a boot refusal, the CLI or the Console — breaking or not. A
73+
non-protocol breaking change keeps its `**BREAKING**` banner and its ADR-0087
74+
disposition. 18.1.0 is the first release cut under the rule: a minor carrying
75+
82 changesets declared breaking, 37 of them graded `patch`.
76+
6777
What that means when you read a version number:
6878

6979
- A **major** release may remove or change schemas in `@objectstack/spec`,
@@ -74,7 +84,9 @@ What that means when you read a version number:
7484
`sys_position.permissions`; `15.1.0` removed `tenancy.strategy` and
7585
`tenancy.crossTenantAccess` — all in minor releases. As the v17 notes put it,
7686
17.1.0 and 17.2.0 are minors by version number, not by blast radius.
77-
- A **patch** release fixes bugs.
87+
- A **patch** release fixes bugs. On the v18 line after 18.0.0 it may also
88+
carry a breaking change to anything that is not the metadata protocol: a REST
89+
response, a boot refusal, a CLI exit status, a removed runtime export.
7890

7991
⚠️ **The version number is not the upgrade-safety signal.** Read the release
8092
note for the version you are moving to — each one leads with breaking changes

‎content/docs/releases/v18/18-0.mdx‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ Read with `npm view` and `npm pack` on 2026-10-20, after the publish:
5959
| Prereleases | `18.0.0-next.0` … `next.3` and `next.5`. `next.4` was never published, although the CHANGELOG carries a section for it |
6060

6161
Install 18 by its exact version (`18.0.0`) or a caret range (`^18.0.0`); both
62-
resolve `latest`. Moving the stale `next` tag is a release act, outside these
62+
resolve `latest`. A caret range also takes every later 18.x release by itself,
63+
and under the v18 level rule a later minor or patch can break you: 18.1.0 does
64+
(see the [18.1.0 notes](/docs/releases/v18/18-1)). Pin the exact version when
65+
you cannot read each release's notes before it lands. Moving the stale `next` tag is a release act, outside these
6366
notes.
6467

6568
### How to read the 18.0.0 CHANGELOG
@@ -622,7 +625,8 @@ Every line here was answered by the walk's 18.0.0 server after the ceremony.
622625
The v18 line keeps landing on `main`, and the version commit did not take
623626
everything that landed before it. Read on `main` at `71696121a6`: 26 pending
624627
changesets, ten of them `minor`, so the release that publishes them is
625-
**18.1.0**. They fall in two sets.
628+
**18.1.0**. They fall in two sets. (By the 18.1.0 cut the pending set had grown
629+
to more than 220 changesets; the [18.1.0 notes](/docs/releases/v18/18-1) cover all of them.)
626630

627631
**Shipped in 18.0.0, listed in no 18.0.0 CHANGELOG.** Eight of the 26 belong to
628632
commits that landed before the 18.0.0 version commit (`06cab4849a`), so their

0 commit comments

Comments
 (0)