Skip to content

Commit 8a7b08b

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/issue-23415-drop-storage-other-rows
Claude-Session: https://claude.ai/code/session_0121ooBYRmS8ziFXm9ai5YHm Co-authored-by: Claude <noreply@anthropic.com>
2 parents dce4a7e + 05ab9ef commit 8a7b08b

67 files changed

Lines changed: 2778 additions & 382 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
'@objectstack/spec': minor
3+
---
4+
5+
feat(spec)!: a page action row declares `ActionSchema`'s own `operation` enum and refuses `onSuccess` beside `operation: 'update'`, with the action's text
6+
7+
Clause-②: no (narrowing)
8+
9+
<!-- adr-0087: registered ui-page-action-row-operation-declared -->
10+
11+
**BREAKING**: an accept-set narrowing on two keys of four published page component rows, shipped as `minor` under the launch-window convention for accept-set narrowings.
12+
13+
The page action rows are `action:button` and `action:icon` (`properties`), and each member of an `action:group` or `action:menu` (`properties.actions[]`). Each forwards `operation` to the console's action runner, which reads it before any executor: `operation: 'update'` performs the declarative write through the platform action route and runs no executor of its own. The rows typed `operation` as an open value and never carried `ActionSchema`'s refusal of `onSuccess` beside `operation: 'update'`, so a row with an `api` or `script` executor, the write and a hop parsed while the same action was refused. Now:
14+
15+
- a row's `operation` is `ActionSchema`'s own enum (one member, `'update'`); `'delete'` and `'custom'` get the action's "bulk-def operation with no row-level form" refusal, and any other value is refused at `operation`;
16+
- a row's `onSuccess` beside `operation: 'update'` is refused whatever executor the row names (or none), with ONE text shared with `ActionSchema`: the hop would follow the write, whose success carries no result `${result.*}` could read.
17+
18+
`ActionSchema`'s reach is unchanged. Its message for the pairing used to open "`onSuccess` is not defined for an `operation: 'update'` action yet"; it now states what the runner does (reads `operation` before any executor, writes, then hops) and keeps the prescription "Drop `onSuccess`".
19+
20+
### FROM → TO
21+
22+
| before | what to write instead |
23+
| --- | --- |
24+
| `{ actionType: 'api', operation: 'update', patch: { status: 'done' }, onSuccess: { navigate: '/done' } }` (or `type` on a member, or no executor) | the same row without `onSuccess`: the runner performs the write before any executor, so the hop followed a write whose success declares no result |
25+
| `{ operation: 'delete', … }` / `{ operation: 'custom', … }` on a row | no `operation`: a row delete is the object's own delete affordance, and a row is already the action a bulk def's `'custom'` would name |
26+
| any other `operation` value | `operation: 'update'` with a `patch`, or no `operation` (the runner ran nothing for it) |
27+
28+
**The one-line fix: on a page action row, write `operation` only as `'update'`, and never beside `onSuccess`.** `os migrate meta --from 17` lists the D3 entry `ui-page-action-row-operation-declared`; the rewrite is by hand.
29+
30+
**What an author now sees.** `os validate`'s props gate reports the refusal at the row's `operation` or `onSuccess` (`properties.…`, or `properties.actions.N.…` for a member). For example, `{ actionType: 'api', operation: 'update', patch: { status: 'done' }, onSuccess: { navigate: '/done' } }` on an `action:button` gets: ``An `action:button`'s `onSuccess` (`operation: 'update'`) would follow a result the contract does not declare: the console's action runner reads `operation` before any executor, …``. The same row without `onSuccess` parses unchanged.
31+
32+
**Measured producers.** None in this repository. In objectui (at its pin `1fb1ced36243` and its main `b9814b3`), the action renderers' own tests carry `operation: 'update'` rows without `onSuccess`, which stay accepted; no row carries another `operation` value or the pairing. objectui's metadata-admin form already clears `onSuccess` when an author switches an action into an update.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
'@objectstack/spec': minor
3+
---
4+
5+
feat(spec)!: the page parse refuses a page component's `data` prop that names the retired view-level `api` data source, so the Studio, REST and MCP save door refuses it as `os validate` does (#23357)
6+
7+
**BREAKING** — a page whose `object-grid`, `object-map`, `object-gantt` or `object-tree` component carries `properties.data` with `provider: 'api'` is now refused by `PageSchema`, at the component's `properties.data.provider`, with the retirement's own prescription. Those four components take a view data source (`ViewDataSchema`) as `data`, so the step-18 retirement of the view-level `api` source reached them through the same schema; but the page parse leaves a component's `properties` an open record, and the component-props gate that refused the binding runs at the CLI doors only. A page saved through the Studio, REST or MCP therefore kept the binding, with its request headers, and the console kept sending it.
8+
9+
Clause-②: yes (narrowing)
10+
11+
The judge is the retirement's own: `ViewDataSchema` parses the component's `data`, and the prescription it raises is raised by the page parse unchanged (one text for a view and a page; the page's issue `code` is `custom`, as every object-level check on `PageSchema` raises). It reaches every component under `regions` and `slots`, at any depth, a component nested in a `page:tabs` item or a container included. It judges nothing else in the bag: another `data` provider, a component whose `data` is a row array (`object-kanban`, `object-calendar`, `object-timeline`), a custom or registered type with no props row, and a component's own `dataSource` binding are untouched. `checkPageComponentViewData` is exported from `@objectstack/spec/ui`, like the four other `PageSchema` checks, so a mirror built from `PageSchema.shape` can re-attach it.
12+
13+
## FROM → TO
14+
15+
| you wrote (accepted by the page parse until this change) | write instead |
16+
| --- | --- |
17+
| `properties.data` with `provider: 'api'` (and its `read` / `write` request blocks) on an `object-grid`, `object-map`, `object-gantt` or `object-tree` page component | `properties.data` with `provider: 'object'` and `object: '<object_name>'`, or `provider: 'value'` with `items: [...]`; an endpoint the page must read is a page component's `dataSource: { provider: 'api', read: { url: '/api/...' }, path? }`, same-origin and with no credential key |
18+
| `read.headers: { Authorization: '...' }` inside that binding | nothing: a credential never lives in metadata, and the console reads an element binding with its own signed-in fetch |
19+
20+
**The one-line fix:** bind each such component to its object or to static rows, and move any endpoint read onto a page component's `dataSource`.
21+
22+
**What an author who still writes it sees.** `definePage()`, `defineStack({ pages })`, `os validate` and `PUT /api/v1/meta/page/:name` refuse the page at `regions[i].components[j].properties.data.provider` (or the nested or slot position) with the prescription. At the save door that is `422 INVALID_METADATA`, nothing persisted.
23+
24+
**A page already stored with such a component.** `os migrate meta --stored` lists it by page and component (the step-18 entry `view-data-api-provider-retired`), and nothing rewrites it: deleting `data` would make the component query its object instead. Left as stored, the page still loads and is served, registered under `[metadata_spec_invalid]` with the refusal in the `_diagnostics` of every read, and its next save is refused with 422. The console stops sending the request when its own reader of the retired arm is deleted (objectstack-ai/objectui#12325); until then a stored page keeps sending it.
25+
26+
<!-- adr-0087: not-required (already-registered view-data-api-provider-retired) the step-18 entry already names the data prop of these four page components in its scope; this change makes the page parse refuse what that entry retired, and its acceptance criteria now name the page parse beside the component-props gate -->
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'@objectstack/plugin-security': patch
3+
---
4+
5+
refactor(plugin-security): the audience-anchor binding gate on `sys_position_permission_set` is deleted
6+
7+
Clause-②: no
8+
9+
`SecurityPlugin`'s private engine-middleware gate that refused binding a high-privilege permission set to the `everyone` or `guest` position guarded writes to `sys_position_permission_set` only. C3 stage 8 (#23222) unregistered that object, so no write has reached the gate since. The gate, its call in the middleware and its three unit cases are removed.
10+
11+
No behaviour changes, and nothing exported changes. The anchor tier itself (`describeAnchorForbiddenBits` from `@objectstack/spec/security`) still applies wherever a binding is made: when an `everyone` suggestion is confirmed (`confirmAudienceBindingSuggestion`), and on every derivation of the `everyone` anchor. No door binds a set to `guest`.

‎.changeset/console-b9814b334d8a.md‎

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
"@objectstack/console": minor
3+
---
4+
5+
Console (objectui) refreshed to `b9814b334d8a`. Frontend changes in this range:
6+
7+
Derived from the changesets objectui declared over the range — 31 releasing of 35 changesets added across 36 non-merge commits; omitted: 4 release-nothing changesets, 4 commits carrying no changeset (they ship no package code).
8+
9+
- **minor** — Studio's first draft save after opening an item no longer replaces a draft that was saved elsewhere in the meantime (objectui#11773). (objectui `b9814b334`)
10+
- **minor** — An empty list draws its declared link, and a list page's own empty state wins over its source view's (objectui#12270). (objectui `b434f5f47`)
11+
- **minor** — A `record:details` section heading can show how many values a field holds (objectui#12192). (objectui `c08c9332a`)
12+
- **minor** — The console and the runner bundles are built against `@objectstack/*` 18.0.0-next.0 (objectui#12030). In both, the `@objectstack/*` ranges are `devDependencies`, but each package… (objectui `c5406c201`)
13+
- **minor** — The ten locale packs follow `@objectstack/spec` 18's platform capability set (objectui#12030): the key `capability.label.manage_org_presentation` is replaced by `capability.label.… (objectui `c5406c201`)
14+
- **minor** — **BREAKING** — Depend on the `@objectstack/*` 18 prerelease line (objectui#12030). (objectui `c5406c201`)
15+
- **minor** — A report the viewer may not read shows the no-access state, not the server's refusal (objectui#12330). (objectui `2b06a91e6`)
16+
- **minor** — A flow action launched from a list toolbar now resolves the row selection by the same rule as a script action: `@object-ui/core`'s `resolveServerActionRecordId` (objectui#12331).… (objectui `2722d33c5`)
17+
- **minor** — Console writes that landed in silence now say so, and controls disabled on a read-only package say why to every user, not only to a mouse (objectui#12303). (objectui `b64fda3f6`)
18+
- **minor** — A record page draws one provenance footer for its record, whatever the number of `record:details` nodes it carries (objectui#12307). (objectui `28ebfb5f8`)
19+
- **minor** — The marketplace package page offers the install modes a package permits, managed or an unmanaged copy, and reads what the install door answers (objectui#12288, the objectui stage… (objectui `cea429b98`)
20+
- **minor** — Calendar quick-create no longer offers a dialog that cannot succeed. On an object with a required field it cannot fill, an empty-day click opens the full create form with the clic… (objectui `ee470719e`)
21+
- **minor** — A grid's inline-edit save no longer overwrites a concurrent write without a word (objectui#12292). The grid's default row save and "Save All" now send each row's `updated_at` as `… (objectui `3092aca7a`)
22+
- **minor** — The OAuth consent page names the requesting application by its registered name again, and never shows the raw `client_id` in the name's place (objectui#12301). (objectui `ca45c6d55`)
23+
- **minor** — The strict authoring face accepts `dataSource` on `record:related_list` (objectui#12302). The block's renderer has honoured the spec's per-element binding since objectstack#6953:… (objectui `093d55bb6`)
24+
- **minor** — `record:details`, `record:highlights` and `record:quick_actions` honour the per-element `dataSource` binding the spec already declares on every page component (objectui#12294). A… (objectui `82e5f5348`)
25+
- **minor** — `AutoNumberFieldMetadata` declares `autonumberFormat`, typed by reference to `@objectstack/spec`'s `FieldSchema.autonumberFormat`, and keeps `format` as its shorthand (objectui#12… (objectui `fd4872f9e`)
26+
- **minor** — **BREAKING** — `buildValidationRules` stops compiling a field-level `pattern` / `pattern_message` and `validate` (objectui#12242, maintainer ruling A). `@objectstack/spec`'s `FieldSchema` refuse… (objectui `5d3f437ab`)
27+
- **minor** — **BREAKING** — The field metadata types stop declaring the keys a host writes at runtime and the field-level regex keys, and `geolocation` leaves the `FieldMetadata` union (objectui#12242, secon… (objectui `5d3f437ab`)
28+
- **minor** — `@object-ui/fields` exports `fieldHelpText(field)`, the one read of the help line a field draws under its control (objectui#12213). (objectui `5b45c0d50`)
29+
- **minor** — **BREAKING** — A dashboard or report route's breadcrumb no longer carries a 「Dashboards」 or 「Reports」 crumb (objectui#12273, applying the maintainer's ruling on objectstack-ai/cloud#2768, as obj… (objectui `9f282ef53`)
30+
- **patch** — `data-table`: an inline edit made while a row save or Save All is in flight is no longer dropped when the save settles (objectui#12322). (objectui `72594f29e`)
31+
- **patch** — A failed first `connect()` with `autoReconnect` now retries discovery and settles (objectui#12318). The retry used to call `connect()` from inside the attempt it was retrying. `co… (objectui `866763bda`)
32+
- **patch** — Metadata admin detail pages no longer overprint their header on a narrow window (objectui#12306). (objectui `67ca3af91`)
33+
- **patch** — An inline edit in a grid is no longer written to another record when the rows are re-read in a new order (objectui#12310). The table kept each pending edit under its row's positio… (objectui `a8051d654`)
34+
- **patch** — Each app tile in Home's "Your apps" strip is now a link to the app, so an app can be opened in a new tab and its address can be copied (objectui#12305). (objectui `0ffa07605`)
35+
- **patch** — The connection state follows the requests the console already makes, so the header chip now shows a mid-session outage (objectui#12295). (objectui `40cb13b2e`)
36+
- **patch** — The console's Setup › Apps page reports what the server did with a write (objectui#12300). Before, a Delete and a Disable could report success for a write that changed nothing. (objectui `068a5407f`)
37+
- **patch** — Saving a master-detail edit form no longer rewrites the position of lines the user did not touch (objectui#12286). (objectui `f0532d8a8`)
38+
- **patch** — A dashboard header action of type `url`, or of no declared type, now goes through the action runner, like every other header action (objectui#12275). (objectui `74964ad68`)
39+
- **patch** — A flow action whose flow runs straight through, with no screen, now closes with the flow's own `successMessage` when the action declares none (objectui#12274). (objectui `bfca2a2ce`)
40+
41+
⚠️ 4 of these carry a breaking change: 4 by the author's own breaking annotation in the changeset body — objectui declares no `major` inside a launch window (`scripts/check-changeset-no-major.mjs`). Each is marked **BREAKING** in the list above — read them before compiling the release record.
42+
43+
**In this console build, declared nowhere** — objectui merged 4 commits in this range with no `.changeset/*.md`. The code is inside the pin above and ships here, but nothing upstream declared them, so they appear in no objectui CHANGELOG and in no entry above. Listed by subject rather than counted, because a count cannot tell a dependency bump from a form-behaviour change (objectstack#6174); the upstream gate that would prevent this is objectui#3387.
44+
45+
- _(no changeset)_ docs(ci): retire the four-shard leftovers in AGENTS.md section 9 and two comment sites (#12287) (objectui `157017967`)
46+
- _(no changeset)_ docs(fields): the auto-number page teaches the spec's format tokens, with no quarter token and no hand-written renderer (objectui#12258) (#12280) (objectui `5595aabca`)
47+
- _(no changeset)_ ci(spec-main-shape-gate): drop the merge_group trigger now the context is out of the required set (objectui#12252) (#12262) (objectui `a1a917a08`)
48+
- _(no changeset)_ ci(type-check): the affected speed builds the packages the repo-root setup program imports (objectui#12272) (#12277) (objectui `48fb558d3`)
49+
50+
Clause-②: no
51+
52+
<!-- adr-0087: not-required (no-migration-prescription)
53+
This diff moves `.objectui-sha` and the artefacts that travel with it: this console
54+
changeset, the re-recorded `scripts/sdui-manifest.record.json` and the regenerated
55+
`sdui.manifest.json`, the re-recorded `packages/sdui-parser/objectui-lockstep.json`,
56+
the re-measured pin citations in `packages/spec/src`, and the describe and ledger text
57+
this hop makes true (`EmptyStateSchema.link`, `interfaceConfig.emptyState`, the
58+
`record:details` section `count` and the `object-grid` `emptyState` member), which carry
59+
their own `@objectstack/spec` patch changeset. It adds, removes or renames no
60+
ObjectStack-authorable key: no Zod shape, no spec declaration and no stored
61+
`sys_metadata` shape moves in it, so `objectstack migrate meta` has nothing here to
62+
rewrite, and this body carries no FROM/TO prescription of its own.
63+
The range carries four declared-breaking objectui changes, each by its author's
64+
breaking annotation and none by a declared `major`, and the digest marked all four.
65+
Each is answered against this tree:
66+
(1) objectui#12030 (`c5406c201`): the `@object-ui/*` packages depend on the
67+
`@objectstack/*` 18 prerelease line. This tree is that line (`@objectstack/spec` and
68+
`@objectstack/client` are `18.0.0-next.0`, and the console build injects both), and no
69+
package or example here depends on any `@object-ui/*` package.
70+
(2) objectui#12242 (`5d3f437ab`), `@object-ui/fields`: `buildValidationRules` stops
71+
compiling a field-level `pattern` / `pattern_message` / `validate`. `@objectstack/spec`'s
72+
`FieldSchema` already refuses all three as unrecognized keys, and no example field
73+
authors any of them.
74+
(3) objectui#12242 (`5d3f437ab`), `@object-ui/types`: the field metadata types stop
75+
declaring host-written and field-level regex keys, and `geolocation` leaves the
76+
`FieldMetadata` union. No package or example here depends on `@object-ui/types`, and none
77+
declares `type: 'geolocation'`.
78+
(4) objectui#12273 (`9f282ef53`), `@object-ui/i18n`: the pack keys
79+
`console.breadcrumb.dashboards` and `console.breadcrumb.reports` are retired. Nothing in
80+
this tree reads either key.
81+
Scope of the claim, stated rather than implied: it is a claim about THIS diff, not a
82+
per-entry re-measurement of the upstream declared-breaking entries.
83+
-->
84+
85+
objectui range: `1fb1ced36243...b9814b334d8a`

0 commit comments

Comments
 (0)