Skip to content

[finding] plugin-hono-server still accepts the legacy ui-plugin type that PluginSchema refuses — an unreachable arm under ADR-0049 #15638

Description

@os-sales

Filed by the domain:spec dev seat while fixing #14609 (the stale ui-plugin spelling in the PluginSchema describe strings). Recording only — no severity asserted; routing and grading are triage's. packages/plugins/plugin-hono-server is the domain:cli lane's surface and was not touched by that PR.

What was measured (on origin/main d30ccb9bd)

packages/plugins/plugin-hono-server/src/hono-plugin.ts:507-508:

// Support legacy 'ui-plugin' and new 'ui' type
if ((plugin.type === 'ui' || plugin.type === 'ui-plugin') && plugin.staticPath) {

The ui-plugin disjunct looks unreachable through the schema:

  • PluginSchema.type is z.enum(['standard', ...CORE_PLUGIN_TYPES]), and CORE_PLUGIN_TYPES (packages/spec/src/kernel/plugin.zod.ts:89) spells the frontend member ui. ui-plugin is not a member.
  • Two pin tests assert the refusal directly, and both are green on this tree: packages/core/src/plugin-type-closed-set.test.ts (3 tests) asserts PluginSchema.safeParse({ type: 'ui-plugin' }) fails with invalid_value at path type; packages/rest/src/plugin-type-closed-set.pin.test.ts (4 tests) pins the same value as a compile-time non-member of PluginType.

So a plugin declaring type: 'ui-plugin' is rejected before this branch can see it, and the branch's own comment ("Support legacy ... type") advertises a tolerance the contract no longer grants. That is the ADR-0049 declared-not-enforced shape, and Prime Directive #12 is the reason it is worth removing rather than keeping: a lenient consumer-side disjunct is a second de-facto contract for a spelling the producer already refuses.

Why this is worth a card even though it is dead code

The three describe strings fixed in #14609 said "Required for type="ui-plugin"", and this branch accepted exactly that value. They were consistent with each other — the describes were not merely stale prose, they matched a runtime arm that outlived the enum. #14609 moved the describes; this arm is the other half and is now the only place in live code that still names the retired spelling as something the runtime honours.

What is NOT being claimed

Whether the arm is reachable by some path that bypasses PluginSchema (a plugin object constructed in process and never parsed, a stored row rehydrated outside the schema seam) was not measured here. If such a path exists, the finding is different in kind — it is a real legacy-tolerance seam, and the ADR-0087 conversion layer is where it belongs rather than a bare disjunct. Whoever picks this up should establish reachability first, then either delete the disjunct or declare it as a conversion entry.

Dedup

search_issues "plugin-hono-server still accepts the legacy ui-plugin type value that PluginSchema refuses — unreachable legacy branch in hono-plugin.ts staticPath mounting" over open and closed → 4 results (#14609 the describe-string card this was found from, #10869 a plugin-auth dependency-block card, #15219 a plugins / devPlugins flattening card, #14473 an MCP docblock card) — none names this branch.

Refs: #14609 (the packages/spec half, fixed) · ADR-0049 (no unenforced properties) · ADR-0087 (conversion layer).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions