Skip to content

spec: name the live ui plugin type in the PluginSchema describe strings - #15639

Merged
os-sales merged 2 commits into
mainfrom
claude/issue-14609-plugin-describe-ui-plugin-spelling
Sep 5, 2026
Merged

spec: name the live ui plugin type in the PluginSchema describe strings#15639
os-sales merged 2 commits into
mainfrom
claude/issue-14609-plugin-describe-ui-plugin-spelling

Conversation

@claude

@claude claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Fixes #14609

PluginSchema.type is z.enum(['standard', ...CORE_PLUGIN_TYPES]), and CORE_PLUGIN_TYPES spells the frontend member ui. The staticPath, slug and default describe strings two lines below it still named ui-plugin — a value the same schema refuses. They are not merely stale: they read as instructions ("Required for type="ui-plugin""), so an author or an agent following the field's own documentation writes a value that is then rejected, with the correct spelling nowhere in the sentence that sent them there.

What changed

file change
packages/spec/src/kernel/plugin.zod.ts :126-:128 the three describe strings now read (Required for type="ui"), (Required for type="ui"), (Only one "ui" plugin can be default)
content/docs/plugins/anatomy.mdx :80, :96 the two prose sites now read "ui plugin references" and "ui plugins"; the page's own heading already read ### 2. UI Plugin (\ui`)`
content/docs/references/kernel/plugin.mdx regenerated, never hand-edited — pnpm --filter @objectstack/spec gen:schema && gen:docs. Its banner reads "AUTO-GENERATED — DO NOT EDIT"
.changeset/plugin-describe-ui-type-spelling.md patch on @objectstack/spec

On the default string, ui-plugin was doing duty as a noun ("only one ui-plugin"), so a bare substitution would have left "Only one "ui" can be default". It is spelled Only one "ui" plugin can be default — the quoted token is still exactly the enum member an author must type.

The correction reaches the published surface, not just the source file. These describes compile into the shipped Zod schema, the generated JSON Schema and the reference page. After a full rebuild: zero occurrences of ui-plugin in packages/spec/dist/, zero in the bundled json-schema/objectstack.json (1,589 definitions), and the reference table now agrees with the type row printed directly above it — that row already listed 'ui' among the accepted members while the three rows underneath told the reader to write ui-plugin.

Census — every ui-plugin occurrence was disambiguated, not swept

ui-plugin occurs in 17 files. Each was read to its declaring meaning before anything was touched.

Deliberately unchanged, and why:

  • packages/core/src/plugin-type-closed-set.test.ts and packages/rest/src/plugin-type-closed-set.pin.test.ts name ui-plugin as a non-member on purpose. They are the reason this correction is provable, and both stay green (3 + 4 tests).
  • packages/spec/src/system/core-services.zod.ts:71, packages/metadata-protocol/src/protocol.ts:3574 and scripts/check-service-providers.mjs:12not the same drift. All three carry one copied incident narrative about a hand-written remedy table in which ten of fifteen entries named a package that does not exist; ui-plugin there is one of those fabricated package names, not a PluginSchema.type member. Rewriting it would make the sentence false — it would claim the old table said ui, which it did not. (Triage read core-services.zod.ts as "a second packages/spec instance, same drift" and scoped it in; that reading does not survive reading the surrounding docblock. The third copy in scripts/check-service-providers.mjs was in neither the card nor triage's census and corroborates the narrative reading.)
  • docs/adr/**, docs/design/** and the CHANGELOG.md files — historical records. Several are just links to 0026-client-ui-plugin-distribution.md, an ADR filename.
  • packages/plugins/plugin-hono-server/src/hono-plugin.ts:507-508 — a runtime arm that still accepts the value. Out of scope for this lane; filed separately as [finding] plugin-hono-server still accepts the legacy ui-plugin type that PluginSchema refuses — an unreachable arm under ADR-0049 #15638 and not edited here.

Verification

All at 6fd712857, the pushed HEAD, with a clean tree.

  • pnpm --filter '@objectstack/spec^...' build && pnpm --filter @objectstack/spec build — exit 0, check-dts-emitted: 34/34 declaration file(s) present.
  • pnpm --filter @objectstack/spec test472 test files, 12,686 tests passed. pnpm --filter @objectstack/spec typecheck — exit 0.
  • Closed-set pins, run targeted: @objectstack/core plugin-type-closed-set.test.ts 3/3, @objectstack/rest plugin-type-closed-set.pin.test.ts 4/4. type: 'ui-plugin' is refused before and after; type: 'ui' is accepted before and after. No accept/reject behaviour moves, and no key is added, renamed or removed.
  • 19 gate families derived from the real change set with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (exit 0; it read the merge base itself rather than a hand-built list) — all exit 0, each captured before any pipe. Notably check:generated, spec check:docs, check:authorable-surface, check:merge-driver, check:docs-audit-scope, check:corpus-claim-drift, the three changeset gates, and check:nul-bytes (OK (scanned 7572 text files ... no raw ASCII control bytes)).
  • pnpm lint (eslint . --no-inline-config, whole repo) — exit 0. Run in full, so this is a measurement and not a narrowing.
  • authorable-surface.base.json was deliberately not re-anchored: the build prints re-anchoring as its own reviewed act (gen:authorable-surface-base), never a side effect of a regeneration run.
  • Governed-surface predicate over the final four-path file list: node scripts/pm/check-governed-merges.mjs --test ... → exit 0, "NOT governed". Ordinary queue landing applies. Opened as a draft; not flipped ready, not enqueued, no auto-merge.

One thing left open for the PM

The packages/core pin's comment reads "'ui-plugin' is the spelling a stale describe() string still uses" — present tense, and this PR makes it false. The pinned value must not change, but that sentence now points a reader at a stale describe that no longer exists. Those exact lines were fenced must-not-change in dispatch, so I did not touch them; a one-line tense correction is the obvious follow-up if the fence lifts.


🤖 Generated with Claude Code

https://claude.ai/code/session_01G4138K1EG7kQ81FNba5Kp4


Generated by Claude Code

claude Bot and others added 2 commits September 5, 2026 00:48
`PluginSchema.type` is `z.enum(['standard', ...CORE_PLUGIN_TYPES])` and
`CORE_PLUGIN_TYPES` spells the frontend member `ui`. The `staticPath`,
`slug` and `default` describe strings still named `ui-plugin`, a value the
same schema refuses two lines above — and they read as instructions
("Required for type=..."), so an author or agent following them writes a
value that is rejected.

Also updates the two `content/docs/plugins/anatomy.mdx` prose sites that
used the retired spelling; the page's own section heading already reads
`### 2. UI Plugin (\`ui\`)`.

No accept/reject behaviour changes: `type: 'ui-plugin'` is refused before
and after, `type: 'ui'` accepted before and after.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G4138K1EG7kQ81FNba5Kp4
`content/docs/references/kernel/plugin.mdx` is auto-generated from
`packages/spec/src/kernel/plugin.zod.ts` (banner: "AUTO-GENERATED — DO NOT
EDIT. Run build-docs.ts to regenerate"), so the three table rows follow the
describe strings. Regenerated with `pnpm --filter @objectstack/spec
gen:schema && gen:docs` — never hand-edited.

`authorable-surface.base.json` was deliberately NOT re-anchored: the build
prints re-anchoring as its own reviewed act (`gen:authorable-surface-base`),
not a side effect of this run.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G4138K1EG7kQ81FNba5Kp4
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tooling labels Sep 5, 2026
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec, touching 1 documentable anchor(s).

1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/getting-started/quick-reference.mdx (via PluginSchema (symbol, a top-level const))
What this run could not see
  • the SDK route bridge reached 61 of 219 client-bound route-ledger rows — the other 158 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 158: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 56 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 102 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 129 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json d30ccb9bd963942d33072443f680a32664087346packageMentionDocs.

Which tree this was computed on

This run read content/docs from 3fc1e452eeaa5097a3c203601bd22ce44f79f061 — the merge of head 6fd7128575e748bb6fe1e1bfdbdabbe422a02c1e into base d30ccb9bd963942d33072443f680a32664087346, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 3fc1e452eeaa5097a3c203601bd22ce44f79f061 && git checkout 3fc1e452eeaa5097a3c203601bd22ce44f79f061
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin d30ccb9bd963942d33072443f680a32664087346 6fd7128575e748bb6fe1e1bfdbdabbe422a02c1e && git checkout -B drift-repro d30ccb9bd963942d33072443f680a32664087346 && git merge --no-ff 6fd7128575e748bb6fe1e1bfdbdabbe422a02c1e

node scripts/docs-audit/affected-docs.mjs --json d30ccb9bd963942d33072443f680a32664087346

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs d30ccb9bd963942d33072443f680a32664087346 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@os-sales
os-sales marked this pull request as ready for review September 5, 2026 01:47
@os-sales
os-sales enabled auto-merge September 5, 2026 01:47
@os-sales
os-sales added this pull request to the merge queue Sep 5, 2026
Merged via the queue into main with commit 5eb24f8 Sep 5, 2026
36 checks passed
@os-sales
os-sales deleted the claude/issue-14609-plugin-describe-ui-plugin-spelling branch September 5, 2026 02:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] plugin.zod.ts describe() strings for staticPath / slug / default still say type="ui-plugin" — the enum member is ui

1 participant