按 Prime Directive #10 记录,#4318(PR #4448)收尾时把 SERVICE_CONFIG 剩下的路由逐条核了一遍,发现同款构造还剩两条。今天不发出(两个槽位都没有任何东西注册,registeredServices.has() 恒假),所以危害度比 #4318 低一档 —— 但构造上的谎是同一个,而且任何人往槽位里塞一个实现的那天就开始广播 404。
现象
1. workflow —— 两个 builder 都声明,没有任何 handler
// packages/metadata-protocol/src/protocol.ts:1245
workflow: { route: '/api/v1/workflow' },
// packages/runtime/src/http-dispatcher.ts:980
workflow: hasWorkflow ? `${prefix}/workflow` : undefined,
// :1184
workflow: hasWorkflow ? svcAvailable(routes.workflow, undefined, workflowSvc) : svcUnavailable('workflow'),
而全仓没有任何东西服务这条路径:
packages/runtime/src/domains/ 下没有 workflow 域 —— 已注册的域前缀是 /actions /ai /analytics /auth /automation /data /i18n /keys /mcp /meta /notifications /packages /security /share-links /ui;
packages/rest/src/rest-route-ledger.ts 里没有 workflow family;
- 全仓没有任何
registerService('workflow', …) 或 providesServices: ['workflow'];
CORE_SERVICE_PROVIDER['workflow'] 是 null,注释写着 "nothing implements those slots(no consumer either — ADR-0115 Evidence 5)"。
即:槽位有名分(workflow 是合法 CoreServiceName)、路由有声明、实现和 handler 都不存在。
2. graphql —— dispatcher 明说删掉了,metadata-protocol 还在声明
// packages/metadata-protocol/src/protocol.ts:1255
graphql: { route: '/graphql' }, // GraphQL uses /graphql by convention (not versioned REST)
// packages/runtime/src/http-dispatcher.ts:1591
// /graphql removed — GraphQL is not in the product plan (#2462 follow-on).
比 workflow 更靠不住的地方在于:graphql 根本不是 CoreServiceName。它只出现在两处 —— CORE_SERVICE_PROVIDER['graphql'] = null 和上面这行 SERVICE_CONFIG。一个不在服务枚举里的槽位,声明了一条产品计划里已经明确否掉的路径。
为什么现在不发出
两个槽位都没有任何 provider,所以 SERVICE_CONFIG 循环走的是 else 分支(unavailable,不带 route)。实测(showcase,pnpm dev -- --fresh -p 39514,本 PR 分支 @ 5293114):
workflow status=unavailable handlerReady=None route=None
routes keys: analytics,auth,automation,data,i18n,metadata,notifications,storage,ui
和 #4318 的区别正在这里:cache/queue/job 有 kernel 兜底占位,所以每个默认部署都发;这两个是空槽,声明躺在表里等一个占位者。
证据方法上的一个说明
我也直接 curl 了这两条路径,都是 404。但这条证据不是决定性的,记下来免得下一个人被它误导:/api/v1/i18n 这种确实挂载了域的路径,裸前缀同样返回 404(域自己对未知子路径的应答)。unavailable.ts 把这层区分写得很清楚 —— 404 = 路由没挂,501 = 路由挂了但没实现。所以判定"有没有人挂"要看域注册表 / route ledger / registerService 调用点这些结构事实,404 只是与之一致而已。
两者需要拍板的东西不一样,所以没有并进 #4448
#4318 的结论是"这三个槽位永远不会有 HTTP 面"(provider 是进程内契约),摘 route 是唯一正确解。这两条不同:
workflow:要先定 workflow 引擎还做不做。做 ⇒ route 声明保留、补 dispatcher 域(或 REST ledger 条目),让 declared === enforced;不做 ⇒ 连槽位一起退役(ADR-0115 Evidence 5 已经说了 no consumer,那就是往退役方向走的证据)。
graphql:dispatcher 那行注释已经把结论写了 —— 不在产品计划里。倾向直接从 SERVICE_CONFIG 和 CORE_SERVICE_PROVIDER 里删掉,它连槽位都不是。
把它们和 #4318 混在一条 PR 里,会让"没人挂 ⇒ 不声明"这条规则的适用依据变模糊(一个是永远不会有,一个是还没决定要不要有),所以单开。
关联
#4318(PR #4448)、#3898、#4089(#4114)、#4130(#4141)、#3891、#2462、ADR-0076 D12、ADR-0115 Evidence 5。
核对于 origin/main @ 5293114。
按 Prime Directive #10 记录,#4318(PR #4448)收尾时把
SERVICE_CONFIG剩下的路由逐条核了一遍,发现同款构造还剩两条。今天不发出(两个槽位都没有任何东西注册,registeredServices.has()恒假),所以危害度比 #4318 低一档 —— 但构造上的谎是同一个,而且任何人往槽位里塞一个实现的那天就开始广播 404。现象
1.
workflow—— 两个 builder 都声明,没有任何 handler而全仓没有任何东西服务这条路径:
packages/runtime/src/domains/下没有 workflow 域 —— 已注册的域前缀是/actions/ai/analytics/auth/automation/data/i18n/keys/mcp/meta/notifications/packages/security/share-links/ui;packages/rest/src/rest-route-ledger.ts里没有 workflow family;registerService('workflow', …)或providesServices: ['workflow'];CORE_SERVICE_PROVIDER['workflow']是null,注释写着 "nothing implements those slots(no consumer either — ADR-0115 Evidence 5)"。即:槽位有名分(
workflow是合法CoreServiceName)、路由有声明、实现和 handler 都不存在。2.
graphql—— dispatcher 明说删掉了,metadata-protocol 还在声明比 workflow 更靠不住的地方在于:
graphql根本不是CoreServiceName。它只出现在两处 ——CORE_SERVICE_PROVIDER['graphql'] = null和上面这行SERVICE_CONFIG。一个不在服务枚举里的槽位,声明了一条产品计划里已经明确否掉的路径。为什么现在不发出
两个槽位都没有任何 provider,所以
SERVICE_CONFIG循环走的是else分支(unavailable,不带 route)。实测(showcase,pnpm dev -- --fresh -p 39514,本 PR 分支 @ 5293114):和 #4318 的区别正在这里:cache/queue/job 有 kernel 兜底占位,所以每个默认部署都发;这两个是空槽,声明躺在表里等一个占位者。
证据方法上的一个说明
我也直接 curl 了这两条路径,都是 404。但这条证据不是决定性的,记下来免得下一个人被它误导:
/api/v1/i18n这种确实挂载了域的路径,裸前缀同样返回 404(域自己对未知子路径的应答)。unavailable.ts把这层区分写得很清楚 —— 404 = 路由没挂,501 = 路由挂了但没实现。所以判定"有没有人挂"要看域注册表 / route ledger / registerService 调用点这些结构事实,404 只是与之一致而已。两者需要拍板的东西不一样,所以没有并进 #4448
#4318 的结论是"这三个槽位永远不会有 HTTP 面"(provider 是进程内契约),摘 route 是唯一正确解。这两条不同:
workflow:要先定 workflow 引擎还做不做。做 ⇒ route 声明保留、补 dispatcher 域(或 REST ledger 条目),让 declared === enforced;不做 ⇒ 连槽位一起退役(ADR-0115 Evidence 5 已经说了 no consumer,那就是往退役方向走的证据)。graphql:dispatcher 那行注释已经把结论写了 —— 不在产品计划里。倾向直接从SERVICE_CONFIG和CORE_SERVICE_PROVIDER里删掉,它连槽位都不是。把它们和 #4318 混在一条 PR 里,会让"没人挂 ⇒ 不声明"这条规则的适用依据变模糊(一个是永远不会有,一个是还没决定要不要有),所以单开。
关联
#4318(PR #4448)、#3898、#4089(#4114)、#4130(#4141)、#3891、#2462、ADR-0076 D12、ADR-0115 Evidence 5。
核对于
origin/main@ 5293114。