Skip to content

capability 无 DEFAULT_METADATA_TYPE_REGISTRY / schema 条目 —— PUT /api/v1/meta/capability/:name 接受任意 JSON 且 /meta/types 报 allowRuntimeCreate:true(与 #5271 的 api 同形) #5961

Description

@baozhoutao

在实现 #5870(把 capabilities 接进 ObjectQL 的 provenance 盖章缝)时发现,未在该 PR 中修复,按 Prime Directive #10 记录。未指派 —— 无人在做。

证据(均读自 origin/main a6b3ee7)

capability 既不在 DEFAULT_METADATA_TYPE_REGISTRY(packages/spec/src/kernel/metadata-plugin.zod.ts,permission / position 都在,见 ~775-776),也不在 BUILTIN_METADATA_TYPE_SCHEMAS(packages/spec/src/kernel/metadata-type-schemas.ts,Security Protocol 段只有 permission / position),也不在 HAND_CRAFTED_SCHEMAS(packages/metadata-protocol/src/protocol.ts ~189,只有 object)。三处皆缺,导致两个后果:

  1. 写入门无校验。 isRuntimeCreateAllowed()(protocol.ts ~6810)在 RUNTIME_CREATE_ALLOWED_TYPES 未命中后走这条兜底:

    // Runtime-registered types (no static registry entry) are
    // synthesised by getMetaTypes() with allowRuntimeCreate=true;
    // mirror that here so /api/v1/meta and PUT /api/v1/meta agree.
    if (!this.STATIC_REGISTRY_TYPES.has(singular)
        && !this.STATIC_REGISTRY_TYPES.has(type)) {
        return true;
    }

    STATIC_REGISTRY_TYPESDEFAULT_METADATA_TYPE_REGISTRY 派生,不含 capability,所以该分支恒真。又因 getMetadataTypeSchema('capability') 返回 undefined,saveMetaItem 走它自己那条「未注册类型 → 不校验直接存」的分支 —— 于是 PUT /api/v1/meta/capability/:name 接受任意 JSON 落进 sys_metadata。这正是 [spec] api 补进 DEFAULT_METADATA_TYPE_REGISTRY 与 BUILTIN_METADATA_TYPE_SCHEMAS(#5206 第 1 步,拆单) #5271api 修掉的同一形态(该 issue 的结论写在 metadata-type-schemas.tsapi: 条目注释里)。

  2. /meta/types 合成一个假描述符。 getMetaTypes()(protocol.ts ~2988)对无注册条目的类型合成 allowRuntimeCreate: truesupportsOverlay: falseschema: undefinedlabel: 'capability' 的最小描述符。Studio 的 metadata-admin 引擎据此渲染一个无 schema 的 raw-JSON 文本框创建表单

#5870 的关系(重要,别误判为回归)

写入门的判定只读注册表、不读 item store,所以这条路在 #5870 之前就已敞开 —— #5870 不会打开它。#5870 改变的只是可见性:capabilities 现在真的会注册进 SchemaRegistry,于是 capability 开始出现在 getMetaTypes() 的枚举里(此前包声明的 capability 根本没进过 registry,该类型从不出现)。也就是说这是一个既存缺陷,被 #5870 从不可见变为可见#5870 的 changeset 已就「运行时可创建性未改变」这一点作了明确陈述。

为什么值得修

sys_capability 是授权面。一条未经 CapabilityDeclarationSchema 校验就落库的 capability 行,其 name 可以不满足 schema 的 ^[a-z][a-z0-9_.]*$,scope 可以是任意字符串 —— 而 systemPermissions / requiredPermissions 是按 name 字符串解析的。declared ≠ enforced 的一个变体:声明面有 Zod,写入面没有。

建议修法(需裁决,故不夹带)

至少三个选项,取舍不属于 #5870 的范围:

  • A. 补 BUILTIN_METADATA_TYPE_SCHEMAS['capability'] = CapabilityDeclarationSchema + 一条 DEFAULT_METADATA_TYPE_REGISTRY 条目并显式设 allowRuntimeCreate: false(与 ADR-0066 D1「packages DEFINE capabilities」一致:capability 由包声明,不由管理员在运行时凭空创建)。这条同时关掉无校验写入门与假的可创建描述符。
  • B. 只补 schema,让 422 校验生效,但保留运行时可创建 —— 需要先确认真有「管理员运行时新建 capability」的业务拉力。
  • C. 判定 capability 根本不该出现在 /meta/types,改合成逻辑而非补条目。

另需注意:MetadataTypeSchema(metadata-plugin.zod.ts ~72 的 z.enum)也不含 'capability',A/B 两案都要一并处理,并按 AGENTS.md 重新生成 spec 的产物(check:authorable-surface / check:docs / check:api-surface)。

同类邻居(同样缺注册条目、同样走合成分支)还有 role / profile / policy —— 它们连 PLURAL_TO_SINGULAR 映射都没有,以复数键注册。是否一并处理请一并裁决。

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions