@@ -1085,6 +1085,86 @@ The Console side follows: `@object-ui/types` drops its
10851085pointed at the same retired cluster (objectui #2860 ). Import what you still need
10861086from ` @objectstack/spec ` directly.
10871087
1088+ ### Field widgets receive their metadata on one key, ` field ` (objectui #3233 )
1089+
1090+ ` FieldWidgetComponentProps ` no longer declares ` schema ` . The prop was a second
1091+ carrier for what ` field ` already means: ` SchemaRenderer ` passed the authored
1092+ node as ` schema ` , the form renderer's ` renderFieldComponent ` passed
1093+ ` schema={props.field || props.schema || props} ` * alongside* ` field ` , and about
1094+ thirty widgets settled the disagreement themselves with ` field || schema ` — one
1095+ concept, two spellings, a de-facto second contract.
1096+
1097+ ** Reading the metadata** — drop the fallback:
1098+
1099+ ``` diff
1100+ - const config = field || (props as any).schema;
1101+ + const config = field;
1102+ ```
1103+
1104+ ** Registering a widget** that can be rendered from a schema node — anything
1105+ ` SchemaRenderer ` dispatches, not just forms — wrap it once so it still receives
1106+ ` field ` :
1107+
1108+ ``` diff
1109+ + import { withFieldCarrier } from '@object-ui/fields';
1110+ +
1111+ - ComponentRegistry.register('color', ColorField, { namespace: 'field' });
1112+ + ComponentRegistry.register('color', withFieldCarrier(ColorField), { namespace: 'field' });
1113+ ```
1114+
1115+ ` withFieldCarrier ` forwards the node ** by reference** — nothing is copied,
1116+ narrowed or renamed — and consumes ` schema ` so it cannot reach the DOM through a
1117+ widget's ` ...props ` spread. The SDUI node → ` field ` translation now happens
1118+ exactly once, in that adapter, and every built-in field widget is registered
1119+ through it.
1120+
1121+ ** Who is affected:** anyone who wrote a field widget. In TypeScript, reading
1122+ ` props.schema ` is now a compile error rather than a silent ` any ` ; a third-party
1123+ widget that keeps reading it and is ** not** re-registered through the adapter
1124+ reads ` undefined ` in 17 and renders its empty or default state without
1125+ complaining. That is the deliberate cost of a major boundary — one contract
1126+ beats N dialects, and picking the wrong spelling should fail at compile time
1127+ rather than work under one host and not another.
1128+
1129+ ** Host metadata is untouched.** No authored SDUI JSON changes — this is a change
1130+ to how widgets are * written* , not to what apps declare. ` schema ` also remains the
1131+ universal SDUI prop every registered component receives from ` SchemaRenderer `
1132+ (` element:* ` , ` page:* ` , grids, reports); only the * field-widget* contract retired
1133+ it.
1134+
1135+ ### Flow node geometry is the spec's ` FlowNode.position ` (objectui #3172 )
1136+
1137+ The flow designer writes node coordinates as ` position: { x, y } ` — the key
1138+ ` @objectstack/spec ` has modelled all along — instead of its own ` ui: { x, y } ` .
1139+ Dragging, adding-at-a-point and insert-on-edge each wrote the local spelling;
1140+ all three now write ` position ` , and the canvas migrates on write: a stored
1141+ flow's legacy ` ui ` is lifted onto ` position ` and the key removed in the first
1142+ patch the canvas emits, geometry-related or not.
1143+
1144+ ** This is a behaviour fix, not a rename.** ` FlowNodeSchema ` has been ` .strict() `
1145+ since #4001 , so ` ui ` is an ` unrecognized_keys ` error: client validation flagged
1146+ the draft on every keystroke and the server rejected the save with a 422. In
1147+ other words, dragging a node made the flow unsavable — the convergence is what
1148+ makes the designer's most basic gesture round-trip again.
1149+
1150+ ** Who is affected:** anything reading ` node.ui ` off a flow draft. After the
1151+ author's first edit the key is gone and the coordinates live under
1152+ ` node.position ` :
1153+
1154+ ``` diff
1155+ - const { x, y } = node.ui;
1156+ + const { x, y } = node.position;
1157+ ```
1158+
1159+ ** Reading a stored flow stays backwards-compatible.** ` manualPosition() ` prefers
1160+ ` position ` and falls back to a legacy ` ui ` , so a flow saved before this change
1161+ still opens with its nodes exactly where the author left them. The fallback is a
1162+ migration path, not a second contract: nothing writes ` ui ` , and the canvas
1163+ strips it at its input boundary, so no patch can re-emit it. Nothing in this
1164+ repo or the engine ever read the key — it was designer-local, and the schema
1165+ rejected it — so the migration reaches only code written against the designer's
1166+ own drafts.
1167+
10881168### Smaller breaking changes
10891169
10901170- ** MongoDB driver declares itself single-tenant** and refuses to boot in a
@@ -1966,12 +2046,16 @@ rc.1, and administrators should know what changed:
19662046 the generated upgrade guide and the `spec_changes` MCP tool actually
19672047 report the 16 → 17 chain (they still said 16.0.0).
19682048
1969- ### New in Console — bundled objectui advanced `4a4829d0ef39 → 785b8a5d432c `
2049+ ### New in Console — bundled objectui advanced `4a4829d0ef39 → f995a452d2ca `
19702050
19712051143 objectui commits across five pin moves, released as **objectui 17.1.0**.
19722052(The pin changesets enumerate 79 of them; one range under-enumerated its own
19732053window and is recorded by `console-bebaebd39ace-backfill` — the fixes it
19742054covers are folded into the list below rather than left to the changelog.)
2055+ Two later pin moves carried the bundle on to `f995a452d2ca` — 129 further
2056+ commits, enumerated in `console-f5bc4c78be76` and `console-f995a452d2ca`. The
2057+ two author-facing breaking migrations in that range are documented under
2058+ *Breaking changes & migration* above.
19752059
19762060- **The lockstep half of ADR-0110 — release-critical.** The rc.0 pin predates
19772061 the client fix, so the Console it built still posted `action.target` to
@@ -2058,11 +2142,11 @@ covers are folded into the list below rather than left to the changelog.)
20582142These changes are on `main` after the `rc.1` cut and **roll into 17.0.0-rc.2**.
20592143At the time of writing the window has left 209 changesets pending — 46
20602144`major`-class, 74 `minor`, 55 `patch`, and 34 that release nothing (CI, tooling
2061- and docs). The Console pin is **unchanged** at `785b8a5d432c`, so the objectui
2062- delta rc.2 bundles is the one already documented in the section above; there is
2063- no new Console delta this round. (If `scripts/bump-objectui.sh` advances the pin
2064- before the cut, that range needs its own section — objectui `main` has moved
2065- past `785b8a5d432c`.)
2145+ and docs). The Console pin was `785b8a5d432c` when this window was written and
2146+ has since advanced to `f995a452d2ca` in two moves; that delta is carried by the
2147+ range on *New in Console* above and enumerated in the two pin changesets. Its
2148+ two author-facing breaking migrations are documented with the other breaking
2149+ changes above.
20662150
20672151Two campaigns dominate the window, and both are *finishing* rather than
20682152starting: the #4535 dual-source convergence and #4001's close of the authorable
0 commit comments