Skip to content

check:init-service-contract 只认 getService,不认 getServiceAsync —— #4772 就是从这个洞里溜过去的 #4835

Description

@xuyushun441-sys

#4777 建门禁时顺带发现,不在该 issue 范围内,按 Prime Directive #10 单独记录。

发现

scripts/check-init-service-contract.mjs(#4471 / ADR-0116 的声明覆盖门禁)只匹配一个 callee:

// scripts/check-init-service-contract.mjs
if (ts.isPropertyAccessExpression(callee) && callee.name.text === 'getService') {

而 kernel 的服务解析有两个入口 —— getServicegetServiceAsync
(packages/core/src/kernel.ts:505)。两者的排序风险完全相同:插件 init() 的执行顺序
决定能不能解析到,ADR-0116 的 dependencies / optionalDependencies / requiresServices
对两者一视同仁地生效。但门禁只看得见前者。

这不是理论问题 —— #4772 正是这么溜过去的

AuthPlugin.init() 里(修复前,f2eb85007^):

cache = await (ctx as { getServiceAsync?: (n: string) => Promise< unknown > }).getServiceAsync?.('cache');

当前是否已经红?

否。今天 packages/** 里的 getServiceAsync 调用点(rest/src/rest-server.ts
runtime/src/http-dispatcher.tsruntime/src/dispatcher-plugin.ts)都在请求期路径上,
不在任何插件的 init() 里 —— 所以这是一个潜伏的洞,不是现存的红。
补上词表大概率仍然是绿的,应该顺手做掉。

建议

getServiceAsync(以及 hasService 之类真正读注册表的入口,如果确认存在)加进该脚本的
lookup 词表,并补一条 self-test:init() 里未声明的 getServiceAsync('X') 必须判红。
需要顺带核对 --list 的边名输出(现在硬编码写作 getService('X'))。

为什么不在 #4777 里一并做

#4777 建立的是另一条规则(「读注册表可以,记账不行」),两条门禁互补:
#4471 说「你得声明」,#4777 说「你没声明就不许记账」。#4471 的词表是它自己的
scope,而且改动会波及一条与本次派发不同的判定语义,单独一 PR 更干净。

发现于:PR #4833(#4777)。

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions