Skip to content

ApiEndpointSchema 无法对未知键收紧 —— 同一个 schema 既解析作者声明又解析存量行(行上带 packageId / state) #5309

Description

@os-zhuang

越范围发现,记录于 #5271(apiDEFAULT_METADATA_TYPE_REGISTRY)实现期,不在该 PR 内修 —— 修法是元数据层的信封/正文分离,那是另一个量级的改动。

事实

api#5271 成为注册类型后,ApiEndpointSchema 落入 #4001 收紧运动的不变量。尝试用 strictObject 关闭它,实测结果是 packages/metadata 里 10 条测试转红:

unrecognized_keys: ['packageId', 'state']

原因是这个 schema 不只是作者面,它也是存量行的解析器:

  • buildEndpointIndex(packages/metadata/src/endpoint-matcher.ts)对每条存量 api 行跑 ApiEndpointSchema.safeParse;
  • MetadataManager.publishPackagegateApiItemsForPublish 同样。

而存量行带着元数据层自己的记账键 —— packageIdstate,由 MetadataManager.register(metadata-manager.ts:542)与 publishPackage(:1438:1574)写入,又被 publishPackage 自己的包过滤器(:1337)读回。这两个键不是端点词表

关闭后的实际后果(不是推测,是跑出来的):装载期兜底把端点整条排除出索引(它声明的路由答 404),publish 门则报一条 schema 错误、而不是它本该给出的 ADR-0121 D6 判决。

代价(为什么这不是「无所谓」)

留着 strip,一个 cacheTTL / outputMappings / objectParam 的拼写错误会解析通过、publish 通过,然后端点上线时不带作者写的那条策略或投影 —— ADR-0078 的静默失效元数据,而且是在 AI 作者(ADR-0033)会写的面上。

形状与 view 同类

这正是 STILL_STRIP 里 view 的理由换了身衣服:一个类型名同时承担作者文档线上行#5271 已把 api 加进 STILL_STRIP 并把上述实测写在该列表的注释里,所以这条债有名有主、不是静默豁免。

建议方向(不预判)

修法应当是把存量信封与正文分开,让匹配器与 publish 门解析正文、记账键待在信封上 —— 而不是反过来教 ApiEndpointSchema 认两个存储层的键(那等于让作者契约去描述存储层,正是这场运动拒绝的交易)。做完之后 api 就能从 STILL_STRIP 上摘下来。

关联

#5271(本发现的出处)、#5206(父单)、#4001(收紧运动)、ADR-0078、ADR-0010。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions