Skip to content

fix(spec,metadata-protocol,runtime): 摘掉 cache/queue/job 三条不存在的 route (#4318) - #4448

Merged
os-zhuang merged 2 commits into
mainfrom
claude/discovery-cache-queue-route-conflict-8fwmfc
Aug 1, 2026
Merged

fix(spec,metadata-protocol,runtime): 摘掉 cache/queue/job 三条不存在的 route (#4318)#4448
os-zhuang merged 2 commits into
mainfrom
claude/discovery-cache-queue-route-conflict-8fwmfc

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

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;
  • cache/queue/job 的契约本来就是进程内的 —— "没有 HTTP 面"对它们不构成削减,一个真实的(不带 marker 的)Redis cache 仍然报 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 那样漂移。

验证

顺带

service-cache / service-job README 里的 "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

claude added 2 commits August 1, 2026 07:44
…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.
@vercel

vercel Bot commented Aug 1, 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 1, 2026 7:51am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation protocol:system tests tooling size/m labels Aug 1, 2026
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 5 package(s): @objectstack/metadata-protocol, @objectstack/runtime, @objectstack/service-cache, @objectstack/service-job, @objectstack/spec.

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

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • 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/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/runtime, packages/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/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/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 @objectstack/service-cache, packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @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/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/metadata-protocol, @objectstack/service-cache, @objectstack/service-job, @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/service-cache, @objectstack/spec)
  • content/docs/permissions/authentication.mdx (via @objectstack/runtime)
  • content/docs/permissions/authorization.mdx (via 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/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/runtime, @objectstack/service-cache, @objectstack/service-job, @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/spec)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/runtime)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @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/runtime, @objectstack/service-cache, @objectstack/service-job, @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/spec)
  • content/docs/releases/v17.mdx (via @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.

@os-zhuang
os-zhuang merged commit 20bc357 into main Aug 1, 2026
18 checks passed
@os-zhuang
os-zhuang deleted the claude/discovery-cache-queue-route-conflict-8fwmfc branch August 1, 2026 08:06
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 protocol:system size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

discovery 的 cache/queue/job 槽位声明了三条不存在的 route —— 同一条记录里 handlerReady:false 与 route 互相矛盾

2 participants