Skip to content

[REQ-128][VERIFY] 打包版真机 L2:本地插件包导入八步端到端取证 - #794

Merged
jinjunnn merged 2 commits into
alphafrom
verify/783-packaged-l2
Aug 2, 2026
Merged

[REQ-128][VERIFY] 打包版真机 L2:本地插件包导入八步端到端取证#794
jinjunnn merged 2 commits into
alphafrom
verify/783-packaged-l2

Conversation

@jinjunnn

@jinjunnn jinjunnn commented Aug 2, 2026

Copy link
Copy Markdown
Owner

大白话

#783 的最后一件事做完:在真的打包出来的 mac 应用里,把「导入一个本地 Claude 插件包 →
装 10 个技能 → 显示未启用 → 用户拨开关 → 下一条消息里真能用 → 整包移除」这条路从头走了一遍,
把看到的东西原样记下来。方案基线 §12 的风险 5「零真机证据」到此为止。

只加了一份证据文档和六张截图,没有改任何生产代码。

被测件

  • 9996d2c9(origin/alpha,工作树干净)打出的 packages/ui-mac/dist/mac-arm64/alpha-code.app
  • com.tide.alphacode.dev / 0.1.2 / 构建于 2026-08-02 10:11:45 EDT / Electron 42.3.3 / electron-builder 26.15.2
  • Developer ID 签名并 codesign --verify --deep --strict 通过;app.isPackaged=true
  • 语料 ~/.claude/plugins/marketplaces/tide-plugin(本轮亲测:10 skills + 9 commands + 1 agent + .mcp.json)

第 7 步用的是什么判据

R1 的 Blocker 是「读引擎会读的那个文件 ≠ 跑引擎的读」,所以本轮不查账本、不查 skills-enabled.json

判据 = 运行中引擎的 GET /skill(OpenAPI app.skills)。它由 packages/opencode/src/skill/index.ts
Skill.Service 服务,而 session/system.ts:98-110SystemPrompt.skills 调的是同一个 service
available() —— 即下一条消息系统提示里 <available_skills> 的那一个集合。

时点 /skill 数量 tide 技能
装之前 20
装完 10 个、全部 disabled 20 ← 裁决 B 在引擎侧为真
拨开一个开关 21 仅那一个
整包移除后 20

全程未重启应用、未重启 sidecar。另补一次真实模型回合:正向出现「技能 chain-analysis 已加载」;
负向由引擎自己吐出 Skill "tide-intro" not found. Available skills: … chain-analysis … ——
含被拨开的那个、不含同一个包里其余九个。

如实记下的三处没做到 + 一处口径修正

  1. 原生 NSOpenPanel 没有由真人点击。取证窗口内本机屏幕处于锁定态
    (CGSSessionScreenIsLocked=true),锁屏下 screencapture 只给壁纸、System Events 对所有进程报 0 windows。
    改用生产代码里既有的 main 侧短路 ALPHA_OPEN_DIR;被替换的只有 picker 的返回值,#255 的安全性质不受影响。
  2. 界面经 CDP 驱动(本仓既有口子 ALPHA_CDP=1,与 2026-07-27-e7-packaged-live/ 同款),
    未覆盖真实鼠标/键盘/无障碍输入面。
  3. 「拨开关 → 紧接着发消息」的完全连续链路本轮没一次性跑通,中间有一次 renderer reload
    (原因见下方第 8 节的 composer 门)。未经 reload 的那一半由 GET /skill 覆盖。
  4. 口径修正:整包移除后插件正文仍在 CAS 里。账本 / ext-store / 引擎三面逐字干净,
    cas/v1/sha256 下 10 个 blob(那 10 份 SKILL.md 正文,52K)仍在,
    ext-cas-gc.ts:34CAS_GC_GRACE_MS_DEFAULT = 6 小时定时 GC 才清。
    这是既有设计(#194)的后果不是本期缺陷,但「移除无残留」在用户口径上是有条件的,建议 owner 判是否要在文案上说明。

顺带记下的打包坑(下一个人会踩)

  • electron-builder 26.xidentity: null 不做 ad-hoc 签名,只是跳过签名 ⇒ 产物 Killed: 9
    零日志零窗口。配置里的注释「null => ad-hoc sign」与 26.15.2 的实际行为不符。
    只跑 package:mac 不跑 install:local 的人必踩。
  • 本机 DNS 对 models.dev 被污染 ⇒ prebuild 直接挂;用 MODELS_DEV_API_JSON(generate.ts 自带入口)绕开。
  • scripts/worktree-link-deps.sh 不链 node_modules/.bin(glob 不含点开头条目)⇒ worktree 里
    electron-vite/electron-builder/tsgocommand not found。跑 bun 的门没暴露过它。
  • 锁屏会让 GUI 取证手段静默失效;判据是 ioreg | grep -a CGSSessionScreenIsLocked,先判它再判 UI。

与本期无关、建议单开票的一条

sidecar 因 token 轮换 respawn 之后,composer 的模型预检认为「本次引擎启动没有加载这个模型」,
直到 renderer 重载才恢复
(平台模型与 BYOK 都被拦,而引擎 /config/providers 同一时刻列得出 10 个模型)。
已排除 G20 的 refreshEngine():reload 后跑完一次完整安装(必走 refreshEngine)再发消息仍然成功。
这是相关性不是隔离出的因果,建议按 REQ-109/110 的 token 轮换面单独查。

文档影响

docs/verification/ 新增一份记录 + docs/verification/assets/ 六张截图。
未改 CHANGELOG(本 PR 无用户可见变更;功能本身的条目已随 #791 落地)。
未改方案基线 —— §12 风险 5 的收口指针是否要写回基线,留给编排者裁。

Fixes #783
Refs #784

jinjunnn and others added 2 commits August 2, 2026 12:07
#783 AC⑤ 的真机半场。被测件 = 从 `9996d2c9` 打出的 `alpha-code.app`
(Developer ID 签名、`app.isPackaged=true`),八步在打包产物上逐步实跑。

第 7 步的判据**不查账本、不查 `skills-enabled.json`**,取运行中引擎自己的
`GET /skill`(`app.skills`)—— 它由 `Skill.Service` 直接服务,而
`SystemPrompt.skills` 调的是同一个 service 的 `available()`,
即「下一条消息系统提示里的那一个集合」。实测 20 →(装完 10 个全 disabled)
20 →(拨开一个开关)21 且只多出那一个 →(整包移除)20,全程未重启。
另补一次真实模型回合:正向「技能已加载」,负向由引擎自己吐出
`Skill "tide-intro" not found. Available skills: …` —— 含被拨开的那个、
不含同包其余九个。

如实记下三处**没做到**与一处口径修正:
- 原生 NSOpenPanel 未由真人点击(屏幕锁定,改用生产短路 `ALPHA_OPEN_DIR`);
- 界面经 CDP 驱动,未覆盖真实鼠标/键盘输入面;
- 「拨开关→紧接着发消息」的完全连续链路本轮没一次性跑通(中间有一次 renderer reload);
- **整包移除后插件正文仍在 CAS 里最长 6 小时**(`ext-cas-gc.ts:34`),
  「无残留」在账本/ext-store/引擎三面成立,在 CAS 面不成立。

顺带记了四个打包坑(其中 `identity:null` 不做 ad-hoc 签名 ⇒ 静默 SIGKILL,
和 `worktree-link-deps.sh` 不链 `.bin`,都会让下一个人白跑一轮),
以及一条与本期无关的 composer 门(sidecar token 轮换后模型预检失效)。

Fixes #783
Refs #784
原稿写「GET /skill 返回的集合就是系统提示里 <available_skills> 的集合」,比事实强一格。
实读 skill/index.ts:301-315:all() 与 available(agent) 读同一份 InstanceState 的 state.skills,
差别是 available 在传 agent 时多按 Permission.evaluate 过滤 deny;本次无 deny 规则故两者重合。

残余那一格由真实模型回合闭合(引擎自报 Skill.NotFoundError.available,不经 /skill),
该条与计数证据同等承重。§6 另补一条未覆盖:agent 权限过滤分支恒不触发,
「本次没有反例」不等于「验过了」。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REQ-128][VERIFY][cap:extension-package-ingestion] 本地导入矩阵:真实语料 + 敌意夹具 + 每道闸的绕过记录 + 真机 L2

1 participant