diff --git a/.changeset/5213-widget-ts-retired-spec-anchor-history.md b/.changeset/5213-widget-ts-retired-spec-anchor-history.md new file mode 100644 index 000000000..3571ee7fd --- /dev/null +++ b/.changeset/5213-widget-ts-retired-spec-anchor-history.md @@ -0,0 +1,46 @@ +--- +'@object-ui/types': patch +--- + +`RuntimeWidgetManifest` / `RuntimeWidgetSource` document the spec's retired +`WidgetManifest` / `WidgetSource` as HISTORY, instead of describing them as a +live schema (objectui#5213). + +Both JSDoc blocks were written while `@objectstack/spec/ui` still exported a +field-widget-plugin `WidgetManifest` and a `WidgetSource` union — they said the +local types were "renamed off the spec's name", in the present tense, and the +manifest block enumerated the spec shape key by key (`fieldTypes`, `category`, +`lifecycle`, `events`, `properties`, `implementation`, `screenshots`, `license`, +`aria`, `performance`). Protocol 17 retired that entire widget-registration +vocabulary under ADR-0049 enforce-or-remove (objectstack#5055): the installed +`@objectstack/spec` 17.2.0 exports none of those names, and its own tombstone +records why there is nothing to migrate — no schema ever declared a carrier key +of a widget shape, so the record is the D3 `SemanticMigration` +`ui-widget-i18n-family-retired` plus `ui/WidgetManifest` in +`RETIRED_DEFS_BY_MAJOR` for major 17. + +A per-key description of a schema that no longer exists is the ADR-0033 failure: +an AI author reads a published docblock as present-tense fact and builds on it. +The enumeration is dropped rather than re-dated, and the blocks now say what is +true today — the bare names are owned by NOBODY, `RuntimeWidgetManifest` is +objectui's only widget-registration contract, and the `Runtime` prefix is kept +BY CHOICE (objectstack#4988's precedent: a freed word is not a reason to spend a +second breaking rename taking it back; the unlock is recorded, not taken, in +objectui#4164). The `inline` collision that made the `WidgetSource` rename +urgent is kept, in the past tense, because it is the reason the prefix exists. +Both blocks now point at the live assertion instead of restating it: the "the +spec no longer owns" rows in +`packages/types/src/__tests__/page-nav-misc-spec-parity.test.ts`, which are what +goes red if the spec ever re-publishes either name. + +Comments only. No type, signature, member or test changed, and the parity test +that owns this fact was already correct — it moved both rows to its "spec no +longer owns" table on the 17.0.0-rc.6 bump. + +Declared a `patch` for `@object-ui/types` alone because the emit was measured, +not assumed: both blocks sit on EXPORTED declarations, so they publish. Rebuilt +from a cleared `dist` and `tsconfig.tsbuildinfo` on both sides and compared by +SHA-256 — `dist/widget.d.ts` `bb4f2fd702cac02a…` -> `db1d5fbd53d305f5…` +(a consumer reads this text on hover and in the API docs), while +`dist/widget.js` is byte-identical across the rebuild +(`a3de34c54213a269…` both sides), so nothing runtime moved. diff --git a/packages/types/src/widget.ts b/packages/types/src/widget.ts index 1db9c9c79..85dd8a9ad 100644 --- a/packages/types/src/widget.ts +++ b/packages/types/src/widget.ts @@ -27,17 +27,37 @@ import type { ComponentInputControlType } from './base.js'; * A manifest provides all metadata needed to discover, load, and render * a widget without requiring an upfront import of its code. * - * Renamed off the spec's `WidgetManifest` name (objectstack#4115): the spec's - * is the **field-widget plugin** manifest that sits beside its - * `FieldWidgetProps` — `{ fieldTypes, category: input|display|picker|editor, - * lifecycle: { onMount, onValidate, … }, events, properties, implementation, - * screenshots, license, aria, performance }`. This one is the **SDUI component** - * manifest: `type` is a schema-renderer component key, and it carries `source`, - * `defaultProps`, `inputs`, `isContainer` and `capabilities`, none of which the - * spec's models. The only keys the two share are `name`/`label`/`version`/ - * `icon`/`description`. + * Today this is objectui's ONLY widget-registration contract: no published + * `@objectstack/spec` schema models one. * - * Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`. + * HISTORY — why the `Runtime` prefix exists, and why it stays. + * `@objectstack/spec/ui` ONCE exported a **field-widget plugin** + * `WidgetManifest` (beside its `FieldWidgetProps`), and this interface was + * renamed off that name to end the collision (objectstack#4115). ⚠️ That schema + * is GONE — its keys are deliberately no longer enumerated here, and the + * prefix is not evidence that a spec twin exists: protocol 17 retired the whole + * widget-registration vocabulary — `WidgetManifest`, `WidgetLifecycle`, + * `WidgetEvent`, `WidgetProperty`, `WidgetSource` — under ADR-0049 + * enforce-or-remove (objectstack#5055, maintainer ruling 2026-08-06). There is + * no tombstone key to migrate, because there was never a carrier key: the + * record is the D3 `SemanticMigration` `ui-widget-i18n-family-retired` plus + * `ui/WidgetManifest` in the spec's `RETIRED_DEFS_BY_MAJOR` for 17. That entry + * states the relationship these two types always had, verbatim: "objectui's + * registry has always carried its own runtime manifest for that + * (`RuntimeWidgetManifest` / `RuntimeWidgetSource` in `@object-ui/types`, + * objectui#3161 / #4115), which models different keys and never derived from + * these". `field.widget` is still what it always was — a `z.string()` naming a + * component the RENDERER has registered. + * + * So the bare name is now owned by NOBODY, and the prefix is kept BY CHOICE: a + * freed word is not a reason to spend a second breaking rename taking it back + * (objectstack#4988 precedent; the unlock is recorded, not taken — + * objectui#4164). + * + * Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`. Its "the spec no + * longer owns `WidgetManifest`" row is the LIVE assertion of that vacancy — + * read it, not this comment, for what the spec owns today; it goes red if the + * spec ever re-publishes the name while this package holds it. * * @example * ```ts @@ -106,20 +126,25 @@ export interface RuntimeWidgetManifest { /** * Describes how to load the widget's code at runtime. * - * Renamed off the spec's `WidgetSource` name (objectstack#4115). Both are - * discriminated unions on `type`, which is what makes the collision dangerous: - * they share the member name `inline` and mean opposite things by it. The - * spec's `inline` carries source **code** to evaluate (`{ type: 'inline', code: - * string }`), objectui's carries an **already-resolved component** - * ({@link WidgetSourceInline}). The other members do not overlap at all — the - * spec has `npm`/`remote`, objectui has `module`/`registry` — so a value of one - * union is never a valid value of the other. + * HISTORY — the same rename as {@link RuntimeWidgetManifest}, and the more + * dangerous half of the collision it ended. `@objectstack/spec/ui` ONCE + * exported a `WidgetSource` union too (objectstack#4115). Both WERE + * discriminated unions on `type` that shared the member name `inline` and meant + * opposite things by it: + * the spec's `inline` carried source **code** to evaluate (`{ type: 'inline', + * code: string }`), objectui's carries an **already-resolved component** + * ({@link WidgetSourceInline}). The other members never overlapped — the spec + * had `npm`/`remote`, objectui has `module`/`registry` — so a value of one + * union was never a valid value of the other. ⚠️ The spec's union was retired + * with the rest of the widget-registration vocabulary (objectstack#5055): the + * union declared below is objectui's own, and never derived from it. * - * The variant interfaces keep their `WidgetSource…` names: the spec does not - * export those, and renaming them would churn the public surface without + * The variant interfaces keep their `WidgetSource…` names: the spec never + * exported those, and renaming them would churn the public surface without * removing a collision. * - * Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`. + * Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts` — its "the spec no + * longer owns `WidgetSource`" row pins the vacancy. */ export type RuntimeWidgetSource = | WidgetSourceModule