docs(protocol): drop the phantom configSchema manifest file-map row from plugin-spec - #13697
Merged
os-project-manager merged 2 commits intoAug 31, 2026
Conversation
… from plugin-spec The `objectstack.config.ts` example on content/docs/protocol/kernel/plugin-spec.mdx carried a `configSchema: 'src/config.schema.ts'` row at the tail of its `metadata:` file-map. `packages/spec/src/kernel/manifest.zod.ts` declares no such key -- and because `ManifestSchema` is not `.strict()`, an author who copies the example gets no error at all: the key is silently stripped and the file is never loaded. Only the manifest file-map row is removed. The page's "Configuration Schema" section and best-practice 4 (`configSchema.parse(this.options)` in `init`) describe the plugin-owned self-parse pattern, which is real and is untouched -- the same identifier means two different things on this page. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
…ugin-spec-phantom-configschema-row
This was referenced Aug 31, 2026
os-project-manager
marked this pull request as ready for review
August 31, 2026 07:27
os-project-manager
deleted the
claude/issue-12690-plugin-spec-phantom-configschema-row
branch
August 31, 2026 07:47
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #12690
What changed
Removed the phantom
configSchemarow from the manifest file-map in theobjectstack.config.tsexample oncontent/docs/protocol/kernel/plugin-spec.mdx.translations: [ 'i18n/**/*.json', ], - - // Configuration schema - configSchema: 'src/config.schema.ts', },Three lines, one file, no other change in the diff.
Why the row is phantom, not merely undocumented
packages/spec/src/kernel/manifest.zod.tsdeclares noconfigSchemakey —git grep configSchema packages/spec/src/kernelreturns nothing at all.The sharper half:
ManifestSchemais not.strict()(the schema says so infour places, on the tombstoned keys). So an author who copies this example gets
no error whatsoever — the key is silently stripped and
src/config.schema.tsis never loaded by the manifest. A phantom row on a not-strict schema fails
silently by construction, which is why nothing has ever caught it.
The manifest example block carries no
os:checkmarker, so no gate validates itssnippet against the live schema. That is why this survived while the neighbouring
lifecycleandpermissionsshapes each acquired an explicit note.Per the triage ruling the row is dropped, not annotated as proposed-shape:
permissionsis annotated as proposed because someone intends to build it, andlifecycleas removed because it once existed. Neither is true here, and thedirection of travel is the opposite of proposed — #11982 ruled the kernel
configSchemaretirement.The real
configSchemacontent survives — proofThe identifier appears on this page meaning two different things. Only the
manifest file-map row was removed. Everything describing the plugin-owned
self-parse pattern is untouched:
config.schema.ts # Configuration schema (Zod)### Configuration Schema// src/config.schema.tsexport const configSchema = z.object({export type PluginConfig = z.infer<typeof configSchema>;configSchema.parse(this.options)initconfigSchemamentions went 4 to 3 on the page; the one that left is the file-maprow. The edit was anchored on the row's position in the file-map — asserted to
be the final entry before that block's closing brace — never on the identifier,
because a grep-and-delete here removes true documentation.
Scope note
The surrounding example keys that
ManifestSchemaalso does not declare(
metadata,config,marketplace,optionalDependencies,peerDependencies,definePluginitself) are deliberately disclaimed by the page's topCallout type="warn"as target/design intent, and by the inline comment on thesnippet. They are documented-as-proposed on purpose, so they are out of scope and
were left alone — no finding filed for them.
Verification
Gate family derived with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(the script reads its own change set from the merge base; no hand-rolled path list).
26 families derived. Run on
1515f0a8f, the branch head after syncingmain:scripts/check-test-completeness.mjs— NOT MEASURED, exit 3PREREQUISITE NOT MET. It grades a savedturbo run testlog and the familylist names it with no argument; its own output says this branch is unreachable
in CI and is "not a red, and there is nothing here to fix".
pnpm check:nul-bytesgreen (7561 files); the edited file self-scanned cleanfor raw control bytes.
Three gates first read NOT MEASURED against missing
dist/output, were rebuilt(
@objectstack/lint,@objectstack/client-react,@objectstack/spec), and thenproduced real green measurements:
check:doc-formula-expressions,check:doc-security-posture,check:skill-examples(260 prose examplestype-check across 3 surfaces).
Repo-wide
pnpm lintnarrowed, and the narrowing is measured rather thanassumed: eslint's own config restricts every
filesglob to{ts,tsx,mts,cts,js,jsx,mjs,cjs}, so.mdxis in no population it lints. Runningeslint content/docs/protocol/kernel/plugin-spec.mdx --no-inline-config --format jsonreturns 1 result entry, 0 errors, with eslint's own message
File ignored because no matching configuration was supplied.Since the diffchanges exactly one
.mdxfile and no eslint config, notsconfig, and no.tssource, no untouched file's lint verdict can move.
Changeset
No changeset, and the PR carries
skip-changeset. The card is docs-only: one fileunder
content/docs/**, publishing nothing from any package.scripts/pm/dispatch-gates.mjsstates the rule directly — "write one unless thiscard is docs-only" — and
scripts/check-empty-changeset.mjsrejects a newly addedempty-frontmatter changeset, so there is no package-less form to write; naming a
package here would emit a release-note row for code that did not change. Precedent
for this exact shape: PR #13337, a docs-only phantom-shape removal under
content/docs/**, carriesskip-changesetand added no changeset.dispatch prompt's
skip-changesetclosed list enumeratesdocs/adr/**,.claude/**,scripts/pm/**, tests/workflow and comments — it does not listcontent/docs/**,though the criterion stated with it ("publishes nothing from any package") is met.
Reversing this is a one-line change if the seat reads the enumerated list as binding.
Generated by Claude Code