Skip to content

feat(core,components): the html tier registers and declares code — an html page's code tag renders its text, not the field:code editor (objectui#10756) - #10776

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-10756-html-tier-code-element
Sep 27, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-10756-html-tier-code-element

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #10756
Clause-②: yes — the published sdui.manifest.json gains one html-tier tag (code, stamped tier: 'html'; 47 becomes 48).

Executes triage 5853741286 on objectui#10756 under ruling A on objectstack-ai/objectstack#20112 (5852014527): a kind:'html' page may author the intrinsic tags its renderer registers, and the published manifest declares that set. PR objectui#10753 (objectui#10735) landed the roster and ledgered code out because the only bare code registration was the field:code widget's namespace fallback; this PR is the element that ledger was waiting for. Base origin/main b5b6f37531; head d601b5c1d2 (four commits: the feature 974840acbd; 2fb626af0d, which enrols ui:code in the app-shell DOM-leak sweep after CI went red on the feature commit; b62fca8044, two comment-only prose counts; d601b5c1d2, the changeset-text fix contract review 5856453707 required). H1 to H5 below are the round-1 readings taken at 974840acbd; the round-2 section records what changed after it; the round-3 section records the changeset-only text fix.

What changed

  • packages/components/src/renderers/basic/html-elements.tsx — code joins TAGS (registered ui:code, sanitised like its siblings: className and the children slot). The header no longer lists code as "registered elsewhere"; the exclusion comment drops it.
  • packages/fields/src/index.tsx — code joins FIELD_TYPES_SKIP_FALLBACK: the widget keeps field:code and stands down from the bare key, so ui:code is the one bare claimant (file-surface amendment, forced by H2 below: the bare-name collision gate refuses a second claimant, and in the console graph the widget registers AFTER the passthrough and would have won the bare key back).
  • packages/core/src/registry/html-tier-intrinsics.ts — code joins HTML_TIER_INTRINSICS; the header's "deliberately NOT here" bullet for code is replaced by the admission note.
  • packages/types/src/zod/layout.zod.ts and packages/types/src/layout.ts — HtmlElementSchema (zod and TS) names code (file-surface amendment, forced by the objectui#8499 parity pin: HtmlElementSchema must name exactly the tags TAGS registers).
  • Tests — new apps/console/src/__tests__/html-tier-code-element-10756.test.tsx; html-tier-manifest.test.ts (ledger drops code; declares code; the compile case flips from refuses to accepts); core html-tier-intrinsics.test.ts (roster carries code; the squatting-widget case moves to summary, plus a projection case for the stand-down); react-page-scope.test.tsx (no Code wrapper); fields registry-collision.test.ts (code joins the colliding set); types node-slot-registered-arms-8499.test.ts (count guards 37 to 38, 47 to 48 literals); prose counts in container-declaration-census.test.tsx and public-contract.test.ts (all three of its 37-tag sentences now read 38; the note under the 8499 pin's toBe guards likewise).
  • packages/app-shell/src/__tests__/widget-dom-leak-sweep.test.tsx — ui:code is enrolled where its TAGS siblings ui:cite / ui:strong sit: COMPONENTS_PLAIN_TYPES (rendered with the shared readiness class and scanned) and the BARE_SPREAD group of COMPONENTS_LEAK_GROUPS (the same factory forwards its whole prop bag, so it leaks the same fourteen attributes, objectui#5574's recorded shape). The docblock counts the file pins against its own arrays move with it: targets 159 to 160, plain 140 to 141, ledgered 89 to 90, ready-matched 156 to 157, all targets 182 to 183, all ledgered 91 to 92; clean stays 70. The completeness assertion is untouched.
  • Generated — packages/cli/src/utils/known-schema-types.ts regenerated by scripts/regenerate-known-schema-types.mjs (+ui:code); scripts/body-dialect-census.mjs mirrors the tag list.
  • Changesets — .changeset/10756-html-tier-code-element.md declares minor for @object-ui/components, @object-ui/core, @object-ui/types, @object-ui/fields and @object-ui/cli. Round 3 (contract review 5856453707) gave the @object-ui/fields bullet a BREAKING (authoring) banner: the bare code key no longer resolves to the code-editor widget, migration { "type": "code" } becomes { "type": "field:code" }, and it stays minor under objectui's version policy. The same round also appended the AnyComponentSchema / objectui validate accept-set-widening sentence to the @object-ui/types bullet, corrected the intro's span clause, and added the @object-ui/cli bullet (known-schema-types.ts regenerates and gains ui:code; the objectui#9533 and objectui#6416 precedent). Dated notes in the objectui#10533 form remain on .changeset/10735-html-tier-manifest.md (47 to 48, code now declared) and .changeset/8499-node-slot-registered-arms.md (37 to 38). check-changeset-overwrite reports both modifications (report-only, exit 0) and did not refuse them.
  • ⛔ Not touched: PUBLIC_BLOCKS, kbd, div, docs/adr/**, anything in objectstack (the lockstep port and the manifest regeneration at the pin are [Decision] may a kind:'html' page author intrinsic HTML tags (div, a)? The console manifest says no, 3 of 3 shipped html pages say yes, and #19922's fallback cannot go live until one side changes objectstack#20112's lane).

H1 — reproduced on origin/main (b5b6f37531)

The new console pin, run on a detached worktree at the base commit through the real page path (SchemaRenderer with a kind:'html' page whose source is a main holding a p that holds a code tag with the text inline and className="k"):

  • renders the authored text inside a code element — AssertionError: expected null to be truthy (no code element rendered; the bare key drew the field widget).
  • compiles cleanly against the live page manifest — expected [ 'not-a-container:code' ] to deeply equal [] (the widget declared no child slot).
  • resolves to the field widget under its namespaced key, while the bare key is the passthrough — expected 'field:code' to be 'ui:code'.
  • Lit control on the same base tree: pre and strong rendered their text (the control case passed on base and on head).

H2 — the registration, measured (ComponentRegistry answers in the console registration graph: @object-ui/components plus src/register-plugins.ts, which pulls @object-ui/fields through plugin-form)

key base b5b6f37531 head 974840acbd
code field:code (namespace field, inputs [], FieldCarrier) ui:code (namespace ui, inputs className, children, the forwardRef passthrough)
ui:code not registered ui:code
field:code field:code (unchanged) field:code (unchanged)
kbd / ui:kbd ui:kbd, inputs label, className unchanged
getPublicConfigs() 106 entries, 47 stamped html, no code 107 entries, 48 stamped html, code stamped html

How the TAGS passthroughs register: ComponentRegistry.register(tag, Component, { namespace: 'ui', … }) — every roster tag is ui-namespaced and also takes the bare key (the register fallback branch). The bare key is last-writer-wins, and in the console graph @object-ui/fields registers after @object-ui/components, so without the stand-down field:code would have taken code back (ablation L3 below shows exactly that). FIELD_TYPES_SKIP_FALLBACK is the repository's settled mechanism for this shape (textarea, select, email, password, slider already stand down to ui:*). Forms resolve widgets through the field: namespace (form.tsx resolves field:${type}), so a field of type code renders the same editor; a JSON-surface field:code node is unchanged; only a bare JSON { "type": "code" } node moves, and it now renders the element — the widget's key is field:code. check:registry-bare-names stays at 0 contested keys; nothing is added to its shrink-only ledger.

H3 — the roster and the regenerated artefacts

Generated with the repo's own generator (buildArtifacts in packages/sdui-parser/scripts/gen-manifest.ts) over the console registration graph with the 16 plugin modules eager-imported in dev/manifest-dump.tsx order, once on the base tree and once on head:

artefact base head
sdui.manifest.json components 106 (59 curated + 47 html) 107 (59 curated + 48 html): +1 (code), 0 removed, 0 curated entries changed
code entry absent { type: 'code', namespace: 'ui', tier: 'html', inputs: className (string), children (slot) }
div / kbd present no no
sdui-intrinsics.d.ts 897 lines 902 lines (+CodeProps interface, +"code": CodeProps intrinsic)
sdui-blocks.md 119 lines, ## html tier intrinsic elements (47) 120 lines, ## html tier intrinsic elements (48); # SDUI public blocks (59) unchanged

code leaves EXCLUDED_HTML_NAMED in apps/console/src/__tests__/html-tier-manifest.test.ts; the ledger's liveness pin would have gone red had it stayed. The 47 count PR objectui#10753 pinned lives in prose only (its changeset and the core roster test's "three registered elsewhere" case, which stays at three because code is now on the JSON-surface enum too); the changeset takes a dated note.

H4 — pins, red on the base and green on the head

Run on a detached worktree at b5b6f37531 with the six pin files copied in: Test Files 6 failed (6) · Tests 13 failed | 68 passed (81). Run on head 974840acbd (16 files including the neighbours): Test Files 16 passed (16) · Tests 241 passed (241).

pin base head
console: code with text renders the text in a code element (real page path) red — expected null to be truthy green
console: live compile reports nothing for the tag red — not-a-container:code green
console control: field:code renders the widget (read-only pre with the value) and keeps its key red on the registry half ('field:code' to be 'ui:code') green
console manifest: declares code (tier html, ui, className + children) red — expected undefined to be defined green
console census: every HTML-named registration on a roster or in the ledger red — unaccounted: code green
console compile against the published manifest: accepts code with children red — two error diagnostics green
core roster: carries code, leaves kbd out red green
core projection: a roster tag is projected from whatever holds its bare key red — expected undefined to be 'html' green
react-page scope: no Code wrapper, code stamped html red — expected undefined to be truthy green
fields: bare code is not the field renderer red — both lookups were FieldCarrierAdapter green
types: HtmlElementSchema names exactly TAGS (38), literal count 48 red — expected 37 to be 38, expected 47 to be 48 green

Per-hunk ablations (each through scripts/ablation-replace.mjs from ../objectstack, --delete mode, on the committed head; the tool printed anchor x1 -> x0 and the blob change for every leg, and restore proof blob == HEAD plus empty git diff HEAD; an outer hash-against-HEAD check agreed on all legs; final git status clean). Pin set: the six files above plus zod-mirror-parity.test.ts (118 tests).

leg hunk removed result
L1 'code' out of TAGS 13 red / 4 files — the render pin, the compile pin, the registry pin, the roster-vs-manifest pins, the react-page pin, the 8499 parity
L2 'code' out of HTML_TIER_INTRINSICS 8 red / 3 files — declares code, the census (code unaccounted), the react-page pin, the core roster pins; the render pin stayed green (the renderer does not read the roster)
L3 'code' out of FIELD_TYPES_SKIP_FALLBACK 8 red / 3 files — the render pin, the compile pin (not-a-container:code), declares code (the projection copied the widget), the fields collision pin; and check:registry-bare-names exit 1 naming the contested bare key code
L4 'code' out of the zod enum 3 red / 2 files — the 8499 parity and literal count, the core "exactly three registered elsewhere" case
L5 | 'code' out of the TS union 0 red in vitest — the TS face is not a runtime value; L5b ran the instrument that sees it: pnpm --filter @object-ui/types type-check exit 2, zod-mirror-parity.test.ts … TS2322: Type '"layout.zod.ts#HtmlElementSchema"' is not assignable to type 'never'

Disclosed: a first ablation pass was a no-op — ablation-replace.mjs refused every leg before any test ran (the replacement count moved 1 -> 1, a rise of 0: the replacement text was a substring of the anchor) and restored each file; the pass above is the rerun in --delete mode.

H5 — kbd, measured only

packages/components/src/renderers/data-display/kbd.tsx registers ui:kbd with inputs label, className, no child slot; it reads schema.keys (array) or schema.label and renders one kbd per key inside a wrapper div. That is a component under an HTML tag name, not an element passthrough — a different shape from code. Untouched; it stays in EXCLUDED_HTML_NAMED with its reason.

Round 2 — CI red on 974840acbd, and the repair

Test (shard 6/8) (run 36319935360, job 108621700100) failed the sweep's completeness case: the sweep covers a real, non-empty target set (objectui#4425) › components: every widget it registers is swept — a new one cannot slip past, expected [ 'action:bar', …(158) ] to deeply equal [ 'action:bar', …(159) ], missing "ui:code". The case derives the registered set from ComponentRegistry and compares it with the enumerated targets, so the ui:code this PR registers had no target.

  • Reproduced locally first, with the sweep file at 974840acbd's blob written into the worktree (on-disk blob 76f8f62ca0 equal to 974840acbd's, zero 'ui:code' occurrences) and restored afterwards (blob 6bed2c87dc equal to HEAD's, git diff HEAD empty): Test Files 1 failed (1) · Tests 1 failed | 229 passed (230), the same case, the same - "ui:code" diff.
  • Green on the repaired head: Test Files 1 passed (1) · Tests 231 passed (231). The file gains one test because ui:code is now its own swept case.
  • Ablation (through ../objectstack's scripts/ablation-replace.mjs, wrap mode; each leg printed anchor x1 -> x0 with the blob change, and restore blob == HEAD plus empty git diff HEAD; an outer hash-against-HEAD check agreed after each leg):
leg removed result
A 'ui:code' from COMPONENTS_PLAIN_TYPES (the enrolment) 11 red / 230 — the completeness case (every widget it registers is swept) first, then the ledger's well-formedness, the family-size / ledgered / clean cases, five derived-count cases and the reading table
B 'ui:code' from the BARE_SPREAD ledger group 7 red / 231 — the ui:code sweep case itself (ui:code leaked 14 non-DOM attribute(s), read off a rendered code element carrying the readiness class), plus the ledgered / clean / derived-count / reading-table cases

Leg A shows the completeness case catches a missing enrolment; leg B shows the enrolled code is actually rendered and scanned, not only listed. Disclosed: the first ablation attempt was a no-op — the tool refused both legs before any mutation (not inside a git repository: it was invoked from outside the worktree); the legs above are the rerun from the worktree root.

  • Census — git grep for every test or script that enumerates the TAGS roster, ui:cite or a sibling tag, or states the 37 / 47 / 106 counts; every one run at b62fca8044:
    • DOM batch, 13 files, Test Files 13 passed (13) · Tests 368 passed (368): app-shell widget-dom-leak-sweep; console html-tier-code-element-10756, html-tier-manifest, public-contract; components container-declaration-census, span-deprecation-provenance, registration-uniqueness, shadowed-renderer-behaviour, react-page-scope; fields cellRenderers.childlessContainer-8580, richtext-cell-renderer-5452, registry-collision; sdui-parser inline-whitespace.
    • Node batch, 15 files, Test Files 15 passed (15) · Tests 430 passed (430): core html-tier-intrinsics; types node-slot-registered-arms-8499, arm-named-export-8784, form-barrel-mirror-9406, node-recursion-point-8344, zod-mirror-parity, breadcrumb-object-tree-nameable-7917; sdui-parser html-tier-manifest-10735; scripts check-doc-component-types, body-dialect-census, known-schema-types-derivation-5115, check-component-surface-parity, registry-bare-name-collisions, check-handler-key-read-sites; cli check-known-types.
    • Scripts that enumerate the roster, run as themselves: regenerate-known-schema-types.mjs --check OK; check:registry-bare-names 0 contested ✓; census:body-dialect exit 0; check:component-surface-parity report-only exit 0; check:doc-types ✅.
    • Count prose found stale and repaired in b62fca8044: public-contract.test.ts's anti-vacuity note (37 spellings, now 38) and the note under the 8499 pin's toBe guards. Left as historical readings, not live counts: check-component-surface-parity.mjs's "(37 + 7 tags)" (it describes the guard's earlier shape, objectui#4631 review F1), and the AnyComponentSchema 106 / 107-arm figures in node-recursion-point-8344, node-slot-registered-arms-8499, breadcrumb-object-tree-nameable-7917 and check-handler-key-read-sites (a different population, the union's arms; this PR adds a literal to an existing enum arm, not an arm).

Round 3 — text-only FAIL on b62fca8044, and the repair

Contract review 5856453707 (VERDICT: FAIL, code/pins/manifest/CI/boundaries
PASS) held the changeset text short of the protocol's BREAKING-banner
requirement for a bare-key resolution change (the objectui#9533 precedent) and
listed two nits plus an advisory. Only .changeset/10756-html-tier-code-element.md
changed; no source, test or generated file moved.

  • The @object-ui/fields bullet is replaced verbatim with the review's
    BREAKING (authoring) banner text: the bare code key no longer resolves
    to the code-editor widget, with the { "type": "code" } → { "type": "field:code" } migration, and the explicit "released as minor... a
    breaking change never declares major" sentence.
  • The @object-ui/types bullet gains the AnyComponentSchema /
    objectui validate accept-set-widening clause the review's nit asked for.
  • The intro's "pre, strong, em and span rendered their children
    through the passthrough" is corrected to "pre, strong and em rendered
    their children through the passthrough, and span through its own
    renderer" (span.tsx:149 is its own renderer, per the review's nit).
  • '@object-ui/cli': minor joins the frontmatter per the review's advisory
    (known-schema-types.ts gains ui:code; the objectui#9533 and objectui#6416
    precedents name it in the fixed group either way), with a one-sentence body
    bullet in the same house style those two precedents use.
  • Every other sentence in the changeset is unchanged; none of them was found
    false by this round's re-read.

Verified with a normalized-whitespace string match that the replaced
@object-ui/fields bullet is byte-for-byte the review's quoted text (ignoring
line-wrap only).

Gates, each run as itself at head d601b5c1d2, all exit 0: node scripts/check-changeset-presence.mjs (✅ 15 source file(s) of 7 released package(s) changed, and this change declares 1 changeset(s)); node scripts/check-changeset-no-major.mjs (✅ No changeset declares a major bump.); node scripts/check-changeset-overwrite.mjs (report-only; reports the
same two pre-existing dated-note modifications as round 2, unchanged by this
round); node scripts/check-changeset-fixed.mjs (✅ All workspace packages are in the changeset fixed group. / ✅ privatePackages declared: version=true, tag=false.); pnpm check:control-bytes (✅ … scanned 8958 tracked text file(s); skipped 85 binary); pnpm check:new-line-citations (VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0). No test suite was run: nothing executable changes (git diff --stat against b62fca8044: 1 file changed, 20 insertions, 10 deletions).

Merge: git fetch origin main then git merge-tree --write-tree HEAD origin/main at d601b5c1d2 against origin/main bf14b64608 (main moved 7
commits / 76 files past b62fca8044, none of them this branch's one file):
exit 0, tree dfe14b140f, no conflicts, no merge commit needed. Pushed once,
b62fca8044..d601b5c1d2. CI on d601b5c1d2 read once after the push, not
waited on: 27 check-runs, 26 queued, 1 skipped, 0 failing.

Gates (local, targeted; the farm is CI's)

  • Round 2, at b62fca8044: the sweep and the 28-file census above; check-changeset-presence: ✅ 15 source file(s) of 7 released package(s) changed, and this change declares 1 changeset(s); check-control-bytes ✅; check-new-cross-file-line-citations 0 new citation(s); eslint --no-inline-config over the three round-2 files: 3 files, 0 errors, 0 warnings.
  • Round 3, at d601b5c1d2 (changeset text only): check-changeset-presence ✅ (15 source file(s) of 7 released package(s), 1 changeset(s)); check-changeset-no-major ✅; check-changeset-overwrite report-only, same two pre-existing dated notes; check-changeset-fixed ✅ (both lines); check:control-bytes ✅ (8958 scanned, 85 binary skipped); check:new-line-citations 0 new citation(s). No test suite: this round touches only .changeset/10756-html-tier-code-element.md.
  • Round 1: pnpm exec vitest run over 16 files at 974840acbd: Test Files 16 passed (16) · Tests 241 passed (241) (console html-tier-code-element-10756, html-tier-manifest, public-contract; core html-tier-intrinsics; types node-slot-registered-arms-8499, arm-named-export-8784, zod-mirror-parity; fields registry-collision; components react-page-scope, span-deprecation-provenance, registration-uniqueness, container-declaration-census, shadowed-renderer-behaviour; sdui-parser html-tier-manifest-10735; scripts body-dialect-census, known-schema-types-derivation-5115).
  • pnpm --filter PKG type-check after pnpm --workspace-concurrency=2 --filter '@object-ui/fields^...' build (the dependency closure): @object-ui/types, @object-ui/core, @object-ui/fields, @object-ui/components, @object-ui/cli all exit 0. @object-ui/console type-check NOT MEASURED locally: it needs every plugin's dist/ and the first attempt without the closure failed on TS2882 / TS6305 "not built" errors, not on this diff — declared to CI's Type Check.
  • node scripts/check-registry-bare-name-collisions.mjs: 0 contested; ledger holds 0 … ✓ no new bare-name collision.
  • node scripts/regenerate-known-schema-types.mjs --check: OK … matches the registry derivation.
  • node scripts/check-changeset-presence.mjs: ✅ 13 source file(s) of 6 released package(s) changed, and this change declares 1 changeset(s). check-changeset-no-major: ✅. check-changeset-overwrite: reports the two dated-note modifications, report-only exit 0.
  • check-doc-component-types ✅ · check-new-cross-file-line-citations: 0 new citation(s) · check-test-path-roots ✅ · check-control-bytes ✅ · check-pending-changeset-literals ✅ · check-prompt-component-keys OK · check-side-effects-array ✅.
  • pnpm exec eslint --no-inline-config --format json over the 15 changed lintable files: 0 errors, 155 warnings, all in the pre-existing classes (no-explicit-any, react-refresh/only-export-components; the two in the new test are the as any casts the sibling console suites use). eslint.config.js configures no type-aware linting (no parserOptions.project / projectService), so this diff moves no untouched file's verdict; the repo-wide pnpm lint population is CI's.

Serial

Open-PR file lists were read by the seat before dispatch (none touches these files). Before the round-2 push: git fetch origin main:refs/os-dev/issue-10756/main -f — main moved from b5b6f37531 to 17b323e5ca (2 commits, 24 files), none of them among this branch's 19; git merge-tree --write-tree HEAD refs/os-dev/issue-10756/main exit 0, no conflicts. No merge commit was needed.

Acceptance notes

  • kbd: measured above (H5) — a ui component reading keys / label, no child slot; not the same shape; not widened here.
  • ADR-0081 §2 lists no code; docs/adr/** is a governed surface and is not edited in this PR. The admission is documented in the roster's header (html-tier-intrinsics.ts) and the changeset. Carrier: none named.
  • Observation (prose only): the FIELD_TYPES_SKIP_FALLBACK comment above time / address says no other package owns those bare keys, while html-elements.tsx registers ui:time and ui:address from TAGS. Behaviour is unaffected (both stand down already); noted, not touched.
  • Observation: scripts/body-dialect-census.mjs carries a hand-copied HTML_ELEMENT_TAGS list with no pin against TAGS; updated here to include code, drift otherwise unguarded.
  • A bare JSON node { "type": "code" } used to draw the field:code editor through the fallback and now draws the element passthrough. No producer in this tree authors that node (the type: 'code' hits in plugin-designer / plugin-charts are input-kind declarations, not node types); the changeset says so — BREAKING (authoring), migration field:code; see the changeset.
  • The objectstack side: the tracked sdui.manifest.json there regenerates at its next .objectui-sha bump under [Decision] may a kind:'html' page author intrinsic HTML tags (div, a)? The console manifest says no, 3 of 3 shipped html pages say yes, and #19922's fallback cannot go live until one side changes objectstack#20112; nothing in objectstack changes here.

Generated by Claude Code

… html page's code tag renders its text

On a kind:'html' page, `<code>inline</code>` resolved to the bare `code` key,
which was the `field:code` widget's namespace fallback — a code editor reading
`value`, no declared inputs, no child slot — so the authored text was dropped
while `pre`, `strong`, `em` and `span` rendered theirs through the passthrough.
The published manifest left `code` undeclared for the same reason.

- components: `code` joins the `TAGS` loop of `html-elements.tsx` (registered
  `ui:code`, sanitised like its siblings: `className` + the `children` slot);
  the header no longer calls it "registered elsewhere".
- fields: `code` joins `FIELD_TYPES_SKIP_FALLBACK` — the widget keeps
  `field:code` and stands down from the bare key, so `ui:code` is the one bare
  claimant (the bare-name collision gate stays at zero contested keys).
- core: `code` joins `HTML_TIER_INTRINSICS`; `getPublicConfigs()` projects it
  stamped `tier: 'html'` — the regenerated manifest grows from 106 to 107
  components (48 html-tier), 0 curated entries changed, `div` / `kbd` absent.
- types: `HtmlElementSchema` (zod + TS) names `code`, keeping the JSON-surface
  arm equal to the registration as the objectui#8499 parity pin requires
  (its count guards move 37 -> 38).
- pins: the console renders the text in a `code` element and compiles the tag
  cleanly against the live page manifest; `field:code` still renders the
  widget; the manifest declares `code`; the react-page scope injects no `Code`
  wrapper; the console ledger drops `code`, the core roster test carries it.
- generated: `known-schema-types.ts` gains `ui:code`; `body-dialect-census.mjs`
  mirrors the tag list; two pending changesets take dated notes (47 -> 48,
  37 -> 38); one new changeset declares minor for components/core/types/fields.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
@github-actions

github-actions Bot commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 23 pending changeset(s) describe a file this change touches

Their bodies publish verbatim into the CHANGELOG at the next release, so this is a request to re-read them against your diff — addressed here because you are the one seat that can answer it without re-deriving anything.

⛔ Nothing here blocks, and nothing here is a verdict on your change. This gate exits 0, is not a required context, and judges name resolution, never meaning: it asked whether a pending body names a file you touched. "Is this sentence still true?" is the one question it will not answer, and the one you are being asked to answer.

.changeset/4895-retire-block-schema-family.md

  • names packages/types/src/layout.ts → packages/types/src/layout.ts — edited by this change

    ⚠️ Not this family, and not touched. The live slotted record-page vocabulary — PageNodeSchema.kind === 'slotted' with slots?: PageSlotMap (packages/types/src/layout.ts), rendered by usePageAssignment / PageBlockCanvas / PageBlockInspector in @object-ui/app-shell — shares the words "block" and "slot" with the retired family and shares no declaration, type or file with it. Neither is the type: 'component' NAVIGATION item kind ({ type: 'component', componentRef }, NavigationItemSchema in zod/app.zod.ts), a different declaration in a different module.

.changeset/5632-svg-host-dom-passthrough.md

  • names packages/types/src/layout.ts → packages/types/src/layout.ts — edited by this change

    Both renderers forwarded their whole prop bag to the SVG they render, so every authored SDUI key on the node became an attribute — 14 per target, and icon="check" on all 71 icon nodes in the schema catalog. The two nodes declare different keys, and each renderer consumes its own node's keys by name: IconSchema (packages/types/src/layout.ts) against the pass-through docblock in renderers/basic/icon.tsx, and SpinnerSchema (packages/types/src/feedback.ts) against the one in renderers/feedback/spinner.tsx. icon and color are IconSchema's alone — SpinnerSchema declares neither. Read those two declarations for what they carry; this paragraph deliberately copies no member list. So the SDUI pass-through list withholds nothing they need.

.changeset/6416-plugin-report-namespace.md

  • names packages/cli/src/utils/known-schema-types.ts → packages/cli/src/utils/known-schema-types.ts — edited by this change

    packages/cli/src/utils/known-schema-types.ts is regenerated from the registrations, dropping report:report, report:report-viewer and report:spec-report.

.changeset/6625-retire-fieldmeta-decimals.md

  • names fields/src/index.tsx → packages/fields/src/index.tsx — edited by this change

    buildFieldMeta computed decimals: overrides.decimals ?? meta?.decimals ?? meta?.scale on every call and the value reached nothing. Re-measured on this branch's base (efdc6c62): zero .decimals member reads across @object-ui/fields, @object-ui/i18n, @object-ui/components, @object-ui/core and plugin-dashboard itself — the only non-comment occurrence was the write being removed here. The positive control in the same query shape fires: .scale member reads hit NumberField.tsx, GridField.tsx and fields/src/index.tsx. So the zero is a finding, not a broken query. The overrides.decimals ?? head of that chain had already lost its only feeder when objectui#6425's ruling removed the authored read from ObjectDataTable.enrich(); RecordDetailDrawer, the only other buildFieldMeta caller, passes no overrides at all. Both halves retire together, so the key leaves in one move.

.changeset/6694-dashboard-lookup-reference-meta.md

  • names packages/fields/src/index.tsx → packages/fields/src/index.tsx — edited by this change

    ⚠️ The copy set is three keys where ObjectGrid's RELATIONAL_META_KEYS is nine, and the difference is measured per key, not preferred. The grid's cells are EDITABLE, so its extra keys drive the inline picker's query (LookupField / UserField read id_field, description_field, lookup_filters, lookupFilters); these two widgets are read-only and their render path ends at a cell renderer. packages/fields/src/index.tsx reads exactly reference_to, reference and display_field off a cell's field prop; titleFormat is never read off a field meta at all (its readers take it off the object schema, which arrives here through useRefObjectSchema(reference_to)), and reference_to_field has zero member reads anywhere in the repo. Copying the other six would mint six members written on every call and read by nothing — precisely what objectui#6625 (decimals) and objectui#6597 (referenceTo) retired from this same file.

.changeset/6771-retire-body-child-list-dialect.md

  • names scripts/body-dialect-census.mjs → scripts/body-dialect-census.mjs — edited by this change

    BaseSchema declared two spellings of one concept — body and children — and left the choice per component. Thirteen registrations read body and nothing else, so it was their ONLY door — the twelve the ruling enumerated plus tooltip, which it did not, and which is the count the committed instrument carries (BODY_ONLY plus BODY_ONLY_UNRULED in scripts/body-dialect-census.mjs). div, card, page, button, aspect-ratio, the seven sectioning tags and the safe-HTML tag factory read children || body and took either. The authoring tier only ever knew children, so an author writing the one spelling that resolved got unknown-prop — the same warning a typo draws, on the tier built to accept AI-authored pages, where the diagnostic is the contract (objectui#6771).

.changeset/6837-reference-to-arm-deletion.md

  • names fields/src/index.tsx → packages/fields/src/index.tsx — edited by this change

    Three readers were deliberately left alone. LookupCellRenderer (fields/src/index.tsx), LookupField and UserField read FieldMetadata — ObjectUI's OWN contract, whose LookupFieldMetadata declares reference_to and never declares reference. They are fed by the emitters above and by published example schemas (examples/schema-catalog/src/schemas/fields-lookup/*.json), so narrowing them would break in-repo producers, and plugin-grid's relationalMetaCopySet.derivation.test.ts re-derives its read set from exactly those three sources — where reference_to is recorded with verdict adapter-stamped. DetailViewFieldSchema is likewise untouched.

.changeset/6951-text-value-retired.md

  • names layout.ts → packages/types/src/layout.ts — edited by this change

    Two published faces, one retirement. The TypeScript interface TextSchema (@object-ui/types, layout.ts) declares value?: never; the Zod mirror TextSchema (@object-ui/types/zod, layout.zod.ts) declares value as a retirementTombstone(), so the key stays DECLARED and is refused BY NAME — a plain deletion would have let an authored value ride BaseSchema's .passthrough() into a silent blank, which is worse than the tolerated fallback it replaces. The value?: string members of TextSpanSchema and TabsSchema in the same file are other schemas' contracts and are unchanged.

  • names layout.zod.ts → packages/types/src/zod/layout.zod.ts — edited by this change

    Two published faces, one retirement. The TypeScript interface TextSchema (@object-ui/types, layout.ts) declares value?: never; the Zod mirror TextSchema (@object-ui/types/zod, layout.zod.ts) declares value as a retirementTombstone(), so the key stays DECLARED and is refused BY NAME — a plain deletion would have let an authored value ride BaseSchema's .passthrough() into a silent blank, which is worse than the tolerated fallback it replaces. The value?: string members of TextSpanSchema and TabsSchema in the same file are other schemas' contracts and are unchanged.

.changeset/7122-spec-17-3-0-parity-reconciliation.md

  • names known-schema-types.ts → packages/cli/src/utils/known-schema-types.ts — edited by this change

    user:profile is retired across all three sites. 17.3.0 dropped it from PageComponentType (measured: the enum went 34 → 32 options, lost set exactly ['user:profile', 'element:form'], gained set empty). objectui went on knowing it in three places, so all three moved together: the Studio palette exclusion ledger, PROTOCOL_COMPONENTS in renderers/placeholders.tsx, and the regenerated known-schema-types.ts the CLI checks schemas against. Nothing user-reachable went with it — neither type had a renderer, user:profile had only the dashed "Component Placeholder" scaffold, and the app shell's own profile affordance is a React slot, never this block type. A page schema still naming it now draws the loud "Unknown component type" panel rather than a silent grey box, which is this repo's standing treatment for a type outside the supported surface.

.changeset/7166-retire-inert-fieldmeta-copies.md

  • names packages/fields/src/index.tsx → packages/fields/src/index.tsx — edited by this change

    applyRelationalMeta writes the copy set onto the fieldMeta that generateColumns hands to ANGLE-BRACKETS(CellRenderer) as the field prop — six JSX passes across the three column-building paths, and nowhere else. For a relational column that resolves to LookupCellRenderer, which reads exactly reference_to, reference, display_field, displayField, reference_field and options; a user column resolves to UserCellRenderer, which destructures { value } and reads no field meta at all. Measured by receiver rather than by count: packages/fields/src/index.tsx, the file holding every cell renderer, contains zero occurrences of the three retired keys, against a control of 22 occurrences of the display_field / displayField / reference_to spellings the cell does read.

.changeset/7704-schema-registry-chatbot-keys.md

  • names packages/cli/src/utils/known-schema-types.ts → packages/cli/src/utils/known-schema-types.ts — edited by this change

    packages/plugin-chatbot/src/renderer.tsx registers three components — chatbot, chatbot-enhanced and chatbot-floating — and SchemaRegistry mapped one of them. Since ComponentType = keyof SchemaRegistry is the published union, a consumer discriminating on it was told two registered keys do not exist: an author narrowing a node by ComponentType, or writing a RecordANGLE-BRACKETS(ComponentType, …) table, had no arm for either. The asymmetry that showed which half was wrong is that packages/cli/src/utils/known-schema-types.ts keeps its own parallel list containing both keys, precisely because this map did not.

.changeset/7735-zod-mirrors-stop-authoring-defaults.md

  • names layout.zod.ts → packages/types/src/zod/layout.zod.ts — edited by this change

    What changed. All 41 .default() call sites under packages/types/src/zod/ are removed — layout.zod.ts 22, crud.zod.ts 11, form.zod.ts 5, views.zod.ts 2, app.zod.ts 1. @object-ui/components reconciles the third face objectui#8229 found: flex's registration defaultProps.align seeded 'center', the value its own renderer never applies, so a designer-made node laid out differently from a hand-authored one; it now seeds 'start'.

.changeset/8478-describe-line-addresses.md

.changeset/8478-zod-pins-form-layout.md

.changeset/8505-grid-columns-breakpoint-narrowing.md

.changeset/8516-8556-mirror-partial-record-narrowing.md

  • names zod/layout.zod.ts → packages/types/src/zod/layout.zod.ts — edited by this change

    | key | mirror was | mirror is | | :-- | :--------- | :-------- | | GridSchema.columns (zod/layout.zod.ts) | z.record(z.string(), z.number()) | a PARTIAL record over the six breakpoints | | ReportComponentSchema.exportConfigs (zod/reports.zod.ts) | z.record(z.string(), ReportExportConfigSchema) | a PARTIAL record over ReportExportFormat |

.changeset/8760-unfulfilled-chart-stubs.md

  • names node-slot-registered-arms-8499.test.ts → packages/types/src/__tests__/node-slot-registered-arms-8499.test.ts — edited by this change

    What moved. The stub lists in apps/console/src/register-plugins.ts and apps/console/src/preview-gallery.tsx (both loops, because the doc gate's key universe is their union — retiring one alone would have changed nothing observable); the dashboard doc snippet plus a note on how chart families are actually spelled; the regenerated KNOWN_SCHEMA_TYPES snapshot (six entries, three bare and three namespaced); and the line-chart leg of node-slot-registered-arms-8499.test.ts, whose premise this retirement changed and which reads the stub list rather than the file so the ⛔ comment left behind cannot satisfy it.

.changeset/8802-8257-8008-kanban-gantt-family-retirement.md

  • names known-schema-types.ts → packages/cli/src/utils/known-schema-types.ts — edited by this change

    ⚠️ objectui check will NOT flag either namespaced spelling. The CLI's known-schema-types.ts is generated from the repository's real registration calls, and the placeholder registration is a real one — so view:kanban and view:gantt are still on that list and still validate green, while the node renders a placeholder rather than a board. The bare kanban / gantt entries DID leave the generated list; only the namespaced pair survives, and only because of the placeholder. Grep your documents for the namespaced spellings directly; do not rely on objectui check to find them.

.changeset/8871-page-node-refuses-breadcrumbs.md

  • names layout.ts → packages/types/src/layout.ts — edited by this change

    What was measured, on this branch's base 93127bd6f. Zero readers, with a point-access probe rather than a bare word: on that base \.breadcrumbs scores 0 tree-wide (exit 1) against \.breadcrumb\b's 12 files tree-wide (10 under packages/) as the lit control. At head the same two probes read 16 and 13 and \.breadcrumbs is exit 0 over 4 files — every hit one of this branch's own four files (this changeset, the refusal pin, layout.ts, zod/layout.zod.ts) quoting the probe string, and the pin's own exclusions put head back at exit 1. The base reading is the measurement; the head reading is this branch's echo of it. The bare word would have lied — it also names Sentry's own unrelated concept (app-shell/src/observability/sentry.ts) and appears in two comments listing UI surfaces (core/src/utils/record-title.ts, layout/src/NavigationRenderer.tsx), so a bare probe reports five readers that do not exist.

  • names zod/layout.zod.ts → packages/types/src/zod/layout.zod.ts — edited by this change

    What was measured, on this branch's base 93127bd6f. Zero readers, with a point-access probe rather than a bare word: on that base \.breadcrumbs scores 0 tree-wide (exit 1) against \.breadcrumb\b's 12 files tree-wide (10 under packages/) as the lit control. At head the same two probes read 16 and 13 and \.breadcrumbs is exit 0 over 4 files — every hit one of this branch's own four files (this changeset, the refusal pin, layout.ts, zod/layout.zod.ts) quoting the probe string, and the pin's own exclusions put head back at exit 1. The base reading is the measurement; the head reading is this branch's echo of it. The bare word would have lied — it also names Sentry's own unrelated concept (app-shell/src/observability/sentry.ts) and appears in two comments listing UI surfaces (core/src/utils/record-title.ts, layout/src/NavigationRenderer.tsx), so a bare probe reports five readers that do not exist.

.changeset/9092-inline-locale-declared-face.md

  • names layout.ts → packages/types/src/layout.ts — edited by this change

    • AppComponentSchema.label (app.ts) - ObjectGridSchema.label and .description (objectql.ts) - PageNodeSchema.aria.ariaLabel (layout.ts)

.changeset/9533-dashboard-bare-key-converge-plugin-namespace.md

  • names packages/cli/src/utils/known-schema-types.ts → packages/cli/src/utils/known-schema-types.ts — edited by this change

    What changed. The renderer registers as plugin-dashboard:dashboard, the namespace every sibling plugin, both console stubs and the CLI whitelist already use, so the console stubs are cleared on load and all three claimants of the bare key name ONE full type. The retired view:dashboard key answers RetiredDashboardNodeTombstone — an inline refusal, plus a console.error carrying the same text — registered with skipFallback: true so it claims no bare key. Its spelling is withheld from the derived key universe by declaration in scripts/check-doc-component-types.mjs, the same disposition the RETIRED_FIELD_TYPES tombstones take, so objectui check names it in a file it recognises rather than blessing it; packages/cli/src/utils/known-schema-types.ts regenerates and loses that one entry.

.changeset/layout-default-jsdoc-7361.md

  • names layout.ts → packages/types/src/layout.ts — edited by this change

    The published @default documentation on two layout.ts members now matches the value the renderer actually applies. ContainerSchema.maxWidth documented 'lg' while container.tsx applies schema.maxWidth ?? 'xl', and the shared FlexLayoutProps.align documented 'center' while flex.tsx applies schema.align || 'start' and stack.tsx applies schema.align || 'stretch'. The renderers are unchanged — they are the authority for what runs — so only the docblocks moved; align now states both consumers in prose instead of carrying a single @default, because one member shared by two deliberately divergent component types cannot have one correct default.

.changeset/page-source-tailwind-prose-retraction-5469.md

  • names src/renderers/basic/html-elements.tsx → packages/components/src/renderers/basic/html-elements.tsx — edited by this change

    • @object-ui/react-runtime: README.md is published to npm (npm includes README.md in the tarball regardless of files). Its "no sandbox" callout is the paragraph that routes untrusted-author work to the html tier, and it carried the retracted framing line-wrapped across :17-18. It also gains the §Styling section it was missing — the absence is why the framing survived here. - @object-ui/sdui-parser: the corrected header of src/types.ts projects verbatim into the published dist/types.d.ts. - @object-ui/components: the corrected header of src/renderers/basic/html-elements.tsx projects verbatim into the published dist/renderers/basic/html-elements.d.ts. The kind === 'html' dispatch-arm comment in src/renderers/layout/page.tsx does not project (it is inside a function body) and is included here only because the same package already owes an entry.

Read the paragraph, not the line: both false halves of the objectui#8617 claim sat in one paragraph, and correcting either alone would have left it asserting the same wrong thing.

If a claim did go false, correct the body. That is precedented and prose-only, frontmatter untouched; check-changeset-overwrite.mjs will report the correction as its own case 2 ("correcting a declaration on purpose … legitimate"), which is the intended shape — one gate asks for the read, the other records the write.

Not covered, stated so nobody reads this as more: a born-false claim that spells no line address at all (objectui#9495 coordinated one by ORDINAL — "a grep finds that member first" — and deciding that means reading what the sentence means), a claim spelled as a symbol or a package rather than a backticked file name, and a file named ambiguously.

Angle-bracketed names in the quoted prose above are rewritten as ANGLE-BRACKETS(name): GitHub deletes tag-shaped fragments from a stored body, and a quote that silently loses the identifier it is about is worse than a visible repair.

Compared the checked-out tree with bf14b6460 (merge-base with origin/main): 16 file(s) changed outside .changeset/, read against 1585 pending declaration(s) that publish a body (2173 pending in total). · run

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3068.2 KB 3104.5 KB
Main entry chunk (gzip) 148.3 KB 350 KB
Entry file index-CJY_CGfp.js —
Status PASS —

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.57KB 6.15KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.17KB 10.58KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.52KB 3.45KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.13KB 7.95KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 554.95KB 132.67KB
core (index.js) 9.57KB 3.81KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 223.93KB 62.31KB
fields (index.js) 259.30KB 65.64KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.40KB 12.91KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 39.28KB 11.09KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.01KB 3.93KB
plugin-calendar (index.js) 51.65KB 14.69KB
plugin-charts (index.js) 82.37KB 22.57KB
plugin-chatbot (index.js) 198.40KB 47.22KB
plugin-dashboard (index.js) 134.11KB 35.62KB
plugin-designer (index.js) 216.25KB 44.39KB
plugin-detail (index.js) 233.23KB 61.74KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 157.44KB 40.24KB
plugin-gantt (index.js) 169.75KB 41.96KB
plugin-grid (index.js) 218.12KB 59.72KB
plugin-kanban (index.js) 48.43KB 15.11KB
plugin-list (index.js) 114.70KB 28.42KB
plugin-map (index.js) 22.90KB 7.62KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.55KB 11.99KB
plugin-timeline (index.js) 30.91KB 9.05KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 87.83KB 22.01KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 116.21KB 38.14KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.03KB 1.86KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.78KB 2.09KB
sdui-parser (codegen.js) 7.50KB 3.05KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.16KB 2.71KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 18.27KB 6.20KB
types (ai.js) 4.11KB 2.06KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 17.15KB 6.32KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

…elements siblings

The sweep's completeness case ("components: every widget it registers is
swept") derives the registered set from the registry and compares it with the
enumerated targets, so the `ui:code` passthrough registered by the previous
commit went red there: expected [ 'action:bar', …(158) ] to deeply equal
[ 'action:bar', …(159) ], missing "ui:code".

`ui:code` joins `COMPONENTS_PLAIN_TYPES` (rendered with the shared readiness
class and scanned like `ui:cite` / `ui:strong`) and the BARE_SPREAD ledger
group those siblings sit in — the same `html-elements.tsx` factory forwards its
whole prop bag, so it leaks the same fourteen attributes. The docblock's
hand-written counts and the sentences the file pins them against move with it
(targets 159 -> 160, plain 140 -> 141, ledgered 89 -> 90, ready 156 -> 157,
all targets 182 -> 183, all ledgered 91 -> 92); the clean count stays 70.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
…with `code` in the html tier

The branch moved `HtmlElementSchema` from 37 to 38 tags and updated the count
guards and most of the prose beside them, but two sentences still read 37:
`public-contract.test.ts`'s anti-vacuity note ("a single enum arm contributes
37 spellings") and the 8499 parity pin's note on its own `toBe(...)` guards.
Both now read 38; comment-only, no assertion changes.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3068.2 KB 3104.5 KB
Main entry chunk (gzip) 148.3 KB 350 KB
Entry file index-CJY_CGfp.js —
Status PASS —

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.57KB 6.15KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.17KB 10.58KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.52KB 3.45KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.13KB 7.95KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 554.95KB 132.67KB
core (index.js) 9.57KB 3.81KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 223.93KB 62.31KB
fields (index.js) 259.30KB 65.64KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.40KB 12.91KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 39.28KB 11.09KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.01KB 3.93KB
plugin-calendar (index.js) 51.65KB 14.69KB
plugin-charts (index.js) 82.37KB 22.57KB
plugin-chatbot (index.js) 198.40KB 47.22KB
plugin-dashboard (index.js) 134.11KB 35.62KB
plugin-designer (index.js) 216.25KB 44.39KB
plugin-detail (index.js) 233.23KB 61.74KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 157.44KB 40.24KB
plugin-gantt (index.js) 169.75KB 41.96KB
plugin-grid (index.js) 218.12KB 59.72KB
plugin-kanban (index.js) 48.43KB 15.11KB
plugin-list (index.js) 114.70KB 28.42KB
plugin-map (index.js) 22.90KB 7.62KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.55KB 11.99KB
plugin-timeline (index.js) 30.91KB 9.05KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 87.83KB 22.01KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 116.21KB 38.14KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.03KB 1.86KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.78KB 2.09KB
sdui-parser (codegen.js) 7.50KB 3.05KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.16KB 2.71KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 18.27KB 6.20KB
types (ai.js) 4.11KB 2.06KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 17.15KB 6.32KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: b62fca804404d1deb32a00d61f75a157e2a8101f

① Derived judgments

  • Scope. There are 3 commits over base b5b6f37531 and 19 files, not 18: round 2 added widget-dom-leak-sweep.test.tsx.
  • Registry answers, derived from Registry.register and get.
    • html-elements.tsx registers ui:code plus the bare key through the fallback branch.
    • Fields registers field:code with skipFallback, so fields writes no bare key and components never writes field:code.
    • Base: code is the field:code widget (inputs empty), ui:code is not registered, and field:code is the widget.
    • Head: code is ui:code (className and a children slot), ui:code is the passthrough, and field:code is the widget.
    • The head answers are the same in both registration orders. The triage ⛔ holds: field:code is untouched in either order.
  • Census of bare code authors. No surface that meant the editor now gets the passthrough.
    • git grep -nE "type:\s*['\"]code['\"]|\"type\":\s*\"code\"" excluding *.md gives 30 hits at head:
      • 21 are component inputs kind declarations: plugin-designer 14, plugin-charts 3, plugin-ai 2, plugin-report 2.
      • The rest are the metadata-admin CodeWidget, which imports plugin-editor directly; the local block type in MarkdownText; the CodeFieldMetadata type; and 4 field-metadata test fixtures.
      • Zero are SDUI page nodes.
    • The same grep over md, mdx, json and yaml finds only the new changeset.
    • objectstack origin/main c02fa12767, examples/ content/ apps/ packages/: 13 files, all object-field types, form-spec widgets or AI content parts. Zero page nodes.
    • ComponentRegistry.get/getConfig/getMeta/has('code') in production source: 0 at base and 0 at head.
    • How forms resolve a field of type code:
      • form.tsx renderFieldComponent and resolvesToRegisteredFieldWidget look up field:${type} only; the bare tail was removed in objectui#5254.
      • mapFieldTypeToFormType maps code and json to field:code.
      • getLazyFieldWidget and resolveFormWidgetType read fieldWidgetLoaderByKey, not the registry.
      • InlineFieldInput reaches no registry.
      • The FieldDesigner, previews and ObjectFormDesigner hits are field-type lists or local maps.
    • The sdui-parser code hits are the input-kind arm. CLI KNOWN_SCHEMA_TYPES keeps bare code and gains ui:code.
    • The only path that moves is SchemaRenderer with a bare node written as type code, and no producer in either repo writes one.
  • The fields widening.
    • It is minimal: one entry in the existing settled FIELD_TYPES_SKIP_FALLBACK mechanism.
    • It is forced: without it, pin 3 fails in the console graph and L3 ablation turns check:registry-bare-names red.
    • No other package or app lists bare code as a registry widget.
    • It is not the bounded in-place exemption. It is the card's own fix breaching the claimed surface, and the claim says "stop on breach". The dev continued and disclosed it in the report and the PR body, and the claim was not amended on the card. This is a process note for the seat, not a blocker.
  • The types widening.
    • LayoutSchema, AnyComponentSchema and so objectui validate now accept a node of type code, which they refused before. That is an additive accept-set widening.
    • The 37 to 38 and 47 to 48 counts are consistent: roster 38 + 3 + 7 = 48.
    • The stale-count sweep is clean. The "(37 + 7)" in surface-parity is past tense.
  • Rendering.
    • code goes through the same factory as its siblings: it strips on* handlers and dangerouslySetInnerHTML, and declares className and the children slot.
    • It leaks the siblings' 14-attribute BARE_SPREAD shape (objectui#5574), which the ledger records honestly.
    • The console pins render the text in a code element, compile clean, and render field:code as the widget's pre.
  • Manifest. +1 code with tier: 'html', 0 curated changes, div and kbd still out. The react-page pin shows no Code identifier.
  • Pins. They are real: the base leg failed 13 of 81 with the failure messages quoted, and the L1–L5b and round-2 A/B ablations are consistent with the code.
    • Two soft spots, not blocking:
      • The core "projects from whatever holds the bare key" case is synthetic, so its first half is tautological. The real stand-down is pinned by the fields collision pin and the console pin.
      • The fields collision pin never asserts that the bare key resolves to something (pre-existing).
    • The sweep enrolment is genuinely rendered and scanned (leg B). The completeness assertion is untouched.
  • Type Check: CI success.

② Semver level

  • minor is right for all four packages: components (new ui:code), core (the manifest grows), types (accept-set widening) and fields.
  • The fields stand-down changes resolution for existing consumers.
    • ComponentRegistry.get('code') changes from the widget to ui:code, or to nothing without components.
    • A bare node of type code changes from the editor to an empty code element.
    • The protocol, the objectui AGENTS.md version policy, and the 9533 precedent all want minor plus a BREAKING banner. The changeset has the migration sentence but no banner. FAIL.
  • Replacement for the @object-ui/fields bullet:
    • "- @object-ui/fields — BREAKING (authoring): the bare code key no longer resolves to the code-editor widget. code joins FIELD_TYPES_SKIP_FALLBACK, so the widget is registered field:code only. A node authored as bare { "type": "code", "value": … } now renders the html tier's code element (it draws children, not value); in a registry without @object-ui/components the bare key resolves to nothing. Migration: { "type": "code" } becomes { "type": "field:code" }. Form fields of type code resolve through the field: namespace and render the same editor as before. Released as minor under objectui's version policy; a breaking change never declares major."
  • Nits in the new changeset:
    • Add this to the types bullet: "— so AnyComponentSchema (and objectui validate) now accepts { "type": "code" }, which it refused before."
    • "pre, strong, em and span rendered their children through the passthrough" is loose: span is its own renderer (span.tsx:149). Suggested: "pre, strong and em rendered their children through the passthrough, and span through its own renderer".
    • Advisory: name '@object-ui/cli': minor, since known-schema-types.ts gains ui:code. The 9533 and 6416 precedents name it; the fixed group bumps it either way.
  • Dated notes. The 10735 and 8499 notes are in the objectui#10533 form and true.
  • The 23 bot-listed pending changesets.
    • None is newly falsified: none says bare code is the widget or gives a live html-tier count.
    • 5469's "corrected header … projects verbatim" still holds.
    • 8499's "47 new literals, 107 to 154" is the reading of that change.
  • The live PR body is stale. FAIL.
    • It says "head 974840acbd (one commit)" and "this branch's 18".
    • It omits widget-dom-leak-sweep.test.tsx and has no Round 2 section.
    • Fix: the seat applies pr_body_replacement from comment 5856338409 verbatim. It then adds to the Acceptance note on the bare JSON node: "— BREAKING (authoring), migration field:code; see the changeset."
  • objectstack manifest lag. It is stated and correct in the changeset and the PR body.

③ Boundary flags

Implemented-by: claude/issue-10756-html-tier-code-element
Reviewed-by: session_014mXUNuFomfj24w7s1pZzhN

VERDICT: FAIL

  1. .changeset/10756-html-tier-code-element.md needs the BREAKING (authoring) banner for the bare-key stand-down in @object-ui/fields. The replacement bullet is in ②. It stays minor, never major.
  2. The live PR body describes round 1. The seat applies the round-2 pr_body_replacement (comment 5856338409) plus the BREAKING clause in the Acceptance note.

After these two text fixes, the code, pins, manifest, CI and boundaries pass as reviewed.

…li names ui:code

Contract review 5856453707 (VERDICT: FAIL, text only) on objectui#10756:
- The `@object-ui/fields` bullet gets the BREAKING (authoring) banner the
  protocol and the objectui#9533 precedent require for a bare-key resolution
  change, with the `field:code` migration sentence, and stays `minor` (a
  breaking change never declares `major`).
- The `@object-ui/types` bullet gains the `AnyComponentSchema` /
  `objectui validate` accept-set-widening clause.
- The intro's "`pre`, `strong`, `em` and `span` rendered their children
  through the passthrough" corrects `span`'s own renderer (`span.tsx:149`).
- `@object-ui/cli` joins the frontmatter as `minor` (`known-schema-types.ts`
  gains `ui:code`; the objectui#9533 and objectui#6416 precedents name it in
  the fixed group either way) with a body bullet.

No code, test or manifest changes; check:changeset-presence,
check:changeset-no-major, check:changeset-overwrite (report-only) and
check:changeset-fixed all exit 0, as do check:control-bytes and
check:new-line-citations.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3068.4 KB 3104.5 KB
Main entry chunk (gzip) 148.3 KB 350 KB
Entry file index-X3o8YlTC.js —
Status PASS —

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.57KB 6.15KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.17KB 10.58KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.52KB 3.45KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.13KB 7.95KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 554.95KB 132.67KB
core (index.js) 9.57KB 3.81KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 223.93KB 62.31KB
fields (index.js) 259.29KB 65.67KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.40KB 12.91KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 39.28KB 11.09KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.01KB 3.93KB
plugin-calendar (index.js) 51.65KB 14.69KB
plugin-charts (index.js) 82.37KB 22.57KB
plugin-chatbot (index.js) 198.40KB 47.22KB
plugin-dashboard (index.js) 134.11KB 35.62KB
plugin-designer (index.js) 216.25KB 44.39KB
plugin-detail (index.js) 233.23KB 61.74KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 158.35KB 40.47KB
plugin-gantt (index.js) 169.75KB 41.96KB
plugin-grid (index.js) 218.12KB 59.72KB
plugin-kanban (index.js) 48.43KB 15.11KB
plugin-list (index.js) 114.70KB 28.42KB
plugin-map (index.js) 22.90KB 7.62KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.55KB 11.99KB
plugin-timeline (index.js) 30.91KB 9.05KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 87.83KB 22.01KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 116.21KB 38.14KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.03KB 1.86KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.78KB 2.09KB
sdui-parser (codegen.js) 7.50KB 3.05KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.16KB 2.71KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 18.27KB 6.20KB
types (ai.js) 4.11KB 2.06KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 17.15KB 6.32KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: d601b5c1d2bd51adff60e3a481c51b6b30b80931

Narrow round-3 review, run in-seat by the dispatching seat, of the delta b62fca8044..d601b5c1d2 (one commit) against the round-2 FAIL record 5856453707. Every other judgment in that record stands: registry answers, the census of bare code authors, both widenings, rendering, manifest, pins and boundaries. No source, test or generated file has moved since b62fca8044.

① Derived judgments

  • The delta is the changeset only: .changeset/10756-html-tier-code-element.md, +20 / −10.
  • Item 1 is resolved.
    • The @object-ui/fields bullet now opens with BREAKING (authoring): the bare code key no longer resolves to the code-editor widget. The rest of the bullet is the review's replacement text: FIELD_TYPES_SKIP_FALLBACK, the bare JSON node now drawing the element's children instead of the widget's value, the registry-without-components case, the field:code migration, forms unchanged, and "minor … never major".
    • The dev reports a whitespace-normalised match against the review's text. The seat read it against the record and it matches.
  • The nits are carried.
    • The @object-ui/types bullet gains the AnyComponentSchema / objectui validate accept-set sentence.
    • The intro's span clause now names span as its own renderer.
    • The advisory is taken: '@object-ui/cli': minor joins the frontmatter with a body bullet (known-schema-types.ts gains ui:code).
  • Item 2 (the stale PR body) is resolved by the dev's round-3 pr_body_replacement. The seat applies it at landing. It carries:
    • the four-commit head;
    • Round 2 and Round 3 sections;
    • the 19-file scope with widget-dom-leak-sweep.test.tsx;
    • the Acceptance-note BREAKING clause.

② Semver level

minor for @object-ui/components, @object-ui/core, @object-ui/types, @object-ui/fields and @object-ui/cli, with the fields BREAKING (authoring) banner. Clause-②: yes. No major: check-changeset-no-major passed. check-changeset-fixed and check-changeset-presence pass at head (the dev's reading).

③ Boundary flags

  • CI on d601b5c1d2: 43 check runs; 40 success, 3 skipped, 0 failure, 0 pending.
  • Merge: git merge-tree --write-tree against main bf14b64608 is clean, tree dfe14b140f. Main's commits since b62fca8044 do not touch the one changed file.
  • NOT GOVERNED.
  • The PR is draft; the assignee is os-elon-musk.
  • The card carries needs:contract-review, which is cleared at landing.

Implemented-by: claude/issue-10756-html-tier-code-element
Reviewed-by: session_014mXUNuFomfj24w7s1pZzhN

VERDICT: PASS

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review September 27, 2026 14:26
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Sep 27, 2026
Merged via the queue into main with commit 29b45f6 Sep 27, 2026
45 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-10756-html-tier-code-element branch September 27, 2026 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment