From 012c57cb87e78b162a76807edf38ab15cceffac4 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Aug 2026 17:09:14 +0000 Subject: [PATCH 1/3] docs(react): toRenderableSchema's header says the bridge is permanent (#4622) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The closing paragraph of `toRenderableSchema`'s JSDoc said the two competing repo-wide `SchemaNode` spellings "have not been reconciled" and that "when it lands, the call sites using this can go back to forwarding directly". Both halves went false when PR #4608 merged, and the second half is the harmful one: it is an instruction whose trigger condition has now fired, sitting directly above the function a future author is about to call. The reconciliation (objectui#4580 / PR #4608) resolved the collision in favour of `@object-ui/types`' union — `packages/core/src/types/index.ts:41` is now `export type { SchemaNode } from '@object-ui/types';` — while SchemaRenderer's prop stays deliberately narrow per objectui#4548 ruling Q2 (`schema: BaseSchema | string | null | undefined`, no `number` / `boolean`). So a `SchemaNode` became LESS assignable to that prop, not more, and the bridge is a permanent crossing between two intentionally different types. Following the old instruction has a measured cost, and the new paragraph names it: five `apps/site` call sites were forwarding directly when PR #4608 landed, and `Build Docs` was red on `main` for roughly five hours until PR #4621 routed all five through this function (objectui#4617). Comment-only. The emitted JavaScript is byte-identical (both revisions of the file transpiled with `tsc --removeComments`, sha256 ce9ba5c4ce7590dce63e5ca853cfb7a79d55df338d1fd32403b215b39cefda06 on each side), and no changed line falls outside the JSDoc block. The paragraph does ship, which is why a patch changeset is owed: this package builds with plain `tsc`, so the comment is carried into `dist/schema-input.d.ts`. Fixes #4622 Claude-Session: https://claude.ai/code/session_012u2pRjcqAYtoEjgr3wwhnK Co-authored-by: Claude --- .../schema-input-bridge-permanent-4622.md | 28 +++++++++++++++++++ packages/react/src/schema-input.ts | 18 +++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 .changeset/schema-input-bridge-permanent-4622.md diff --git a/.changeset/schema-input-bridge-permanent-4622.md b/.changeset/schema-input-bridge-permanent-4622.md new file mode 100644 index 0000000000..b7ae71a011 --- /dev/null +++ b/.changeset/schema-input-bridge-permanent-4622.md @@ -0,0 +1,28 @@ +--- +'@object-ui/react': patch +--- + +`toRenderableSchema`'s header now says the bridge is permanent, instead of instructing +callers to remove it (objectui#4622). + +Comment-only — the emitted JavaScript is byte-identical. The paragraph nonetheless ships: +this package builds with plain `tsc`, so the JSDoc is carried into +`dist/schema-input.d.ts` and is what an editor shows on hover at every call site. + +The old closing paragraph said the two competing repo-wide `SchemaNode` spellings "have +not been reconciled" and that "when it lands, the call sites using this can go back to +forwarding directly". Both halves went false when PR #4608 merged, and the second half is +the harmful one: it is an instruction whose trigger condition has now fired, sitting +directly above the function a future author is about to call. + +The reconciliation (objectui#4580 / PR #4608) resolved the collision in favour of +`@object-ui/types`' union — `@object-ui/core` now re-exports it rather than hand-declaring +an interface — while `SchemaRenderer`'s prop stays deliberately narrow per objectui#4548 +ruling Q2 (`schema: BaseSchema | string | null | undefined`, no `number` / `boolean`). So +a `SchemaNode` became *less* assignable to that prop, not more, and the bridge is a +permanent crossing between two intentionally different types rather than scaffolding +awaiting a merge. + +Following the old instruction has a measured cost: five `apps/site` call sites were +forwarding directly when PR #4608 landed, and `Build Docs` was red on `main` for roughly +five hours until PR #4621 routed all five through this function (objectui#4617). diff --git a/packages/react/src/schema-input.ts b/packages/react/src/schema-input.ts index 8d0a40a078..519d76bbe9 100644 --- a/packages/react/src/schema-input.ts +++ b/packages/react/src/schema-input.ts @@ -25,10 +25,20 @@ import type { SchemaRendererProps } from './SchemaRenderer.js'; * tells no lie — the value a caller forwards renders identically whether or not * it passes through here. * - * It exists because the two competing repo-wide `SchemaNode` spellings - * (`@object-ui/core`'s interface vs `@object-ui/types`' union) have not been - * reconciled; that reconciliation is tracked separately. When it lands, the - * call sites using this can go back to forwarding directly. + * The bridge is PERMANENT — not scaffolding awaiting a merge. The two competing + * repo-wide `SchemaNode` spellings ARE reconciled (objectui#4580, PR #4608): + * `@object-ui/core` stopped hand-declaring its own interface and now re-exports + * `@object-ui/types`' union, so one declaration is left to disagree with. That + * reconciliation resolved in favour of the UNION, while `SchemaRenderer`'s prop + * stays deliberately narrow (objectui#4548 ruling Q2 — it declares no `number` + * or `boolean`), so a `SchemaNode` is now LESS assignable to that prop than it + * was, not more. This step therefore bridges two intentionally different types, + * and it stays. ⛔ Do not "tidy" a call site back into a direct forward: the + * five `apps/site` sites that were forwarding directly when PR #4608 landed are + * what kept `Build Docs` red on `main` for ~5 hours — each one a TS2322 naming + * `number` against this function's return type — until PR #4621 routed all five + * through here (objectui#4617). An earlier revision of this paragraph said the + * reconciliation was still pending and invited exactly that edit. */ export function toRenderableSchema( node: BaseSchema | string | number | boolean | null | undefined, From d51022bb085016668ad69ad5d5ddacf7e77edaee Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Aug 2026 17:22:18 +0000 Subject: [PATCH 2/3] =?UTF-8?q?docs(react):=20correct=20the=20emit=20claim?= =?UTF-8?q?=20on=20this=20branch=20=E2=80=94=20the=20JSDoc=20does=20ship?= =?UTF-8?q?=20as=20bytes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The changeset on the previous commit said "the emitted JavaScript is byte-identical". That is FALSE, and the way it became false is worth recording, because it is the same failure mode this card exists to prevent — a confident claim that does not survive being checked. The measurement behind it transpiled both revisions with `tsc --removeComments` and compared sha256s. That is a correct measurement of a build this repo does not perform: `tsconfig.base.json:22` sets `"removeComments": false` deliberately, and this package builds with plain `tsc`, so comments are emitted into `dist/*.js`. The flag measured away the very thing being measured. Re-measured by building the package the way the repo builds it, at both revisions, with `dist/` cleared between runs: dist/schema-input.js 1,486 B -> 2,316 B (1.45 KB -> 2.26 KB) gzipped 850 B -> 1,246 B (0.83 KB -> 1.22 KB) +830 B raw, +396 B gzipped which reproduces CI's bundle-size rows for this PR (2.26 KB / 1.22 KB) and for two sibling PRs cut from the same merge-base that do not touch this file (1.45 KB / 0.83 KB). What IS true, and is what the changeset now says: all 18 differing lines in the emitted file are JSDoc continuations, and the three executable lines are byte-identical, so the growth is the paragraph and nothing else. The source change remains comment-only — the `git diff -U0` structural check is unaffected and still holds. The doc paragraph itself is unchanged: it makes no claim about emitted bytes, and the size is not being chased. Roughly 0.4 KB gzipped is the deliberate price of not repeating a five-hour `Build Docs` outage. Claude-Session: https://claude.ai/code/session_012u2pRjcqAYtoEjgr3wwhnK Co-authored-by: Claude --- .changeset/schema-input-bridge-permanent-4622.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.changeset/schema-input-bridge-permanent-4622.md b/.changeset/schema-input-bridge-permanent-4622.md index b7ae71a011..05a652d65f 100644 --- a/.changeset/schema-input-bridge-permanent-4622.md +++ b/.changeset/schema-input-bridge-permanent-4622.md @@ -5,9 +5,19 @@ `toRenderableSchema`'s header now says the bridge is permanent, instead of instructing callers to remove it (objectui#4622). -Comment-only — the emitted JavaScript is byte-identical. The paragraph nonetheless ships: -this package builds with plain `tsc`, so the JSDoc is carried into -`dist/schema-input.d.ts` and is what an editor shows on hover at every call site. +No executable line changes — but the artifact is **not** unchanged, and that is worth +stating plainly rather than rounding to "comment-only". This package builds with plain +`tsc`, and `tsconfig.base.json` sets `"removeComments": false` deliberately, so the JSDoc +is emitted into `dist/schema-input.js` as well as `dist/schema-input.d.ts` — it is both +what an editor shows on hover at every call site and bytes that ship. + +Measured by building the package the way the repo builds it, at both revisions: +`dist/schema-input.js` grows from 1,486 to 2,316 bytes (1.45 KB to 2.26 KB), and from 850 +to 1,246 bytes gzipped (0.83 KB to 1.22 KB) — **+830 bytes raw, +396 gzipped**. All 18 +differing lines in the emitted file are JSDoc continuations and the three executable lines +are byte-identical, so the growth is the paragraph and nothing else. The trade is +deliberate: roughly 0.4 KB gzipped, against the five-hour `Build Docs` outage the old +paragraph's instruction produced once already. The old closing paragraph said the two competing repo-wide `SchemaNode` spellings "have not been reconciled" and that "when it lands, the call sites using this can go back to From 21d9d47261a4b8be2e4d661894e82b7942079d33 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Aug 2026 17:29:36 +0000 Subject: [PATCH 3/3] docs(react): scope the union spelling to #4617's logs, so it cannot go stale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PM ruling on the wording of the TS2322 clause: neither "against this function's return type" alone nor a bare `string | BaseSchema | null | undefined` alone, but both, with the literal spelling scoped as a historical quotation. The reasoning is the axis I had not weighed. Describing the type by its ROLE is self-updating — if `SchemaRendererProps['schema']` gains or loses a member tomorrow, the sentence stays true with no edit. Hardcoding today's spelling as a present-tense claim is NOT self-updating, and would have added a fresh way for this paragraph to go false, which is the exact defect the paragraph exists to fix. Attributing the spelling to what #4617's logs said in August 2026 is a fixed fact that cannot rot however the union evolves, and it hands a reader with the log open the exact string to match in one hop. - `number` against this function's return type — until PR #4621 routed all five - through here (objectui#4617). + `number` against this function's return type, spelled + `string | BaseSchema | null | undefined` in objectui#4617's logs — until + PR #4621 routed all five through here. The paragraph grew, so both byte figures in the changeset are re-measured rather than left stale — the same build, at both revisions, with `dist/` cleared between runs: dist/schema-input.js 1,486 B -> 2,377 B (1.45 KB -> 2.32 KB) +891 B gzipped 850 B -> 1,266 B (0.83 KB -> 1.24 KB) +416 B previously 2,316 B / 1,246 B for the shorter paragraph. All 19 differing lines in the emitted file are JSDoc continuations (was 18) and the three executable lines remain byte-identical, so the growth is still the paragraph and nothing else. Noted for next time, per the PM: quoting exact byte counts in a changeset couples it to the comment's length, which is what made this edit cost a re-measure. Still the right call here — the numbers are the honest replacement for a claim that was wrong — but a cost to choose deliberately rather than by default. Claude-Session: https://claude.ai/code/session_012u2pRjcqAYtoEjgr3wwhnK Co-authored-by: Claude --- .changeset/schema-input-bridge-permanent-4622.md | 4 ++-- packages/react/src/schema-input.ts | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.changeset/schema-input-bridge-permanent-4622.md b/.changeset/schema-input-bridge-permanent-4622.md index 05a652d65f..4b78051281 100644 --- a/.changeset/schema-input-bridge-permanent-4622.md +++ b/.changeset/schema-input-bridge-permanent-4622.md @@ -12,8 +12,8 @@ is emitted into `dist/schema-input.js` as well as `dist/schema-input.d.ts` — i what an editor shows on hover at every call site and bytes that ship. Measured by building the package the way the repo builds it, at both revisions: -`dist/schema-input.js` grows from 1,486 to 2,316 bytes (1.45 KB to 2.26 KB), and from 850 -to 1,246 bytes gzipped (0.83 KB to 1.22 KB) — **+830 bytes raw, +396 gzipped**. All 18 +`dist/schema-input.js` grows from 1,486 to 2,377 bytes (1.45 KB to 2.32 KB), and from 850 +to 1,266 bytes gzipped (0.83 KB to 1.24 KB) — **+891 bytes raw, +416 gzipped**. All 19 differing lines in the emitted file are JSDoc continuations and the three executable lines are byte-identical, so the growth is the paragraph and nothing else. The trade is deliberate: roughly 0.4 KB gzipped, against the five-hour `Build Docs` outage the old diff --git a/packages/react/src/schema-input.ts b/packages/react/src/schema-input.ts index 519d76bbe9..1d05d4733b 100644 --- a/packages/react/src/schema-input.ts +++ b/packages/react/src/schema-input.ts @@ -36,9 +36,10 @@ import type { SchemaRendererProps } from './SchemaRenderer.js'; * and it stays. ⛔ Do not "tidy" a call site back into a direct forward: the * five `apps/site` sites that were forwarding directly when PR #4608 landed are * what kept `Build Docs` red on `main` for ~5 hours — each one a TS2322 naming - * `number` against this function's return type — until PR #4621 routed all five - * through here (objectui#4617). An earlier revision of this paragraph said the - * reconciliation was still pending and invited exactly that edit. + * `number` against this function's return type, spelled + * `string | BaseSchema | null | undefined` in objectui#4617's logs — until + * PR #4621 routed all five through here. An earlier revision of this paragraph + * said the reconciliation was still pending and invited exactly that edit. */ export function toRenderableSchema( node: BaseSchema | string | number | boolean | null | undefined,