Skip to content

feat(spec,core,runtime)!: 声明式 apis: 响亮拒绝 + ApiRegistry 整面退役 (#4936, #4939) - #5065

Merged
os-zhuang merged 7 commits into
mainfrom
claude/issue-4936-apis-loud-reject
Aug 4, 2026
Merged

feat(spec,core,runtime)!: 声明式 apis: 响亮拒绝 + ApiRegistry 整面退役 (#4936, #4939)#5065
os-zhuang merged 7 commits into
mainfrom
claude/issue-4936-apis-loud-reject

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes#4936
Fixes#4939

按维护者 2026-08-04 00:20Z 裁决(#4936 评论,改良第三路)执行,⛔ 不重议的四件均已照办:硬拒路线、ApiEndpointSchema 词表保留、#4939 无条件退役、跟踪指针落 #5040

为什么是「拒绝」而不是「退役」

声明式 apis:装载全绿、执行为零的整面。元数据侧完美:defineStack 收下、GET /api/v1/meta/api 原样返回两个端点。执行侧一次都没响过 —— 声明的 path 从未挂载,请求死在 Hono 的 notFound(那个裸 {"error":"Not found"},不是 dispatcher 的语义 404);其后的 handleApiEndpoint 分支调用的 matchEndpoint,全仓没有任何实现提供过,恒等于 { handled: false }

于是 ApiEndpointSchema 每个键都是 declared ≠ enforced ——— 包括 authRequired,一个解析全绿、把关为零的安全语义。这是 ADR-0049 要杀的 false compliance,不是欠债。

裁决选了保留词表、拒绝授权:端点词表是行业极稳定形状,退役只会原样再引入一遍;响亮拒绝同样杀谎,还保住词表与元数据投资。

五件套落地

1. 非空 apis: 硬拒(breaking)

拒绝点落在 ObjectStackDefinitionSchemaapis 字段本身 —— 这是 defineStack、metadata plugin 的 artifact 装载(ObjectStackDefinitionSchema.parse)、os validate、lint scorer、EnvironmentArtifactSchema共同且唯一的必经闸门,所以不存在「某条路径忘了检查」。空数组 / 缺省照旧通过。

真实 CLI 上的实测(把 showcase 端点临时放回去跑 objectstack validate):

✗ defineStack validation failed (1 issue):
✗ apis: `apis:` (declarative ApiEndpoint) is DECLARED BUT NOT EXECUTABLE in this runtime,
so a non-empty array is rejected instead of silently accepted (#4936). Nothing mounts the
declared `path`, no endpoint matcher exists, and therefore NO key on the endpoint takes
effect — `authRequired` included, which would parse green while gating nothing.
Fix: delete the `apis:` entries (an empty array or an absent key is fine). To serve the
route today, mount it in code — a plugin manifest `contributes.routes` entry or an
`http.server` route — which is the path the showcase now uses.
The `ApiEndpoint` vocabulary is deliberately KEPT: the executor ... is tracked by
https://github.com/objectstack-ai/objectstack/issues/5040, and this rejection is replaced
by real execution there — your endpoint definitions stay valid.

处方按裁决落 #5040(活跟踪位),#4936 作为裁决出处随本 PR 关闭。

2. 执行残骸摘除

handleApiEndpoint 整体删除;tsc 随即用 TS6133 指出它是 dispatcher 私有 callData 代理的唯一调用者,一并删除(其余数据路径本来就直接走 actionExec.callData(deps, …),是 D11③ 的正规形状)。/__api-endpointLEGACY_CHAIN_PREFIXESROUTE_LEDGER 移除。⚠️ 今日已合 #5006 的入站 rateLimit seam 零触碰

3. #4939 无条件退役

registry.zod.ts 整个家族(12 个 JSON-Schema def、67 个 authorable key)、packages/coreApiRegistry + createApiRegistryPlugin + 两者测试 + example、API_REGISTRY.md,以及 hono 那个从未被读useApiRegistry 选项。它只在 packages/core/examples/ 装配过,所以 requiredPermissions 以现在时承诺的 gateway 校验从来没有 gateway 执行 —— 两套声明形状就此收敛为一套。

⚠️ConflictResolutionStrategy 保留,移入 api/router.zod.ts。它被两条互相独立的 ratchet 钉死为 ./api 导出:仓内 spec/src/automation/sync-retirement.test.ts(#4738 的「第四个亲戚」),以及跨仓 objectui 的 offline-nav-performance-spec-parity.test.ts —— 后者的 useOffline 正是因为这个名字被占用才改的名。退役它是一次跨仓变更,不在本单裁决范围内。

退役套件按 spec-property-retirement skill 走完:#2978 manifest ratchet 先开火(12 条,自证「整 def 删除」路线),再按 gate (c) 路径 3(def 不再 emit)删 authorable 基线;生成物一律整体重生成。

4. showcase 处置

两个端点注释保留 + 缘由(便于 #5040 落地时原样恢复),apis: [];coverage.ts 那条 demonstrated … executed by the runtime dispatcher (handleApiEndpoint) 改为 waiver —— 它正是 Prime Directive #10 明禁的失实覆盖声明。test/gap-fill.test.ts 的断言反转而非删除:删掉只会让端点悄悄漂回来,而现在漂回来会直接打死 objectstack validate

5. #5006 四处指针#5040(dispatcher-plugin.tsinbound-rate-limit.tsstack-server.zod.ts + 生成 mdx、http-protocol.mdx),只改跟踪位,不动 seam 逻辑。

另修两处顺带被本变更证伪的记载:ADR-0088 router 行(原文把 apis: 记作「executed by handleApiEndpoint」)加了带日期的更正,ADR 决定本身不变;PROTOCOL_MAP.mdregistry.zod.ts 行删除(其死链被 spec 自己的 gate 抓到)。

验证

merge origin/main(含 #5045 把 runtime src 接进 turbo typecheck)之后全部重跑:

结果
pnpm turbo run typecheck(全仓)124/124 successful
spec check:generated 八件8/8 up to date
spec 八件纯审计(liveness / empty-state / exported-any / dual-source-exports …)8/8 PASS
@objectstack/spec test7575 passed (299 files)
@objectstack/runtime test1131 passed (82 files)
@objectstack/core test419 passed (27 files)
@objectstack/example-showcase test83 passed (11 files)
client / plugin-hono-server / metadata test222 / 150 / 336 passed
objectstack validate(showcase)✓ Validation passed
破坏性 sabotage(端点放回去)按上文原文拒绝 ✓

api-surface.json delta 精确为 −25 / +0,零残留,幸存者 ApiEndpointSchemaConflictResolutionStrategy 均在。

新增 pin 测试两组:apis-no-executor.test.ts(拒绝含处方 + 指针为 #5040 + 空/缺省通过 + 词表零折腾的反空洞断言)、registry-retirement.test.ts(15 个退役名消失 + ConflictResolutionStrategy 值域逐个保真 + 单一属主)。

Changeset 已加,major 语义,带 FROM → TO 与一行修法。⛔ 未触碰 content/docs/releases/

CI 知会

Validate Package Dependencies job 目前被 OSV 每日公告(fast-uri/hono/undici)打红,修复 #5039 在飞 —— 若本 PR 该 job 红,请先与 main 对照,非本变更引入。

🤖 Generated with Claude Code

https://claude.ai/code/session_01EYGdmvWP1ieZSLqvAW6uyd


Generated by Claude Code

… ApiRegistry family (#4936, #4939)
The declarative `apis:` surface was zero-execution end to end while reporting
perfect health. Metadata loaded fine — `GET /api/v1/meta/api` returned every
declared endpoint with every key — but no route was ever mounted for a declared
path, so a request died at Hono's `notFound` (a bare 404, not the dispatcher's
semantic one), and the `handleApiEndpoint` branch behind it called a
`matchEndpoint` method no implementation in this repo has ever provided. Every
key on `ApiEndpointSchema` was therefore declared != enforced, `authRequired`
included — a security semantic that parsed green and gated nothing.
Per the maintainer verdict (2026-08-04, #4936), this takes the third route:
keep the vocabulary, refuse the authoring.
- spec: a non-empty `apis:` is rejected on `ObjectStackDefinitionSchema` — the
one choke point `defineStack`, metadata artifact ingestion, `os validate`,
the lint scorer and `EnvironmentArtifactSchema` all run through, so no path
can forget to check. The rejection carries its own prescription and names
#5040 (the executor) as the live tracker. Empty/absent still pass.
`ApiEndpointSchema` itself is untouched: retiring an industry-stable endpoint
shape would only mean re-introducing it identically later.
- runtime: `handleApiEndpoint`, its now-orphaned private `callData` delegate
(tsc TS6133 found it) and the `/__api-endpoint` ledger + legacy-prefix
entries are deleted, so the absence is loud instead of grep-able dead code.
- spec/core (#4939): the second, unrelated endpoint declaration shape retires
whole — `ApiEndpointRegistration`/`ApiRegistry`/`ApiRegistryEntry` and their
value schemas (12 JSON-Schema defs, 67 authorable keys), the ~500-line
`ApiRegistry` service, `createApiRegistryPlugin`, and hono's unread
`useApiRegistry` option. It was composed only in `packages/core/examples/`,
so `requiredPermissions` promised gateway enforcement no gateway performed.
`ConflictResolutionStrategy` survives, moved to `api/router.zod` — two
independent ratchets (spec sync-retirement, objectui parity) pin it.
- showcase: declares no endpoints (both definitions preserved, commented, with
the rationale); the coverage manifest's "demonstrated ... executed by the
runtime dispatcher" claim is corrected to a waiver — it was the exact
advertise-what-you-do-not-deliver claim Prime Directive #10 forbids.
- the #4910/#5006 endpoint-level `rateLimit` tracking pointers now name #5040,
since #4936 closes here.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYGdmvWP1ieZSLqvAW6uyd
@vercel

vercelBot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 4, 2026 2:21am

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 5 package(s): @objectstack/core, @objectstack/metadata-protocol, @objectstack/plugin-hono-server, @objectstack/runtime, @objectstack/spec.

120 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/actions-as-tools.mdx(via @objectstack/core)
  • content/docs/ai/agents.mdx(via @objectstack/spec)
  • content/docs/ai/knowledge-rag.mdx(via @objectstack/core)
  • content/docs/ai/natural-language-queries.mdx(via @objectstack/core)
  • content/docs/ai/skills-reference.mdx(via @objectstack/spec)
  • content/docs/ai/skills.mdx(via @objectstack/spec)
  • content/docs/api/client-sdk.mdx(via packages/runtime, @objectstack/spec)
  • content/docs/api/environment-routing.mdx(via @objectstack/spec)
  • content/docs/api/error-catalog.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx(via @objectstack/spec)
  • content/docs/api/index.mdx(via @objectstack/runtime, @objectstack/spec)
  • content/docs/api/wire-format.mdx(via @objectstack/runtime)
  • content/docs/automation/approvals.mdx(via @objectstack/spec)
  • content/docs/automation/connectors.mdx(via @objectstack/spec)
  • content/docs/automation/flows.mdx(via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx(via @objectstack/runtime, packages/spec)
  • content/docs/automation/hooks.mdx(via @objectstack/spec)
  • content/docs/automation/index.mdx(via @objectstack/spec)
  • content/docs/automation/webhooks.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/automation/workflows.mdx(via @objectstack/spec)
  • content/docs/concepts/architecture.mdx(via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx(via packages/spec)
  • content/docs/concepts/index.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx(via @objectstack/metadata-protocol, @objectstack/runtime, packages/spec)
  • content/docs/concepts/north-star.mdx(via packages/core, packages/runtime, @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx(via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx(via @objectstack/runtime, @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx(via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx(via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx(via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx(via @objectstack/spec)
  • content/docs/data-modeling/index.mdx(via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx(via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx(via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx(via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx(via @objectstack/spec)
  • content/docs/deployment/cli.mdx(via @objectstack/spec)
  • content/docs/deployment/index.mdx(via @objectstack/runtime)
  • content/docs/deployment/migration-from-objectql.mdx(via @objectstack/core)
  • content/docs/deployment/production-readiness.mdx(via @objectstack/runtime)
  • content/docs/deployment/single-project-mode.mdx(via @objectstack/runtime)
  • content/docs/deployment/troubleshooting.mdx(via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx(via @objectstack/spec)
  • content/docs/deployment/vercel.mdx(via @objectstack/runtime)
  • content/docs/getting-started/build-with-claude-code.mdx(via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx(via @objectstack/spec)
  • content/docs/getting-started/examples.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx(via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx(via @objectstack/plugin-hono-server, @objectstack/runtime, @objectstack/spec)
  • content/docs/kernel/cluster.mdx(via @objectstack/runtime, @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx(via packages/spec)
  • content/docs/kernel/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx(via @objectstack/core)
  • content/docs/kernel/runtime-services/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx(via packages/spec)
  • content/docs/kernel/services-checklist.mdx(via @objectstack/core, @objectstack/metadata-protocol, @objectstack/spec)
  • content/docs/kernel/services.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/permissions/authentication.mdx(via @objectstack/core, @objectstack/plugin-hono-server, @objectstack/runtime)
  • content/docs/permissions/authorization.mdx(via packages/core, packages/runtime, @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx(via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx(via @objectstack/spec)
  • content/docs/permissions/positions.mdx(via @objectstack/spec)
  • content/docs/permissions/rls.mdx(via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx(via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx(via @objectstack/spec)
  • content/docs/plugins/anatomy.mdx(via @objectstack/core)
  • content/docs/plugins/development.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/plugins/index.mdx(via @objectstack/core, @objectstack/plugin-hono-server, @objectstack/spec)
  • content/docs/plugins/packages.mdx(via @objectstack/core, @objectstack/plugin-hono-server, @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx(via @objectstack/spec)
  • content/docs/protocol/diagram.mdx(via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/kernel/http-protocol.mdx(via @objectstack/plugin-hono-server, @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx(via @objectstack/core, @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx(via @objectstack/core, @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/knowledge.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx(via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx(via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx(via @objectstack/core, @objectstack/plugin-hono-server, @objectstack/runtime, @objectstack/spec)
  • content/docs/releases/index.mdx(via @objectstack/spec)
  • content/docs/releases/v12.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/releases/v13.mdx(via @objectstack/spec)
  • content/docs/releases/v15.mdx(via @objectstack/core)
  • content/docs/releases/v16.mdx(via @objectstack/plugin-hono-server, @objectstack/spec)
  • content/docs/releases/v17.mdx(via @objectstack/core, @objectstack/runtime, @objectstack/spec)
  • content/docs/releases/v9.mdx(via @objectstack/metadata-protocol, @objectstack/spec)
  • content/docs/ui/actions.mdx(via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx(via @objectstack/spec)
  • content/docs/ui/dashboards.mdx(via @objectstack/spec)
  • content/docs/ui/forms.mdx(via @objectstack/spec)
  • content/docs/ui/index.mdx(via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx(via @objectstack/spec)
  • content/docs/ui/setup-app.mdx(via @objectstack/spec)
  • content/docs/ui/translations.mdx(via @objectstack/spec)
  • content/docs/ui/views.mdx(via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

…ublic method
`HttpDispatcher.handleApiEndpoint()` carried no `private` modifier, so deleting
it removes a symbol from `@objectstack/runtime`'s public surface even though the
method returned `{ handled: false }` on every call it ever received. Record it
as breaking with that nuance stated, rather than letting a `minor` imply the
symbol survived. Also drops the `@objectstack/client` entry: that change is a
comment in a `.test.ts`, which never ships.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYGdmvWP1ieZSLqvAW6uyd
The APIS_NO_EXECUTOR_GUIDANCE const landed between the two doc-comment
blocks that both belong to ObjectStackDefinitionSchema, orphaning the
first. Move the const above them — no behaviour change.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYGdmvWP1ieZSLqvAW6uyd
The test claimed the prescription does not name #4936 as the tracker but
only asserted #5040 was present — true even with a stale issues/4936 link
beside it. Assert the set of issue URLs in the message is exactly {5040}.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYGdmvWP1ieZSLqvAW6uyd
…1 D1 renames paths on restore
ADR-0121 (accepted 2026-08-04, after this branch opened) namespaces
endpoint paths as `<runtime-prefix>/apps/<namespace>/<subpath>`. The
rejection message said definitions "stay valid"; that is true of every
key except `path`, so it is now stated precisely, with the FROM -> TO.
The showcase's commented endpoints carry the same note — they would be
rejected under D1 if uncommented verbatim.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYGdmvWP1ieZSLqvAW6uyd
@os-zhuangClaude

Copy link
Copy Markdown
ContributorAuthor

与 ADR-0121(#5064,本 PR 开工后合入)的对账

开工中途 main 合入了 ADR-0121《声明式端点的路由归属与通道分工》。已逐条核对,无冲突,且互为前置:

一处因它而必须修正的措辞(已在 e050719 落):原拒绝信息结尾写「your endpoint definitions stay valid」。ADR-0121 D1 把端点路径收紧为 <运行前缀>/apps/<命名空间>/<子路径>,所以除 path 外每个键确实原样有效,path 则要改写。现在信息里直接给出 FROM → TO:

One thing WILL change when they come back: ADR-0121 D1 namespaces endpoint paths as <runtime-prefix>/apps/<namespace>/<subpath>, so a path like /api/v1/my/thing becomes /api/v1/apps/<your manifest.namespace>/thing. Everything else about the endpoint is unchanged.

showcase 里注释保留的两个端点同样加了这条警告 —— ADR-0121 §D1 已点名它们回迁后的形态是 /api/v1/apps/showcase/tasks/api/v1/apps/showcase/inquiries/purge(由 #5040 E8 执行),照原样反注释会被 D1 拒掉,这一点必须写在文件里而不是留给下一位作者去踩。

二次 merge 后的复验(fbf7a02,含 #5042 / #5053 / #5012 / #5064 等 8 个提交)

结果
pnpm turbo run typecheck(全仓)124/124
spec check:generated8/8 up to date
@objectstack/spec test7651 passed (302 files)
runtime / core / showcase / client / hono test82 / 27 / 11 / 17 / 13 files,全绿

⚠️ 其中 #5053(composeStacks 不再静默丢弃顶层键)与本 PR 同改 stack.zod.ts,merge 无冲突,合并后 compose-stacks-key-loss.test.ts 与本单新增 pin 测试同时全绿。


Generated by Claude Code


Generated by Claude Code

@os-zhuangClaude

Copy link
Copy Markdown
ContributorAuthor

范围外发现,已另开单:#5078

摘除 handleApiEndpoint 时,在它紧邻的上一个 if 里发现同一形状的第二处,未在本 PR 修(本 PR scope 严格限定为 apis:ApiRegistry):

http-dispatcher.ts/openapi.json 分支探测 metaSvc.generateOpenApi,而该方法全仓 + cloud + objectui 零实现(精确名 grep 仅 4 处命中,其中 3 处是 documentation.zod.ts 里一个同名但无关的配置布尔键)。与 matchEndpoint 完全同类。

差别在于:这条路由并非无人服务 —— packages/rest/src/rest-server.ts:2523 真实提供它并从 @objectstack/spec/openapi.json 加载 base spec。所以是 ADR-0076 D1 的影子重复(一路两主),外加 route-ledger.ts:252 那句 falls through when metadata service lacks a generator 措辞失准(实为 100% fall through,从来没有过 generator)。

单里明确标注了我没有实测的那一点:两个属主在真实 composition 下谁先接到请求 —— 这决定它是纯死代码还是用户可见 404,建议按 ADR-0076 结尾那句起真实 boot curl 定级,不做 grep 推断。


Generated by Claude Code


Generated by Claude Code

@os-zhuangClaude

Copy link
Copy Markdown
ContributorAuthor

CI 全绿(e050719)

24 项检查全部落定:23 success + 1 skipped(Console Pin Gate,paths 过滤跳过),0 failure。

关键门禁逐项:

门禁结果
TypeScript Type Check(含 spec 八件生成物 + api-surface)
Spec property liveness
Test Core (1/3, 2/3, 3/3)
Dogfood Regression Gate (1/3, 2/3, 3/3)
Dogfood Verify CLI
Temporal Conformance (live PG + MySQL)
Build Core / Build Docs
ESLint / Check Changeset / Check PR Size
No other open PR may claim the same issue

关于交办时提示的 Validate Package Dependencies(OSV 每日公告打红,修复 #5039):该 job 本次 run 未出现在检查列表中 —— 期间合入的 caf144a(ci(deps): OSV batch 2026-08 — undici 7.29.0, hono 4.12.34, fast-uri 3.1.5)与 70c0769(OSV 逃生口机械门禁)已经落地,本 PR 因此不受该问题影响,无需与 main 对照排除。

Draft 状态保持,等待维护者/PM 复核后再决定转 ready。


Generated by Claude Code


Generated by Claude Code

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

Labels

documentationImprovements or additions to documentationprotocol:systemprotocol:uisize/xlteststooling

Projects

None yet

2 participants

@os-zhuang@claude