Repository navigation
Commit 8fbbd50
docs(releases): state 18.0.0 as the v18 GA release, so the GA Version Packages PR renders (#24584)
Fixes #24569
Clause-②: no
The v18 GA release prose for the two release-owned pages that refuse the
GA Version Packages PR. This PR pairs with PR #24555, which exits
Changesets pre mode. With both applied, the `version-pr` lane's Render,
Validate and Restore steps all exit 0 and the lockstep group renders
`18.0.0`. **Draft, for the maintainer to merge.**
**Merge order:** PR #24555 first, this PR second, then one Version
Packages refresh.
⛔ Nothing was published or tagged. No release workflow was dispatched.
The Version Packages PR (#24524) and `changeset-release/main` were not
touched. The dry-run ran in a scratch clone outside the worktree, and
nothing from it was committed or pushed. No gate or rewriter changed.
Head `b174b74605` is `ba4afcc239` (`origin/main`, merged in before
opening) plus two docs commits. The worktree's base was `04669a467e`.
## The change (docs only, `content/docs/releases/` only)
### `content/docs/releases/index.mdx`
1. The v18 entry's trailing status is now in the one shape
`sync-release-index-currency` rewrites (`STATUS_SHAPE`):
```text
before: (prerelease: `18.0.0-next.N` on npm's `next` tag, no GA date)
after: (current series: 18.0.0, released 2026-10-19)
```
The prose before the status now reads: "its breaking changes landed in
stages through the `18.0.0-next.N` prereleases on npm's `next` tag, each
with its own changeset and migration, and its GA release, 18.0.0,
publishes to npm's `latest` tag and moves it from 17.x to 18".
2. The paragraph "**The v18 line is a major in prerelease.** …" (old
lines 58-62) is now "**The v18 line is a major, and 18.0.0 is its GA
release.**" The pre-mode regime is in the past tense, and the paragraph
states the exited state: the 18.0.0 cut publishes to `latest`, and
`check-changeset-no-major.mjs` again fails a pull request that declares
a major bump. The wording follows PR #24555's edit of
`backward-compatibility.mdx`.
### `content/docs/releases/v18/index.mdx`
1. The `description` front matter is now: "The v18 line and its GA
release, 18.0.0, which closes the `18.0.0-next.N` prerelease train and
publishes to npm's `latest` tag. …"
2. The release-status blockquote, in full:
```md
> **Release status: 18.0.0 is GA — the release this page documents.** It
> closes the v18 prerelease train, which published as `18.0.0-next.N` on
npm's
> `next` dist-tag. The 18.0.0 cut leaves Changesets pre mode, so the
> `@objectstack/*` packages stop publishing as `18.0.0-next.N`, and
18.0.0
> publishes to npm's `latest` dist-tag, which moves from 17.x to 18 with
it. A
> `^17` dependency range still never moves to 18 by itself: move every
> `@objectstack/*` dependency to 18 together, and read
> [Upgrading](/docs/upgrading) before you do.
```
3. The two pre-mode bullets are rewritten. "Through `next` before
`latest`" (old `:27`) is now in the past tense and ends with "18.0.0 is
the cut that takes the line to `latest`". "GA ends the prerelease" (old
`:62`) is now "**18.0.0 ends the prerelease.** It is the GA cut: it
leaves pre mode and publishes the line to `latest`." The "Curated notes
… are not written yet" sentence is kept verbatim.
4. One more sentence, of the same class and in the same file (second
commit `b174b74605`): "While the line is open, every other breaking
change that lands on `main` ships on it too" is now in the past tense.
That sentence stops being true once the guard fails a major bump again.
Every heading and anchor is unchanged. In particular `## How a breaking
stage lands on this line` stays as it is: its anchor is linked from the
release index and five times from `protocol/backward-compatibility.mdx`.
### Why the text is worded this way
- **The status shape.** `(current series: X.Y.Z, released YYYY-MM-DD)`
is the only shape the rewriter rewrites, so the 18.1.0 version pass will
stamp the next minor without a person. A probe of the rewriter's own
functions on this text: `rewriteStatusField(field, '18.0.0', …)` returns
`null`, meaning it leaves a field that already names the newest GA
alone, date included. `rewriteStatusField(field, '18.1.0',
'2026-11-01')` returns `current series: 18.1.0, released 2026-11-01`.
- **The blockquote's assertion.** It uses "18.0.0 is GA", one of the
forms `releasedAssertionRe` accepts. It contains none of the six
`PAGE_STALE_SIGNALS`. Probed with the gate's own predicates:
`pageStatusProblems(18)` returns `[]`, `indexStatusProblems(18)` returns
`[]` and `indexCurrencyFindings(18, '18.0.0')` returns `[]`. The control
on the base text: 1 page problem, the index signals `prerelease-word`
and `prerelease-version`, and 1 currency finding.
- **True on both sides of the publish.** Nothing here says that npm
already serves 18.0.0 on `latest`, or that "a plain install now resolves
18.0.0". 18.0.0 is described as the release the page documents and by
what it does: it "publishes to npm's `latest` dist-tag". That stays true
for a reader on `main` between this merge and the publish, and after the
publish. The one dated claim is the index status, discussed next.
## DATE
`released 2026-10-19` is the UTC day this PR is opened.
- No gate checks the date, re-measured: `indexCurrencyFindings` judges
the version only, and `check:release-page-status`'s index matcher judges
only the prerelease signals.
- The rewriter never re-dates a field that already names the newest GA.
The dry-run below printed "every in-scope entry … (v16, v17, v18)
already names the newest GA release of its major … nothing rewritten",
and the date came through the version pass unchanged.
- So nothing corrects the date later. **If the maintainer merges on a
later day, the seat re-dates it in this PR before the merge.**
## Proof: the paired dry-run (scratch clone, never pushed)
Setup:
- A clone of `/home/user/objectstack` at a short scratch path, with the
push URL set to an invalid path.
- Full history (`--is-shallow-repository` false). Local `main` is
`ba4afcc239`.
- Branch `rehearsal2` = this PR's head `b174b74605` merged with PR
#24555's head `abec338235`, giving merge `468a6ad229`. That tree differs
from `main` in exactly the 4 files of the two PRs, and
`.changeset/pre.json` reads `mode: "exit"`.
- `release-rehearsal-clone.mjs` reported "✓ FIT". `pnpm install
--frozen-lockfile` ran with its scripts this time, since the short path
stays under tsx's IPC socket limit.
- The three `version-pr` steps were **extracted verbatim from
`release.yml`** with a YAML parser. The blob `47db41eeea` is the same in
the clone and on `main`. They ran under `bash -e` with `RUNNER_TEMP`,
`GITHUB_OUTPUT` and `GITHUB_STEP_SUMMARY` pointed at scratch files, each
under `os-verify-lock.sh`.
| step | exit | reading |
|---|---|---|
| Render the post-version tree | **0** | `pending_before=1029`, 1205
paths moved. `sync-release-index-currency`: "(v16, v17, v18) already
names the newest GA release … nothing rewritten".
`check-skill-compatibility-version --fix`: 10 of 10 SKILL.md stamps
moved to `18.0.0`. |
| Validate the post-version tree | **0** | "Post-version tree
validated.", with 15 of 15 content gates green,
`check:release-page-status` and `check:release-index-currency-sync`
among them. "1205 path(s), all inside the reviewed shape",
"major-boundary surfaces left unvalidated: 0". |
| Restore the pre-version tree | **0** | "Pre-version tree restored:
1029 pending changeset(s), working tree clean." |
Rendered versions:
- `@objectstack/spec` is **`18.0.0`**.
- The fixed group reads 73 of 73 members at `18.0.0`.
- `.changeset/pre.json` was deleted by the pass.
- The index status survived the pass byte-identical: `(current series:
18.0.0, released 2026-10-19)`.
The first round on head `3754bbeddb`, before commit 2, gave the same
three exit codes and the same readings.
NOT MEASURED: the read-rehearsal steps (`changesets/action`), because
that is a GitHub Action.
## This PR alone on `main` (still `mode: "pre"`)
It may sit on `main` briefly before or after #24555, so every docs gate
was run on this branch's own head (`b174b74605`, `.changeset/pre.json`
at `mode: "pre"`). Exit codes were captured before any pipe.
- **Derived families:** `node scripts/pm/dispatch-gates.mjs --commands
--repo objectstack-ai/objectstack` derives **47** commands for the
two-file diff, and all 47 exit 0. The `--ran` reconciliation reads "47
derived, 47 run, 0 NOT-MEASURED (a DERIVED zero — all 47 recorded an
exit code and none of them is 3)". On the first pass, five families
(`check:doc-formula-expressions`, `check:doc-security-posture`,
`check:docs`, `check:skill-examples` and `check:docs-transcript-drift`)
returned a PREREQUISITE refusal (exit 3, or exit 1 "Generate it first").
I built `@objectstack/spec` plus the `@objectstack/lint...` closure, and
the `@objectstack/client-react...` closure, under `os-verify-lock.sh`,
then re-ran all 47.
- **Release-docs gates beyond the derivation, all exit 0:**
`check:release-index-currency-sync`, `node
scripts/sync-release-index-currency.mjs` (wrote nothing; the tree stayed
clean), `check:docs-image-tag`, `check:docs-image-tag-sync`,
`check:release-page-status`, `check-release-section-coverage.mjs
--strict` and `check:release-notes`. On `main` the CHANGELOG has no `##
18.0.0` heading yet, so the v18 entry is not in those gates' GA scope.
The text is green there for that reason, and green on the post-version
tree as shown above.
- **Control bytes:** the self-scan finds none in either file.
## Changeset and label
There is no changeset, because nothing here publishes. Neither file is
reachable from any public package's `files[]`: 73 public packages, none
of whose `files[]` entries names `content`, `docs` or `releases` or
climbs out of its package. The positive control is that 73 of 73 name
`dist`. So `skip-changeset` rides the create.
## Acceptance notes
- **After the GA publishes, the release-coverage patrol reports the v18
page.** Validate's advisory `check-release-section-coverage` already
reports it on the post-version tree: "NO heading on this page names the
18.0 series". It is advisory in Validate and green there. The nightly
`release-coverage-patrol.yml` runs `--strict` and records it on its
anchor issue until the curated 18.0.0 notes are compiled. That compile
is the release-time step the page itself names ("Curated notes … are
compiled at release time"), as with every 17.x minor. Writing a heading
only to satisfy the patrol would be a heading with no notes under it.
Noted, not carded.
- **Bullets 2-4 of "How a breaking stage lands on this line" are still
in the present tense** ("ADR-0131 lands in stages", "Protocol 18 comes
with it", "The AI skills move with the packages"). None of them states
the pre-mode regime, and none is made false by the exit. Turning the
section into the line's history belongs to the curated 18.0.0 notes.
Noted only.
- **The index link text stays `[v18]`.** GA lines use `[v17.0.0]`-style
text, but no gate reads link text and the card did not ask for it. Noted
only.
## 维护者速读(草稿)
**改了什么**:只改了两页发布文档,都在 `content/docs/releases/` 下。
- 发布索引里 v18 条目的状态从"预发布、没有 GA 日期"改为 `(current series: 18.0.0, released
2026-10-19)`。这是版本步骤的改写器唯一能识别、以后能自动更新的格式。同一页的"v18 正在预发布"段落改成已退出预发布的说法。
- v18 发布页的 `description`、发布状态引用块,以及三句预发布模式下的现在时句子,改为"18.0.0 是 GA 版本,发布到
npm 的 `latest`"。
- 没有改任何代码、门禁、改写器或 changeset。
**为什么改**:PR #24555 退出预发布模式后,版本 PR 的刷新会在这两处按设计拒绝:Render 卡在
`sync-release-index-currency`,Validate 卡在
`check:release-page-status`。在临时克隆里同时套上 #24555 和本 PR,原样重放 `release.yml` 的
Render / Validate / Restore 三步:退出码都是 0,15 个内容门禁全绿,`@objectstack/spec`
渲染为 `18.0.0`,73 个锁步包全部是 `18.0.0`。
**风险与代价(含回滚)**:
- 措辞在 npm 发布前后都成立:没有写"npm 已经在 `latest` 上提供 18.0.0",只写 18.0.0 是本页记录的 GA
版本,它会发布到 `latest`。唯一带日期的说法是索引里的 `released 2026-10-19`。
- 日期没有门禁校验,改写器也不会改它。如果合并不在 2026-10-19(UTC),席位会在合并前在本 PR 里改成合并当天的日期。
- 本 PR 单独留在 `main` 上(仍是 `mode: "pre"`)时,派生出的 47 个门禁全部为 0,其余发布文档门禁也全绿。
- 顺序反了的代价:如果本 PR 先于 #24555 合并,`main`
上会短暂出现"已退出预发布模式"的文字,但当时仍处于预发布模式。门禁不会变红。
- GA 发布后,夜间的 release-coverage patrol 会报告 v18 页还没有 18.0 的小节标题,直到整理好的
18.0.0 发布说明写完。这和每个 17.x 小版本的流程一样。
- 回滚:GA 版本 PR 合并前,直接 revert 本 PR 即可。
**席位意见**:
**你要做的**:
1. 选定 GA 当天先合并 PR #24555,再合并本 PR,然后触发一次版本 PR 刷新。
2. 确认刷新后版本 PR 的 head 里 `@objectstack/spec` 是 `18.0.0`,再按发布流程合并版本 PR
并批准发布。
3. 如果合并日期不是 2026-10-19,先让席位改日期再合并。
---
_Generated by [Claude
Code](https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 407f870 commit 8fbbd50
2 files changed
Lines changed: 26 additions & 20 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| |||
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
62 | 65 | | |
63 | 66 | | |
64 | 67 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
7 | | - | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
12 | 14 | | |
13 | 15 | | |
14 | 16 | | |
15 | 17 | | |
16 | 18 | | |
17 | 19 | | |
18 | 20 | | |
19 | | - | |
20 | | - | |
| 21 | + | |
| 22 | + | |
21 | 23 | | |
22 | 24 | | |
23 | 25 | | |
24 | 26 | | |
25 | 27 | | |
26 | 28 | | |
27 | | - | |
28 | | - | |
29 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
30 | 32 | | |
31 | 33 | | |
32 | 34 | | |
| |||
59 | 61 | | |
60 | 62 | | |
61 | 63 | | |
62 | | - | |
63 | | - | |
64 | | - | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
0 commit comments