Observed while implementing #9805 (typing the non-door getMetaItems request literals in rest-server.ts). Recording it rather than widening that card — different file, and the fix needs a judgement call this observation does not make.
The observation
PackageRoutesOptions in packages/rest/src/package-routes.ts (around :237) declares its protocol option as a hand-rolled structural shape:
protocol?: {getMetaItems?(req: {type: string}): Promise<{items: any[]}>;deletePackage?(req: {packageId: string;actor?: string;allTenants?: boolean}): Promise<…>;…};Both verbs are already declared in packages/spec — getMetaItems(request: GetMetaItemsRequest): Promise< GetMetaItemsResponse > on MetadataProtocol (protocol.zod.ts), where the request carries type, packageId, organizationId and (since #9741) previewDrafts. The local re-declaration names only type, and its response names only items (the spec's also carries type).
Not asserted: no defect today. Both call sites (:486, :555) pass exactly { type: 'package' }, which is a valid GetMetaItemsRequest, and both read result?.items defensively. Nothing is broken.
What it is, is the same blindness class #9805 was filed about, one level up: the request type is re-stated locally rather than read from the spec, so the spec is free to move underneath it — a narrowed type vocabulary, a newly required member, a renamed key — and this module keeps compiling green against a shape the protocol no longer has. #9805's sibling sites got compiler coverage by naming the declared type; these two did not, because there is no declared type at this seam to name.
The judgement this does not make: MetadataProtocol declares getMetaItems as a required member while this option declares it optional and feature-detects it at both call sites (typeof … === 'function'). So this cannot simply be swapped for MetadataProtocol — either the option type keeps its optionality while sourcing the request/response types from the spec (getMetaItems?(req: GetMetaItemsRequest): Promise< GetMetaItemsResponse >), or the seam changes what it tolerates, which is a behaviour question. The narrow version is the cheap half and probably the right one.
Repo: objectstack. File: packages/rest/src/package-routes.ts. Related: #9805 (where this was seen; the PR there names it as out of scope), #9741 (the declared meta-read request shapes and the TransportScopedMetaRequest envelope).
Generated by Claude Code
Observed while implementing #9805 (typing the non-door
getMetaItemsrequest literals inrest-server.ts). Recording it rather than widening that card — different file, and the fix needs a judgement call this observation does not make.The observation
PackageRoutesOptionsinpackages/rest/src/package-routes.ts(around:237) declares itsprotocoloption as a hand-rolled structural shape:Both verbs are already declared in
packages/spec—getMetaItems(request: GetMetaItemsRequest): Promise< GetMetaItemsResponse >onMetadataProtocol(protocol.zod.ts), where the request carriestype,packageId,organizationIdand (since #9741)previewDrafts. The local re-declaration names onlytype, and its response names onlyitems(the spec's also carriestype).Not asserted: no defect today. Both call sites (
:486,:555) pass exactly{ type: 'package' }, which is a validGetMetaItemsRequest, and both readresult?.itemsdefensively. Nothing is broken.What it is, is the same blindness class #9805 was filed about, one level up: the request type is re-stated locally rather than read from the spec, so the spec is free to move underneath it — a narrowed
typevocabulary, a newly required member, a renamed key — and this module keeps compiling green against a shape the protocol no longer has. #9805's sibling sites got compiler coverage by naming the declared type; these two did not, because there is no declared type at this seam to name.The judgement this does not make:
MetadataProtocoldeclaresgetMetaItemsas a required member while this option declares it optional and feature-detects it at both call sites (typeof … === 'function'). So this cannot simply be swapped forMetadataProtocol— either the option type keeps its optionality while sourcing the request/response types from the spec (getMetaItems?(req: GetMetaItemsRequest): Promise< GetMetaItemsResponse >), or the seam changes what it tolerates, which is a behaviour question. The narrow version is the cheap half and probably the right one.Repo:
objectstack. File:packages/rest/src/package-routes.ts. Related: #9805 (where this was seen; the PR there names it as out of scope), #9741 (the declared meta-read request shapes and theTransportScopedMetaRequestenvelope).Generated by Claude Code