You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
spec: PluginSchema makes staticPath / slug really required for type: "ui" (superRefine), and core's Plugin interface derives from PluginDefinition (spec half of #16049) #16334
Spec half of #16049, split by director ruling (decision batch #58, 2026-09-06, option A — enforce PluginSchema at kernel.use()). Not blocking #16049: the engine card enforces the schema as it stands; this card makes the schema say what its prose already promises.
Why
packages/spec/src/kernel/plugin.zod.ts describes staticPath and slug as "Required for type="ui"" while declaring both .optional(). Once #16049 runs the schema on the boot path, that prose becomes a promise the runtime visibly does not keep. Separately, packages/core/src/types.ts's Plugin interface declares neither key (os-litant's measurement on #16049, comment 5557890760), so an in-repo plugin cannot carry them without widening its own type — two shapes for one contract.
Scope
PluginSchema.superRefine: when type === 'ui', staticPath and slug are required; refusal carries a stable code so the engine card's boot-path refusal can surface it.
Keep default semantics as documented (only one ui plugin may be default) — refine only if it is cheap to check per object; cross-object uniqueness stays the kernel's job.
Core's Plugin interface derives from PluginDefinition (z.input<typeof PluginSchema>) for the metadata keys, so the two shapes cannot drift; runtime-only members (init, lifecycle hooks) stay on the interface.
Spec half of #16049, split by director ruling (decision batch #58, 2026-09-06, option A — enforce
PluginSchemaatkernel.use()). Not blocking #16049: the engine card enforces the schema as it stands; this card makes the schema say what its prose already promises.Why
packages/spec/src/kernel/plugin.zod.tsdescribesstaticPathandslugas "Required for type="ui"" while declaring both.optional(). Once #16049 runs the schema on the boot path, that prose becomes a promise the runtime visibly does not keep. Separately,packages/core/src/types.ts'sPlugininterface declares neither key (os-litant's measurement on #16049, comment 5557890760), so an in-repo plugin cannot carry them without widening its own type — two shapes for one contract.Scope
PluginSchema.superRefine: whentype === 'ui',staticPathandslugare required; refusal carries a stable code so the engine card's boot-path refusal can surface it.defaultsemantics as documented (only oneuiplugin may be default) — refine only if it is cheap to check per object; cross-object uniqueness stays the kernel's job.Plugininterface derives fromPluginDefinition(z.input<typeof PluginSchema>) for the metadata keys, so the two shapes cannot drift; runtime-only members (init, lifecycle hooks) stay on the interface.core/src/types.ts:127's comment ("PluginSchema.typerefuses it at parse") to point at the boot-path refusal once [finding] PluginSchema has zero runtime callers — the boot path validates name, init and semver only, so the declared plugin contract is never enforced #16049 lands.Acceptance
uiplugin withoutstaticPathorslugfailsPluginSchema.safeParsePluginmetadata keys are derived, not restated