fix(spec,metadata-protocol,runtime): 摘掉 cache/queue/job 三条不存在的 route (#4318) - #4448
Merged
os-zhuang merged 2 commits intoAug 1, 2026
Merged
Conversation
…kernel-internal cache/queue/job slots (#4318) `SERVICE_CONFIG` declared `/api/v1/cache`, `/api/v1/queue` and `/api/v1/jobs`. Those three lines were the only mention of those paths in the repository: no dispatcher domain under `packages/runtime/src/domains/`, no adapter mount, no plugin registration. Nor is one pending — the slots' shipped providers (`service-cache` / `-queue` / `-job`, per `CORE_SERVICE_PROVIDER`) are in-process contracts and mount no HTTP surface at all. The kernel pre-injects in-memory fallbacks into all three on every default boot, and those self-report `handlerReady: false`. So every default deployment emitted a `ServiceInfo` whose `route` said "call me here" next to its own `handlerReady: false` saying "there is no handler" — the D12 honesty defect of #4089/#4130 sharpened to a contradiction *inside a single record*. Route removed at the root rather than suppressed per-occupant: the slots are route-less now, structurally, the way `realtime` already was. What differs from `realtime` is the unmarked case, so each route-less entry states it: `realtime`'s advertised capability IS the missing HTTP/WS surface, so an in-process bus there is `degraded`; a cache/queue/job slot's contract is in-process to begin with, so a real (unmarked) implementation stays `available` — "no HTTP surface" is not reduced capability for it. The dispatcher builder had the same defect one field over: `svcAvailable` gave an unmarked occupant `handlerReady: true`, a handler that does not exist. It reports these slots through `svcInProcess` now — `handlerReady` is pinned `false`, which for a route-less slot is not a proxy for anything, it is the fact itself (the reason `file-storage` stays in `DISPATCHER_GATED_SERVICES`). The explanatory message is written once, as `inProcessServiceMessage()` in `@objectstack/spec/system`, so the two builders cannot drift the way they did for `metadata` and `data`. Tests pin both builders and, for cache/queue/job, pin them against *each other* across both occupant shapes (real/unmarked and the kernel fallback). The two service READMEs advertised REST endpoint tables for surfaces that were never mounted — replaced with what is actually true.
…e-queue-route-conflict-8fwmfc
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 5 package(s): 114 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
os-zhuang
deleted the
claude/discovery-cache-queue-route-conflict-8fwmfc
branch
August 1, 2026 08:06
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.
Closes #4318.
采用 修法 A(摘掉 route),但 issue 里担心的两条连带代价都不必接受 —— 它们是
noHttpSurface这个单一分支捆绑出来的,而不是 A 本身的必然结果。问题
SERVICE_CONFIG声明了/api/v1/cache、/api/v1/queue、/api/v1/jobs。全仓提到这三条路径的地方就是这三行本身:没有 dispatcher 域、没有 adapter 挂载、没有插件注册。也不是"等插件补上" —— 这三个槽位的 provider(service-cache/-queue/-job,见CORE_SERVICE_PROVIDER)是进程内契约,不挂任何 HTTP 路由。kernel 在默认 boot 时给这三个槽位注入内存兜底,而兜底自报
handlerReady: false。于是每个默认部署的 discovery 都输出一条route说"去这里调用"、handlerReady: false说"没有 handler" 的记录 —— #4089/#4130 那类 D12 诚实性缺陷,尖锐到同一条记录内部自相矛盾。修法
从根因摘掉 route,而不是按占位者抑制。 这三个槽位现在结构性无路由,和
realtime一样。与 realtime 不同的是"无 marker 占位者"该报什么,所以每条无路由条目自己声明。 原来
!config.route ⇒ degraded把两种不同情况压成了一条规则:realtime对外宣称的能力就是那个缺失的 HTTP/WS 面 —— 没有它确实是能力削减,无 marker 的 bus 报degraded;available。这样 issue 里 A 的第 1 条代价(真实 cache 从
available掉到degraded)不发生,第 2 条(message 对跨进程 Redis 不准确)也一并消失 —— message 跟着按槽位走了。dispatcher 侧同款缺陷一并修掉。 issue 只提到
route: undefined这一半,但svcAvailable(undefined, undefined, cacheSvc)对不带 marker 的占位者返回handlerReady: true—— 声称一个根本不存在的 handler。今天没暴露纯粹是因为默认 boot 里坐着的是自报false的兜底。现在走svcInProcess,handlerReady钉死false:对无路由槽位它不是任何东西的代理,它就是事实本身(与file-storage留在DISPATCHER_GATED_SERVICES的理由同构)。文案写在一处。
inProcessServiceMessage()放在@objectstack/spec/system,和serviceUnavailableMessage同一位置、同一理由 —— 两个 builder 不能像当年metadata/data那样漂移。验证
pnpm test全绿(132/132 tasks),pnpm typecheck通过,check:generated八项产物同步status/handlerReady/message/route必须逐字段相等 —— 这正是 core 的内存 fallback 带 _fallback: true 而非 __serviceInfo,readServiceSelfInfo 不识别 —— AppPlugin 注册的 i18n fallback 在 discovery 里报 available #4089/discovery 的data槽位仍是硬编available—— 目前只靠 plugin-dev 的加载顺序约定兜住,不是构造上的保证 #4130 那类漂移逃掉的地方route=undefined,routesmap 仍是data,metadata,i18norigin/main(含 fix(spec,objectql,metadata-protocol): auserfield carries its target in the TYPE — bare{type:'user'}is not targetless #4438 对protocol.ts的改动,在assertExpandTargetsExist,与本 PR 无语义交叠)并重跑全量顺带
service-cache/service-jobREADME 里的 "REST API Endpoints" 表格是同一个谎的文档版本(GET /api/v1/jobs/:name/history之类,一条都没挂),换成说明这两个服务没有 HTTP 面。protocol-discovery.test.ts里"queue/job/cache 的路由由注册它的插件挂载"那条注释也已证伪,一并改掉。关联:#3898、#4089(#4114)、#4130(#4141)、#3891、ADR-0076 D12、#2462。
Generated by Claude Code