From f5c3414189cf9c73e2674adbf706e091606e907f Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 02:29:03 +0000 Subject: [PATCH] docs(releases): fold #25563, #25564, #25565 and #25560 into the 18.1.0 notes Five more changesets reached main before the cut. Three are breaking patches: the temporary auth secret is development-only, findWithWindowFunctions serves a closed set (both #25563), and a REST credential is honoured only in the environment that validated it (#25565). #25564 records #25483's change of meaning on runAs (semantic). #25560 is a fix. Counts move to 258 entries (81/9/47/3/118) and 90 declared breaking, 42 of them graded patch. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01At7xrR4rgknXtej5ZkMJHd --- .../docs/protocol/backward-compatibility.mdx | 2 +- content/docs/releases/index.mdx | 2 +- content/docs/releases/v18/18-1.mdx | 55 +++++++++++++++---- content/docs/releases/v18/index.mdx | 2 +- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/content/docs/protocol/backward-compatibility.mdx b/content/docs/protocol/backward-compatibility.mdx index 50273a89c41..49f1ab46dca 100644 --- a/content/docs/protocol/backward-compatibility.mdx +++ b/content/docs/protocol/backward-compatibility.mdx @@ -19,7 +19,7 @@ ObjectStack follows strict backward compatibility guarantees to ensure predictab **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). -**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 87 changesets declared breaking. +**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 90 changesets declared breaking. 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. diff --git a/content/docs/releases/index.mdx b/content/docs/releases/index.mdx index 9372d4c0edf..3eeceeae09a 100644 --- a/content/docs/releases/index.mdx +++ b/content/docs/releases/index.mdx @@ -72,7 +72,7 @@ meaning takes `minor`, and every other change takes `patch` — a REST door, a driver, a boot refusal, the CLI or the Console — breaking or not. A non-protocol breaking change keeps its `**BREAKING**` banner and its ADR-0087 disposition. 18.1.0 is the first release cut under the rule: a minor carrying -87 changesets declared breaking, 39 of them graded `patch`. +90 changesets declared breaking, 42 of them graded `patch`. What that means when you read a version number: diff --git a/content/docs/releases/v18/18-1.mdx b/content/docs/releases/v18/18-1.mdx index 9e4a0918d3b..25981ed6264 100644 --- a/content/docs/releases/v18/18-1.mdx +++ b/content/docs/releases/v18/18-1.mdx @@ -5,14 +5,14 @@ description: "Release notes and upgrade checklist for 18.1.0, the first minor of **How this page was compiled.** From the 18.1.0 changesets on `main` at -`03243fc637` (2026-10-24), before the 18.1.0 cut: a rehearsed +`ba9e0c3749` (2026-10-24), before the 18.1.0 cut: a rehearsed `pnpm run version` in a throwaway clone at `b2c0752900` (73 packages move to -18.1.0, and their `## 18.1.0` sections held 227 distinct entries), and the 26 -changesets merged after it, graded the same way. That makes **253 distinct +18.1.0, and their `## 18.1.0` sections held 227 distinct entries), and the 31 +changesets merged after it, graded the same way. That makes **258 distinct entries**. The five sections below use the grouping the GitHub Release body -uses, and the counts are that grouping's: **78** need you to act, **9** are -converted for you, **47** add capabilities, **2** declare a semantic change, -and **117** are other fixes. Nothing here was +uses, and the counts are that grouping's: **81** need you to act, **9** are +converted for you, **47** add capabilities, **3** declare a semantic change, +and **118** are other fixes. Nothing here was read off a published 18.1.0 package or walked on an upgrade yet: every refusal is described as its changeset describes it. Anything that lands on `main` before the cut is in the CHANGELOG and not on this page. @@ -20,7 +20,7 @@ the cut is in the CHANGELOG and not on this page. ## Highlights — 18.1.0 -- ⚠️ **A minor that breaks.** 18.1.0 is a minor version, and 87 of its +- ⚠️ **A minor that breaks.** 18.1.0 is a minor version, and 90 of its changesets are declared breaking. Under the level rule the maintainer ruled on 2026-10-21 (#25105, "ruling A"), the v18 line takes no further major: a change to the metadata protocol takes `minor`, and every other change takes @@ -88,7 +88,7 @@ else: | Everything else: REST, drivers, services, the CLI, the Console, `feat:` and `fix!:` alike | `patch` | So a **patch** release can break a REST client, a boot or a deployment -script, and 18.1.0 carries 39 changesets graded `patch` that say **BREAKING**, +script, and 18.1.0 carries 42 changesets graded `patch` that say **BREAKING**, beside 48 graded `minor` ones. Pin exact `@objectstack/*` versions, and read the release notes for every version you cross. Each entry in a CHANGELOG states its kind on its own `Metadata-protocol:` line, and the GitHub Release body groups the @@ -102,7 +102,7 @@ you change them. ### Breaking changes you must act on -The 78 entries that are breaking and have no ADR-0087 conversion, and one boot +The 81 entries that are breaking and have no ADR-0087 conversion, and one boot refusal (`db1c7cc`) that its changeset declares as an addition. Each line names the one fix; the CHANGELOG entry carries the full FROM → TO. @@ -116,6 +116,14 @@ the one fix; the CHANGELOG entry carries the full FROM → TO. is too. Fix: set `OS_AUTH_SECRET`, and enable auth on a stack that mounts none. A development boot (`os dev`, `--dev`) and an embedded kernel are not affected. +- **A boot with no `OS_AUTH_SECRET` uses the temporary secret on a development + boot only** (`6abee03`, #25563). It used it whenever `NODE_ENV` was anything + but exactly `production` (unset, `staging`, a typo); now any boot other than + `NODE_ENV=development` or `test` throws `OS_AUTH_SECRET is required outside + development`. `os serve` and `os start` already default an unset `NODE_ENV` + to `production`, so CLI boots behave as before: an embedder that builds its + own kernel is the one that meets it. Fix: set `OS_AUTH_SECRET`, or + `NODE_ENV=development` for a local boot. - **A production `os serve` whose `@objectstack/plugin-auth` fails to load is refused, naming the load error** (`b2e964f`, #25231), `os start` included. 18.0.0 booted it without auth, silently or with one @@ -253,6 +261,14 @@ door (`422 INVALID_METADATA`), where 18.0.0 accepted it. starts empty, and a read-only boot no longer opens an empty in-memory database over a file it cannot open or create (`4d99158`, #25007). Fix: restore from a backup, or move the file aside yourself; an absent file is created empty. +- **`SqlDriver.findWithWindowFunctions()` serves a closed set** (`6abee03`, + #25563), and so do `driver-sqlite-wasm` and `driver-turso`'s local and + replica transports: the function is one of `row_number`, `rank`, + `dense_rank`, `percent_rank` or `cume_dist`, the direction `asc` or `desc`, + and every `partitionBy` / `orderBy` field is quoted as a column. Anything + else answers `400 INVALID_QUERY`. Fix: use one of those; send a window that + takes an argument (`lag`, `lead`, `ntile`) through `execute()` with bound + parameters. - **On PostgreSQL, `introspectSchema` reads each table in its own schema**, and refuses a `search_path` that reaches one table name in two schemas (`74fcec1`, #24920). Fix: point the connection at one schema. @@ -302,6 +318,16 @@ door (`422 INVALID_METADATA`), where 18.0.0 accepted it. naming the parameter (`17f3c65`, #25260), and the published list-query schemas declare it a non-negative integer (`5f30f00`, #25300). Fix: send a whole count of zero or more, or leave it out. +- **A credential is honoured only in the environment whose auth service + validated it** (`1361a5a`, #25565), on every route behind the shared REST + auth gate: crud, actions, import and export, batch, sharing, approvals, + analytics, search and security, scoped and unscoped. Before, an environment + with no `auth` service of its own fell back to the default environment's. + A mismatch now answers the same `401` as an unauthenticated request. Only a + multi-environment host whose per-environment kernels carry no `auth` + service meets it; a single-kernel deployment is unchanged. Fix: give each + environment's kernel its own `auth` service, and sign in to the environment + you call. - **`GET {base}/docs`, the OpenAPI HTML viewer page, is retired** (`1b3b65e`, #25124). `GET {base}/openapi.json` stays: point your own viewer at it. @@ -472,6 +498,12 @@ rows. `controlled_by_parent` detail follows its master. Nothing changes for a principal that does not hold the `external` grade, and no earlier release shipped it. +- **`FlowSchema.runAs` now says what a `system` run may not write** + (`025f6de`, #25564): its description names the refused writes to the four + identity-assignment objects (above, under security), and ADR-0087 D3 records + the change of meaning as `flow-run-as-system-identity-assignment-write-refused`, + so `os migrate meta` lists it for a flow that wrote those rows. It carries no + conversion, and every flow parses as before. A change of meaning that also breaks is listed with the breaking changes above. @@ -585,7 +617,8 @@ reinstall. #### 2. Before the first boot - Production `os serve` or `os start`: set `OS_AUTH_SECRET`, and do not rely on - `--no-server` or `OS_MIGRATE_AND_EXIT=1` to boot without it. + `--no-server` or `OS_MIGRATE_AND_EXIT=1` to boot without it. A kernel you + embed needs it too, unless it boots with `NODE_ENV=development` or `test`. - A stack that mounts no auth (`auth` tier off, `--preset minimal`) fails a production boot: enable auth. - CORS: list every cross-origin front-end in `OS_CORS_ORIGIN`, loopback origins @@ -628,3 +661,5 @@ managed datasource. assignments, invitations or memberships, and move it to `runAs: 'user'` or the organization endpoints. - Read the boot's upgrade impact report beside the access upgrade report. +- On a multi-environment host, give each environment's kernel its own `auth` + service before callers reach it, or they get `401`. diff --git a/content/docs/releases/v18/index.mdx b/content/docs/releases/v18/index.mdx index 5d721af2d94..a5d2a8937ef 100644 --- a/content/docs/releases/v18/index.mdx +++ b/content/docs/releases/v18/index.mdx @@ -135,7 +135,7 @@ Each release below is a self-contained page: what it changed, what breaks, and its own upgrade checklist. - **[18.1.0](/docs/releases/v18/18-1)** — the first minor, and a minor that - breaks: 87 of its changesets are declared breaking (ruling A grades a + breaks: 90 of its changesets are declared breaking (ruling A grades a non-protocol breaking change `patch` and a protocol narrowing `minor`). Its [upgrade checklist](/docs/releases/v18/18-1#upgrade-checklist) moves an 18.0.0 app to 18.1.0; it was compiled from the changesets before the cut and