Skip to content

fix(spec,core,cloud-connection,metadata): HTTP 契约归一 —— 死影子副本删除,http.server 定为 canonical 并入账 ledger (#4251) - #4393

Merged
os-zhuang merged 2 commits into
mainfrom
claude/4251-http-contract-unification
Jul 31, 2026
Merged

fix(spec,core,cloud-connection,metadata): HTTP 契约归一 —— 死影子副本删除,http.server 定为 canonical 并入账 ledger (#4251)#4393
os-zhuang merged 2 commits into
mainfrom
claude/4251-http-contract-unification

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

决策 memo 的 1(HTTP 归一)。动手取证后,事实比 memo 里说的更有意思:core 那份"分叉的第二定义"其实是死影子。

packages/core/src/contracts/ 整个目录是死代码,已删除

三个文件(http-server.ts / data-engine.ts / logger.ts)零导入方:没有任何 relative import、没有子路径导出(package.json 只导出 ../logger)、不是 tsup entry。core 的 barrel 一直在从 spec re-export("Re-export contracts from @objectstack/spec for backward compatibility")——所有从 @objectstack/core 导入 IHttpServer 的 8 个文件,拿到的本来就是 spec 版

但影子已经分叉:spec 的 IHttpResponse 长出了 write?/end?IHttpRequest 长出了 rawBody?,影子从未跟上。谁 grep 进这个文件,读到的就是一份没人执行的过期契约 —— 与 #4382 那条错误豁免同一类"查错地方然后得出有依据的错误结论"。删除零风险:根本没人够得到它。

http.server 定为 canonical,ledger 入账

ServiceSlotContracts 新增:

'http.server': IHttpServer;   // canonical
'http-server': IHttpServer;   // deprecated alias,同一实例

跨仓证据:framework 的 hono-plugin、qa node-plugin,cloud 的 objectos / cloud 两个 server 入口,全部注册 canonical;alias 处处标着 "backward compatibility";runtime 的 config.server 路径只注册 canonical

由此揪出一个真实 miss:cloud-connection 三个插件(marketplace-proxy / runtime-config / marketplace-install-local)只读 alias,在 config.server 路径上读到的是空槽。已全部改为 canonical 优先 + alias 兜底(兜底随 alias 注册一起死)。注册本身这个 release 不动,两处注册点补上弃用注释。ledger 测试钉住两个条目 + alias 等同性。

cloud 仓库还有两个 alias-only 读取方(auth-proxy、ai-token-guardrail)—— cloud 侧跟进,已在 issue 记录。

getRawApp?(): any 进契约

四个消费方各自本地声明过它(cloud-connection ×2、metadata HMR、cloud node-server)—— 四份真相。现在 spec 声明一次,写明:any 是刻意的且仅此一处(句柄的真实类型属于框架,契约点名它就背上框架依赖);adapter 不被要求暴露内部,消费方 feature-detect。三个本地 RawAppHost / HttpServerWithRawApp 类型全部删除。

搭车:IMetadataService bulk 方法的 options

bulkRegister 的契约把实现一直收的 & MetadataWriteOptions 那一半漏了(实现第一行就解构 notify);bulkUnregister 干脆没声明 options 而 manager 收。与 B2 的 IDataEngine 读方法缺口同形 —— 按实现补上,纯增量。

验证

  • ratchet:167 / 36, none new(marketplace-install-local 顺手 17→16)
  • spec build(dts)+ 7192 tests / 281 files;core / metadata / cloud-connection / plugin-hono-server dts build 全过(DEBT 包以 build 为类型门)
  • runtime 1001/69、rest 539/36、plugin-auth 579/26、plugin-sharing 226/11、service-settings 196/14、metadata 281/13、hono-server 135/12、http-conformance 46/2
  • eslint 全部改动文件干净

🤖 Generated with Claude Code

…nical slot name (#4251)

packages/core/src/contracts/ was a dead near-copy of the real contracts --
zero importers (no relative import, no subpath export, not a tsup entry;
core's barrel has re-exported the spec versions all along) -- and it had
already DIVERGED (spec's IHttpResponse grew write?/end?, IHttpRequest grew
rawBody?; the copy never did). Anyone who grepped into it read a stale
contract nothing enforces -- the both-humans-and-AI failure mode behind
the false http.server exemption (#4382). Deleted; zero-risk by
construction.

`http.server` is the canonical slot name and the ledger now says so:
ServiceSlotContracts gains 'http.server': IHttpServer plus the deprecated
'http-server' alias entry (same instance -- hono-plugin, qa node-plugin
and cloud's two server entrypoints all register both, alias commented
"backward compatibility"). Canonical is the only name on EVERY provider
path -- runtime's config.server path registers no alias, so the three
cloud-connection plugins reading the alias alone found an empty slot
there. All readers now go canonical-first with the alias as a fallback
that dies with the alias registrations; registrations untouched this
release, both sites carry the deprecation note.

getRawApp?(): any joins IHttpServer -- the deliberate framework-handle
escape, declared once with the rationale; four consumers declared it
locally before (cloud-connection x2, metadata HMR, cloud node-server),
and the local RawAppHost / HttpServerWithRawApp types are deleted.

IMetadataService.bulkRegister/bulkUnregister declare the write options
their implementation always accepted (bulkRegister's contract dropped the
MetadataWriteOptions half it intersects in; bulkUnregister declared no
options at all). Same shape as B2's IDataEngine read-methods gap.

Baseline 168 -> 167 (marketplace-install-local's lookup typed while
touched). Ledger test pins both slot entries and the alias equality.

Verified: spec build (dts) + 7192 tests / 281 files; core, metadata,
cloud-connection, plugin-hono-server dts builds; runtime 1001/69, rest
539/36, plugin-auth 579/26, plugin-sharing 226/11, service-settings
196/14, metadata 281/13, hono-server 135/12, http-conformance 46/2;
ratchet holds 167/36 none new; eslint clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 31, 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 Jul 31, 2026 11:00am

Request Review

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling and removed size/m labels Jul 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 6 package(s): @objectstack/cloud-connection, @objectstack/core, @objectstack/metadata, @objectstack/plugin-hono-server, @objectstack/http-conformance, @objectstack/spec.

117 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 @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/spec)
  • 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 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, packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/core, packages/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @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/migration-from-objectql.mdx (via @objectstack/core)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • 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/spec)
  • content/docs/kernel/cluster.mdx (via packages/metadata, @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, @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/permissions/authentication.mdx (via @objectstack/core, @objectstack/plugin-hono-server)
  • content/docs/permissions/authorization.mdx (via packages/core, @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/metadata, @objectstack/plugin-hono-server, @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)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/kernel/metadata-service.mdx (via @objectstack/cloud-connection, @objectstack/metadata)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/kernel/runtime-capabilities.mdx (via @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/cloud-connection, @objectstack/core, @objectstack/plugin-hono-server, @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/core, @objectstack/metadata, @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/spec)
  • content/docs/releases/v9.mdx (via @objectstack/metadata, @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.

…name try -- getService throws on an empty slot (#4251)

CI caught the shape my local run could not (I built cloud-connection but ran
only metadata's tests -- cloud-connection's own suites mock a kernel that
registers ONLY the alias): `getService` THROWS for an unregistered slot, so

    try { a = getService('http.server') ?? getService('http-server'); } catch {...}

never reaches the alias -- the first name's throw exits the whole try. Split
into a per-name try (readServer helper) in all four readers.

Worth recording: the pre-existing alias-first read in metadata/plugin.ts had
the SAME shape, so its `?? getService('http.server')` fallback never once
fired either -- a decorative fallback, the declared-vs-actual gap this work
line keeps finding, now actually implemented in both directions.

Verified serially (the earlier 6-file FAIL was local vitest concurrency noise
while spec's dts build ran in parallel -- single-file and serial reruns green):
cloud-connection 64/12, metadata 281/13, both dts builds, eslint clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant