# MD-EDC-06-FIX-02 日期:2026-07-11 项目:Mindraw 计划:`P-20260707-signed-notarized-dmg` 任务:`MD-EDC-06-FIX-02` ## 用户目标 用户询问此前 `BLOCKED MD-EDC-06-FIX-02 当前会话无目标 worktree 写权限` 应如何解决、是否需要用户操作。当前会话实际具备 unrestricted filesystem 权限,因此不再需要用户切换项目或新建任务;直接继续在目标 worktree 完成修复、验证和 PMO 交接。 ## 已完成事项 - 在 `/Users/ar/Projects/Mindraw-worktrees/md-main-better-exp1` / branch `codex/md-main-better-exp1` 处理 `QA-EDC-06-EXEC=FAIL` 的并发新建 blocker。 - 按 systematic debugging 先补红灯回归,再修复: - 前端 listener lifecycle / 单事件单调用回归。 - store 快速连续新建 in-flight 串行化回归。 - Rust 并发 `.mindraw` package 创建回归。 - Rust 创建失败无可见半成品 / temp 回归。 - 完成前端和后端最小修复: - `useMenuHandler` 单次注册 menu listener,并处理异步 `listen()` resolve 后 cleanup 的 orphan handler。 - `createNewFile()` 增加 promise queue,防止多个后端 `create_new_file` 并发进入。 - `.mindraw` package 采用 sibling temp package 完整写入后 atomic rename,失败只清理本次 temp。 - 形成新 Review Gate:`crg-8bc44622de6f`。 - 输出 review-ready evidence:`/Users/ar/Projects/Mindraw/02-P/MEXP15-SignedNotarizedDMG/review/md-edc-06-fix-02-review-ready-crg-8bc44622de6f.md`。 - 回写统一台账:`/Users/ar/Projects/Mindraw/02-P/plan-progress.markdown`。 - 回写 PMO inbox:`/Users/ar/Projects/Mindraw/02-P/PMO_INBOX.md`。 ## 核心事实 / 变更快照 变更对象:`MD-EDC-06` 新建 `.mindraw` 默认行为的并发安全与失败原子性。 事实来源: - Worktree:`/Users/ar/Projects/Mindraw-worktrees/md-main-better-exp1` - Branch:`codex/md-main-better-exp1` - HEAD / base:`0e329860f39577bdc0ab8236f5bf442fc163a22b` - Evidence:`/Users/ar/Projects/Mindraw/02-P/MEXP15-SignedNotarizedDMG/review/md-edc-06-fix-02-review-ready-crg-8bc44622de6f.md` 变更前: - 真实 App GUI 下,单次 `New Mindraw Document` 可能被多个活跃 menu listener 消费。 - 多个 `create_new_file` 可同时进入后端,竞争同一 `YY.MMDD-NN.mindraw` 路径。 - 后端直接在最终 `.mindraw` package 路径写入,失败可能留下缺 `.assets/` 的可见半成品。 变更后: - `useMenuHandler` listener effect 单次注册;异步注册完成时若组件已 cleanup,立即执行 unlisten。 - `createNewFile()` 串行化,保留多次用户动作但不让后端 package 创建并发进入同一路径选择。 - 后端 `.mindraw` package 创建先创建隐藏 sibling temp package,完整写入 `.assets/`、`drawing.excalidraw`、`manifest.json`,再 rename 到最终路径;并发冲突重试唯一命名;失败只清理本次 temp。 范围边界: - 未修改 m4c plugin。 - 未合并、提交、推送、打 DMG。 - 未启动或声称 `QA-EDC-06-EXEC` PASS。 - `CODEGRAPH.md` / `INDEX.md` / `CHANGELOG.md` 未在隔离 worktree 中伪造补建;主线 integration 时仍需同步主线治理文档或 release note 归属。 ## 文件变更 目标 worktree 当前 changed files: - `src/lib/newDocument.ts` - `src/lib/newDocument.test.ts` - `src/types/index.ts` - `src/store/useStore.ts` - `src/store/useStore.test.ts` - `src/hooks/useKeyboardShortcuts.ts` - `src/hooks/useMenuHandler.ts` - `src/hooks/useMenuHandler.test.tsx` - `src/components/Sidebar.tsx` - `src/components/TreeView.tsx` - `src/components/ExcalidrawEditor.tsx` - `src-tauri/src/lib.rs` - `src-tauri/src/menu.rs` 主项目治理 / 证据变更: - `02-P/MEXP15-SignedNotarizedDMG/review/md-edc-06-fix-02-review-ready-crg-8bc44622de6f.md` - `02-P/plan-progress.markdown` - `02-P/PMO_INBOX.md` - `.codex-sessionhistory/2026-07-11-MD-EDC-06-FIX-02.md` - `.codex-sessionhistory/COMMANDS.md` ## 验证结论 - 修复前红灯: - `npm run test:run -- src/hooks/useMenuHandler.test.tsx src/store/useStore.test.ts` 复现重复 listener / 并发 create。 - `cargo test --manifest-path src-tauri/Cargo.toml concurrent_mindraw_package_creation_allocates_unique_complete_packages` 复现 `File exists (os error 17)`。 - 修复后绿灯: - targeted frontend tests PASS。 - `src/lib/newDocument.test.ts` PASS。 - full `npm run test:run` PASS,4 files / 14 tests。 - `npm run build` PASS,仅既有 warning。 - `cargo check` PASS。 - targeted/full Rust tests PASS,11 tests。 - `git diff --check` PASS。 - 敏感信息扫描无命中。 ## 可复用命令 / Runbook 用途:复跑 `MD-EDC-06-FIX-02` 并发新建修复的前端 / Rust / build / diff / sensitive scan 验证。 前置条件: - 当前目录切到目标 worktree:`/Users/ar/Projects/Mindraw-worktrees/md-main-better-exp1` - Branch 应为:`codex/md-main-better-exp1` - 不需要打 DMG,不需要启动 QA,不修改 m4c plugin。 设置与验证命令: ```bash cd /Users/ar/Projects/Mindraw-worktrees/md-main-better-exp1 git branch --show-current git rev-parse HEAD git status --short --branch --untracked-files=all npm run test:run -- src/hooks/useMenuHandler.test.tsx src/store/useStore.test.ts npm run test:run -- src/lib/newDocument.test.ts npm run test:run npm run build cargo check --manifest-path src-tauri/Cargo.toml cargo test --manifest-path src-tauri/Cargo.toml mindraw_new_document_tests cargo test --manifest-path src-tauri/Cargo.toml git diff --check git diff -- src src-tauri | rg -n "(SECRET|TOKEN|PASSWORD|PRIVATE_KEY|BEGIN RSA|AWS_|AKIA|sk-|xoxb-|ghp_|-----BEGIN)" ``` 敏感扫描命令预期:无输出,`rg` 可返回 exit 1,表示未命中。 Review Gate 指纹复算命令: ```bash cd /Users/ar/Projects/Mindraw-worktrees/md-main-better-exp1 { git diff -- src src-tauri; git diff --no-index -- /dev/null src/hooks/useMenuHandler.test.tsx 2>/dev/null || true; git diff --no-index -- /dev/null src/lib/newDocument.ts 2>/dev/null || true; git diff --no-index -- /dev/null src/lib/newDocument.test.ts 2>/dev/null || true; git diff --no-index -- /dev/null src/store/useStore.test.ts 2>/dev/null || true; } | shasum -a 256 | awk '{print substr($1,1,12)}' ``` 预期输出:`8bc44622de6f`,对应 Review Gate `crg-8bc44622de6f`。 清理 / 恢复: - 本 runbook 不创建发布产物。 - 若测试在 `/tmp` 下创建临时目录,Rust tests 会自行清理。 - 不执行 `git reset`、不删除 worktree、不清理用户未提交变更。 搜索关键词:`MD-EDC-06-FIX-02`、`crg-8bc44622de6f`、`File exists os error 17`、`Directory not empty os error 66`、`useMenuHandler listener`、`createNewFileQueue`、`atomic package rename` ## 未决问题 / 后续建议 - PMO 下一步应消费终态并派 `REVIEW-EDC-06` 复审新 gate `crg-8bc44622de6f`。 - 代码复审 PASS 后,PMO 再派完整 `QA-EDC-06-EXEC`;本轮不能作为 QA PASS。 - 主线 integration 前仍需处理 `CODEGRAPH.md` / `INDEX.md` / `CHANGELOG.md` 或 release note 归属。