fix(catalog): publish and document only what the manifests actually carry - #73
Merged
Merged
Conversation
…arry Three claims in the catalog layer had nothing behind them. `ingress[].methods` read `r.methods ?? null` against a manifest key that does not exist: core's `PluginIngressRoute` declares route, mode, signature, challenge, verify, maxBodyBytes, conversationId and response — no `methods`. Both published entries were `null`, and a reader of a security-facing column cannot tell a route that accepts every method from a field that can never be filled. The column is gone, and the test now pins the entry's key set so a published field always has a manifest field behind it. `sessionScoped: manifest.sessionScoped ?? false` defaulted to the opposite of the host, which treats a plugin as global only when the manifest says `false` explicitly. The default was unreachable — validateManifest refuses an undefined value first, and all ten manifests declare it — so nothing was ever published wrongly, but the line told a reader the inverse of the rule it was implementing. Dropped rather than inverted: with the validation above it, any default is dead code. The repo-gates paragraph listed two of the five conditions that fail the build, omitting the three a contributor actually trips: a missing CHANGELOG.md, a changelog with no released heading, and a version that disagrees with the manifest. It also said a missing i18n locale is "a warning, not a failure" — true of catalog.mjs and false of CI, where one test fails a stable plugin missing any locale and another fails any plugin whose locale translates the name but not the config fields. 550 tests, catalog:check, typecheck and build all pass; the regenerated catalog differs by exactly the two deleted lines.
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.
Three claims in the catalog layer turned out to have nothing behind them. All three came from the same reflex — writing down what a field ought to say instead of checking what produces it.
ingress[].methodscould only ever be nullThe generator mapped
methods: r.methods ?? nullfrom the manifest's ingress route. Core'sPluginIngressRoutedeclaresroute,mode,signature,challenge,verify,maxBodyBytes,conversationIdandresponse. There is nomethods. Both published entries werenull, and always would be.That matters more here than a spare key normally would: this block exists so an operator can see what a plugin binds before installing it, and a provisioned ingress route is a
@Public()endpoint. A null in a security-facing column reads as "any method" or "unknown" — neither of which was ever measured.The column is removed, and the ingress test now pins the entry's key set, so a published field has to have a manifest field behind it. Verified by putting the line back: the suite drops to 1 failure and returns to green when it is removed again.
sessionScopeddefaulted to the opposite of the hostThe host decides the other way round —
plugin-loader.service.tstreats a plugin as global only wheremanifest.sessionScoped === false, so an absent value means session-scoped.Nothing was ever published wrongly:
validateManifestthrows on an undefined value before this line runs, and all ten manifests declaretrue. So this is a readability fix, not a correctness one — but the line stated the inverse of the rule it implemented, in a file whose whole job is to describe plugins accurately. Dropped rather than inverted, because with that validation above it any default is dead code.The repo-gates paragraph listed two of five
It named the
sessionScopedandtestedOpenWAVersiongates and stopped, omitting the three a contributor actually trips: a missingCHANGELOG.md, a changelog with no released## [x.y.z] — YYYY-MM-DDheading, and a manifest version that disagrees with that heading.It also said a missing
i18nblock or locale is "a warning, not a failure". That is true ofcatalog.mjsand false of CI: one test fails astableplugin missing any supported locale, and another — added last week afteresshipped half-translated — fails any plugin with a locale that translates the name and description but not everyconfigSchemafield. A contributor reading the old sentence would take a red build as a bug in the gate.The paragraph now lists all five hard failures and says where i18n is actually enforced.
Verification
550 tests,
catalog:check,typecheckandbuildall pass. The regeneratedplugins.jsondiffers from the committed one by exactly the two deleted"methods": nulllines.One thing left alone, noted rather than fixed: the supported-locale list exists twice, in
catalog.mjsand in the test, so adding a locale in one place silently fails to enforce it in the other. Deduplicating means makingcatalog.mjsimportable — it does its work at module top level — which is a larger change than this one.