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 test 7575 passed (299 files)
@objectstack/runtime test 1131 passed (82 files)
@objectstack/core test 419 passed (27 files)
@objectstack/example-showcase test 83 passed (11 files)
client / plugin-hono-server / metadata test 222 / 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

claude added 2 commits August 4, 2026 01:21
… 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

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 4, 2026 2:21am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation protocol:system tests protocol:ui tooling labels Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

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.

claude added 5 commits August 4, 2026 01:54
…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

Copy link
Copy Markdown
Contributor Author

与 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:generated 8/8 up to date
@objectstack/spec test 7651 passed (302 files)
runtime / core / showcase / client / hono test 82 / 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

Copy link
Copy Markdown
Contributor Author

范围外发现,已另开单:#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

Copy link
Copy Markdown
Contributor Author

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 free to join this conversation on GitHub. Already have an account? Sign in to comment