Skip to content

Commit f87fdf3

Browse files
huangyiireneclaude
andauthored
docs(releases): split the v17 page per minor, and draft the missing 17.4.0 section (#17105)
* docs(releases): split the v17 page per minor, and draft the missing 17.4.0 section `content/docs/releases/v17.mdx` had reached 5,611 lines / 369 KB — 5.7x the finished v16 page, at 17.3.0, with 17.4.0 still to land. At roughly 90k tokens it is two thirds of the budget this project advertises for an entire application, in one release-notes file. It is now a folder, one self-contained page per minor: v17/index.mdx major landing: intro, release status, the cross-release upgrade-checklist guidance, References v17/17.0.mdx 1,917 highlights + detail + its own upgrade checklist v17/17.0-prerelease.mdx 1,688 archive: the rc.0 … rc.6 train, 30% of the old page and read by nobody upgrading between shipped versions v17/17.1 .. 17.3.mdx the same shape, 375-783 lines each v17/17.4.mdx NEW — see below A reader's question is per-minor, and the old page answered it in three places 1,200 lines apart: "What's new in 17.2.0", "Breaking changes & migration in 17.2.0", and "17.2.0" under a separate "Upgrade checklist" heading. Each minor page now carries all three. Content is conserved: every line of the old body appears in exactly one new file, verified by set difference. The `### 17.x.0` checklist headings are kept verbatim, so their `#1730`-style anchors survive the move. 17.4.0 was published on 2026-09-09 — the releases index already named it the current series — and had no section on any page. `v17/17.4.mdx` is a MACHINE DRAFT and says so at the top: 396 changesets de-duplicated by hash across all 61 package changelogs (a changeset that bumps six packages appears once), split into 35 carrying a breaking marker, 140 other minor entries, and 221 patch entries reported as counts rather than enumerated. No editorial pass has been made, the Highlights section is deliberately absent rather than guessed, and the upgrade checklist is not written because nobody has walked 17.3.0 → 17.4.0. Deciding what is user-facing is the maintainer's judgement at release time. Two gates learn the second layout rather than being weakened. `check-release-notes` (page existence) and `check-release-page-status` (what the page says) now accept either `v<major>.mdx` or `v<major>/index.mdx`; neither layout is deprecated and no baseline or exception list is introduced. Both pass, as does `check-release-section-coverage`, which skips v17 and names its own reason. `role-word-baseline.json` records a pure relocation: the single row `content/docs/releases/v17.mdx: 2` becomes `v17/17.0.mdx: 2`. Nothing else in the baseline moved — the sum is unchanged and no other file was re-baselined in the same stroke. One reserved word in a changeset's own headline is elided in 17.4.mdx with the elision stated inline, rather than silently rewritten. `upgrading.mdx` follows the checklist links to their new pages and gains a 17.4.0 row that says plainly that its checklist is not written. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016M1gHPfToXY4sUdzsD2CHa * docs(releases): nest the 17.0 pre-release archive under 17.0, and give 17.4.0 the sibling section shape Two corrections to the split. The rc.0 … rc.6 archive sat at the top level of `v17/`, so the sidebar listed it as a peer of the five real releases. It is not a release — it is 17.0.0's own pre-history — so 17.0.0 becomes a folder and the archive moves inside it: v17/17.0/index.mdx the release v17/17.0/prerelease.mdx the train that preceded it v17/17.0/meta.json The archive is now one level down, reachable by expanding 17.0.0 rather than sitting beside it, and its URL says the same thing: `/docs/releases/v17/17.0/prerelease`. Its title is now "Pre-release train (rc.0 … rc.6)" so the nav entry reads as an archive without opening it. The minors that have no sub-pages stay flat files; a minor becomes a folder only when it has something to nest. 17.4.0 now carries the same section shape as 17.1.0 through 17.3.0 — "Highlights — 17.4.0", "What's new in 17.4.0" with "Breaking changes & migration", "New capabilities", "Fixes" and "New in Console (Studio)" beneath it, then "Upgrade checklist" — so a reader crossing releases lands where they expect. Only the shape is finished. The two sections no mechanical pass can produce say so where they stand instead of being filled with a guess: Highlights is a judgement about audience, and the upgrade checklist is a walked route nobody has walked for 17.3.0 → 17.4.0. The Console section names the pin endpoints it can measure — `00d3f09c500c` (the last of 17.3.0's four moves, per that page) to `53ded82bf7a4` (the value of `.objectui-sha` on this tree, bumped by 30b0990) — and states plainly that the intermediate bumps are NOT enumerated, because this checkout's history for that file does not carry them. Naming the gap beats guessing the chain. `role-word-baseline.json` follows the move: one row, path only, `v17/17.0.mdx: 2` to `v17/17.0/index.mdx: 2`. Count unchanged, nothing else re-baselined. check-release-notes, check-release-page-status, check-role-word, check-doc-anchors (337 fragment links, all resolving) and check-docs-single-h1 all pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016M1gHPfToXY4sUdzsD2CHa * docs(releases): delete the 17.0.0 pre-release archive instead of housing it The rc.0 … rc.6 archive was 1,688 lines — 30% of the old monolithic v17 page — describing changes BETWEEN release candidates of a version that shipped on 2026-08-14. The train it records ended 2026-08-10. Everything it carried is contained in the shipped 17.0.0. It had no good home. Flat inside `v17/` it sat in the sidebar as a peer of the five real releases, which it is not. Nested under `17.0/` it forced a folder and a fourth path segment into existence for one archive page, and made 17.0.0 the only minor that expands. Both placements were wrong for the same reason: the page does not earn a place in the reading path, so any place given to it is one too many. Deleted. `17.0` goes back to a flat file, the folder and its `meta.json` go with it, and the sidebar loses the nesting level entirely: Releases > v17 > [v17, 17.4.0, 17.3.0, 17.2.0, 17.1.0, 17.0.0] Nothing is lost that a reader can reach for. "When exactly did X change during the rc train" is a changelog question, not a documentation-site one, and it is answered by the `CHANGELOG.md` files inside the published npm tarballs and by this repository's history. 17.0.0's own page now says that in place of the archive link, rather than pointing at a page that is gone. The two links into the archive — both written earlier in this same branch — go with it. `role-word-baseline.json` follows the file back to the flat path: `v17/17.0/index.mdx: 2` returns to `v17/17.0.mdx: 2`, count unchanged, nothing else re-baselined. check-release-notes, check-release-page-status, check-role-word, check-doc-anchors and check-docs-single-h1 all pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016M1gHPfToXY4sUdzsD2CHa * docs(releases): give the v17 minor pages dotless slugs so link checking resolves them The v17 split landed the per-minor pages as `17.0.mdx` … `17.4.mdx`, and "Check Documentation Links" went red with 20 `File not found` errors, all of them `/docs/releases/v17/17.N`. Root cause, reproduced against the pinned lychee 0.24.2 with the workflow's own argv and isolated in a three-link fixture: /docs/t/17.3 (17.3.mdx exists) -> ERROR File not found /docs/t/17-3 (17-3.mdx exists) -> OK /docs/t/plain (plain.mdx exists) -> OK `--fallback-extensions mdx,md` does not fire when the last path segment already contains a dot — lychee reads `.3` as the extension and never tries `.mdx`. It is the filename shape, not the split, that the checker cannot follow. So the slugs lose the dot. Nothing else moves: * `git mv` 17.N.mdx -> 17-N.mdx, contents untouched; * every `/docs/releases/v17/17.N` link rewritten to `17-N`; * `v17/meta.json` pages renamed to match; * the role-word baseline key follows the file (count stays 2 — pure relocation, the one path that gate documents as legitimate). Frontmatter titles are unchanged, so the sidebar still reads 17.0.0 … 17.4.0 — the slug is invisible to readers. Verified locally with the workflow's exact command line: 2152 links, 0 errors (was 20). check-release-notes, check-release-page-status, check-doc-anchors, check-docs-single-h1 and check-role-word all pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016M1gHPfToXY4sUdzsD2CHa * fix(gates): regenerate the hand-written docs ledger, and stop the coverage gate skipping v17 Two consequences of the v17 split that CI found and the local run had not. 1. `scripts/docs-audit/handwritten-docs.json` is GENERATED output — the audit scope, derived as `content/docs/**/*.mdx` minus the generated references, with hand-editing rejected outright. The split moved six pages under it, so `check:docs-audit-scope` went red naming both directions of the drift: one listed path gone, six real pages unlisted. Regenerated with the gate's own `--write`; the diff is exactly those six for that one, nothing else moved. Left unfixed this is not cosmetic: a FULL audit would have called itself full while silently skipping every v17 page, and an agent pointed at the dead path would report "0 fixes" — indistinguishable in the summary from a page that was read and found accurate. 2. `check-release-section-coverage` looked only for a flat `v<major>.mdx`, so after the split it printed "(v17: … skipped)" and then reported "2 GA major(s) in scope (v16, v17); every one has a heading on its major's release page". It was asserting nothing about v17 while naming it as covered. The skip is explicitly justified in the source by the two sibling gates going red on the same fact — and this PR taught both of them the folder layout, so that justification had gone. It now reads either layout, the folder as one corpus, because "some heading names this minor" is a property of the major's prose wherever it is written; the split moved `## What's new in 17.1.0` from line 3475 of one file to line 5 of another, which is not a coverage change. Proven to measure rather than merely stop printing "skipped": with every heading naming the 17.4 series mutated away, the gate reports the finding against `content/docs/releases/v17/` and exits 0 advisory / 1 --strict. Its 50-case self-test is unchanged and still passes. No gate is weakened and no baseline or exception list is added: one generated artifact regenerated by its own generator, and one lookup taught the second layout its two siblings already accept. check:docs-audit-scope, doc-anchors, doc-authoring, docs-redirects, docs-single-h1, release-notes, release-page-status, release-index-currency-sync, role-word, quick-reference-counts, corpus-claim-drift, published-readme-links, org-identifier and docs-image-tag all pass; lychee reports 2152 links, 0 errors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016M1gHPfToXY4sUdzsD2CHa --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent f904e61 commit f87fdf3

14 files changed

Lines changed: 4529 additions & 5627 deletions

content/docs/releases/v17.mdx

Lines changed: 0 additions & 5611 deletions
This file was deleted.

content/docs/releases/v17/17-0.mdx

Lines changed: 1919 additions & 0 deletions
Large diffs are not rendered by default.

content/docs/releases/v17/17-1.mdx

Lines changed: 720 additions & 0 deletions
Large diffs are not rendered by default.

content/docs/releases/v17/17-2.mdx

Lines changed: 377 additions & 0 deletions
Large diffs are not rendered by default.

content/docs/releases/v17/17-3.mdx

Lines changed: 783 additions & 0 deletions
Large diffs are not rendered by default.

content/docs/releases/v17/17-4.mdx

Lines changed: 449 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
---
2+
title: v17
3+
description: "The v17 line — a truth-telling release. Files become owned records, the export privilege stops riding on read, the SDK is reconciled against the routes the server mounts, and a boot that cannot reach its datasource stops pretending it can. Per-release notes for 17.0.0 through 17.4.0."
4+
---
5+
6+
**The v17 line** is a truth-telling release. Where v16 made *declared metadata*
7+
honest, v17 does the same for the surfaces around it: files stop being inline
8+
blobs and become owned `sys_file` records with a governed download path; the
9+
export privilege stops being a free rider on read; the SDK stops shipping
10+
methods no server ever answered; a datasource that cannot connect stops booting
11+
clean and failing every query afterwards; and an approval request stops being
12+
readable by everyone in the tenant. Alongside that, `agent.tools[]`, the
13+
GraphQL surface, the `ObjectStackProtocol` alias, and a long tail of
14+
parsed-but-never-enforced spec clusters are removed rather than maintained.
15+
16+
> **Release status: 17.4.0 is released**, and is the current version of the v17
17+
> line. It was published on 2026-09-09, taking over from
18+
> 17.3.0 — published 2026-09-04, which took over from
19+
> 17.2.0 — published 2026-08-23, which took over from 17.1.0 — published
20+
> 2026-08-20, which took over from 17.0.0 — published 2026-08-14, closing a
21+
> train that ran through `17.0.0-rc.0``rc.6` (the last of them cut
22+
> 2026-08-10). A plain install now resolves 17.4.0. `changeset pre
23+
> exit` ran with the 17.0.0 cut, so the `@objectstack/*` packages no longer
24+
> publish as `17.0.0-rc.N`. Caret ranges on `^16.x` hold at 16.x until you opt
25+
> in, which is the reason this train is a major at all: its breaking density
26+
> (the `ApiMethod` shrink, the GraphQL removal, the ADR-0104 write cutover, the
27+
> dead-cluster retirements) is too high to auto-upgrade `^16.x` consumers into
28+
> on their next install.
29+
>
30+
> ⚠️ **17.1.0, 17.2.0, 17.3.0 and 17.4.0 are minors by version number, not by
31+
> blast radius. Moving between them is not a tag swap.** Several of 17.1.0's security
32+
> corrections change who can read or write on an existing deployment — read its
33+
> upgrade checklist below. 17.2.0 adds write-path accept-set tightenings of the
34+
> same shape: a by-id `update`/`delete` that used to silently drop an extra
35+
> `where` predicate, or a mismatched `data.id` / `where.id`, now refuses loudly
36+
> instead (#11009, #11142). 17.3.0 goes further still: it renames a published
37+
> SDK namespace with **no aliases** (`client.projects.*`
38+
> `client.environments.*`), flips the self-registration default to
39+
> `invite_only`, starts enforcing `unique` / `indexes[]` on `driver-memory`,
40+
> makes a permission-store outage fail loudly, and tenant-scopes
41+
> `sys_record_share` with an operator-invoked backfill for the rows written
42+
> before it. Read **[Breaking changes & migration in
43+
> 17.2.0](/docs/releases/v17/17-2#breaking-changes--migration-in-1720)** and **[Breaking changes &
44+
> migration in 17.3.0](/docs/releases/v17/17-3#breaking-changes--migration-in-1730)** before upgrading.
45+
>
46+
> **17.4.0's notes are a machine draft, not curated.** 396 changesets across 61
47+
> packages landed in it, 35 of them carrying a breaking marker, and no editorial
48+
> pass has been made — see **[17.4.0](/docs/releases/v17/17-4)**, which says so at
49+
> the top and lists what it does and does not cover. Its upgrade checklist is
50+
> **not written**: nobody has walked 17.3.0 → 17.4.0.
51+
52+
## Per-release notes
53+
54+
Each release below is a self-contained page: what it changed, what breaks, and its own upgrade checklist.
55+
56+
- **[17.4.0](/docs/releases/v17/17-4)** — current
57+
- **[17.3.0](/docs/releases/v17/17-3)**
58+
- **[17.2.0](/docs/releases/v17/17-2)**
59+
- **[17.1.0](/docs/releases/v17/17-1)**
60+
- **[17.0.0](/docs/releases/v17/17-0)** — the major cut
61+
62+
## Upgrade checklists
63+
64+
One checklist per release, for the release you are landing on **and** every
65+
release you cross to get there.
66+
67+
<Callout type="warn">
68+
**How far each list below has actually been walked.** The 17.3.0 list is the only
69+
one on this page written against a **measured upgrade**: an application
70+
repository was moved 17.2.0 → 17.3.0 by a reader holding nothing but the
71+
published documentation, the `CHANGELOG.md` files inside the published npm
72+
tarballs, and the `os` CLI's own output. Every line it produced is marked
73+
**measured**, and several of them are changes whose own changelog entries are not
74+
marked breaking — which is exactly why a checklist is not a restatement of
75+
[Breaking changes & migration in 17.3.0](/docs/releases/v17/17-3#breaking-changes--migration-in-1730).
76+
77+
**That run covered one hop, 17.2.0 → 17.3.0. Nobody has walked 17.1.0 →
78+
17.2.0.** Every line in the 17.2.0 list is derived from a change's own
79+
**Migration** note and is marked **not exercised**: accurate about what changed,
80+
unproven about what it costs to cross. The two are kept apart on purpose — a step
81+
nobody has run, presented beside steps that were, is how a reader finishes a
82+
checklist and believes they are done.
83+
</Callout>
84+
85+
Per-release checklists: [17.4.0](/docs/releases/v17/17-4#upgrade-checklist) · [17.3.0](/docs/releases/v17/17-3#upgrade-checklist) · [17.2.0](/docs/releases/v17/17-2#upgrade-checklist) · [17.1.0](/docs/releases/v17/17-1#upgrade-checklist) · [17.0.0](/docs/releases/v17/17-0#upgrade-checklist)
86+
87+
## References
88+
89+
ADR-0104 (field runtime value-shape contract / file-as-reference) · ADR-0105
90+
(group tenancy posture) · ADR-0106 (metadata-plane FLS, proposed) · ADR-0108
91+
(membership grade is not capability) · ADR-0109 (agent tools from skills) ·
92+
ADR-0076 D9/D11 (protocol alias dissolution, dispatcher decomposition) ·
93+
ADR-0087 D4 (change manifest / `migrate meta`) · ADR-0049 (enforce-or-remove) ·
94+
ADR-0078 (loud at the producer) · ADR-0090 D3 (`team` recipient) ·
95+
#3825 (Node 22) · #3544/#3710 (export axis) · #3543/#3391 (ApiMethod
96+
derivation) · #3760 (user-less runs) · #3855 (alias retirement) ·
97+
#3820 (agent authoring) · #3590 (approval visibility) · #3865 (sharing `full`) ·
98+
#3617 (files-to-references migration) · #3447 (dynamic approver routing) ·
99+
#3563/#3587/#3612/#3718 (route ledger + SDK surface) · #2462 (GraphQL removal) ·
100+
#3741/#3758/#3826 (datasource fail-fast) · #3696 (per-tenant `unique`) ·
101+
#3676/#3778/#3847 (i18n contract conformance).
102+
103+
Landed since rc.0: ADR-0110 (action declaration admission) · ADR-0111 (sharing
104+
authority) · ADR-0112 (error-code vocabulary) · ADR-0113 (`required` split) ·
105+
ADR-0114 (field-error catalog) · ADR-0115 (no fabricating fallbacks) ·
106+
ADR-0116 (declared plugin ordering) · ADR-0053 (temporal semantics) ·
107+
#3962/#3951 (actions speak HTTP) · #3915 (action type dispatch) ·
108+
#4121/#4134/#4164/#4181/#4226/#4254/#4256/#4363 (list queries apply or fail) ·
109+
#3795/#4346/#4371 (one alias fold) · #3899/#3878 (request-body validation) ·
110+
#3939/#3897/#3933/#3946/#3960 (bulk binding + caps) · #3843/#3983/#4038/#4053
111+
(envelope convergence) · #3957 (localized validation) · #4093/#4113/#3891/#4087
112+
(honest absence) · #4073 (Hono transport adapter) · #4065/#4083 (memory-driver
113+
persistence) · #4246 (`artifact-api` removal) · #3903 (stored-metadata
114+
conversion replay) · #4277/#4045/#4027/#4347 (flow config enforcement) ·
115+
#3948/#4029 (view-filter operator parity) · #4157/#4128 (analytics stops
116+
guessing) · #3916 (report ordering) · #4350 (protocol-17 relabel) ·
117+
#4127/#4251 (typed service slots + fail-open fixes) · #3917/#3924 (`os migrate`
118+
occupancy + deferred DDL) · #4243/#4270 (platform-objects infrastructure) ·
119+
#4395/#4396 (unmeasured effects) · #4365/#4366 (approval reassign + audit
120+
attribution) · #4261/#4248 (published-files hygiene).
121+
122+
Landed since rc.1: ADR-0118 (non-user actor contract) · ADR-0119
123+
(plugin-reachable transactions, migration journal) · ADR-0088 (metadata-kind
124+
admission) · ADR-0103 (`managedBy` buckets) · #4535 + #4411 (dual-source
125+
convergence C1–C17: #4572, #4587, #4610, #4641, #4653, #4658, #4661, #4684,
126+
#4688, #4691, #4703, #4737, #4738, #4739, #4740, #4741) · #4537/#4538/#4539
127+
(enum, contracts and cross-form convergence) · #4446 (symbol-identity ratchet) ·
128+
#4001 final batches (#4514/#4519/#4522/#4527/#4528/#4529/#4530/#4531/#4532/#4533/#4534/#4541) ·
129+
#4544 (ADR-0078 completeness, Phases 1/3/4: #4501, #4565, #4574, #4599) ·
130+
#4463 (runtime authoring gate) · #4409/#4487/#4488 (rule + liveness coverage) ·
131+
#4583/#4634/#4484/#4618/#4579/#4657/#4673/#4616 (enforce-or-remove: datasource,
132+
driver and contract surfaces) · #4509 (validation kind, job door, doc.tags,
133+
email-template bridge) · #4667 (authorWarn keys) · #3355 (`system-data`) ·
134+
#4612/#4617/#4620 (atomicity + migration journal) · #4793 (batch row shape) ·
135+
#4639/#4626/#4602/#4678 (event contracts + client-react) · #4343 (`script`
136+
node) · #4649/#4770/#4775/#4784 (predicate and condition semantics) ·
137+
#4419 (`findOne`) · #4462/#4410/#4456 (datasource routing + config contract) ·
138+
#4630/#4651/#4722/#4757 (security corrections) · #4433/#4434/#4640/#4669
139+
(sharing + permission corrections) · #4467/#4437/#4442/#4708/#4820 (analytics) ·
140+
#4327/#4454/#4542 (stored-metadata migration).
141+
142+
Landed since rc.2: ADR-0122 (parsed/author state naming: #5551, #6350 phase 2) ·
143+
ADR-0045 (app publish gate: #4829) · ADR-0097 §3 (connector credential
144+
references) · #4936/#4939/#5111/#5040 (declarative `apis:` goes live) ·
145+
#6345 (one driver vocabulary, `mongo``mongodb`) ·
146+
#6212/#6075/#6320/#6321 (driver query contract narrowing) ·
147+
#5488 (`api` is code-only) · #5561 (`resumeAuthority` fail-closed) ·
148+
#6361 (notification `cursor` retirement) · #5775/#6776 (SDUI component props) ·
149+
#6239 (`ViewProtocol` retirement) · #6188 (aggregation function narrowing) ·
150+
#5051 (`composeStacks` i18n) · #5945 (`HookContext.api`) · #6139
151+
(`HierarchyScopeContext` posture) · #5599 (view union identity) ·
152+
#4671 (`system-data` import) · #5696/#5351 (transaction tightening) ·
153+
#6536 (`ExportFieldMeta`) · #6704 (`runAutomations` default) ·
154+
#6748 (`ActionDescriptor.isAsync`) · #6771 (overlay index producer).
155+
156+
Landed since rc.6: ADR-0123 D2 (active-organization write refusal:
157+
#8247/#8208) · #7990/#8082/#8336/#8075 (inline credentials refused at publish) ·
158+
#7986/#7799/#7722/#8022/#8542/#8558 (webhook credential handling) ·
159+
#7522/#8273 (settings crypto fail-closed + wire code) · #7728 (`internal: true`) ·
160+
#8136/#8333/#8441/#8442/#8443/#8086/#8502 (driver-text disclosure) ·
161+
#8323/#8468/#8554/#8555/#8577/#8459/#8375 (per-organization uniqueness) ·
162+
#7626 (expand disclosure) · #7835/#7738/#8119 (federated tenancy) ·
163+
#8095/#8240/#7761/#7795/#8158 (org-scoped sharing + invitation reads) ·
164+
#5222/#7597/#7598/#8220/#7929/#7988 (`$field` cross-field comparison) ·
165+
#7606 (closed query-parameter ingress) · #6682/#6518 (`$contains` case
166+
sensitivity) · #8010 (`view.exportOptions`) · #7176 (list-view passthrough
167+
keys) · #7893 (`field.allowRuntimeCreate`) · #8057 (`engine.update` upsert) ·
168+
#7481 (auth config flags) · #7596 (list comparand references) · #7496
169+
(`submitBehavior.url`) · #7780 (cross-tenant uninstall) · #6915 (memory-driver
170+
tenancy) · #7501/#7918/#7768 (number and currency contracts) ·
171+
#8445/#8567/#8592 (unbacked conflict targets) · #8269/#8283 (autonumber) ·
172+
#7580/#5346/#5376 (MongoDB query surface) · #8144/#8145/#8594/#8400 (audit
173+
writers) · #7533/#8050/#7639/#7546 (automation run durability) ·
174+
#8368 (`OS_ARTIFACT_URL`) · #5320/#8070 (`viewItems:`) · #7616/#8326 (security
175+
service surface) · #8600/#7891 (authored OWD at the object door) ·
176+
#8309/#8307/#7220 (security posture at runtime publish) · #7751 (`object-*`
177+
block props) · #8315/#7675 (audit action enum) · #7735/#8019 (change-email) ·
178+
#7762/#7978/#7685 (verification harness).
179+
180+
**17.1.0** — ADR-0049 (enforce-or-remove) · ADR-0055 (`controlled_by_parent`) ·
181+
ADR-0066 D3 (field `requiredPermissions`) · ADR-0067 (revert plans) · ADR-0068
182+
(platform-admin gate) · ADR-0090 D1 (OWD baseline) · ADR-0105 D7 (extension
183+
fields) · ADR-0110 D3 (failure is not emptiness) · ADR-0111 D7 (inert grants) ·
184+
ADR-0112 (error-code vocabulary, amended 2026-08-18) · ADR-0120 D3 (partitioned
185+
uniqueness) · #8613 (`active` stops granting) · #8710 (deactivated position,
186+
sharing rules) · #8681 (admin export wildcard) · #8993 (partial field masking) ·
187+
#8652 (read-only approval visibility) · #8155 (credential re-homing) · #8287
188+
(API-key organization) · #8778 (`tenancy.organizationField`) · #9934
189+
(`userMessage`) · #9106 (`error.code` closed at every door) · #9446 / #9462
190+
(flow-dispatch status table) · #8896 (four read seams) · #7529 / #9612 / #9176
191+
(runtime publish gate) · #8687 (strict top-level stack keys) · #9013 (dashboard
192+
`modal` target) · #9698 (sharing-rule enforceability) · #9257 (list-view `sort`) ·
193+
#8934 (`icontains`) · #8704 (`relatedListFilter`) · #9566 / #9474
194+
(`ActionSchema.onSuccess`) · #9225 / #9205 (email template rendering) · #8928
195+
(`os migrate duplicates`) · #9666 (scaffolds compile) · #8978 (ready banner) ·
196+
#8985 (`OS_INTERNAL_ARTIFACT_PATH`) · #9683 (`storage` slot) · #9730
197+
(`delegated_from`) · #8926 / #8807 / #8755 / #8622 / #9354 (MySQL driver) ·
198+
#9040 / #8337 / #9041 / #9091 / #9147 / #8495 (credential refusals at publish) ·
199+
#8873 / #8874 / #8696 (credentials reach the driver).
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"title": "v17",
3+
"pages": [
4+
"index",
5+
"17-4",
6+
"17-3",
7+
"17-2",
8+
"17-1",
9+
"17-0"
10+
]
11+
}

content/docs/upgrading.mdx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -295,10 +295,11 @@ have no other channel to reach you than the page below.
295295

296296
| Release | Where its upgrade notes live |
297297
| :--- | :--- |
298-
| v17.3.0 | [Upgrade checklist — 17.3.0](/docs/releases/v17#1730) |
299-
| v17.2.0 | [Upgrade checklist — 17.2.0](/docs/releases/v17#1720) |
300-
| v17.1.0 | [Upgrade checklist — 17.1.0](/docs/releases/v17#1710) |
301-
| v17.0.0 | [Upgrade checklist — 17.0.0](/docs/releases/v17#1700) |
298+
| v17.4.0 | [17.4.0](/docs/releases/v17/17-4) — ⛔ checklist not written; machine-draft notes only |
299+
| v17.3.0 | [Upgrade checklist — 17.3.0](/docs/releases/v17/17-3#upgrade-checklist) |
300+
| v17.2.0 | [Upgrade checklist — 17.2.0](/docs/releases/v17/17-2#upgrade-checklist) |
301+
| v17.1.0 | [Upgrade checklist — 17.1.0](/docs/releases/v17/17-1#upgrade-checklist) |
302+
| v17.0.0 | [Upgrade checklist — 17.0.0](/docs/releases/v17/17-0#upgrade-checklist) |
302303
| v16.0.0 | [Upgrade checklist](/docs/releases/v16#upgrade-checklist) |
303304
| v15.0.0 | [Upgrade checklist](/docs/releases/v15#upgrade-checklist) |
304305
| v14.0.0 | [Upgrade checklist](/docs/releases/v14#upgrade-checklist) |

scripts/check-release-notes.mjs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,15 @@ if (!inRootNav && !onDocsHome) {
8383
for (const major of releasedMajors()) {
8484
if (major < FLOOR_MAJOR || KNOWN_MISSING.has(major)) continue;
8585
const slug = `v${major}`;
86-
if (!existsSync(`${RELEASES_DIR}/${slug}.mdx`)) {
86+
// Two layouts, both first-class, and this gate owns EXISTENCE only: one flat
87+
// `v16.mdx`, or a `v17/` folder whose `index.mdx` is the major's landing page
88+
// with one file per minor beside it. Either satisfies "the major has a
89+
// curated, navigable page" — the nav entry is the folder name in both cases,
90+
// so the `metaPages` check below is unchanged. ⛔ Neither layout is deprecated.
91+
if (!existsSync(`${RELEASES_DIR}/${slug}.mdx`) && !existsSync(`${RELEASES_DIR}/${slug}/index.mdx`)) {
8792
problems.push(
88-
`${RELEASES_DIR}/${slug}.mdx is missing — @objectstack/spec shipped a ${major}.x ` +
93+
`${RELEASES_DIR}/${slug}.mdx (or ${RELEASES_DIR}/${slug}/index.mdx) is missing — ` +
94+
`@objectstack/spec shipped a ${major}.x ` +
8995
`release but there is no curated release page. Write it (lead with breaking ` +
9096
`changes + migration), then add "${slug}" to ${META_PATH}.`,
9197
);

0 commit comments

Comments
 (0)