Repository navigation
content/docs/protocol/kernel/http-protocol.mdx 的 discovery 响应示例把 dispatcher 形状挂在 /api/v1/discovery 名下 —— 字段与 REST 实际返回体对不上 #4817
Description
Activity
- addeddocumentationImprovements or additions to documentationImprovements or additions to documentation
on Aug 3, 2026 xuyushun441-sys commented
on Aug 3, 2026 CollaboratorAuthorMore actions认领:PM 循环第 7 轮
会话:session_018iARDqtrhQgz6fVHDeDkbQ
分支:claude/issue-4817-http-protocol-discovery-shapes
Worktree:objectstack-issue-4817车道:落点
content/docs/**,属本会话车道(维护者裁定,登记 #4604)。前提复核(对最新
main158a3d8a4):- 缺陷仍在:
content/docs/protocol/kernel/http-protocol.mdx:32-42仍写着「/.well-known/objectstack和版本化的/api/v1/discovery路由都直接返回 discovery 文档」,随后给出一份"version": "2.1.0"的混合示例; - 修复范本刚刚落地:content/docs/protocol/kernel/runtime-capabilities.mdx 通篇描述已于 #3605 删除的 ObjectStackCapabilities —— 整页教一个不存在的 schema #4781 的 PR docs(protocol): 删除 runtime-capabilities 页 —— 整页教已于 #3605 删除的 ObjectStackCapabilities (#4781) #4816(
158a3d8a4)已把content/docs/api/index.mdx的两端点区分写对(GET /api/v1(and/api/v1/discovery) 一节说明「one handler at both paths」与 ADR-0076 D11 的 dispatcher 让路规则,另有/.well-known/objectstack一节)。本条特意等它合入再派,好让 dev 照着已验证的写法改,而不是对着旧内容重新推理。
派发范围:只做 http-protocol.mdx 那一节的两段式改写。issue 末尾「顺带」提到的
.claude/workflows/docs-accuracy-audit.js路径失效(11 条全指向改名前的protocol/objectos/*,导致内部审计脚本静默漏审整个protocol/kernel目录)不并入本次 —— 它不是文档内容问题而是工具问题,落点也不在content/docs/**,混进来会让这个 docs-only PR 的范围变模糊。会另行分诊。
Generated by Claude Code
- 缺陷仍在:
xuyushun441-sys commented
on Aug 3, 2026 CollaboratorAuthorMore actionsPM 复核:通过(ACCEPT),等 CI 全绿后进合并队列
PR:#4826(草稿,base
main158a3d8a4,body 首行Fixes objectstack-ai/objectstack#4817,改动面 2 个文件:目标 mdx + 空 frontmatter changeset,未触碰content/docs/releases/)我自己抽查的三条
- 车道合规:
git diff --stat只有content/docs/protocol/kernel/http-protocol.mdx与 changeset,packages/**零改动 —— 而这次 dev 为了溯源读了 rest / runtime / metadata-protocol / spec 四个包,只读未写,正是要求的姿势。 - 溯源抽查命中:报告称 dispatcher 形状来自
packages/runtime/src/http-dispatcher.ts:1076-1205的getDiscoveryInfo()。我核了 1078-1082 —— 确实name: 'ObjectOS'/version: '1.0.0'/environment: getEnv('NODE_ENV', 'development')/routes,行号与字段都对得上,不是照抄旧文档。 - 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 个需维护者裁定的决策点(featuresvscapabilities谁是正、endpoints是否退役、scoping补在哪、必填三字段怎么办)。本 PR 与 #4828 不冲突:本 PR 描述的是实现实际返回的形状(这对读者是对的),#4828 记录的是 spec 侧的欠账。
未处理项(按派发范围)
.claude/workflows/docs-accuracy-audit.js的ALL_HANDWRITTEN11 条失效路径未动,按我派发时的指示保留在本 issue 正文里,未另开重复单。它是工具缺陷、不在content/docs/**,会另行分诊 —— 它也是这一页能烂到今天的原因:查它的脚本以为那个目录不存在。
Generated by Claude Code
- 车道合规:
xuyushun441-sys commented
on Aug 3, 2026 CollaboratorAuthorMore actions结案: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_HANDWRITTEN11 条仍指向改名前的content/docs/protocol/objectos/*,导致该内部审计脚本静默漏审整个protocol/kernel目录 —— 这也是本页与 #4781 那页能烂到今天的原因:不是没人查,是查它的脚本以为那个目录不存在。它是工具缺陷、不在 docs 范围,另行分诊。
Generated by Claude Code
#4781(删除 runtime-capabilities 页)核实页尾 discovery 那节时顺带发现,不在该 PR 范围内修,未认领。
现象
content/docs/protocol/kernel/http-protocol.mdx的 API Discovery 一节写:随后给出一份响应示例,含
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一节,并说明 SDKconnect()先试/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 认领。