Skip to content

Commit f35b4e1

Browse files
docs(protocol): Support Windows states latest-only support, and the releases index closes the v17 line (#25146)
Fixes #25102 Clause-②: no A docs-only PR. It executes the maintainer's ruling `6328214336` on #25102, **letter A, latest-only** (「25134 25092 25102 同意」). It changes two hand-written pages by +9 / -7 lines: - `content/docs/protocol/backward-compatibility.mdx`; - `content/docs/releases/index.mdx`. This is the releases index, not a per-release page. No file under `content/docs/releases/v17/**` or `v18/**` is touched. It edits no code, workflow, gate, changeset or ADR, and it takes no release action. ## What the ruling binds, and what this PR does not do - **Done (ruling item 1):** the Support Windows table is replaced by a latest-only statement. The previous MAJOR receives no fixes, and an application upgrades through ADR-0087's conversion layer and `os migrate meta`. The page links both. - **Not done (ruling item 3):** no B (an on-demand security line) and no C (a two-branch model). - **Not written (ruling item 2):** the emergency-branch option. The page names no emergency branch, no date or window, and no EE-specific promise. ## Support Windows: before and after **Before** (`:153`-`:159` at `abc25a3536`): ```text ### Support Windows | Version | Status | Support Level | |:---|:---|:---| | Current MAJOR (N) | **Active** | Full feature development, bug fixes, security patches | | Previous MAJOR (N-1) | **Maintenance** | Critical bug fixes and security patches only | | Older versions (N-2+) | **End of Life** | No support; upgrade recommended | ``` **After:** the heading text "Support Windows" is unchanged, so `#support-windows` still resolves (see *Inbound anchors* below). Then a lead sentence and five bullets, in the bold-lead bullet shape of the page's "SemVer Guarantees" and "Migration Guides" sections. Each clause and its source: | Clause on the page | Source | |:---|:---| | **Only the current MAJOR receives fixes.** There is no maintenance line for an older MAJOR: compatibility across majors is carried by the conversion layer and migration chain (ADR-0087), not by patching old releases. | Ruling item 1. npm re-check below: no version line of ours has ever published again after a newer line shipped. | | **The current MAJOR**: bug fixes and security patches ship in the next release cut from `main`. While the next MAJOR is in prerelease, every release cut from `main` is one of its prereleases on the pre-mode dist-tag (`next` on the v18 line), so a fix reaches `latest` only when that MAJOR goes GA. | `.github/workflows/release.yml`'s header: `npm publish` lives in one job, reachable only from a `push` to `main` and from the repair dispatch, and the repair "cannot mint a version". The card's fact 4 measured the consequence: between 17.7.0 and 18.0.0, `latest` received no fix. The page's own top callout already states the pre-mode half. The tag is written "the pre-mode dist-tag" because nothing fixes it: `changeset pre enter` takes the tag as an argument, v16 and v17 ran on `rc` and v18 on `next`, and `.github/workflows/cut-rc.yml:235` requires `tag: rc` for its own lane only. | | **The previous MAJOR, and every older one**: receives no fixes, and no backport or maintenance release is promised. To take a fix, upgrade to the current MAJOR. | Ruling item 1. | | **The conversion layer** (ADR-0087 D2): as the runtime loads your metadata, it converts the previous MAJOR's lossless changes (renames, alias removals, field moves) to the current shape and emits a deprecation notice per conversion. Those shapes keep loading after you move the runtime forward. It covers only the previous MAJOR and only lossless changes; `os migrate meta` carries everything else. | ADR-0087 D2: scope "losslessly mappable changes only — renames, alias removals, field moves, enum re-spellings"; window "N accepts N−1 shapes at load"; "emitting a structured deprecation notice per applied conversion"; "Semantic changes are excluded … it goes to D3". | | **`os migrate meta`** (ADR-0087 D3): `--from N` replays the chain from the major your metadata was authored against (protocol 16 or later, the chain's floor) to the current one in a single pass, and lists the edits your source needs. With `--write` it writes the mechanical ones it can trace to one literal into your source files. It reads no database. `--stored` replays the same chain over one deployment's `sys_metadata` rows and, with `--apply`, rewrites the ones still carrying an older shape. Links: the CLI reference (`/docs/deployment/cli#os-migrate-meta---stored`) and Upgrading, "The metadata app". | ADR-0087 D3 (cross-major in one command). `content/docs/deployment/cli.mdx`: the `os migrate meta --stored` row of the Data migrations table (`:1252`) and the section's "division of labour" paragraph (`:1819`), which states what `--from N` and `--stored` each do. `--write` and `--apply`: the flag descriptions in `packages/cli/src/commands/migrate/meta.ts`. The floor: `MIGRATION_SUPPORT_FLOOR = 16` (`packages/spec/src/migrations/registry.ts.template:79`) and `content/docs/upgrading.mdx:233`. | | **Testing a MAJOR before it reaches `latest`**: `scripts/check-changeset-no-major.mjs` fails a pull request that declares a `major` bump outside Changesets pre mode and stands aside inside it, and a MAJOR declared in pre mode publishes only prereleases, on the pre-mode dist-tag, until pre mode exits. The v18 line used `next` (`18.0.0-next.0` … `18.0.0-next.5`) before 18.0.0. Install from that tag to run your app against a MAJOR before it becomes `latest`. | `scripts/check-changeset-no-major.mjs` at `origin/main` `459afea1f6`: `judge()` (`:678`-`:683`) returns `exempt` when `.changeset/pre.json` has `mode: 'pre'` (`:681`) and `enforce` otherwise (`:682`). The `exempt` case exits 0 (`:818`-`:826`), and the `enforce` case prints the refusal (`:828`). The RC EXEMPTION header (`:113`-`:120`) states the Changesets semantics: in pre mode "a `major` bump only ever produces a … PRE-RELEASE version — nothing final publishes until `changeset pre exit`". npm: `18.0.0-next.0` (2026-10-13) to `18.0.0-next.5` (2026-10-19), then `18.0.0` (2026-10-20). The page says the guard fails "a" pull request, not "any", and it does not say a MAJOR can be declared only in pre mode, because the guard's `allow-major` label escape hatch skips it outside pre mode (header `:122`-`:124`; the label is read live at `.github/workflows/pr-automation.yml:1063`). | The CLI binary is spelled `os`, as everywhere else on this page. `packages/cli/package.json` `bin` maps both `os` and `objectstack` to the same `./bin/run.js`, so this is the ruling's `objectstack migrate meta`. ## Premise re-checks (ruling item 1), verbatim, at `origin/main` `abc25a3536` ```text $ git grep -n -iE "End of Life|security patches only|support window" origin/main -- content skills README.md origin/main:content/docs/protocol/backward-compatibility.mdx:153:### Support Windows origin/main:content/docs/protocol/backward-compatibility.mdx:158:| Previous MAJOR (N-1) | **Maintenance** | Critical bug fixes and security patches only | origin/main:content/docs/protocol/backward-compatibility.mdx:159:| Older versions (N-2+) | **End of Life** | No support; upgrade recommended | (exit 0) ``` ```text $ for p in @objectstack/spec @object-ui/core better-auth; do printf '%s: ' "$p"; curl -s "https://registry.npmjs.org/$p" | jq -r '.time | to_entries[] | select(.key | test("^[0-9]+\\.[0-9]+\\.[0-9]+$")) | "\(.value) \(.key)"' | sort | awk '{split($2,v,"."); print v[1]"."v[2]}' | uniq | sort | uniq -d | tr '\n' ' '; echo; done @objectstack/spec: @object-ui/core: better-auth: 1.4 1.5 1.6 1.7 (exit 0) ``` Both hold as the card states. Neither of ours prints a re-published line, and the `better-auth` positive control prints `1.4 1.5 1.6 1.7`. The card's grep has no "maintenance" term, so a wider grep was run to catch another page that states a maintenance line. The pattern covered `maintenance (line|release|branch|mode|window|period)`, `previous major`, `N-1`, `LTS`, `long-term support`, `backport`, `older (major|versions)`, `end-of-life` and `EOL`, over `content skills README.md`. It found 13 lines; none states a support window or a maintenance line: - the two lines above; - a retry formula (`backoffMultiplier^(n-1)`); - a database maintenance window; - the auto-generated plugin-versioning schema reference; - Node.js end-of-life in the 17.0 notes; - five lines on metadata authored against an older or previous major, which describe the conversion window, the stored-row replay, or a meaning that changed across a major (`upgrading.mdx:23`, `:199`, `cli.mdx:1742`, `api/declarative-endpoints.mdx:266`, `protocol/kernel/http-protocol.mdx:1173`), plus the matching skill line `skills/objectstack-api/SKILL.md:201`; - one unrelated `forms.mdx` hit. So no other page joins the surface. ## Every other sentence changed (ruling items 3 and 4) 1. **`backward-compatibility.mdx:142`, the Migration Support callout's second sentence.** This PR's new upgrade clause would have contradicted it on the same page. - Before: "An automated `codemod` command is referenced in the migration guides but is not yet available; until then, combine `os doctor --scan-deprecations`, `os diff`, and the CHANGELOG migration notes (below) to upgrade across MAJOR versions." - After: "There is no `codemod` command either: to upgrade your metadata across MAJOR versions, run `os migrate meta` (see [Support Windows](#support-windows)), and use `os doctor --scan-deprecations`, `os diff`, and the CHANGELOG migration notes (below) for what it does not rewrite." - Why: the old sentence names doctor, diff and the CHANGELOG as *the* way across majors, ten lines above a section that now says an app upgrades through the conversion layer and `os migrate meta`. - Why "your metadata": `os migrate meta` rewrites metadata. It does not rewrite the TypeScript patterns `os doctor --scan-deprecations` reports, and the comment at `packages/cli/src/commands/doctor.ts:2683` explains why doctor's own hint must not point at it. So the sentence scopes the command to metadata and keeps doctor, diff and the CHANGELOG for the rest. - Its "referenced in the migration guides" clause was also false. `git grep -i codemod -- content/docs skills` outside `releases/` finds only this sentence. The CLI has no `codemod` command: `doctor-deprecation-hint-commands.test.ts:160`-`:162` asserts that `objectstack codemod v2-to-v3` and `os codemod` resolve to no command. - The first sentence of the callout is unchanged. 2. **`releases/index.mdx:22`, the v17 entry's trailing status.** - Before: "(current series: 17.7.0, released 2026-10-06)". - After: "(final release: 17.7.0)". - Why: the index labelled both v18 and v17 "current series", and the latest-only statement allows exactly one. "final release: X" is the index's own wording for a closed line: v16 "(final release: 16.1.0)", v15 "(final release: 15.1.1)", v14 "(final release: 14.8.0)". The v16 label was set the same way when that line closed (`a1ef2c9d63`, the day after 17.0.0 shipped). - Gate compatibility: `check-release-section-coverage.mjs` `indexCurrencyFindings` passes any trailing status that names the newest 17.x GA (17.7.0). `check-release-page-status.mjs` names both wordings as valid. `sync-release-index-currency.mjs` rewrites only a stale `current series:` field and never a `final release:` one, so the version step leaves this entry alone. - The release date is dropped to match the three sibling entries. It stays on the v17 page. No other sentence changed. The rest of `backward-compatibility.mdx` was read in full at `BASE`, including the PR #22988 sentences: the 17.x launch-window rule, the v18 prerelease regime and the "When it stops applying" section. Each of them describes versioning history or the breaking-change regime, and none promises a fix to an earlier line, so all stay. **Releases index (ruling item 4).** No sentence in `content/docs/releases/` promises a previous-major fix. The grep, at `abc25a3536`: ```text git grep -n -i -E "maintenance|backport|security (fix|patch)|previous major|N-1\b|support(ed)? (window|line|policy|period)|end[- ]of[- ]life|\bLTS\b|long[- ]term|current series|final release|receives? (fixes|patches)|patch(es)? (for|to) (the )?(previous|older|17\.x|16\.x)" abc25a3 -- content/docs/releases ``` It found 14 lines (exit 0): - index entries `:21`-`:25`, the status labels; - `v16.mdx:20`, `:21` and `:863`, which state that v16 is closed; - `v17/17-0.mdx:91`, Node.js end-of-life; - `v17/17-4.mdx:355`, a store `maintenance` key; - `v17/17-7.mdx:60`, `:192`, `:563` and `:915`, which concern long-term agent memory. The only contrary statement is the v17 "current series" label (item 2). `meta.json` holds page order only, and `implementation-status.mdx` matched nothing. **Inbound anchors.** `git grep -n -i "#support-windows"` exits 1 in this repo and exits 1 in `../objectui` at `b014f5eea`; the control leg in `../objectui` exits 0. `git grep "backward-compatibility#"` finds one inbound fragment link, `releases/index.mdx:82`, which targets the launch-window anchor and is unchanged. The heading text is kept anyway, because links from outside both repositories cannot be enumerated. ## Gates All readings below are at this branch's head **`f453405903`**, against `origin/main` merge base `abc25a3536`. - **Derivation.** `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 49 commands: 33 pnpm and 16 direct node; 41 matched by path and 8 declared whole-tree. The change set is 2 paths and 16 changed lines. The list is identical at `2b3b50b4da`, `062bfaf1dd` and `f453405903` (`diff` exit 0). - **Ran all 49.** Each exit code was captured before any pipe. All 49 exited 0. - **Reconciliation.** `--ran` printed: "✓ dispatch-gates --ran: 49 derived famil(ies) accounted for — 49 run, 0 NOT-MEASURED (a DERIVED zero — all 49 recorded an exit code and none of them is 3)." - **Prerequisite build.** `pnpm exec turbo run build --filter='@objectstack/lint...' --filter='@objectstack/client-react...' --concurrency=2` ran under `scripts/pm/os-verify-lock.sh`: `VERDICT command-exit 0`, 37 of 37 tasks. In this round all 37 were cache hits on the same inputs. - **Docs-link and docs-audit verdict lines:** - `check:doc-anchors`: "566 internal #fragment link(s) across 424 source file(s) all resolve to a real heading". That covers the new `#support-windows`, `/docs/deployment/cli#os-migrate-meta---stored` and `/docs/upgrading#the-metadata-app` links. - `check:docs-redirects`: "OK (apps/docs/redirects.mjs: 98 entries -- 95 page destination(s) resolved against content/docs …)". - `check:docs-audit-scope`: "docs-accuracy-audit scope is in sync with content/docs/: 206 hand-written doc(s)". No `handwritten-docs.json` write was asked for or made. - `check:docs-transcript-drift`: "4 declared transcript value(s) across 418 page(s) … equal what the registry derives today". - **Release-index verdict lines:** - `check-release-section-coverage.mjs`, plain and `--strict`: "OK — 11 published minor(s) across 3 GA major(s) in scope (v16, v17, v18); … every index entry names the newest release of its major". This covers the v17 entry's new `(final release: 17.7.0)`. - `check:release-page-status`: "OK — 3 GA major(s) in scope (v16, v17, v18); each page's release-status blockquote and index entry describe a shipped release". - `check:release-notes`: "OK". - **Other verdict lines:** - `check:lockstep-package-count`: "all 3 occurrence(s) agree with the true count (73)". The page's lockstep sentences are untouched. - `check:nul-bytes`: "OK (scanned 11726 text file(s) … no raw ASCII control bytes)". - `@objectstack/spec check:docs`: "227 generated files in sync". - `check:skill-examples`: "262 prose examples type-check across 3 surface(s)". - **MDX syntax.** Both edited pages compile with the workspace's `@mdx-js/mdx` 3.1.1. Negative control: an unclosed `Callout` is refused ("Expected a closing tag"). - **Docs site build.** Run locally at `062bfaf1dd` as the production build that CI's `Build Docs` runs (`apps/docs/vercel.json` `buildCommand`), with one declared difference. CI forces turbo (`TURBO_FORCE`) so the docs task cannot be a replayed cache hit; locally the docs package's own `build` script ran directly, outside turbo's cache, after its dependencies built: `pnpm exec turbo run build --filter='@objectstack/docs^...' --concurrency=2 && pnpm --filter @objectstack/docs run build`, under the verify lock. Results: - `VERDICT command-exit 0`; - "✓ Compiled successfully in 2.2min"; - "✓ Generating static pages using 2 workers (1275/1275)"; - `apps/docs/.next/BUILD_ID` present. It was not re-run locally at `f453405903`. The derivation names it only as CI's `Build Docs` job, as before, and the fix changed text inside two bullets without changing the MDX shape: both pages compile, and the unclosed-`Callout` control is refused. CI's `Build Docs` check-run on `f453405903` concluded `success`. - **Merge probe.** `git merge-tree --write-tree` against `origin/main` `459afea1f6` exits 0 (tree `e475552dea`). `main` has moved two commits since the base, and neither touches either path. - **`skip-changeset`, re-measured.** - None of the 73 non-private manifests has a `files[]` entry naming `content` or `docs`. - Under `packages/` (with `dist/`, excluding `node_modules`), the removed phrase "Critical bug fixes and security patches only", the added "Only the current MAJOR receives fixes", "current series: 17.7.0" and "Support Windows" each match 0 files. - Positive control: "defineStack" matches 989 files. - **Not run locally, CI-owned:** - no package is touched, so no package `test` or `typecheck` is owed; - `test:repo` and the `Test Core` shards; - the four Type Check lanes; - the three workflow-valued families (`check-issue-citations.mjs --census`, shard attestation, test completeness); - `pnpm lint`. The PR's check-runs answer them: `Lint & Repo Gates`, `TypeScript Type Check`, `Test Core`, `Build Core`, `Build Docs`. ## Acceptance notes - **ADR-0087 D6 is not cited.** D6 reads "Every major is published to the `next` dist-tag at least one RC cycle before `latest`", but the ADR's 2026-07-15 as-built addendum lists "P3 — MCP tools + RC discipline (D6): deferred, evidence-gated", and npm `@objectstack/spec` does not follow it: - majors 8 to 15 published no prerelease version at all (0 in the registry). That was the pre-launch window, which the same addendum ratifies for 12 to 15. - 16 and 17 ran `-rc.N` prereleases (`16.0.0-rc.0` and `rc.1`; `17.0.0-rc.0` to `rc.6`), and the `rc` dist-tag still points at `17.0.0-rc.6`. - only 18 ran on `next`. So both prerelease clauses rest on `scripts/check-changeset-no-major.mjs`, which holds today, and name `next` only as the v18 instance. Nothing found fixes which tag a future pre mode uses, so the page names none. Not filed: it is history, with no reach. Carrier: none. - **Out of this PR's surface, reported to the seat and filed by it as #25148 (one card for both):** - `content/docs/releases/index.mdx:21` reads "(current series: 18.0.0, released 2026-10-19)". The 18.0.0 Version Packages commit `06cab4849a` is dated 2026-10-20T11:47Z, npm's `time["18.0.0"]` is 2026-10-20T12:51Z, and `releases/v18/18-0.mdx:3` says "published 2026-10-20". - `content/docs/releases/v17/index.mdx`'s status blockquote still says "A plain install now resolves 17.7.0" while `latest` is 18.0.0. That is a per-release page, which this PR does not edit. - **Prose that quotes the old callout wording.** Three places paraphrase the `:142` sentence this PR rewrites: the comments at `packages/cli/src/commands/doctor.ts:2680` and `packages/cli/src/commands/doctor-deprecation-hint-commands.test.ts:18`, and the source note at `docs/qa/platform-checklist/areas/cli.json:1189`. Each quotes "not yet available"; the page now says there is no `codemod` command. None of them reads the page, and no gate compares them. The same `doctor.ts` comment still says both of `os migrate meta`'s writes are `--out` JSON snapshots, which predates `--write`. They are code and QA data, outside this PR's surface. Not filed. Carrier: none. --- _Generated by [Claude Code](https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent c71d03a commit f35b4e1

2 files changed

Lines changed: 9 additions & 7 deletions

File tree

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ os diff <before> <after> --breaking-only
139139
```
140140

141141
<Callout type="info">
142-
There is no `lint --deprecations` flag — deprecation scanning lives on `os doctor --scan-deprecations`. An automated `codemod` command is referenced in the migration guides but is not yet available; until then, combine `os doctor --scan-deprecations`, `os diff`, and the CHANGELOG migration notes (below) to upgrade across MAJOR versions.
142+
There is no `lint --deprecations` flag — deprecation scanning lives on `os doctor --scan-deprecations`. There is no `codemod` command either: to upgrade your metadata across MAJOR versions, run `os migrate meta` (see [Support Windows](#support-windows)), and use `os doctor --scan-deprecations`, `os diff`, and the CHANGELOG migration notes (below) for what it does not rewrite.
143143
</Callout>
144144

145145
### Migration Guides
@@ -152,11 +152,13 @@ Each MAJOR release includes:
152152

153153
### Support Windows
154154

155-
| Version | Status | Support Level |
156-
|:---|:---|:---|
157-
| Current MAJOR (N) | **Active** | Full feature development, bug fixes, security patches |
158-
| Previous MAJOR (N-1) | **Maintenance** | Critical bug fixes and security patches only |
159-
| Older versions (N-2+) | **End of Life** | No support; upgrade recommended |
155+
**Only the current MAJOR receives fixes.** There is no maintenance line for an older MAJOR: compatibility across majors is carried by the protocol's conversion layer and migration chain ([ADR-0087](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0087-metadata-protocol-upgrade-contract.md)), not by patching old releases.
156+
157+
- **The current MAJOR** — bug fixes and security patches ship in the next release cut from `main`. While the next MAJOR is in prerelease, every release cut from `main` is one of its prereleases on the pre-mode dist-tag (`next` on the v18 line), so a fix reaches `latest` only when that MAJOR goes GA.
158+
- **The previous MAJOR, and every older one** — receives no fixes, and no backport or maintenance release is promised. To take a fix, upgrade to the current MAJOR.
159+
- **The conversion layer** ([ADR-0087](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0087-metadata-protocol-upgrade-contract.md) D2) — as the runtime loads your metadata, it converts the previous MAJOR's lossless changes (renames, alias removals, field moves) to the current shape and emits a deprecation notice per conversion, so those shapes keep loading after you move the runtime forward. It covers only the previous MAJOR and only lossless changes; `os migrate meta` carries everything else.
160+
- **`os migrate meta`** ([ADR-0087](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0087-metadata-protocol-upgrade-contract.md) D3) — `os migrate meta --from N` replays the migration chain from the major your metadata was authored against (protocol 16 or later, the chain's floor) to the current one in a single pass, and lists the edits your source needs; with `--write` it writes the mechanical ones it can trace to one literal into your source files. It reads no database. `os migrate meta --stored` replays the same chain over one deployment's stored `sys_metadata` rows and, with `--apply`, rewrites the ones still carrying an older shape. See the [CLI reference](/docs/deployment/cli#os-migrate-meta---stored) and [Upgrading → The metadata app](/docs/upgrading#the-metadata-app).
161+
- **Testing a MAJOR before it reaches `latest`** — `scripts/check-changeset-no-major.mjs` fails a pull request that declares a `major` bump outside Changesets pre mode and stands aside inside it, and a MAJOR declared in pre mode publishes only prereleases, on the pre-mode dist-tag, until pre mode exits; the v18 line used `next` (`18.0.0-next.0` … `18.0.0-next.5`) before 18.0.0. Install from that tag to run your app against a MAJOR before it becomes `latest`.
160162

161163
---
162164

‎content/docs/releases/index.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ migration steps, then covers new capabilities and notable fixes.
1919
## Versions
2020

2121
- [v18](/docs/releases/v18) — The line that carries ADR-0131, total organization ownership with no NULL `organization_id`; 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 (current series: 18.0.0, released 2026-10-19).
22-
- [v17.0.0](/docs/releases/v17) — Files become owned `sys_file` records with server-enforced `accept`/`maxSize` and a governed download path, bulk export becomes its own opt-in privilege, the SDK is reconciled against the routes the server actually mounts (21 dead methods out, 40+ real ones in), approval nodes route approvers dynamically via CEL expressions and decision outputs, a datasource that cannot connect fails the boot, and Node 22 becomes the supported floor; 17.1 adds partial field masking, record-view auditing on `sys_audit_log`, and a per-object read-only approval visibility tier — and makes a deactivated permission set or position actually stop granting access, withdraws the bulk-export wildcard from the shipped admin sets, and gives all three flow doors one honest HTTP status table; 17.2 tightens by-id `update`/`delete` against a silently-dropped `where` predicate or a mismatched id, retires `sys_position.permissions` and other dead ADR-0049 surfaces, and stops analytics from answering the wrong number on a cross-object filter (current series: 17.7.0, released 2026-10-06).
22+
- [v17.0.0](/docs/releases/v17) — Files become owned `sys_file` records with server-enforced `accept`/`maxSize` and a governed download path, bulk export becomes its own opt-in privilege, the SDK is reconciled against the routes the server actually mounts (21 dead methods out, 40+ real ones in), approval nodes route approvers dynamically via CEL expressions and decision outputs, a datasource that cannot connect fails the boot, and Node 22 becomes the supported floor; 17.1 adds partial field masking, record-view auditing on `sys_audit_log`, and a per-object read-only approval visibility tier — and makes a deactivated permission set or position actually stop granting access, withdraws the bulk-export wildcard from the shipped admin sets, and gives all three flow doors one honest HTTP status table; 17.2 tightens by-id `update`/`delete` against a silently-dropped `where` predicate or a mismatched id, retires `sys_position.permissions` and other dead ADR-0049 surfaces, and stops analytics from answering the wrong number on a cross-object filter (final release: 17.7.0).
2323
- [v16.0.0](/docs/releases/v16) — One org identifier (`organizationId`) across hooks and actions, quorum + per-group sign-off (会签) approvals with metadata-declared decision actions, time-relative automations, filtered roll-ups, strict dashboard widgets, an identity-scoped MCP stdio transport, and a platform-wide enforce-or-remove sweep that makes dead metadata loud; 16.1 adds a `requires` capability-provider preflight, two more dashboard build gates, and `runAs:'user'` automations that run with the triggering user's real grants (final release: 16.1.0).
2424
- [v15.0.0](/docs/releases/v15) — Explain record access layer by layer, a docked AI workspace in the Console, project-ready Gantt charts, and phone sign-in; 15.1 adds permission-following attachments, no-code third-party connectors, dashboard-wide filters, pinyin search, and whole-record inline editing — with materially safer multi-tenant and write-path defaults (final release: 15.1.1).
2525
- [v14.0.0](/docs/releases/v14) — ADR-0090 vocabulary convergence completed, object `enable.*` flags become real gates, admin user management, phone/SMS auth, book-audience enforcement, data-lifecycle contract, and effective-dated grants (final release: 14.8.0).

0 commit comments

Comments
 (0)