Skip to content

SDK 的 client.capabilities 声明为 WellKnownCapabilities,但两个 discovery 生产者填的是互不相交的键集 #5672

Closed

Description

@os-zhuang

发现于 #4828 的实施(界外发现,查重无命中故新开;未认领)。

现象

#4828 把 dispatcher 的顶层 features 正名为 capabilities 之后,两个 discovery 生产者都发 capabilities 了 —— 但填的键集互不相交:

生产者 capabilities 的键
getDiscovery()(packages/metadata-protocol,REST /discovery 的上游) comments、automation、cron、search、export、chunkedUpload、transactionalBatch —— 即 WellKnownCapabilitiesSchema 的成员
getDiscoveryInfo()(packages/runtime/src/http-dispatcher.ts,/.well-known/objectstack) search、websockets、files、analytics、ai、notifications、i18n

只有 search 是两边都有的。

而 SDK 侧 packages/client/src/index.ts 的 getter:

get capabilities(): WellKnownCapabilities | undefined {
  const raw = this.discoveryInfo?.capabilities;
  ...
  return result as unknown as WellKnownCapabilities;
}

它把结果断言成 WellKnownCapabilities。所以面对 dispatcher 供的 discovery,client.capabilities.transactionalBatch 的静态类型是 boolean、运行时是 undefined —— 类型在说谎。comments / cron / export / chunkedUpload 同理。

DiscoverySchema.capabilities 本身是开放的记录类型,所以两边都合法,schema 不会红。

为什么不在 #4828 里一起修

#4828 的裁定是「正名取 capabilities」,没有裁定两个生产者的能力词汇表该不该统一 —— 那是一个新的契约决策(要么让 dispatcher 也按 WellKnownCapabilities 词汇表作答,要么承认两套词汇并在 schema 里把它表达出来,要么让 SDK 的 getter 不再撒这个类型谎)。#4828 只是把分裂从「一个发 features 一个发 capabilities」收敛成「都发 capabilities」,分裂的深度减小了但没有消失。

需要说明的是:这不是 #4828 引入的回归。在此之前 dispatcher 完全不发 capabilities,client.capabilities 对 dispatcher 宿主返回的是 undefined(每个标志位都拿不到)。#4828 之后至少 search 等 7 个键有了真实答案。只是分歧现在更容易被看见,也更容易被误用。

决策点(需要维护者定,不要猜)

  1. dispatcher 是否应当按 WellKnownCapabilities 词汇表作答?它没有 engine/registry 访问权,算不出 comments(需要 sys_comment 对象)和 transactionalBatch(需要 engine.transaction),所以「照搬」并不现成。
  2. 还是承认「能力词汇随生产者而不同」,并把这一点写进 DiscoverySchema.capabilities 的声明与文档,同时把 SDK getter 的返回类型改成诚实的(部分可用)形状?

任一方向都会改动公开契约形状,故不猜。

Activity

  1. added
    domain:specDomain lane — seat card indexed by label:pm:seat
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Aug 5, 2026
  2. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    维护者裁定(2026-08-06,经 spec 车道 PM session_018fxLGQdatPbBUvCgiVxg6D 誊写):A —— 统一能力词表。spec 声明封闭词表,两个 discovery 生产者必须全量发,缺能力 = enabled: false 而非缺键(响亮可判,消费者无需知道宿主类型);WellKnownCapabilities 类型随之成真。闸门沿用 #5682 已建的三包 conformance 门,顺延加全量性判据。摘 needs-user-decision 转 pm:queue;排 #5679(routes.mcp)之后——两单同触 rest 生产者面,跨轮串行。


    Generated by Claude Code

  3. added
    pm:queueReady for the PM dispatch loop
    and removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Aug 6, 2026
  4. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    PM 认领(spec 车道 PM,session_018fxLGQdatPbBUvCgiVxg6D,2026-08-06,#5743 落地后按队列序开工)


    Generated by Claude Code

  5. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Aug 6, 2026
  6. self-assigned this
    on Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:specDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatch

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions