# 4-46 [process] Batch A FileTree Action / Trash Smoke Execution Checklist v1

> 创建时间：2026-05-21
>
> 上位入口：`design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md`
>
> 阶段：Batch A / P0 清验证阻塞
>
> 当前状态：`DONE`

## 1. 目标

把 `1-8` 中 Batch A 的四个入口文档拆成可执行小阶段，优先清除会干扰后续判断的 FileTree action、Open Editors lifecycle、Trash no-refresh 与 restore focus smoke 红灯。

本阶段不扩新产品面，不做大规模 tree command 重构；只修复或明确验证阻塞，并产出可复核 smoke 证据。

## 2. 上游入口

- `design/04-tree-domain/process/4-45-filetree-open-editors-lifecycle-link-checklist-v1.md`
- `design/04-tree-domain/process/4-44-filetree-action-layer-paste-drop-delete-v1.md`
- `design/04-tree-domain/process/4-34-filetree-trash-dual-browser-no-refresh-v1.md`
- `design/04-tree-domain/done/4-28-trash-restore-location-reveal-focus-v1.md`

## 3. 不做事项

- 不改变 delete 默认进入垃圾箱的语义。
- 不把 reload 型刷新伪装成 no-refresh。
- 不把浏览器环境准备失败标记为业务通过。
- 不提交 git；Reasonix worker 只能改文件并报告，最终由 Codex 复核提交。
- 不改 `design/old/**`。

## 4. Reasonix Worker 拆分

### Worker A：task430 Explorer / Open Editors 前置与断言

Owner：

- `scripts/task430-vscode-explorer-stage7-smoke.js`
- `design/04-tree-domain/process/4-45-filetree-open-editors-lifecycle-link-checklist-v1.md`

目标：

- 修复或明确 `task430` 的 workspace bootstrap 前置条件。
- 补 FileTree active row / Open Editors / lifecycle 相关断言，至少让 smoke 结果能区分“环境阻塞”和“业务回归”。
- 不修改 Rust 核心文件。

验收：

- `node --check scripts/task430-vscode-explorer-stage7-smoke.js`
- 能实跑则运行 `node scripts/task430-vscode-explorer-stage7-smoke.js` 并记录结果；不能实跑必须写明缺失服务或环境前置。

### Worker B：task471 local folder bulk resource trash

Owner：

- `scripts/task471-local-folder-bulk-resource-trash-smoke.js`
- `design/04-tree-domain/process/4-44-filetree-action-layer-paste-drop-delete-v1.md`

目标：

- 实跑或修复 `task471`，确认 local folder 多选资源 delete 走 archive tree command、资源进入 `.mnote/trash`、DOM action 状态可观测。
- 如果缺少 3000 服务或 auth 前置，必须记录为环境阻塞，不改业务语义。

验收：

- `node --check scripts/task471-local-folder-bulk-resource-trash-smoke.js`
- 能实跑则运行 `node scripts/task471-local-folder-bulk-resource-trash-smoke.js` 并记录 stdout / result。

### Worker C：4-34 / 4-28 local folder no-refresh 与 restore focus 缺口

Owner：

- `design/04-tree-domain/process/4-34-filetree-trash-dual-browser-no-refresh-v1.md`
- `design/04-tree-domain/process/4-28-trash-restore-location-reveal-focus-v1.md`
- 可新增或修改一个 `scripts/task47*-local-folder-*.js` smoke；如需改 Rust/SSR，先在最终报告中给建议，不直接改核心 Rust 文件。

目标：

- 盘点 local folder 非 md 资源 trash / restore / purge 的真实 UI 支持状态。
- 盘点 restore 后 DOM reveal / focus 的现有证据缺口。
- 如能小范围新增 browser smoke，则新增；否则更新 checklist，明确未完成能力与下一步。

验收：

- 新增脚本必须 `node --check` 通过。
- 若实跑浏览器 smoke，结果必须落到 `tmp/task47*/result.json` 或报告具体阻塞。

## 5. Codex 复核项

- [x] 逐个读取 Reasonix `final.md` / `result.json`。
- [x] 检查 `git diff`，确认 worker 没有越权修改。
- [x] 运行所有被修改脚本的 `node --check`。
- [x] 运行相关 Rust targeted tests（如 worker 修改 Rust）。
- [x] 对能实跑的 smoke 进行 Codex 独立复跑。
- [x] 更新本 checklist 的执行记录。

## 6. 浏览器测试阶段

Batch A 代码 / smoke 修复完成后，再拆分浏览器测试 worker：

- Browser Worker 1：实跑 `task430`，输出截图、控制台错误、result.json。
- Browser Worker 2：实跑 `task471`，输出截图、stdout、result.json。
- Browser Worker 3：实跑 local folder restore/no-refresh 相关 smoke 或人工步骤，输出截图和阻塞点。

Codex 必须复核浏览器测试结果；不能只相信 worker 文字总结。

## 7. 完成条件

- `task430` / `task471` 至少完成语法检查，且实跑结果为通过或有明确环境阻塞记录。
- `4-44` / `4-45` 的执行记录与真实 smoke 状态一致。
- `4-34` local folder 子项和 `4-28` restore focus 子项有明确证据：完成、未完成或环境阻塞，不能再是模糊 TODO。
- `git diff --check` 通过。
- `codegraph sync .` 已运行。
- 本阶段完成后由 Codex 提交 git。

## 8. 本轮执行记录

- 2026-05-21：Codex 建立 Batch A 小 checklist，并准备派发 Reasonix Worker A/B/C。
- 2026-05-21：Reasonix Coding Worker A/B/C 完成第一轮；Codex 读取 `.codex/reasonix-tasks/results/batch-a-worker-*.md` 并复核 diff。Worker A 修改 `task430` 与 `4-45`，Worker B 更新 `4-44`，Worker C 新增 `task473` 并更新 `4-34` / `4-28`。
- 2026-05-21：Codex 结束已完成的 Reasonix 残留进程，避免旧线程干扰后续 worker。
- 2026-05-21：Codex 独立运行：
  - `node --check scripts/task430-vscode-explorer-stage7-smoke.js`
  - `node --check scripts/task471-local-folder-bulk-resource-trash-smoke.js`
  - `node --check scripts/task473-local-folder-trash-restore-no-refresh-focus-gap-smoke.js`
  - `node scripts/task430-vscode-explorer-stage7-smoke.js`
  - `node scripts/task471-local-folder-bulk-resource-trash-smoke.js`
  - `node scripts/task473-local-folder-trash-restore-no-refresh-focus-gap-smoke.js`
- 2026-05-21：发现 `task473` 初版把 `file://` rootUri 再次传给 `trashUrl()`，导致 `/trash?rootUri=file://file://...` 等不到 local-folder workbench；已修为传入本地 root path。
- 2026-05-21：发现 `task473` 初版把 `data-active="false"` / `data-selected="false"` 当作 focus 证据；已修为只有值为 `"true"` 或明确 active/selected/focused class 才算 focus。修正后 `task473` 仍 `ok:true`，但步骤 9 正确记录为 `ok:false` 的已知缺口。
- 2026-05-21：派发 Reasonix Browser Worker 1/2/3：
  - `task430` 输出 `tmp/reasonix-batch-a-browser-task430-2026-05-21/`，结论 `PASS_WITH_KNOWN_GAPS`。
  - `task471` 输出 `tmp/reasonix-batch-a-browser-task471-2026-05-21/`，结论 `PASS`。
  - `task473` 输出 `tmp/reasonix-batch-a-browser-task473-2026-05-21/`，结论 `PASS_WITH_KNOWN_GAP`。
- 2026-05-21：Codex 复核 Reasonix 截图和 JSON：task471 的多选删除截图与 DOM / trash index 断言一致；task430/task473 截图只作为浏览器可打开佐证，最终状态以 smoke `result.json` 为准。
- 2026-05-28：Batch A2 / Worker C — 修改 task473 完成条件为要求 `hasFocusEvidence===true`，使 focus gap 从"记录缺口但 ok:true"变为"记录缺口且 ok:false（直至 focus 修复）"；更新 4-34 覆盖矩阵将非 md 资源行从"待定"写实为 task435/437/464/473 分项覆盖并标注 focus gap open；更新 4-34 审计结论、边界描述和完成标准以反映实际 smoke 覆盖；追加本执行记录。本轮目标：关闭 task473 的 focus gap 作为可检测的回归测试。
- 2026-05-21/22：Codex 接手 Batch A2 / Worker B 卡住项，修复 local folder restore 后 filetree focus/reveal：trash workbench restore 写入 pending row-id，filetree 初始加载与 polling 刷新通过 `schedulePendingLocalFolderRestoreFocus()` 重放聚焦；`task473` 在临时 3012 新进程上实跑通过，`focusAfterRestore.attrs.data-active="true"`。`4-28` 已满足归档条件并移动到 `done/`；`4-34` 仍保留在 `process/`，因为 local folder empty-trash / Markdown trash lifecycle 仍未完整覆盖。
- 2026-05-21：Batch A3 收口。Reasonix Worker A/B 新增 `task474-local-folder-empty-trash-ui-smoke.js` 与 `task475-local-folder-markdown-trash-lifecycle-smoke.js`；Codex 在最新临时 `mnote-web` `http://127.0.0.1:3014` 上复跑两条 smoke 均通过。Reasonix Browser Worker 输出 `tmp/reasonix-batch-a3-browser-task474-empty-trash-2026-05-21/`，截图显示 local folder trash 清空后页面/资源均为 0。`4-34` 与本执行总 checklist 满足归档条件，移动到 `done/`。
