Observation recorded while implementing #8421 (not fixed there — out of scope, and fail-closed today).
What was measured
canonicalizeMetaRequestType is documented as the single request boundary — "all six /meta entry points funnel through it" — and #7894 moved that fold off PLURAL_TO_SINGULAR (the manifest-collection map) onto META_URL_TO_SINGULAR (the URL-spelling map) precisely because four registry types are legitimately absent from the manifest map.
publishMetaItem is a seventh entry point on the same URL family, and it does not funnel through it. Measured on f59a135f0:
The verb is reachable with a caller-supplied spelling: the publish family is routed as /api/v1/meta/:type/:name/published (packages/rest/src/meta-published-overlay.test.ts:50).
Why this is an observation and not a defect report
It is fail-closed today, which is why it is filed rather than fixed. Drafts are written through saveMetaItem, which does fold, so a draft only ever exists under the canonical singular; a publish addressed as /meta/views/x looks for a row under type='views', finds none, and errors. Nothing is minted and nothing is bypassed.
What it costs is coherence, in the shape Prime Directive #12 names: the same URL spelling that PUT accepts and folds, publish does not resolve — one contract, two dialects, decided by which verb you used. It also means the four types the manifest map omits (field, seed, external_catalog, translation) reach the draftability check at :12699 as unrecognised, taking the permissive plugin branch of that check rather than their real registry entry — the #7894 shape, one verb over, with no measured consequence today because the row lookup fails first.
Suggested disposition
Route publishMetaItem through canonicalizeMetaRequestType like its six siblings, which is a one-line change plus a pin. Worth checking at the same time whether publishPackageDrafts and deletePackage need it (both iterate rows that are already canonical, so probably not).
Not attached as a sub-issue of #8421: that card is closed by the mint-path refusal and this is a separate seam.
Observation recorded while implementing #8421 (not fixed there — out of scope, and fail-closed today).
What was measured
canonicalizeMetaRequestTypeis documented as the single request boundary — "all six/metaentry points funnel through it" — and #7894 moved that fold offPLURAL_TO_SINGULAR(the manifest-collection map) ontoMETA_URL_TO_SINGULAR(the URL-spelling map) precisely because four registry types are legitimately absent from the manifest map.publishMetaItemis a seventh entry point on the same URL family, and it does not funnel through it. Measured onf59a135f0:packages/metadata-protocol/src/protocol.ts:12538—async publishMetaItem(request: { type, name, ... }); nocanonicalizeMetaRequestTypecall anywhere in its body.:12699— the draftability check folds throughPLURAL_TO_SINGULAR[request.type] ?? request.type, i.e. the manifest map, which is the exact lookup meta-plural-url-bypass:PUT /meta/fields/<name>walks around the whole two-tier registry gate — 4 registry types have no entry inPLURAL_TO_SINGULAR#7894 replaced at the other six.:12720,:12730— the row lookup and the receipt userequest.typeraw.The verb is reachable with a caller-supplied spelling: the publish family is routed as
/api/v1/meta/:type/:name/published(packages/rest/src/meta-published-overlay.test.ts:50).Why this is an observation and not a defect report
It is fail-closed today, which is why it is filed rather than fixed. Drafts are written through
saveMetaItem, which does fold, so a draft only ever exists under the canonical singular; a publish addressed as/meta/views/xlooks for a row undertype='views', finds none, and errors. Nothing is minted and nothing is bypassed.What it costs is coherence, in the shape Prime Directive #12 names: the same URL spelling that
PUTaccepts and folds,publishdoes not resolve — one contract, two dialects, decided by which verb you used. It also means the four types the manifest map omits (field,seed,external_catalog,translation) reach the draftability check at:12699as unrecognised, taking the permissive plugin branch of that check rather than their real registry entry — the #7894 shape, one verb over, with no measured consequence today because the row lookup fails first.Suggested disposition
Route
publishMetaItemthroughcanonicalizeMetaRequestTypelike its six siblings, which is a one-line change plus a pin. Worth checking at the same time whetherpublishPackageDraftsanddeletePackageneed it (both iterate rows that are already canonical, so probably not).Not attached as a sub-issue of #8421: that card is closed by the mint-path refusal and this is a separate seam.