Skip to content

Commit a53c972

Browse files
committed
docs(releases): apply the 13 findings of the 17.7.0 fact-check record
Each finding re-verified against its cited commit, changeset or code at the version commit before it was applied. The stored-metadata summary no longer calls the metadata protocol the only reader for app-authored work (a flow's get_record node reads the projected, keyed form); the data-door filter refusal names its class, not the shapes that evaded 17.6.0's refusal, and two Security lines are reduced to their class the same way; 0fc8087 joins the smaller breaking changes; the datasource default refusal, the public-form withdrawal, the field-level read list, the account-linking opt-out and the approval-node registration claim are narrowed to what their changesets say; 49524f6 joins the Security list; the console CHANGELOG cap is stated; the os secret rewrap step is marked optional with its rollback cost; and the 17-6 correction's link label names where it lands. Claude-Session: https://claude.ai/code/session_016tKoy8NJa35Yih1FdzrVmn Co-authored-by: Claude <noreply@anthropic.com>
1 parent 8347e0d commit a53c972

3 files changed

Lines changed: 69 additions & 39 deletions

File tree

‎content/docs/releases/v17/17-6.mdx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,9 +1512,9 @@ Each was open when this page was written.
15121512
**Correction (2026-10-06):** #21158 will not land. It was closed as not
15131513
planned on 2026-10-04, on the maintainer's ruling that there is no demand for
15141514
the `guest` anchor's grants, so in 17.7.0 too an app-declared anonymous
1515-
endpoint (`authRequired: false`) cannot read or write objects. See [17.6.0's
1516-
known issues](/docs/releases/v17/17-7#notable-fixes-in-1770) on the 17.7.0
1517-
page.
1515+
endpoint (`authRequired: false`) cannot read or write objects. See [Notable
1516+
fixes in 17.7.0](/docs/releases/v17/17-7#notable-fixes-in-1770) (its "17.6.0's
1517+
known issues" list) on the 17.7.0 page.
15181518
- The [known console issues](#new-in-console-studio--objectui-pins-in-1760) at
15191519
the bundled pin.
15201520

‎content/docs/releases/v17/17-7.mdx‎

Lines changed: 60 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ description: "Release notes and upgrade checklist for 17.7.0 of the v17 line."
7272
- **Public forms open only on an explicit switch.** A form is served
7373
anonymously only when its `sharing` sets `enabled: true` beside
7474
`allowAnonymous` and `publicLink` (`6dd99b8`, #21566), and a withdrawal at
75-
any metadata layer holds (`3c7785d`, #21864). ⚠️ **A form that set only
75+
any metadata layer holds, within two [known limits](#public-forms)
76+
(`3c7785d`, #21864). ⚠️ **A form that set only
7677
`allowAnonymous` and `publicLink` answers `404 FORM_NOT_FOUND` after the
7778
upgrade.**
7879
- **Jobs carry their own code.** A job takes a sandboxed `body` (`f1e4ae5`,
@@ -155,8 +156,8 @@ explicitly breaking. Several things in this release change behaviour on a
155156
- a view container with no `form` no longer serves its first `formViews` entry
156157
as the default create and edit form;
157158
- a stored datasource row under a code-defined name no longer replaces the code
158-
definition at boot, and `PUT` / `DELETE /api/v1/meta/datasource/default`
159-
answer `403`;
159+
definition at boot, and `PUT /api/v1/meta/datasource/default`, and a `DELETE`
160+
of it with no stored row, answer `403`;
160161
- on `objectstack start`, the federation boot gate compares every federated
161162
object, so the default `onMismatch: 'fail'` can stop a boot that used to pass;
162163
- the environment-membership gate and the organization slug guard answer
@@ -203,7 +204,9 @@ rewrite; each says so. An app keeps `engines.protocol: '^17'`.
203204

204205
`sys_metadata` holds each metadata body as stored, credential material
205206
included, and `sys_metadata_history` holds its versions. For app-authored work,
206-
the metadata protocol is now their only writer and their only reader.
207+
the metadata protocol is now their only writer. A sandboxed hook, action or job
208+
body also reads them only through it, and a flow's `get_record` node reads them
209+
only in the projected, keyed form the data door serves.
207210

208211
- **Sandboxed bodies.** A hook with a sandboxed `body` whose `object` names
209212
either table, alone or in a list, is not bound: it is refused at
@@ -238,9 +241,8 @@ the metadata protocol is now their only writer and their only reader.
238241
`409 METADATA_CONFLICT`; take the token from the next read and retry. Filter,
239242
sort and group on the two content-hash columns and on the history table's
240243
`change_note` answer `400 INVALID_FIELD` on the data door, the MCP stdio
241-
reader and the analytics door. On the data door, so does a filter that
242-
reaches the body or a hash column through a `{ $field }` comparand, or more
243-
than 32 combinators deep (`5d0e4e2`, #21619).
244+
reader and the analytics door. On the data door, so does any filter that
245+
reaches the body or a hash column indirectly (`5d0e4e2`, #21619).
244246

245247
**Migration.** Change metadata with `PUT /api/v1/meta/:type/:name`, and read it
246248
with `GET /api/v1/meta/:type/:name` and `…/history`. Delete a body hook bound to
@@ -312,7 +314,9 @@ no mechanical rewrite for any of this.
312314
older bare form still opens. ⚠️ **A secret set or rotated on 17.7.0 cannot be
313315
opened by an earlier release**, so a rollback past it needs those values set
314316
again. `os secret rewrap` (dry run by default, `--apply` to write) re-seals the
315-
older ciphertext at rest (`0557c2f`, #21469).
317+
older ciphertext at rest (`0557c2f`, #21469). Nothing on the upgrade path runs
318+
it, and a row it re-seals carries `v2:` too, so an applied run has the same
319+
rollback cost.
316320

317321
#### On the write doors, a row the caller cannot read is not there
318322

@@ -348,8 +352,9 @@ no mechanical rewrite for any of this.
348352
now also keeps verification values in the database, so a reset link, one-time
349353
code or verification link that was in flight in the cache alone at deploy time
350354
can no longer be consumed, and its user requests a fresh one.
351-
Set `account.accountLinking.requireLocalEmailVerified: false` to restore the
352-
old linking, after reading the library's account-takeover warning.
355+
Set `account.accountLinking.requireLocalEmailVerified: false` to turn the
356+
local-verification check off again (an unlinked provider still does not
357+
re-link implicitly), after reading the library's account-takeover warning.
353358

354359
#### Reads and writes serve declared fields, and the engine refuses names it does not know
355360

@@ -429,9 +434,10 @@ no mechanical rewrite for any of this.
429434
`*.datasource.ts` answers `403 NOT_OVERRIDABLE` (it answered `200` and stored a
430435
row), and so does a `DELETE` with no stored row (`9cc2c79`, #21942). The boot
431436
restore no longer lets a stored row displace a code-defined datasource, opens
432-
no pool from one, and logs one warning naming it; `PUT` and `DELETE` on
433-
`/api/v1/meta/datasource/default` answer `403` too, naming the host's database
434-
configuration as the remedy (`753e7a1`, #21965). Change a code-defined
437+
no pool from one, and logs one warning naming it; `PUT` on
438+
`/api/v1/meta/datasource/default`, and a `DELETE` there with no stored row,
439+
answer `403` too, naming the host's database configuration as the remedy
440+
(`753e7a1`, #21965). Change a code-defined
435441
datasource in its source, or in the host's database URL for `default`, and
436442
`DELETE` a row the warning names. Until you do, the metadata door's reads in
437443
17.7.0 still serve that row, not the code definition the boot and the admin
@@ -672,8 +678,9 @@ measured by any of the changes.
672678
#21893), against `ApprovalNodeConfigSchema`: an undeclared key, a refused
673679
value (`escalation.timeoutHours: 0.5`, under its minimum of 1) and a missing
674680
`approvers` are refused at `os validate`, `os compile`, `defineStack`, the
675-
metadata save door and `registerFlow`, where they used to register and fail
676-
every run that reached the node. A stored flow carrying one is skipped at
681+
metadata save door and `registerFlow`. `registerFlow` already refused an
682+
undeclared key; a refused value used to register there and fail every run
683+
that reached the node. A stored flow carrying one is skipped at
677684
boot with a warning. D3 `flow-approval-node-config-contract-refused`.
678685
- **A flow the `kernel:ready` bind refuses is withdrawn** (`54fb60a`, #21897).
679686
It used to stay registered and `active` from the boot pull, with its trigger
@@ -746,7 +753,12 @@ measured by any of the changes.
746753
withdraws is refused `403 NOT_OVERRIDABLE`. A package-shipped form that was
747754
parsed by the strict stack schema and keeps its link without switching
748755
`enabled` on is a withdrawal. Between 17.6.0 and this change an organization
749-
overlay could re-open such a form; that never shipped in a release.
756+
overlay could re-open such a form; that never shipped in a release. Two
757+
limits remain. The form doors may still serve an organization overlay's copy
758+
of the form when that overlay was stored before the withdrawal, or restored by
759+
a rollback or commit revert, which the save check does not gate: withdraw the
760+
form in that overlay too. And a withdrawal closes the view's name in every
761+
package that ships a view of that name (#21934).
750762
- **Walled postures** (`a7ab047`, #21580; `ce53218`, #21473). A form whose object
751763
is walled by an organization column answers `404 FORM_NOT_FOUND` to anonymous
752764
visitors (its submit used to answer `500`); the administrator's read explains
@@ -858,6 +870,13 @@ measured by any of the changes.
858870

859871
#### Smaller breaking changes
860872

873+
- `action-name-undefined` now reads a `record:related_list` block's
874+
`properties.actions`: each id must name an action of the related object
875+
(defined on it, or a `stack.actions` entry bound to it by `objectName`) that
876+
declares a `list_toolbar`, `list_item` or `record_related` location, so a
877+
stack that built clean can fail `os validate`, `os lint` and `os build`
878+
(`0fc8087`, #21626). Such an id never drew a button; define the action on the
879+
related object, or remove the id.
861880
- A file field's `accept` / `maxSize` refusal answers
862881
`400 ERR_FILE_CONSTRAINT` naming the field (it was `500`), and
863882
`FileConstraintError` is constructed as `(field, constraint, message)`
@@ -1000,15 +1019,20 @@ Everything else is in the per-package `CHANGELOG.md` files.
10001019
them before.
10011020
- Field-level reads are narrowed on more surfaces: the object-schema mask
10021021
removes a denied field's references from the whole served document
1003-
(`a6a7547`, #21743) and judges an `objectOverride` param against the object it
1004-
names (`e6dc7a2`, #21904); an activity row whose every changed field the
1005-
reader is withheld is no longer served (`3bddd4a`, #21427); global search
1006-
skips the objects and fields the caller cannot read instead of answering `403`
1007-
(`87712ab`, #21879); and a field-narrowed search no longer matches through the
1008-
pinyin companion of a field outside the set (`0728cbf`, #21930).
1022+
(`a6a7547`, #21743); an activity row whose every changed field the reader is
1023+
withheld is no longer served (`3bddd4a`, #21427); and a field-narrowed search
1024+
no longer matches through a field outside the set (`0728cbf`, #21930). The
1025+
mask also judges an `objectOverride` param against the object it names, so a
1026+
delegated admin is now served the invite action (`e6dc7a2`, #21904), and
1027+
global search skips the objects and fields the caller cannot read instead of
1028+
answering `403` (`87712ab`, #21879).
10091029
- A write refusal on an attachment or a comment no longer names a parent record
10101030
the caller cannot read (`50b5e03`, #21769), and a by-id write of a hidden row
10111031
answers as a missing one ([above](#on-the-write-doors-a-row-the-caller-cannot-read-is-not-there)).
1032+
- A withdrawn public form is refused on both anonymous form routes and creates
1033+
no record, and both routes refuse the request, instead of serving the form,
1034+
when a service they need to resolve it is registered but cannot be reached
1035+
(`49524f6`, #21420).
10121036
- The stored-metadata family's credential material stays behind the door:
10131037
keyed content hashes, refused evaluate shapes, projected reads for host code
10141038
and flows, and no access for app-authored bodies
@@ -1017,8 +1041,8 @@ Everything else is in the per-package `CHANGELOG.md` files.
10171041
responses, events, webhooks, approval snapshots, flow trigger records and the
10181042
share-link password hash
10191043
([above](#credentials-leave-the-copies-they-were-made-into)); the datasource
1020-
read redaction resolves a driver by every spelling the write door accepts
1021-
(`fb69825`, #21963).
1044+
read redaction identifies a driver the way the write door does (`fb69825`,
1045+
#21963).
10221046
- A hook's `handler` name can no longer bind to another package's function
10231047
(`98eb3b9`, #21653), an in-process verb can no longer address an
10241048
unregistered table by name (`eb9ef79`, #21545), and a plugin signature labelled
@@ -1118,7 +1142,8 @@ Five pin moves carry the console half of this release:
11181142
releasing objectui changesets (74, 111, 17, 24 and 3) of the 254 added across
11191143
173 objectui commits; 25 changesets release nothing, and 13 commits carry no
11201144
changeset. The per-commit lists are in `packages/console/CHANGELOG.md` under
1121-
`## 17.7.0`.
1145+
`## 17.7.0`; the second pin's list stops at 100 of its 111 releasing
1146+
changesets.
11221147

11231148
- **17.6.0's console issues are fixed** in the first pin: the dataset designer
11241149
no longer writes `field: ''` (objectui `0858267e4`), an External or
@@ -1271,8 +1296,8 @@ believes they are done — so this list claims nothing it has not been given.
12711296
- **Find code that addresses an object by a name the registry does not hold**
12721297
through the engine, and register the object. *Not exercised.*
12731298
- **If you may need to roll back past 17.7.0**, keep a way to set again every
1274-
secret you set or rotate on it: an earlier release cannot open the new `v2:`
1275-
ciphertext. *Not exercised.*
1299+
secret you set, rotate or re-wrap on it: an earlier release cannot open the
1300+
new `v2:` ciphertext. *Not exercised.*
12761301

12771302
**Getting onto the release**
12781303

@@ -1306,8 +1331,12 @@ believes they are done — so this list claims nothing it has not been given.
13061331
*Not exercised.*
13071332
- **Resume, cancel or purge paused flow runs created before the upgrade**; they
13081333
still hold clear credential values. *Not exercised.*
1309-
- **Run `os secret rewrap`, then `os secret rewrap --apply`**, to re-seal older
1310-
`sys_secret` ciphertext. *Not exercised.*
1334+
- **Optional, and only once you will not roll back past 17.7.0: run
1335+
`os secret rewrap`, then `os secret rewrap --apply`**, to re-seal older
1336+
`sys_secret` ciphertext. Nothing on the upgrade path runs it. Every row it
1337+
re-seals carries `v2:`, which an earlier release cannot open, so `--apply`
1338+
removes the rollback path for those secrets: a rollback past 17.7.0 needs
1339+
each of them set again. *Not exercised.*
13111340
- **On `objectstack start` with federated objects**, expect the boot gate to
13121341
compare them; fix any drift it names or set `onMismatch: 'warn'`. *Not
13131342
exercised.*
@@ -1327,8 +1356,8 @@ believes they are done — so this list claims nothing it has not been given.
13271356
`approval` node configs. *Not exercised.*
13281357
- **Fix the new author-time errors:** `resultDialog` translation keys under an
13291358
action with no `resultDialog`, cube members over JSON-stored or incompatible
1330-
columns, `record:related_list` action ids its related object cannot draw, and
1331-
html-page literals of the wrong type. *Not exercised.*
1359+
columns, `record:related_list` action ids that name no drawable action of the
1360+
related object, and html-page literals of the wrong type. *Not exercised.*
13321361
- **Read the new `component-props-*` advisories** on page blocks and rewrite each
13331362
member in the shape the [page-block
13341363
table](#page-blocks-take-the-shape-their-renderers-read-21464) names; rename

‎content/docs/releases/v17/index.mdx‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,12 @@ parsed-but-never-enforced spec clusters are removed rather than maintained.
8383
> and its **[upgrade checklist](/docs/releases/v17/17-6#upgrade-checklist)**
8484
> before upgrading.
8585
>
86-
> 17.7.0 stays in that register. App-authored bodies and flows reach
87-
> `sys_metadata` and `sys_metadata_history` only through the metadata API; flow
88-
> secrets move into a write-only channel and the audit ledger stops copying
89-
> credential fields, so flow secrets, the JWT signing keys and private share
90-
> links are rotated after the upgrade; a write to a row the caller cannot read
86+
> 17.7.0 stays in that register. App-authored hook, action and job bodies reach
87+
> `sys_metadata` and `sys_metadata_history` only through the metadata API, and a
88+
> flow can no longer write them (its `get_record` node is served the projected
89+
> body and a keyed hash); flow secrets move into a write-only channel and the
90+
> audit ledger stops copying credential fields, so flow secrets, the JWT signing
91+
> keys and private share links are rotated after the upgrade; a write to a row the caller cannot read
9192
> answers as if the row did not exist; reads and writes stop returning a retired
9293
> field's leftover column; a public form needs `sharing.enabled: true`; and the
9394
> in-memory engine is no longer a boot store. Read **[Breaking changes &

0 commit comments

Comments
 (0)