Skip to content

Commit 2e1b65d

Browse files
committed
fix(spec,changeset): the F5-jsx changeset declares platform-objects; the jsx-retirement prose names the doors that parse a page
Claude-Session: https://claude.ai/code/session_01DdfPiKZUYAduc1ERcEvDso Co-authored-by: Claude <noreply@anthropic.com>
1 parent 831a9fa commit 2e1b65d

4 files changed

Lines changed: 8 additions & 5 deletions

File tree

‎.changeset/23543-f5-jsx-retire-page-kind-jsx.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
'@objectstack/metadata-protocol': patch
44
'@objectstack/cli': patch
55
'@objectstack/lint': patch
6+
'@objectstack/platform-objects': patch
67
---
78

89
feat(spec)!: the page kind `jsx` is retired — an authored `kind: 'jsx'` is refused with the prescription naming `html`, and `page-kind-jsx-to-html` leaves the load path
910

1011
Clause-②: yes (narrowing)
1112

12-
**BREAKING (authoring):** `jsx` was the first name of the constrained-JSX page tier (ADR-0080), which ADR-0081 renamed `html`. Through 17 it stayed a declared `PageSchema.kind` member and the loader rewrote an authored `kind: 'jsx'` to `html` with a notice. At 18 it is retired: `PageSchema.kind` declares it through `enumWithRetiredValues`, so every door that parses a page (`defineStack`, `os validate`, `os build`, `os lint`, the metadata save door) refuses it by name: "Page `kind: 'jsx'` was removed in @objectstack/spec 18 (ADR-0087 D2) … Use `kind: 'html'`." Writing it in TypeScript no longer compiles either. The ADR-0087 D2 conversion `page-kind-jsx-to-html` is retired from the load path (`retiredAfter: '17.7.0'`), so the authoring funnel no longer rewrites the value. `COMPILED_PAGE_KINDS` is now `['html']`: `requires` is accepted on an `html` page only.
13+
**BREAKING (authoring):** `jsx` was the first name of the constrained-JSX page tier (ADR-0080), which ADR-0081 renamed `html`. Through 17 it stayed a declared `PageSchema.kind` member and the loader rewrote an authored `kind: 'jsx'` to `html` with a notice. At 18 it is retired: `PageSchema.kind` declares it through `enumWithRetiredValues`, so it is refused by name at `os validate`, `os build`, the metadata save door and `defineStack`, so under `os lint` too when the config calls it: "Page `kind: 'jsx'` was removed in @objectstack/spec 18 (ADR-0087 D2) … Use `kind: 'html'`." Writing it in TypeScript no longer compiles either. The ADR-0087 D2 conversion `page-kind-jsx-to-html` is retired from the load path (`retiredAfter: '17.7.0'`), so the authoring funnel no longer rewrites the value. `COMPILED_PAGE_KINDS` is now `['html']`: `requires` is accepted on an `html` page only.
1314

1415
Migration:
1516

@@ -22,4 +23,6 @@ Stored metadata needs no edit. Every stored-row rehydration seam replays the ret
2223

2324
The readers that branched on the retired value dropped it: the metadata save door's html-page compile gate (`@objectstack/metadata-protocol`), the CLI's SDUI-manifest page count, and the lint page walk, `validateJsxPages` and the page-source styling rule (`@objectstack/lint`) now read `html` (and `react` where they did before) only.
2425

26+
`@objectstack/platform-objects` publishes the Studio page form's `source` help text in four locales (`en`, `zh-CN`, `ja-JP`, `es-ES`); it no longer names `jsx`.
27+
2528
<!-- adr-0087: registered page-kind-jsx-retired -->

‎packages/spec/liveness/page.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"evidenceScope": "in-repo",
1313
"evidence": "PARSE: packages/spec/src/ui/page.zod.ts#checkPageRequiresKind refuses the key on every kind but html (COMPILED_PAGE_KINDS) — a react, full or slotted page, a page that omits kind included — at requires, naming the key, the kind and the compiled kinds. SAVE: packages/metadata-protocol/src/runtime-authoring-gate.ts#findHtmlPageSourceGaps reads the authored list of a kind 'html' page and refuses one that disagrees with the namespaces its compiled source uses — 422 INVALID_METADATA under page-requires-disagrees-with-source, on an active save and on a draft's publish; packages/metadata-protocol/src/runtime-authoring-gate.ts#stampHtmlPageRequires stores the compiled list on save, and packages/metadata-protocol/src/protocol.ts#promoteDraftForPublish applies it again to the body a draft promotion writes. LOAD: packages/metadata-protocol/src/protocol.ts#reportPageRequiresAbsentAtLoad, called from boot hydration (loadMetaFromDb), reports a stored page whose list names a namespace no component in the manifest carries (packages/metadata-protocol/src/runtime-authoring-gate.ts#findPageRequiresAbsentFromManifest), page and plugin named; the page still loads and is served",
1414
"producer": "packages/cli/src/utils/sdui-manifest.ts#registerDeploymentSduiManifest — both moments compare the list against the deployment's SDUI component manifest, a second input: os serve (packages/cli/src/commands/serve.ts, which dev and start spawn) resolves it at boot and registers it under SDUI_MANIFEST_SERVICE, and packages/metadata-protocol/src/protocol.ts#resolveSduiManifest reads that key per publish and at load. A host that registers no manifest judges neither moment and prints one boot line saying so",
15-
"note": "Plugin namespaces an html page's `source` uses (ADR-0080 §5), derived from the source at save. planned → live 2026-10-02 (#20871): refused at save since the save door landed (PR #20852, #20312 stages ① and ②), reported at load and re-stamped on draft promotion since #20870 (PR #21121). An authored list survives only when it agrees with the source; omitting it is the intended authoring. Boundaries: the key exists only on kind 'html' / 'jsx' pages, the kinds compiled at save; on 'react' (not compiled at save, ADR-0081), 'full' and 'slotted' pages, a page with no kind being 'full', the parse refuses it since 2026-10-03 (#21459, ruling A), and the protocol-18 conversion page-requires-non-compiled-kind-removed strips it from stored rows and built artifacts at load; a draft is stored as written and judged at its publish; stored html rows are reported, never rewritten."
15+
"note": "Plugin namespaces an html page's `source` uses (ADR-0080 §5), derived from the source at save. planned → live 2026-10-02 (#20871): refused at save since the save door landed (PR #20852, #20312 stages ① and ②), reported at load and re-stamped on draft promotion since #20870 (PR #21121). An authored list survives only when it agrees with the source; omitting it is the intended authoring. Boundaries: the key exists only on kind 'html' pages, the kind compiled at save; on 'react' (not compiled at save, ADR-0081), 'full' and 'slotted' pages, a page with no kind being 'full', the parse refuses it since 2026-10-03 (#21459, ruling A), and the protocol-18 conversion page-requires-non-compiled-kind-removed strips it from stored rows and built artifacts at load; a draft is stored as written and judged at its publish; stored html rows are reported, never rewritten."
1616
},
1717
"name": {
1818
"status": "live",

‎packages/spec/src/migrations/entries/semantic/18.page-kind-jsx-retired.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export const entry: SemanticMigration = {
1919
"A maintainer ruling retired `jsx` as a page kind at 18. It was the first name of the constrained-JSX "
2020
+ 'tier (ADR-0080), which ADR-0081 renamed `html`; through 17 the loader rewrote an authored '
2121
+ "`kind: 'jsx'` to `html` with a notice. At 18 the page parse refuses it by name with the "
22-
+ 'prescription naming `html`, at every door that parses a page: `objectstack validate`, '
23-
+ '`objectstack build`, `objectstack lint`, `defineStack` and the metadata save door (a 422). The '
22+
+ 'prescription naming `html`: at `objectstack validate`, `objectstack build`, the metadata save '
23+
+ 'door (a 422) and `defineStack`, so under `objectstack lint` too when the config calls it. The '
2424
+ 'rename is lossless — the source is compiled and rendered exactly as before — but no tool makes it '
2525
+ 'for an authored source: the D2 conversion `page-kind-jsx-to-html` belongs to protocol 11, below '
2626
+ 'the migration floor, so change the value by hand. Stored pages need no edit: every stored-row '

‎packages/spec/src/ui/page.form.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export const pageForm = defineForm({
4848
// already uses for every other program-text row (`action.body.source`,
4949
// `object.fields.expression`). `visibleWhen` is a MEANINGFULNESS gate,
5050
// not a parse gate — `PageSchema` accepts the key whatever the `kind`,
51-
// but only the three source-compiled kinds ever read it; the two layout
51+
// but only the two source kinds (`html` / `react`) ever read it; the two layout
5252
// kinds (`full` / `slotted`) compose regions and slots instead.
5353
{ field: 'source', type: 'code', language: 'jsx', colSpan: 2, visibleWhen: "data.kind in ['html','react']", helpText: "Page source text. For kind 'html' it is constrained JSX compiled to the component tree at save time — parsed, never executed. For kind 'react' it is real React executed at render by the trusted runtime." },
5454
],

0 commit comments

Comments
 (0)