Found while implementing #10340 (the REST /meta doors' half). Filed unassigned; recording only, not claiming.
What is wrong
#10340 measured and fixed the REST /meta doors deciding organization scope from the raw URL spelling while storage folds through the complete META_URL_TO_SINGULAR map. The dispatcher transport has the same shape and was outside that card's declared file surface:
Direction already settled
The correction is the one #10340 landed for REST and the one packages/spec/src/meta-spelling/metadata-url-spelling.ts mandates: fold the segment through canonicalMetaUrlType at the boundary, before the scope decision. ⛔ Not by widening declaresOrgOverride — packages/metadata-core/src/meta-write-org-scope.ts now documents and pins that limit (see the ORG_OVERRIDABLE_TYPES header and meta-write-org-scope.test.ts).
Note for whoever takes it: packages/rest/src/rest-server-meta-org-scope-url-spelling.test.ts is the REST-side suite to mirror; the dispatcher's meta-write-org-scope.test.ts twin in packages/runtime pins the end-to-end row and is where the dispatcher-side cases belong.
Reachability caveat (grading input, not a claim)
Whether real callers reach the dispatcher transport with plural spellings is not measured here — the SDK's item routes are the likely producer (#10078's subject). The REST transport was the measured, user-visible surface; this one is recorded so the class is closed on both transports rather than one.
Related: #10340 (REST half, measured + fixed) · #10078 · #7894 · #9454
Generated by Claude Code
Found while implementing #10340 (the REST
/metadoors' half). Filed unassigned; recording only, not claiming.What is wrong
#10340 measured and fixed the REST
/metadoors deciding organization scope from the raw URL spelling while storage folds through the completeMETA_URL_TO_SINGULARmap. The dispatcher transport has the same shape and was outside that card's declared file surface:packages/runtime/src/domains/meta.tstakestypeverbatim from the path (const type = parts[0]) and passes it raw toorganizationIdForMetaWrite(type, activeOrganizationId)on thePUT /metadata/:type/:namebranch (~line 416 at5c3faa70d— re-derive), whileprotocol.saveMetaItemfolds the same string throughcanonicalizeMetaRequestTypefor storage. For the two URL-only spellings ofallowOrgOverride: truetypes —translations,email_templates— an org-active caller's write therefore lands env-wide where the singular twin lands org-scoped. Same class as/metaorg scope is decided from the RAW url spelling:translations/email_templatesread and write env-wide where their singular twin is org-scoped #10340's REST limb, one transport over./publishedbranch falls back togetPublished(type, name)with the raw segment after the layered consult misses (~line 305 — re-derive), so a code/package-published item answers 404 under a recognised plural and 200 under the singular —/metaorg scope is decided from the RAW url spelling:translations/email_templatesread and write env-wide where their singular twin is org-scoped #10340's smaller second site, dispatcher edition.Direction already settled
The correction is the one #10340 landed for REST and the one
packages/spec/src/meta-spelling/metadata-url-spelling.tsmandates: fold the segment throughcanonicalMetaUrlTypeat the boundary, before the scope decision. ⛔ Not by wideningdeclaresOrgOverride—packages/metadata-core/src/meta-write-org-scope.tsnow documents and pins that limit (see theORG_OVERRIDABLE_TYPESheader andmeta-write-org-scope.test.ts).Note for whoever takes it:
packages/rest/src/rest-server-meta-org-scope-url-spelling.test.tsis the REST-side suite to mirror; the dispatcher'smeta-write-org-scope.test.tstwin inpackages/runtimepins the end-to-end row and is where the dispatcher-side cases belong.Reachability caveat (grading input, not a claim)
Whether real callers reach the dispatcher transport with plural spellings is not measured here — the SDK's item routes are the likely producer (#10078's subject). The REST transport was the measured, user-visible surface; this one is recorded so the class is closed on both transports rather than one.
Related: #10340 (REST half, measured + fixed) · #10078 · #7894 · #9454
Generated by Claude Code