Files
ycode/docs/协作/B03-交付-01.md
T

101 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# B03 交付 01:完全访问预授权与底部授权替换
日期:2026-10-21(Asia/Shanghai)。状态:**已实现;Linux 实际内核/SDK 回环及离线交互验证通过;Windows/客户端重启等剩余项目待验收**,不宣称所有 AC 全量通过。
- 需求:[B03-需求](B03-需求.md),YC-007。
- 开发基线:`0bc9faa1292c4223a61608e72ba3cd13d572252b`。
- **受测代码 SHA:`adbbb3bd37f6043d10cbaa59d6c28ade6387a7f3`**。
- B01/B02 及测试清理保持原结论;未启动、修改或中断用户正在运行的会话,未访问原版 WorkBuddy。
## 1. 后端实现
SDK 实装版本为 `@anthropic-ai/claude-agent-sdk@0.3.304`。采用**SDK default + 宿主显式预授权 gate**,不是把 acceptEdits 误称完全访问,也不启用进程级 bypassPermissions 能力:
- craft 且用户选择 full-access:PreToolUse 对普通工具预授权 allow;若 SDK 仍转 callback(包括真实 matchedAskRule),callback 同样按有效宿主权限直接 allow,不发人工审批。
- 默认权限继续使用 SDK 实际判定并进入审批,真实规则匹配仍标记 rule-intercept。
- plan 使用 SDK plan,ask 使用 default;两者均先经过宿主只读模式边界,full-access 偏好不使其变为 craft。
- AskUserQuestion 通过 hook ask 保留业务追问回调;ExitPlanMode 保留计划内容展示/拒绝执行分支,不当成普通审批静默放行。
- 不自动保存全工具 allow 规则,不模拟点击允许,不修改用户全局设置。已有“本次会话始终允许”的 grant 逻辑仍单独存在。
- 策略切换串行化;切换中阻断执行,过期审批不能应用。SDK 控制失败时关闭不一致进程并锁定失败状态,明确重试 setPolicy 成功后才能恢复/重建。
新增白名单脱敏诊断 `[claude-permission]`:宿主权限、agentMode、配置/控制确认的 SDK 模式、分支、匹配 ask-rule 的布尔值、安全分类/未知、原因码是否存在,以及哈希 toolCall 关联。**不保存参数、命令、路径、环境、规则内容或凭据**。SDK mode 字段带来源说明,不是独立 CLI 内部状态探测;原生 EnterPlanMode 自主切换的完整行为未额外验收。
SDK `.d.ts` 没有声明的 decisionReasonType/Code 在 `sdk.mjs` 的 wire 转换确有映射;未知/未提供值记录 unknown,不据此反推原始用户七条请求的确切原因。
## 2. 前端实现
活动工具审批使用 `approvalSlot` 独占底部输入区域,不再挂在完整普通输入框上方。
- 普通输入保持挂载以保存草稿/附件/引用/队列,但 hidden、inert、disabled,不能接受焦点、键盘、拖放或发送;普通发送工具栏移除。
- 业务追问仍是独立的 question 流程,不与工具审批混同。
- 允许、拒绝、失败/重试、取消及会话切换后恢复输入状态;审批响应和停止操作校验捕获的 session/runId。
- 取消失败明确展示错误;取消面板按请求标识隔离,旧请求的迟到结果不能污染新审批。
- 复用现有 Composer/PermissionConfirm 与回归脚本,不另造一套授权业务组件;不恢复已撤回骨架补丁。
## 3. 实际内核 + SDK 证据
[结果 JSON](evidence/B03-delivery-01/real-kernel-results.json)、[脱敏日志](evidence/B03-delivery-01/real-kernel-loopback.txt)。
实际生产 `ClaudeKernel` 打包后仅替换 Electron 的 userData 路径,**SDK query 没有 mock**。真实 Linux CLI 对接固定 SSE 回环模型;临时 HOME/config/userData/workspace,清空环境继承,不使用用户供应商或真实凭据。25 个本地请求、9 个场景全部按预期通过:
| 场景 | 人工审批 | 实际结果 |
| --- | ---: | --- |
| default craft | 1 | 夹具拒绝 Write,目标未创建 |
| 切为 full craft | 0 | Read/Edit/Write、简单及复合 Bash 成功;文件内容正确;新建后删除的目录/文件不存在,完成标记正确;业务追问 1 次 |
| 切为 plan | 0 | Write 被模式边界拒绝,无目标文件 |
| 切为 ask | 0 | Write 被模式边界拒绝,无目标文件 |
| 返回 default craft | 1 | 再次询问并按夹具拒绝 |
| full craft + 真实 SDK ask:Bash 规则 | 0 | 实际 callback matchedAskRule=true,仍按 full-access 直接执行成功 |
| default + 同一 Bash/规则 | 1 | 真正 rule-approval,夹具拒绝,文件保持不变 |
| 销毁重建并传入 full 偏好 | 0 | Write 与业务追问成功,追问 1 次 |
| full 下不存在目标 Edit、Bash exit 7 | 0 | 2 次真实工具错误,不重新弹权限卡 |
ask:Bash 仅通过真实 Query 的 session-only `applyFlagSettings` 配置在测试进程中,不写用户设置。真实 SDK/文件检查支持此 gate 选择,而不仅是合成 callback 元数据测试。
脚本限制 Linux Bash;Windows/PowerShell 不具备环境时明确阻塞。内部有请求上限、100 秒 abort,执行时另加 120 秒外层截止;结束关闭 query/server 并清理临时目录。没有修改网络或 OS 安全设置;未单独审计 CLI 的所有潜在非模型出站尝试。
## 4. 其余回归
[离线与构建日志](evidence/B03-delivery-01/verification.txt):
- `npm test`:退出 0,类型/消息/会话存储/持久化/会话渲染。
- `test:alignment:dom`(指定现成 jsdom 路径):退出 0,offline 11 套、DOM 7 套;其中 B03 actual-kernel/mock-query policy **276 项**、实际 Composer/PermissionConfirm jsdom **43 项**。
- `test:reporting`、`test:composer-capabilities`、`test:tool-approvals`:退出 0。
- `npm run build`:退出 0,含类型检查。
- `check:tokens`:退出 1,保留相同六项既存失败及计数,没有新增漂移、没有改 baseline。
- 独立复审重跑 276/43 项,无剩余阻塞性发现;审查发现的取消错误不可见问题已修复。
- ChatPane 保留基线 CRLF,采用 `git -c core.whitespace=cr-at-eol diff --check` 通过,不为格式统一改写整文件。
## 5. AC 状态与未验证项
| AC | 本轮证据与剩余范围 |
| --- | --- |
| 7.1 | Linux 原生读写/编辑、新增/删除临时对象、简单/复合 Bash 实际 0 审批;Windows PowerShell、原生独立目录工具及全部后续轮次组合待验 |
| 7.2 | 实际 kernel/SDK default + host gate;真实 ask-rule 下 full 0/default 1;classifier/别名/未知字段由 276 项离线矩阵验证 |
| 7.3 | 实际 default、plan、ask、业务追问和执行错误对照通过;ExitPlanMode 为离线验证,文件系统权限拒绝未实测 |
| 7.4 | 检查实装 SDK 类型与 wire 映射;未知字段策略离线验证,原用户 callback 的具体字段仍无法追溯 |
| 7.5 | 实际同内核切换/返回及销毁重建通过;策略失败闭锁与串行 race 离线通过;客户端重启后持久偏好加载、真实首发 UI 全链仍待 Windows 验收 |
| 7.6 | full 自动执行不写 grants;已有 grant policy/replay 离线通过。真实 SDK session-grant 生命周期尚未完整验证,不把本轮自动预授权测试替代它 |
| 7.7 | 已加入最小脱敏分支记录,真实日志有 matchedAskRule 与宿主决策证据;未知原因码明确 unknown |
| 7.8 | 底部替换由实际组件 DOM/CSS 层叠检查通过;没有取得 Windows 同状态截图或原版像素结果 |
| 7.9 | 43 项覆盖允许/拒绝/失败重试/取消、旧取消迟到、隐藏焦点/发送、真实附件 stage 返回、草稿/引用/队列及请求切换;真实窗口 IME/屏幕阅读器和全应用会话切换仍待验 |
因此本交付是已实现并取得部分真实 SDK 证据,**不是整个 B03 全量验收通过**。未通过项不得被核心测试或构建绿灯替代。
## 6. 复跑与交接
按固定代码 SHA 独立安装构建,Windows 应用使用全新 `YCODE_USER_DATA_DIR`,不得操作正在运行的用户会话;dev 启动遵循 Dev 启动 SOP。当前包含 main 代码变更,验收实例应重新启动自己的构建,不复用旧 renderer。
```sh
npm ci --legacy-peer-deps
npm test
YCODE_TEST_DOM_MODULE=/absolute/path/to/jsdom npm run test:alignment:dom
npm run build
# 仅 Linux,有真实 SDK CLI 与本地回环权限,执行前阅读脚本:
timeout --signal=TERM --kill-after=5s 120s npm run test:permissions:loopback
```
PowerShell 的 DOM 环境变量用 `$env:YCODE_TEST_DOM_MODULE = <路径>`。Windows 验收须另补四类操作/PowerShell、底部授权替换截图、失败恢复及持久偏好重启矩阵。
远端推送并核对 SHA 后才算 Git 交接完成。交付后窗口交回验收端,保留旧需求与历史失败记录。