Skip to content

[REQ-223][CODE] 修正 E7 探针四条判据的观测点 —— 三条假红加一条空绿 #651

Description

@jinjunnn

父需求:#223。发现出处:#643 登录态取证(打包版 alpha@e578e00ae),
docs/verification/2026-07-27-e7-packaged-live/results/logged-in-20260728T020545Z.json

四条红/绿里,三红一绿是判据本身下错了观测点,与被测系统无关。四条都在
docs/verification/2026-07-27-e7-packaged-live/probe.ts

① P1.2 假红 —— 判据断在"变量替换之后"的视图上

判据(probe.ts:572:576)要求
config.mcp.cloud.headers.Authorization 形如 Bearer {file:…ALPHA_CLOUD_TOKEN},
但它读的是引擎 GET /config,而引擎在加载时就把 {file:…} 解析掉了
(packages/opencode/src/config/variable.ts:33-61,packages/opencode/src/config/config.ts:220)。
该判据在这个观测点不可满足

不是脱敏造成的:assertCheck 先用原值算 ok(probe.ts:575-576),
redact() 只作用在 observed 上(probe.ts:98)。

也不是真内联 —— 三条独立实证:

  1. 注入面写的是 file ref:packages/ui-mac/src/main/cloud-sidecar-config.ts:6
    headers: { Authorization: \Bearer ${secretRef}` },secretRef来自packages/ui-mac/src/main/alpha-secret-files.ts:49-51({file:}), 锁在 packages/ui-mac/src/main/alpha-config-injection.test.ts:363`;
  2. 磁盘上没有任何配置文件带 Authorization 头(扫过整个
    ~/Library/Application Support/ai.opencode.desktop.dev,零命中;云 MCP 定义只经
    OPENCODE_CONFIG_CONTENTALPHA_CLOUD_MCP_DEF 过河);
  3. 2026-07-28 对同一运行中引擎只读复测:/config 里该头
    === "Bearer " + <ALPHA_CLOUD_TOKEN 文件内容>,即恰好是替换后的值;
    密钥文件本体是 0600、目录 0700

要断的性质在源侧,不在 /config:应断 process.env.OPENCODE_CONFIG_CONTENT
(或磁盘配置)里的 Authorization 是 {file:} 形态,再另断 /config 侧 URL 正确。

② P1.5 假红 —— 断了实现机制,没断可观察结果

判据(probe.ts:621)要求每个 config.agent[*].permission.websearch === "deny"
applyWebSearchDenies 只遍历 alpha 自己注入的那个 config 对象
(packages/ui-mac/src/main/cloud-web-search.ts:167
for (const agent of Object.values(config.agent ?? {}))),
上游原生 general/explore 不在其中,所以这两个键必然缺 —— 但结果是对的

2026-07-28 对同一运行中引擎只读复测(GET /agent,按 Permission.evaluate
findLast 语义算有效判决,packages/opencode/src/permission/index.ts:204-213):

build deny · alpha-automation deny · alpha-automation-standard deny · alpha-readonly deny
compaction deny · explore deny · general deny · plan deny · summary deny · title deny

十个 agent 全 deny。explore 上游确实硬写了 websearch: "allow"
(packages/opencode/src/agent/agent.ts:~200,实测落在规则表第 37 位),
但 alpha 的全局 deny 作为 Permission.merge(defaults, <内置>, user)user 段排在最后
(实测第 61 位)并因此获胜。纵深还有一层:活的 sidecar(pid 实测)带
ALPHA_LOCAL_WEBSEARCH_DENY=1,两条 keyless 出网传输的第一句都读它
(packages/core/src/tool/websearch.ts:37-44packages/opencode/src/tool/mcp-websearch.ts:63-70)。

应断的是有效判决:对 GET /agent 每个 agent 用 findLastwebsearch 的有效
action,要求全 deny。顺带把真正的残余口子写进判据:非 alpha 源定义的用户自有 agent
(其 permissionmerge(item.permission, fromConfig(...)) 里排在全局之后)才是能顶掉
全局 deny 的那一类,现闸确实够不着——那才值得断言。

③ P3.8 假红 —— 与 P1.7 自相矛盾,构造上不可满足

P3.8(probe.ts:944-956)要 platform-pays 下调本地 websearch 并拿到可辨 tool error;
P1.7(同一次运行,pass)断的正是"平台模型的工具表不含 websearch"。
探针传的 tools: { websearch: true } 救不回来:
packages/opencode/src/session/llm/request.ts:208-213resolveTools
用户 map 只能工具(input.user.tools?.[k] !== false),
Permission.disabled 的过滤无条件生效。所以模型根本没被提供该工具,
toolPartsSeen: []判据的必然结果,note 里那句"re-run"是误判 —— 重跑一万次也一样。

改法:要么把 P3.8 降为"该工具不在模型工具表内"(= P1.7,不必重复),
把"拒绝文案可辨"留给已有的 L1(packages/opencode/test/tool/alpha-websearch-failure.test.ts);
要么找一条绕过 permission 过滤的引擎入口直调工具再断言 —— 二选一,别留一条永红的必需项。

④ P1.3 是空绿 —— tools/list 根本不鉴权

P1.3 自称 "deployed cloud worker lists a web-search tool for this account"
(probe.ts:588),但 alpha-cloud/mcp 传输层没有任何鉴权
(alpha-platform packages/gateway/src/cloud.ts:85-100,鉴权只在每个 tool 回调里),
任意 bearer(含无效的)都能列全 8 个工具。这条判据证明不了任何账户相关的事,
"同一 bearer 能 list 却不能 call"也因此不是矛盾。已按真因在 alpha-platform 开票。

负责哪些 AC

不负责 #223 的任何 AC —— 这是 #643 取证工具本身的修复,修完 #643 才能被判。

边界

docs/verification/2026-07-27-e7-packaged-live/probe.ts 与同目录 README 的判据表。

out-of-scope

不动 results/ 下任何已产出的证据(缺陷发现时的原始记录);不改产品代码;
不重跑登录态取证(需 owner 环境)。

退出条件

四条判据各自改到"能被满足且能失败":P1.2 断源侧、P1.5 断有效判决、P3.8 二选一收敛、
P1.3 补一条真的与账户绑定的判据(或如实降级措辞);
每条改完先自己实施一遍绕过确认判据能变红。

Metadata

Metadata

Assignees

Labels

prio:P2Planned normal-priority worktype:bugSomething is incorrect or regressed

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions