Found while implementing #12004 (the save-door request-schema catch-up). Filed rather than touched: different file, different claim area, and the de-cast question here is about a service-resolution seam, not the spec schema.
Measured on 098a08ff (origin/main at measurement time)
packages/runtime/src/domains/packages.ts (the ADR-0045 publish-visibility flip, ~:504-531) feature-detects and calls the metadata protocol through a cast handle:
typeof (protocol as any).getMetaItems === 'function' && typeof (protocol as any).saveMetaItem === 'function'
await (protocol as any).getMetaItems({ type: 'app', packageId: id, ... })
await (protocol as any).saveMetaItem({ type: 'app', name, item, packageId, organizationId?, actor? })
Every key both calls send IS declared on the spec request schemas once #12004 lands (getMetaItems' members predate it; the save members land with it) — so unlike the door casts the #11006 series retired, these casts are NOT request-shape smuggling. They exist because protocol comes from deps.resolveService(context, 'protocol'), whose return is untyped, so nothing downstream of that seam compiles against MetadataProtocol at all. The same pattern repeats across the runtime domains (domains/meta.ts's saveMetaItem dispatcher call is likewise reached through an untyped service handle, though its literal is built field by field and pinned).
Why it may be worth a card anyway
Observation-grade: no behavioural defect measured; declared-vs-served is unaffected. Priority judgment left to triage.
Generated by Claude Code
Found while implementing #12004 (the save-door request-schema catch-up). Filed rather than touched: different file, different claim area, and the de-cast question here is about a service-resolution seam, not the spec schema.
Measured on
098a08ff(origin/main at measurement time)packages/runtime/src/domains/packages.ts(the ADR-0045 publish-visibility flip, ~:504-531) feature-detects and calls the metadata protocol through a cast handle:typeof (protocol as any).getMetaItems === 'function' && typeof (protocol as any).saveMetaItem === 'function'await (protocol as any).getMetaItems({ type: 'app', packageId: id, ... })await (protocol as any).saveMetaItem({ type: 'app', name, item, packageId, organizationId?, actor? })Every key both calls send IS declared on the spec request schemas once #12004 lands (
getMetaItems' members predate it; the save members land with it) — so unlike the door casts the #11006 series retired, these casts are NOT request-shape smuggling. They exist becauseprotocolcomes fromdeps.resolveService(context, 'protocol'), whose return is untyped, so nothing downstream of that seam compiles againstMetadataProtocolat all. The same pattern repeats across the runtime domains (domains/meta.ts's saveMetaItem dispatcher call is likewise reached through an untyped service handle, though its literal is built field by field and pinned).Why it may be worth a card anyway
MetadataProtocol是否应声明publishMetaItem成员 —— 半声明的门(响应已声明、请求未声明) #11006 series' end state ("an undeclared key in a request literal is a compile error") stops one seam short here: a misspelt or undeclared key in the packages-domain literals would compile silently today.package-routes.tsin favor of the spec's declarations — the same direction, one file over.resolveServicereturn for the 'protocol' name (or narrow once at the call sites) so the literals compile againstMetadataProtocol, keeping the runtime feature-detection guards (a host may occupy the slot with a partial object — the documented reason those guards exist).Observation-grade: no behavioural defect measured; declared-vs-served is unaffected. Priority judgment left to triage.
Generated by Claude Code