Recorded while fixing #13762 (the Plugin.type TSDoc under-enumeration). Out of that card's scope — filed for triage, no assignee.
The observation
Plugin.type in packages/core/src/types.ts is declared type?: string. Nothing type-checks a plugin author against the eight values the platform actually accepts, so the TSDoc comment beside it carries the entire enumeration on its own. That is exactly why the comment drifting was worth a card: prose was doing a type's job.
While verifying that assumption for #13762 I measured something the card did not claim:
- There is no
PluginType alias and no typeof CORE_PLUGIN_TYPES derived type anywhere in packages/**. The enumeration exists only as the Zod enum in packages/spec/src/kernel/plugin.zod.ts and as prose.
packages/core already declares @objectstack/spec as a workspace:* dependency. So a type-level narrowing is reachable today without adding a dependency edge.
Sketch of the shape, not a proposal to land as-is:
import type { CORE_PLUGIN_TYPES } from '@objectstack/spec';
type PluginType = 'standard' | (typeof CORE_PLUGIN_TYPES)[number];
type?: PluginType;
Why it needs a decision rather than a patch
This narrows a published type on @objectstack/core. Anything today assigning a computed or third-party string to Plugin.type stops compiling, so it is an accept/reject change on a public surface, not a cleanup — it needs the contract-review path and a deliberate call on whether plugin type is a closed set for external authors or an open one the runtime merely recognises some members of.
It is also worth weighing against #13678, which would close the same drift class mechanically with a gate. These are alternative remedies for one defect, and the type-level one is narrower but stronger: it makes the wrong value unwritable rather than detectable. Whether the platform wants type closed is the real question, and it is a maintainer call.
How it was settled
Read against the implementation on origin/main at 5c34b7e26b: the type?: string declaration in packages/core/src/types.ts, a repo-wide search for a PluginType-shaped alias returning nothing, and packages/core/package.json showing the existing @objectstack/spec dependency.
Generated by Claude Code
Generated by Claude Code
Recorded while fixing #13762 (the
Plugin.typeTSDoc under-enumeration). Out of that card's scope — filed for triage, no assignee.The observation
Plugin.typeinpackages/core/src/types.tsis declaredtype?: string. Nothing type-checks a plugin author against the eight values the platform actually accepts, so the TSDoc comment beside it carries the entire enumeration on its own. That is exactly why the comment drifting was worth a card: prose was doing a type's job.While verifying that assumption for #13762 I measured something the card did not claim:
PluginTypealias and notypeof CORE_PLUGIN_TYPESderived type anywhere inpackages/**. The enumeration exists only as the Zod enum inpackages/spec/src/kernel/plugin.zod.tsand as prose.packages/corealready declares@objectstack/specas aworkspace:*dependency. So a type-level narrowing is reachable today without adding a dependency edge.Sketch of the shape, not a proposal to land as-is:
Why it needs a decision rather than a patch
This narrows a published type on
@objectstack/core. Anything today assigning a computed or third-partystringtoPlugin.typestops compiling, so it is an accept/reject change on a public surface, not a cleanup — it needs the contract-review path and a deliberate call on whether plugintypeis a closed set for external authors or an open one the runtime merely recognises some members of.It is also worth weighing against #13678, which would close the same drift class mechanically with a gate. These are alternative remedies for one defect, and the type-level one is narrower but stronger: it makes the wrong value unwritable rather than detectable. Whether the platform wants
typeclosed is the real question, and it is a maintainer call.How it was settled
Read against the implementation on
origin/mainat5c34b7e26b: thetype?: stringdeclaration inpackages/core/src/types.ts, a repo-wide search for aPluginType-shaped alias returning nothing, andpackages/core/package.jsonshowing the existing@objectstack/specdependency.Generated by Claude Code
Generated by Claude Code