fix(spec,core,cloud-connection,metadata): HTTP 契约归一 —— 死影子副本删除,http.server 定为 canonical 并入账 ledger (#4251) - #4393
Merged
Conversation
…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>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 6 package(s): 117 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…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>
This was referenced Jul 31, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
决策 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新增:跨仓证据: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 等同性。getRawApp?(): any进契约四个消费方各自本地声明过它(cloud-connection ×2、metadata HMR、cloud node-server)—— 四份真相。现在 spec 声明一次,写明:
any是刻意的且仅此一处(句柄的真实类型属于框架,契约点名它就背上框架依赖);adapter 不被要求暴露内部,消费方 feature-detect。三个本地RawAppHost/HttpServerWithRawApp类型全部删除。搭车:
IMetadataServicebulk 方法的 optionsbulkRegister的契约把实现一直收的& MetadataWriteOptions那一半漏了(实现第一行就解构notify);bulkUnregister干脆没声明 options 而 manager 收。与 B2 的IDataEngine读方法缺口同形 —— 按实现补上,纯增量。验证
167 / 36, none new(marketplace-install-local 顺手 17→16)🤖 Generated with Claude Code