Repository navigation
Commit a87d8be
chore(release): enter Changesets pre mode (
Fixes #22080
Clause-②: no
Opens the v18 line on `main`, as ruled B on #22050 (record
`6037890422`). Changesets enters pre mode with the tag `next`, and one
`major` changeset takes the `fixed` group to 18, so the first version
cut is `18.0.0-next.0`. File surface: `.changeset/` plus one line in
`scripts/check-adr-0087-registration.mjs` (the seat's surface amendment
`6040954045` on #22080; see the patch round below). ⛔ No edit to
`.changeset/config.json`, to either changeset guard's logic, or to
`.github/workflows/release.yml`. ⛔ No `changeset version` output is
committed, and nothing was published.
## The change
1. **`.changeset/pre.json`**, written by `pnpm changeset pre enter next`
(`@changesets/cli` 3.0.3) and committed as the tool wrote it (commit
`d3d35a1029`):
```json
{
"mode": "pre",
"tag": "next"
}
```
Under v3 the file holds `mode` and `tag` only. There is no
`initialVersions` and no `changesets` list.
2. **`.changeset/22080-v18-line-opens.md`**, front matter
`"@objectstack/spec": major` (commit `52f7a509c6`). Its body is the v18
line's opening note (ADR-0131; #22050). It carries `Clause-②: no` and
its ADR-0087 disposition (see Gates).
- **Step 2 was not skipped.** The card's count command, re-run on the
cut `3d9188502e`, prints `17 : minor` and `32 : patch`, and no `major`.
No `major` was pending, so without this marker pre mode would version
`17.8.0-next.0`.
- **Why `@objectstack/spec`.** Any `fixed`-group member moves all 69 to
the same version, so the choice decides only where the note lands and
what the major means. `@objectstack/spec` is the protocol package.
`scripts/sync-protocol-version.mjs`, which the root `version` script
runs, derives `PROTOCOL_VERSION` from this package's major, and ADR-0131
C8 calls the line "protocol 18". So the major sits on the package whose
major is the protocol version, and the note lands where an upgrading
reader looks first: `packages/spec/CHANGELOG.md`, under `### Major
Changes`.
## The no-major guard reads `pre.json` from the checkout it runs in (the
head), so steps 1 and 2 ship together
- `scripts/check-changeset-no-major.mjs:396` sets `REPO_ROOT` to the
checkout the script runs in. `readPre(root)` (`:2018`) reads `join(root,
'.changeset', 'pre.json')` from that working tree, `:2098` hands the
result to `judge`, and `judge` returns `exempt` when `pre?.mode ===
'pre'` (`:662`). `--base` sets only where the diff starts. It is never
where `pre.json` is read.
- In CI, the `Check Changeset` job in
`.github/workflows/pr-automation.yml` checks out the PR merge ref (the
default for a `pull_request` event) and runs `node
scripts/check-changeset-no-major.mjs --base "$MERGE_BASE"` (`:1130`).
The merge ref carries this PR's `pre.json`.
- Both legs were measured at `52f7a509c6`:
- **As committed:** exit 0, `✓ Changesets is in pre-release mode (tag:
next) — ... skipping the no-major guard.`, plus a notice naming
`@objectstack/spec`.
- **Control:** with `.changeset/pre.json` deleted from the working tree
only, exit 1, `⛔ This PR introduces changeset(s) that declare a major
bump.` The base `3d9188502e` has no `pre.json` at all, so a guard that
read the base could never have answered `exempt`. Restored with `git
checkout HEAD -- .changeset/pre.json`: `git diff HEAD` is empty, and the
guard exits 0 again.
- So no split is needed, and this PR carries steps 1 and 2.
## Pins
| Pin | Reading |
|---|---|
| In a throwaway worktree, never committed, `changeset version` puts the
`fixed` group at `18.0.0-next.0` | Detached throwaway worktree at
`52f7a509c6`: `pnpm changeset version` exits 0. All 69 `fixed`-group
members read `18.0.0-next.0`, and `pre.json` is unchanged. The 37
consumed changesets (36 pending plus this one) moved to
`.changeset/pre/`. `packages/spec/CHANGELOG.md` opens `## 18.0.0-next.0`
/ `### Major Changes` with this note. The worktree was then removed. |
| `check-changeset-no-major` and `check-changeset-fixed` pass on the PR
| `node scripts/check-changeset-no-major.mjs --base origin/main` exits 0
on the pre-release exemption above. Driven with a `pull_request` payload
carrying this body (`--event`), it also exits 0 with the level axis
read. `node scripts/check-changeset-fixed.mjs` exits 0: `✓
.changeset/config.json "fixed" group is in sync with 69 public workspace
packages.` |
| `.changeset/pre.json` is present at the merge, with `"mode": "pre"`
and `"tag": "next"` | Added in `d3d35a1029` with the content above. No
later commit touches it. It is in the merge ref CI checks out, which is
the file the guard's exemption reads. |
## `release.yml`: in pre mode, `changeset publish` publishes under
`next`, and `latest` stays 17.7.0
This is a reading of the file. Nothing was edited, and no publish was
run.
- `.github/workflows/release.yml:1762` is job `publish`, step `Publish
to npm + push version tags`. At `:1772` it runs `pnpm run release`.
- The root `package.json` `release` script is `pnpm run build && bash
scripts/build-console.sh && bash scripts/release-publish.sh`.
- `scripts/release-publish.sh:64` runs `changeset publish` with no
`--tag`.
- In `@changesets/cli` 3.0.3, `dist/getPublishPlan.mjs:599-603`
`getReleaseTag` works like this: with no `--tag` and a pre state
present, the tag is `preState.tag`, which is `next`. The one exception
is a package whose every published version is already a `next`
prerelease. Separately, `dist/publish.mjs:61-63` refuses a custom
`--tag` in pre mode.
- `npm view` read today: all 69 `fixed`-group packages have `latest` =
`17.7.0` and no `next` tag. So each publishes to `next`, and `latest`
stays `17.7.0`.
## Gates (run on `52f7a509c6`, exit codes captured before any pipe)
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derives 20 commands for this diff. All 20
exit 0, and `--ran` reconciles: `20 derived, 20 run, 0 NOT-MEASURED, 0
UNRUN`.
**Patch round, head `a630de657d` (seat-appended from addendum
`6041313497`).** At `52f7a509c6` the required `Lint & Repo Gates` was
red at `PM dispatch-gates self-test`, case `the extension narrowing
costs no lead … (refused: .changeset/pre)`: with `pre.json` tracked, the
battery's loose and strict hint rules disagreed on the literal
`.changeset/pre/` at `scripts/check-adr-0087-registration.mjs:536`. That
line now names the existing exclusion as `CONSUMED_PRERELEASE_EXCLUDED`
(the predicate's match is unchanged), which the extractor reads as an
excluded surface. At `a630de657d`: 41 derived commands, 41 run, all exit
0; `pnpm check:pm-dispatch-gates` → `1976 cases pass` (965.7 s), the
case reads `(refused: none)`; `check-adr-0087-registration --self-test`
441 assertions and `--base origin/main` exit 0.
- **Changeset gates:**
- `check-adr-0087-registration --base origin/main` exits 0. The gate
requires a disposition for a `major`: a probe commit without one was
refused, exit 1, with `declares a breaking change (major) but no
adr-0087: disposition marker`. The probe was never pushed. The changeset
now carries the `not-required (no-migration-prescription)` marker in the
ADR-0087 HTML-comment form, because the marker moves no authorable key,
export, type or stored shape.
- `check-changeset-no-major --base origin/main` and
`check-empty-changeset --base origin/main` exit 0.
- The self-tests of all three, plus `check:changeset-gate-self-tests`,
exit 0.
- **Remaining derived commands, all exit 0:**
`check-closing-keyword-parity` and its self-test,
`check-comment-mask-corpus`, `release-rehearsal-clone --self-test`,
`release-pending-publish --self-test`, `check:driver-memory-census`,
`check:gitlink-declared`, `check:nul-bytes`, `check:objectui-changeset`,
`check:pm-changeset-deadline-census`, `check:published-files`,
`check:refd-timer-probe` and `check:watch-hint-literal`.
- **Run beyond the derivation, all exit 0:** `check-changeset-fixed` (an
artifact roster under `.changeset/`), `check:future-spec-major`,
`check:lockstep-package-count` and `check:docs-image-tag`.
- **NOT MEASURED:** the four type-check lanes. The diff touches no
TypeScript.
## Read before merging: after this lands, the version-PR refresh goes
red until its major-boundary gates are wired
The card expects changesets/action to refresh #21988 into the
`18.0.0-next.0` version PR once this lands. On the files as they stand,
it will not.
- The `version-pr` job in `release.yml` (cron `0 */6 * * *`) runs `pnpm
run version` in the step `Render the post-version tree` (`:450`). The
step `Validate the post-version tree` (`:518`) then exits 1 at
`:610-613` when the pass wrote any major-boundary path: "this version
pass crossed a MAJOR boundary ... Wire them in before letting this
refresh through." The step `Create or update the "chore: version
packages" PR` has no `if:`, so it does not run after that failure.
- I measured this in the same throwaway. After `changeset version`, the
other three rewriters of the root `version` script exit 0. Replaying the
step's shape assertion gives 0 unexpected paths and 4 major-only paths:
`packages/spec/src/kernel/protocol-version.ts` (`PROTOCOL_VERSION
17.0.0` to `18.0.0`) and the blank template's `objectstack.config.ts`,
`objectstack.manifest.json` and `package.json`.
- The other lane, `cut-rc.yml`, refuses a pre tag other than `rc`
(`:232-237`) and a version not shaped `X.Y.Z-rc.N` (`:156-159`). The
ruled tag is `next`.
- What this means: once this lands, no lane in this repository cuts
`18.0.0-next.0` without a workflow change. That change is outside this
card, which forbids any `release.yml` edit. The red is the lane's own
designed refusal. It publishes nothing and queues nothing. #21988 stays
at its current 17.8.0 content and, as the card says, ⛔ is not merged.
## Acceptance notes
- The same throwaway `pnpm run version` shows two more things that the
lane wiring has to account for.
- `scripts/sync-release-index-currency.mjs` re-dates the v17 entry in
`content/docs/releases/index.mdx` from `17.7.0, released 2026-10-06` to
`released 2026-10-07`. That is the prerelease cut's date. 17.7.0's
version commit `4e4e881427` is dated 2026-10-06. Reported to the seat as
a finding.
- `scripts/sync-docs-image-tags.mjs` moves the 9 pins in
`docker/README.md`, `content/docs/deployment/self-hosting.mdx` and
`content/docs/upgrading.mdx` from `17.7.0` to `18.0.0-next.0`. The
self-hosting docs on `main` would then name a prerelease while `latest`
is 17.7.0. Noted only.
- The opening note says the dist-tag `latest` stays on 17.x until GA.
The pre-mode publish path above is what makes that true.
## 维护者速读(草稿)
**改了什么**:在 `main` 上进入 Changesets 预发布模式(标签 `next`),并加一条把
`@objectstack/spec` 标为 `major` 的 changeset。合并后,下一次切版本得到的是
`18.0.0-next.0`,而不是 `17.8.0`。改动是 `.changeset/`
下的两个文件,加上门禁脚本里的一行重命名:`scripts/check-adr-0087-registration.mjs` 把已有的排除路径
`.changeset/pre/` 写成 `_EXCLUDED` 命名常量(匹配逻辑不变),这样 `pre.json` 存在后 PM
门禁自检能正确识别它。没有代码或工作流改动。
**为什么改**:按 #22050 的裁决 B,v18 直接在 `main` 上开发。v18 的破坏性改动要以 `18.0.0-next.N`
预发布版发到 npm 的 `next` 标签上;`latest` 保持 17.7.0,普通安装的用户不受影响,直到 18.0 正式版。
**风险与代价(含回滚)**:合并后,版本 PR 的自动刷新(`release.yml` 的 `version-pr`,每 6 小时一次)会在
"Validate the post-version tree" 一步变红。原因是这一版跨了大版本,会改写 `PROTOCOL_VERSION`
和模板文件,而这条通道对这些文件还没有门禁,按设计会拒绝。它不发布,也不排队任何东西,但在另开卡把这些门禁接上之前,#21988 不会变成
`18.0.0-next.0`。`cut-rc.yml` 只接受 `rc` 标签,也走不通。#21988 无论如何都不要合并。回滚办法:删除
`.changeset/pre.json` 和 `.changeset/22080-v18-line-opens.md`
两个文件(在切出任何预发布版之前,这一步没有副作用)。
**席位意见**:
**你要做的**:确认后合并本 PR。合并后需要另开一张卡,让版本通道能切出 `18.0.0-next.0`;这张卡由席位提出。
---
_Generated by [Claude
Code](https://claude.ai/code/session_01VF48aw8RPG6wzDnMgp6rtw)_
---------
Co-authored-by: Claude <noreply@anthropic.com>next) with one major marker, so v18 opens at 18.0.0-next.0 (#22084)1 parent 498ea50 commit a87d8be
3 files changed
Lines changed: 20 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
533 | 533 | | |
534 | 534 | | |
535 | 535 | | |
536 | | - | |
| 536 | + | |
| 537 | + | |
537 | 538 | | |
538 | 539 | | |
539 | 540 | | |
| |||
0 commit comments