Skip to content

content/docs/protocol/kernel/http-protocol.mdx 的 discovery 响应示例把 dispatcher 形状挂在 /api/v1/discovery 名下 —— 字段与 REST 实际返回体对不上 #4817

Description

@xuyushun441-sys

#4781(删除 runtime-capabilities 页)核实页尾 discovery 那节时顺带发现,不在该 PR 范围内修,未认领。

现象

content/docs/protocol/kernel/http-protocol.mdx 的 API Discovery 一节写:

/.well-known/objectstack 和版本化的 /api/v1/discovery 路由都直接返回 discovery 文档 —— 两者之间没有 HTTP 重定向

随后给出一份响应示例,含 name / version: "2.1.0" / environment / routes / services / locale。

但这两条路径在挂载了 @objectstack/rest 的常规组合里返回的不是同一形状:

  • /api/v1 与 /api/v1/discovery 由 registerDiscoveryEndpoints(packages/rest/src/rest-server.ts)注册的同一个 handler 服务,body 来自 ObjectStackProtocolImplementation.getDiscovery()(packages/metadata-protocol/src/protocol.ts),形状是 { version, apiName, routes, services, capabilities },再由 rest-server 补 capabilities.transactionalBatch 与 scoping。没有 name、没有 environment、没有 locale,version 还被 config.api.version 覆盖成 v1(不是 2.1.0 这类语义版本)。
  • name / environment / features / locale 是 dispatcher 的 getDiscoveryInfo()(packages/runtime/src/http-dispatcher.ts)才有的字段,由 /.well-known/objectstack 提供(body 还外包一层 { "data": ... })。dispatcher 只在 REST-less 组合里才注册 ${prefix}/discovery,挂了 REST 就把该路由让出去(packages/runtime/src/dispatcher-plugin.ts,单一 owner,ADR-0076 D11)。

所以该页的示例实际上是 dispatcher 形状,却被标注成两条路径共同的返回体;locale 更是读者会直接拿去初始化 i18n 的字段。

对照:content/docs/api/index.mdx 已经把这两者的差别写对了(GET /api/v1 一节 + GET /.well-known/objectstack 一节,并说明 SDK connect() 先试 /api/v1/discovery 再回退)。

建议处置

把 http-protocol.mdx 的这节改成与 api/index.mdx 一致的两段式:一段 REST 形状(version / apiName / routes / services / capabilities),一段 /.well-known/objectstack 形状(含 name / environment / features / locale,{ data: ... } 包裹),并写明「两条路径同文档」只在 REST-less 组合里成立。别再给一份混合示例。

顺带(同一页可一并处理,也可另开):.claude/workflows/docs-accuracy-audit.js 的 ALL_HANDWRITTEN 清单仍用重命名前的 content/docs/protocol/objectos/* 路径,该目录早已改名为 protocol/kernel/,清单里 11 个条目全部指向不存在的文件 —— 这个内部审计脚本会静默漏审整个 protocol/kernel 目录。

发现于 #4781,未认领 —— 谁开工谁按 AGENTS.md 认领。

Activity

  1. xuyushun441-sys commented on Aug 3, 2026

    @xuyushun441-sys
    CollaboratorAuthor

    认领:PM 循环第 7 轮
    会话:session_018iARDqtrhQgz6fVHDeDkbQ
    分支:claude/issue-4817-http-protocol-discovery-shapes
    Worktree:objectstack-issue-4817

    车道:落点 content/docs/**,属本会话车道(维护者裁定,登记 #4604)。

    前提复核(对最新 main 158a3d8a4):

    派发范围:只做 http-protocol.mdx 那一节的两段式改写。issue 末尾「顺带」提到的 .claude/workflows/docs-accuracy-audit.js 路径失效(11 条全指向改名前的 protocol/objectos/*,导致内部审计脚本静默漏审整个 protocol/kernel 目录)不并入本次 —— 它不是文档内容问题而是工具问题,落点也不在 content/docs/**,混进来会让这个 docs-only PR 的范围变模糊。会另行分诊。


    Generated by Claude Code

  2. xuyushun441-sys commented on Aug 3, 2026

    @xuyushun441-sys
    CollaboratorAuthor

    PM 复核:通过(ACCEPT),等 CI 全绿后进合并队列

    PR:#4826(草稿,base main 158a3d8a4,body 首行 Fixes objectstack-ai/objectstack#4817,改动面 2 个文件:目标 mdx + 空 frontmatter changeset,未触碰 content/docs/releases/)

    我自己抽查的三条

    1. 车道合规:git diff --stat 只有 content/docs/protocol/kernel/http-protocol.mdx 与 changeset,packages/** 零改动 —— 而这次 dev 为了溯源读了 rest / runtime / metadata-protocol / spec 四个包,只读未写,正是要求的姿势。
    2. 溯源抽查命中:报告称 dispatcher 形状来自 packages/runtime/src/http-dispatcher.ts:1076-1205 的 getDiscoveryInfo()。我核了 1078-1082 —— 确实 name: 'ObjectOS' / version: '1.0.0' / environment: getEnv('NODE_ENV', 'development') / routes,行号与字段都对得上,不是照抄旧文档。
    3. graphql 自查执行了:两份示例里 graphql 出现 0 次。这是我基于 content/docs/protocol/kernel/runtime-capabilities.mdx 通篇描述已于 #3605 删除的 ObjectStackCapabilities —— 整页教一个不存在的 schema #4781 复核结论点名要求查的 —— 旧文档那份 "graphql": "/graphql" 在 ApiRoutesSchema 里没有任何依据。

    这次做对的关键一点

    dev 没有把 api/index.mdx 的措辞当成「另一份可以照抄的文档」,而是把每个字段追回实现的行号后才写:getDiscovery() 的 return(protocol.ts:2374-2380)、rest-server 追加的 version 覆盖 / transactionalBatch / scoping(rest-server.ts:2397、2470-2489)、{ data: ... } 包裹(dispatcher-plugin.ts:546-561)、让路逻辑与那行 ceded to ... (single owner) 日志(同文件 564-590)。

    **这正是本 issue 与 #4781 共同的教训:文档之间互相抄,是这一族缺陷的传播方式。**范本用来对齐措辞,字段必须回到实现去取。dev 还主动核对了两页改完是否仍会分歧,结论是不会 —— 唯一新增的 scoping 是 api/index.mdx 未展示的,只补充不冲突。

    衍生 #4828:比本 issue 更深一层

    dev 顺带发现,两个 discovery 生产者都返回 spec 未声明的顶层字段:rest-server 的 scoping、dispatcher 的 features 与 endpoints,在 packages/spec/src/api/discovery.zod.ts 里都没有声明。更关键的是:

    • REST 形状永远无法通过 DiscoverySchema.parse() —— name / environment / locale 在 schema 里是必填,而 REST 三个都不产出;
    • dispatcher 形状则不产出 capabilities;
    • 协议层实际引用的是 DiscoverySchema.partial(),zod 默认 strip 未知键,两类问题都被这层宽松包装吃掉,没有任何 gate 比对。

    也就是说:DiscoverySchema 声明的那个形状,没有任何一个生产者真正兑现。这是 declared ≠ delivered 在契约层的形态,比本 issue 的文档层严重。落点在 packages/spec / rest / runtime,不在本会话车道,已按 Prime Directive #10 未认领归档,并列了 4 个需维护者裁定的决策点(features vs capabilities 谁是正、endpoints 是否退役、scoping 补在哪、必填三字段怎么办)。

    本 PR 与 #4828 不冲突:本 PR 描述的是实现实际返回的形状(这对读者是对的),#4828 记录的是 spec 侧的欠账。

    未处理项(按派发范围)

    .claude/workflows/docs-accuracy-audit.js 的 ALL_HANDWRITTEN 11 条失效路径未动,按我派发时的指示保留在本 issue 正文里,未另开重复单。它是工具缺陷、不在 content/docs/**,会另行分诊 —— 它也是这一页能烂到今天的原因:查它的脚本以为那个目录不存在。


    Generated by Claude Code

  3. xuyushun441-sys commented on Aug 3, 2026

    @xuyushun441-sys
    CollaboratorAuthor

    结案:PR #4826 已合入 main,issue 由 Fixes 自动关闭

    content/docs/protocol/kernel/http-protocol.mdx 的 API Discovery 一节已从「一份混合示例 + 两条路径同文档」改成两段式:

    • GET /api/v1(与 /api/v1/discovery)—— @objectstack/rest 的真实形状(version / apiName / routes / services / capabilities,加 rest-server 追加的 scoping);
    • GET /.well-known/objectstack —— dispatcher 形状({ "data": ... } 包裹,含 name / environment / features / locale)。

    「两条路径同文档」被限定为 REST-less 组合才成立,并点名 ADR-0076 D11 的单一 owner 规则。

    这次做对的关键

    dev 没有把 #4816 刚改好的 api/index.mdx 当成「另一份可以照抄的文档」,而是把每个字段追回实现的行号才写:getDiscovery() 的 return(protocol.ts:2374-2380)、rest-server 的 version 覆盖与 scoping(rest-server.ts:2397 / 2470-2489)、{ data: ... } 包裹(dispatcher-plugin.ts:546-561)、让路逻辑与那行 ceded to ... (single owner) 日志(同文件 564-590)。

    我抽查了 http-dispatcher.ts:1078-1082 —— name: 'ObjectOS' / version: '1.0.0' / environment: getEnv('NODE_ENV', ...) / routes,字段与行号都对得上。两份示例里 graphql 零出现(这是我基于 #4781 复核结论点名要求查的:ApiRoutesSchema 里根本没有这个键)。

    文档之间互相抄,正是这一族缺陷的传播方式。 #4781 差点把一段过期内容搬进 API 文档,#4817 本身就是一份 dispatcher 样例被挂在错误的端点名下。范本用来对齐措辞,字段必须回实现取。

    衍生 #4828 —— 比本 issue 深一层,已交对应车道

    dev 顺带发现:DiscoverySchema 声明的形状,没有任何一个生产者真正兑现。

    • REST 形状永远无法通过 DiscoverySchema.parse() —— name / environment / locale 声明为必填,REST 三个都不产出;
    • dispatcher 形状不产出 capabilities;
    • rest-server 的 scoping、dispatcher 的 features / endpoints 在 discovery.zod.ts 里均无声明;
    • 协议层实际引用的是 DiscoverySchema.partial(),zod 默认 strip 未知键,两类问题都被这层宽松包装吃掉,零 gate 比对。

    这是 declared ≠ delivered 在契约层的形态,落点 packages/spec / rest / runtime,不在本会话车道,已未认领归档并列出 4 个待裁定的决策点。与本 PR 不冲突:本 PR 描述的是实现实际返回的形状(对读者是对的),#4828 记的是 spec 侧的欠账。

    未处理项(按派发范围,已记在本 issue 正文)

    .claude/workflows/docs-accuracy-audit.js 的 ALL_HANDWRITTEN 11 条仍指向改名前的 content/docs/protocol/objectos/*,导致该内部审计脚本静默漏审整个 protocol/kernel 目录 —— 这也是本页与 #4781 那页能烂到今天的原因:不是没人查,是查它的脚本以为那个目录不存在。它是工具缺陷、不在 docs 范围,另行分诊。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions