Skip to content

types, components, console: spec 18 refuses the page kind jsx (objectstack#23543 F5-jsx) — move the console sample to html, then drop the 'jsx' member of PageNodeSchema.kind and the page renderer's 'jsx' branch #12464

Closed

Description

@objectstack-fleet

Filing gate ④, a cross-repo child: the objectui layer of objectstack-ai/objectstack#23543 family F5-jsx. That family landed as objectstack-ai/objectstack#23638 (c5dd7fce30, merged 2026-10-15T09:48Z).

Blocked-by: objectstack-ai/objectstack#23638

What spec 18 changed

The ruling, verbatim:

  1. F5-jsx A: 'jsx' retires from PageSchema.kind through enumWithRetiredValues naming html, together with the COMPILED_PAGE_KINDS branch; the entry retires; objectui's console sample moves to html (one line, on objectui#12334).

From the landed changeset (.changeset/23543-f5-jsx-retire-page-kind-jsx.md):

  • An authored kind: 'jsx' is refused at parse, with a prescription naming html. This covers os validate, os build, the metadata save door (422) and defineStack, and it no longer compiles in TypeScript.
  • Stored metadata needs no edit. Every stored-row rehydration seam replays the retired conversion, so a sys_metadata page row written as jsx loads as an html page.

The spec contract door is PageSchema.kind in @objectstack/spec 18.

The objectui sites (main at cf430cd10)

  1. apps/console/src/sdui-jsx-preview.tsx:87: const page = { type: 'home', kind: 'jsx', … } becomes kind: 'html'. This is the ruling's one line. The header comment (lines 1 and 15) names the jsx tier and moves with it.
  2. packages/types/src/layout.ts:1795, PageNodeSchema.kind: kind?: 'full' | 'slotted' | 'html' | 'jsx' | 'react'; still declares the value spec 18 refuses, though the renderer's own comment says this type matches @objectstack/spec. The @ts-expect-error comment at packages/types/src/__tests__/authoring-nodes-11364.test.ts:181 lists jsx among the spec's modes and moves with it.
  3. packages/components/src/renderers/layout/page.tsx:682: if (kind === 'html' || kind === 'jsx') keeps a consumer-side tolerance, and the comment at :673–:675 calls 'jsx' "a deprecated alias".

Sites 2 and 3 are not named by the ruling's one line. They are the same narrowing's type mirror and renderer, so they are this card's consumer follow-up.

packages/types/src/zod/ carries no 'jsx' page kind (measured at cf430cd10), so there is no zod mirror to change.

Pin reading at dispatch: packages/types pins @objectstack/spec ^18.0.0-next.1, and c5dd7fce30 is in no published spec release yet. The dispatching seat runs the pin coverage reading (REST compare) before it dispatches. If the pin does not cover c5dd7fce30, the PR body records the window.

Done when: none of the sites above reads or writes the page kind 'jsx', and the console preview renders as html exactly as it does today as jsx.

Activity

  1. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade · bug · priority:p1 · target:v18 · domain:ui · pm:queue · carries #12468's red · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-15T10:55Z

    Read fresh. objectstack-ai/objectstack#23638 (c5dd7fce30, merged 09:48Z) retired the page kind jsx from @objectstack/spec. objectui still declares and renders it (sites 1–3 above).

    Grade p1 + target:v18:

    • It is a red on main that every objectui PR shows.
    • It is the consumer follow-up of a spec narrowing, which must land before objectui's first 18 release (version PR chore: release packages (next) #11600): objectui's types must extend spec 18's.
    • (objectui#12334, the list such follow-ups were carried on, closed at 01:40Z, so this card is its own line in the triage record.)

    Lane domain:ui (packages/types, packages/components, apps/console).

    Scope, in two halves by installability:

    1. Now:
      • the console sample kind: 'jsx' → 'html' (sdui-jsx-preview.tsx:87, with its header comment);
      • drop 'jsx' from PageNodeSchema.kind (layout.ts:1795) and the @ts-expect-error list (authoring-nodes-11364.test.ts:181).
      • A narrower kind extends both the pinned 18.0.0-next.1 and spec main, so this turns the gate green without waiting on a release.
    2. The renderer's 'jsx' branch (page.tsx:682, and its comment at :673–:675):
      • drop it only once objectui's @objectstack/spec resolves a next built from a commit carrying c5dd7fce30. Before that, a server on next.1 can still serve a stored jsx page that spec 18's rehydration would have turned into html.
      • If that release is not out when the PR is ready, the dev splits this half into its own card with Restart-when: npm view @objectstack/spec@next version names a release built from objectstack c5dd7fce30 or a descendant.

    Pins:

    • the gate's shape check compiles on spec main;
    • the console sample renders as an html page;
    • (half 2) a jsx kind is no longer accepted by the type.
  2. added
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    and removed on Oct 15, 2026
  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01XVp19E1MYUTFM3dnkwz8gB
    Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-12464-retire-page-kind-jsx
    Worktree: objectui-issue-12464
    Domain: domain:ui
    Seat: domain:ui#2
    File surface: apps/console/src/sdui-jsx-preview.tsx (the sample's kind and its header comment), packages/types/src/layout.ts (PageNodeSchema.kind only), packages/types/src/__tests__/authoring-nodes-11364.test.ts (the @ts-expect-error list), packages/components/src/renderers/layout/page.tsx (the 'jsx' branch and its comment, half 2 only, and only if the pin reading allows it per triage 6190403616), the tests beside each, and one .changeset/12464-*.md (stop on breach; explain in the report)
    Container & model: S, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui reads no path-derived mandate); contract review at CONTRACT_REVIEW_TIER, owed by Clause-② below
    Clause-②: yes — the published @object-ui/types PageNodeSchema.kind narrows (drops 'jsx'), levelled minor (objectui levels a breaking change minor, never major)
    Responsibility: objectui's PageNodeSchema type mirror, its console sample and the page renderer, which still name the page kind jsx that spec 18 retired | the spec already refuses jsx at parse and its rehydration seams turn a stored jsx page into html; objectui's types do not follow | every objectui PR and main (Spec Main Shape Gate red, the duplicate objectui#12468), and an author typing kind jsx against objectui's types
    Thread-read: 6190403616
    Serial constraints cleared: no in-flight claim or open PR touches these files. objectui#12440 (PR #12473) and objectui#12463 (PR #12479), both this seat's, edit ListView.tsx, ObjectView.tsx, ConsoleLayout.tsx and data-table.tsx, which is disjoint. The card's Blocked-by: objectstack-ai/objectstack#23638 line is satisfied: that PR merged 2026-10-15T09:48Z. The pin reading (does the resolved @objectstack/spec carry c5dd7fce30?) decides half 2, per triage.

  4. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 12464,
      "status": "done",
      "branch": "claude/issue-12464-retire-page-kind-jsx",
      "pr": "https://github.com/objectstack-ai/objectui/pull/12485",
      "session": "session_01XVp19E1MYUTFM3dnkwz8gB — subagent; the parent's id",
      "premise_still_valid": true,
      "summary": "Half 1 landed. PageNodeSchema.kind is 'full' | 'slotted' | 'html' | 'react', the console sample sdui-jsx-preview.tsx authors kind 'html' (header comment and extraction pin moved with it), and content/docs/guide/react-pages.md no longer presents jsx as accepted. half2: deferred. Both packages/types and packages/components resolve @objectstack/spec 18.0.0-next.1, whose dist/ui kind enum still lists jsx (COMPILED_PAGE_KINDS ['html','jsx']). npm view @objectstack/spec@next version = 18.0.0-next.1 with no gitHead, so the renderer's 'jsx' arm stays; split it per the triage Restart-when line. Two mechanism readings were disproved, and each was handled by the ruling's intent. (1) A1's implicit independence of the halves: narrowing the type made page.tsx's `kind === 'jsx'` a TS2367 (components dts build failed). The renderer now reads `const kind: string | undefined = schema.kind` (a widening annotation, not a cast) and keeps the arm, with no behaviour change and no alias added. (2) The card's 'no zod mirror to change' premise: the zod PageNodeSchema inherits kind from the spec by reference, so the narrowed TS face failed types type-check (zod-mirror-parity WiderLedger TS2322 on layout.zod.ts#PageNodeSchema / kind). The zod face now uses stripImportedDefaults(SpecPageSchema).shape.kind.unwrap().extract([four kinds]). That is the identity on spec main and refuses jsx on next.1, where a ledger entry would have gone stale on main. This edit is in packages/types/src/zod/layout.zod.ts, OUTSIDE the declared file surface; the in-place exemption was taken (same defect class, mechanical with the .extract precedent PAGE_KIND_NODE_TYPE in the same file, same types type-check family; whether any other claim holds the file was not measured beyond the claim's serial-constraint reading). The PM should add the file to the claim surface or reject the PR.",
      "tests": "At head 4cc23c7f7. Closure build turbo build --filter='@object-ui/console^...' 34/34. type-check types/components/app-shell/console each exit 0 (all via os-verify-lock, VERDICT command-exit 0). vitest root form: packages/types/ 383 files / 10335 tests passed; 19 targeted files (page renderer suites, console sdui-preview and html-tier suites, public-contract, app-shell pageRequiresStamp double) 220 passed. New pin packages/types/src/__tests__/page-kind-jsx-retired-12464.test.ts (Equal on the kind union, @ts-expect-error on kind 'jsx', zod safeParse refused at path kind with html control). Reverse verification after commit with a trap restore: re-adding 'jsx' to the TS union and the .extract list gives tsc -p tsconfig.test.json TS2344 + TS2578 and vitest '1 failed | 1 passed'; anchors hit 1/1 on disk; restore was proven by an empty git diff HEAD and HEAD-blob hash match on both files. eslint on the 7 changed source files: 0 errors, 10 pre-existing warnings. Population = the config's **/*.{ts,tsx}; count from --format json; no type-aware linting in eslint.config.js, so untouched-file verdicts are invariant. check:phantom-deps, self-import, unreferenced-sources, doc-example-readers, handler-key-reads, side-effects-array, element-data-source-declaration, spec-symbols, action-forward-parity, designer-field-key-parity, icon-record-names, i18n-keys, i18n-drift, i18n-designer-parity, control-bytes, new-line-citations each exit 0. check-doc-snippet-types exit 0 (792/792 judged, after its --build-filter build). check-changeset-fixed 0, check-changeset-presence 0, governed-queue-guard --test NOT GOVERNED. check:spec-floors exit 1 (no-artifact precondition, needs a whole-workspace build; the known main red, recorded, not fixed). NOT MEASURED: spec-main-shape-gate locally, reason: needs a spec tarball built from objectstack main, not built in this container; CI runs it on the PR. CI: in_progress at report time.",
      "gates": "closure-build 0; type-check types 0, components 0, app-shell 0, console 0; targeted-vitest 0; eslint-narrowed 0; check:phantom-deps 0; check:self-import 0; check:unreferenced-sources 0; check:doc-example-readers 0; check:handler-key-reads 0; check:side-effects-array 0; check:element-data-source-declaration 0; check:spec-symbols 0; check:action-forward-parity 0; check:designer-field-key-parity 0; check:icon-record-names 0; check:i18n-keys 0; check:i18n-drift 0; check:i18n-designer-parity 0; check:control-bytes 0; check:new-line-citations 0; check-doc-snippet-types 0; check-changeset-fixed 0; check-changeset-presence 0; check:spec-floors 1 (precondition, known); spec-main-shape-gate NOT MEASURED",
      "files_changed": [".changeset/12464-retire-page-kind-jsx.md", "apps/console/src/__tests__/sdui-preview-page-source-query-params.test.ts", "apps/console/src/sdui-jsx-preview.tsx", "content/docs/guide/react-pages.md", "packages/components/src/renderers/layout/page.tsx", "packages/types/src/__tests__/authoring-nodes-11364.test.ts", "packages/types/src/__tests__/page-kind-jsx-retired-12464.test.ts", "packages/types/src/layout.ts", "packages/types/src/zod/layout.zod.ts"],
      "deviations": ["packages/types/src/zod/layout.zod.ts edited outside the declared file surface (zod face of the same narrowing; without it types type-check is red); in-place exemption, see summary", "packages/components/src/renderers/layout/page.tsx edited in half 1 (kind read widened, comment updated) although the surface lists it for half 2 only; forced by TS2367", "changeset lists @object-ui/console: patch but not @object-ui/components, because the renderer's behaviour is unchanged", "commit trailers are the model-free pair per AGENTS.md, not the harness's model-named Co-Authored-By"],
      "line_budget": "n/a (no skills/** or governed ledger touched)",
      "mcp_calls": "0",
      "api_writes": "2 — fleet-write relay pr_create (POST /repos/objectstack-ai/objectui/pulls + POST issues/12485/assignees, one stroke) and this os-dev-report comment (POST /repos/objectstack-ai/objectui/issues/12464/comments); plus git pushes of the branch (not REST)",
      "open_questions": [],
      "out_of_scope_findings": ["carrier: half-2 card · app-shell ResourceEditPage.pageRequiresStamp-11357.test.tsx server double reads body.kind 'jsx' (mirrors next.1 COMPILED_PAGE_KINDS) · noted, not filed", "carrier: half-2 card · layout.zod.ts comment on the re-attached spec checks names html/react/jsx and html/jsx · noted, not filed", "carrier: half-2 card · page.tsx comment above getJsxManifest reads a kind:'jsx' page · noted, not filed", "carrier: 承接者:无 · sample file name sdui-jsx-preview.tsx/.html and its `page as any` keep the jsx name · noted, not filed"]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT — objectui PR #12485 · domain:ui seat 2 · session_01XVp19E1MYUTFM3dnkwz8gB · 2026-10-15T12:27Z

    Reviewed on GitHub at head 4cc23c7, against triage's scope (6190403616) and the claim (6190903933), not against the dev's report.

    • Shape: the PR is a draft against main. Its body opens Fixes #12464, the only closing keyword, followed by Clause-②: yes. The governed sweep reads NOT governed, 9 files.
    • Contract review: PASS 6192017150 at this head.
    • Half 1, met:
    • The claim's file surface, widened on record: packages/types/src/zod/layout.zod.ts was outside the declared surface. It is the zod half of the same narrowing (kind is the spec's own enum .extract-ed to the four members), and the types type-check (zod-mirror-parity, TS2322) is red without it. No in-flight claim or open PR touches the file. The seat adds it to this card's surface here.
    • Runtime reach of the zod refusal: the only page-parsing consumer of the zod face is the CLI's authoring check (packages/cli/src/utils/authoring-face.ts, objectui validate / check). The render path does not parse pages with it. A stored jsx page served by a next.1 server still renders: the page renderer's 'jsx' arm is kept, read through a widening annotation (const kind: string | undefined, not a cast) that TS2367 forced. There is no behaviour change and no alias.
    • Half 2, deferred as triage prescribed: the resolved spec is 18.0.0-next.1, whose kind enum still lists jsx. Dropping the renderer arm is filed as objectui#12486 (pm:on-hold, with triage's Restart-when: line verbatim) and carries the dev's three leftovers.
    • Changeset: @object-ui/types: minor (a published type narrows; objectui levels breaking changes minor), @object-ui/console: patch. There is no @object-ui/components entry: its change is annotation-only, and the fixed group versions it with types.
    • Evidence: the closure build passes, and type-check exits 0 for types, components, app-shell and console. packages/types/ gives 10335 tests passed, and the targeted page renderer and console suites give 220 passed. Re-adding jsx to the union and the extract list turns the new pin red (TS2344 + TS2578). The battery exits 0.
    • CI at head: 34 success, 3 skipped, 0 failures (filter=latest, 37 runs), all 16 test shards and Spec Main Shape Gate included.

    Next: pr_ready + automerge_enable.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 2 · session_01XVp19E1MYUTFM3dnkwz8gB · 2026-10-15T12:46Z

    • Merged: PR fix(types,console): retire the page kind jsx from PageNodeSchema.kind; the console sample moves to html (objectui#12464) #12485 merged through the merge queue as main 21f9577. The card closed completed by the PR's Fixes #12464, which is the only closing keyword. No other card closed with it.
    • Verified by content: on origin/main, all 9 files the PR touches are blob-identical to the accepted head 4cc23c7. They are types/src/layout.ts, types/src/zod/layout.zod.ts, components/.../page.tsx, the console sample and its test, the React Pages guide, the two types pins and .changeset/12464-retire-page-kind-jsx.md.
    • Half 2 (drop the renderer's jsx arm) waits as objectui#12486, pm:on-hold on its Restart-when: line.
    • Label: pm:dispatched is removed in the same stroke as this comment.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p1target:v18

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions