unit_matrix.json 39.7 KB
{
  "meta": {
    "project": "graphlemon",
    "version": "v1.1",
    "generated_from": "docs/development-plan.md",
    "source_sdd_version": "v1.6.0",
    "methodology": "project-unit-decomposition + engineering-work-planning (local Hermes planning profile)",
    "date": "2026-07-29",
    "revisions": [
      {"date": "2026-07-30", "note": "计划评审追加 U-004.5(RUN_REAL_AGENT_E2E harness 归属)与 U-024.5(U-024 依赖分级后的 REQ-12 完整验收);U-024 依赖从 U-009~U-021 收窄为 U-012/U-013;U-035 done 标准追加 REQ-03 回归要求"},
      {"date": "2026-07-31", "note": "(2026-08-04 补记)development-plan.md 同批订正/补充:U-002 引用订正(架构文档 §7.3→§13.2);U-009/U-011/U-012/U-013 的 Done 标准过头问题各自订正为 boundary/failure 先行、happy 用例推迟累计满足;U-014 端到端验收落地(补 c_artifact_write);U-016~U-030 大量原文档缺失的 Done/覆盖行补齐。改动内容当时已直接写入对应 units[].done/name 字段文本,但未同步在本 revisions 数组留痕,本条为补记"},
      {"date": "2026-08-01", "note": "(2026-08-04 补记)U-024.5/U-031 相关记录:U-031 回归审计发现 REQ-12 boundary(断线重连拉快照)此前从未真正实现,已修复;U-031 发现 c_work_graph_plan/c_work_graph_execute/c_work_node_run 三层架构彼此隔离测试通过但从未被生产代码真正串联,新增 src/work_graph_orchestrate.py 补上集成。行内文本已记录,本条为补记"},
      {"date": "2026-08-02", "note": "(2026-08-04 补记)U-032~U-043(PH5 全部 10 个 Unit)落地:U-031 REQ-01~14 逐条复核修复 5 处缺口;U-032 补建此前假设存在但从未建过的 src/scheduler.py;U-033 A-2 假设收口(维持部分成立);U-034~U-043 完整 Deploy Supervisor(stage/health_check/cutover/monitor/rollback)+ 自举闭环编排层 + 控制台 v_deployment_status。行内文本已记录,本条为补记"},
      {"date": "2026-08-03", "note": "(2026-08-04 补记)U-042 累计 13 次真实自举压测,依次发现并修复 9 个此前完全未知的真实缺口(worktree 提交兜底及其两层加深修复、prod db 引导期空库、_check_prd_consistency worktree 隔离、graph_manifest 归一化应对完全无 depends_on/edges、http_health 轮询等待端口就绪、rollback_path_a 清理候选 worktree 等),分散记录在 U-011/U-013/U-031/U-037/U-038/U-041 各自 done 字段中。同日还追加了 development-plan.md 第 5/5.1 节两项用户直接请求的控制台功能扩展(v_project_list/v_goal_list CRUD、任务 execute/pause/stop 控制),当时未在 unit_matrix.json 建对应条目。行内文本已记录,本条为补记"},
      {"date": "2026-08-04", "note": "文档一致性核查任务(本次):系统核对 development-plan.md 事后补记(07-31/08-01/08-02/08-03 各段)、unit_matrix.json 结构化字段与 git log 三方一致性。修正 U-009/U-011/U-012/U-013/U-014/U-042 六处 done 字段使其准确反映真实完成状态(U-013 额外补上此前遗漏的第三层 worktree 隔离真实 bug);新增 U-044(v_project_list/v_goal_list CRUD)、U-045(task execute/pause/stop 控制台功能)两个此前无 Unit 认领但已交付的控制台功能;version 由 v1.0 升至 v1.1;classification_summary 计数同步更新(Value Path 17→19)。纯文档订正,未改动 src/ 下任何业务代码或测试"}
    ]
  },
  "units": [
    {"id": "U-001", "phase": "PH0", "sub_phase": "PH0-S1", "name": "01-M 全部 15 实体物理 schema", "classification": "Enabler", "depends_on": [], "coverage": {"model": ["project", "org_graph_definition", "task", "work_graph_run", "work_node_execution", "artifact", "bug_record", "skill", "skill_iteration", "agent_profile", "budget_guardrail_config", "org_concurrency_config", "execution_event", "execution_log_file", "log_retention_config"], "view": [], "controller": [], "process": [], "requirement": []}, "done": "15 张表全部建表成功,关键约束(唯一/外键/枚举)有单测覆盖"},
    {"id": "U-002", "phase": "PH0", "sub_phase": "PH0-S1", "name": "目标项目 Git 仓库目录骨架初始化(仅 .graphlemon/,见架构文档 §13.2;2026-07-31 订正,此前误引用 §7.3)", "classification": "Enabler", "depends_on": ["U-001"], "coverage": {"model": ["project"], "view": [], "controller": ["c_project_create"], "process": [], "requirement": []}, "done": "给定空 git 仓库,能生成 .graphlemon/ 子目录骨架并产生初始化 commit"},
    {"id": "U-003", "phase": "PH0", "sub_phase": "PH0-S1", "name": "graphlemon 平台自身仓库/运行时目录结构", "classification": "Enabler", "depends_on": [], "coverage": {"model": [], "view": [], "controller": [], "process": [], "requirement": []}, "done": "平台目录与目标项目目录物理分离,互不干扰"},
    {"id": "U-004", "phase": "PH0", "sub_phase": "PH0-S2", "name": "Hermes profile 迁移到 .claude/agents/*.md", "classification": "Risk Gate", "depends_on": ["U-002"], "coverage": {"model": [], "view": [], "controller": [], "process": [], "requirement": [], "assumption": ["A-2"]}, "done": "claude --agent planner -p 可正常启动且系统提示词正确;skills/memory/tools/model frontmatter 配置完整"},
    {"id": "U-004.5", "phase": "PH0", "sub_phase": "PH0-S2", "name": "RUN_REAL_AGENT_E2E 门控测试 harness(2026-07-30 新增)", "classification": "Enabler", "depends_on": ["U-004"], "coverage": {"model": [], "view": [], "controller": [], "process": [], "requirement": []}, "done": "有可复用的 skip_unless_env(\"RUN_REAL_AGENT_E2E\") 装饰器/基类;默认 unittest 跳过真实 claude 子进程调用;显式开启环境变量时至少一个真实往返用例可跑通"},
    {"id": "U-005", "phase": "PH0", "sub_phase": "PH0-S2", "name": "c_org_node_trigger 子进程调用封装(骨架)", "classification": "Enabler", "depends_on": ["U-004", "U-004.5"], "coverage": {"model": [], "view": [], "controller": ["c_org_node_trigger"], "process": [], "requirement": []}, "done": "手工调用能触发一个 Org Agent 并拿到文本响应"},
    {"id": "U-006", "phase": "PH0", "sub_phase": "PH0-S2", "name": "Work Graph 调用封装(复用 A-1 spike 代码)", "classification": "Enabler", "depends_on": ["U-004", "U-004.5"], "coverage": {"model": [], "view": [], "controller": ["c_work_graph_execute"], "process": [], "requirement": [], "assumption": ["A-1"]}, "done": "封装为可调用接口,单测通过,--permission-mode auto 生效"},
    {"id": "U-007", "phase": "PH0", "sub_phase": "PH0-S3", "name": "本地后端骨架 + c_pick_folder macOS 实现", "classification": "Enabler", "depends_on": [], "coverage": {"model": [], "view": [], "controller": ["c_pick_folder"], "process": [], "requirement": []}, "done": "后端可启停;macOS 上原生对话框返回真实路径"},
    {"id": "U-008", "phase": "PH0", "sub_phase": "PH0-S3", "name": "前端骨架", "classification": "Enabler", "depends_on": ["U-007"], "coverage": {"model": [], "view": [], "controller": [], "process": [], "requirement": []}, "done": "本地 web 应用路由跳转正常"},

    {"id": "U-009", "phase": "PH1", "sub_phase": "PH1-S1", "name": "c_task_create + task 状态机(c_project_create 已在 U-002 完成)", "classification": "Value Path", "depends_on": ["U-001", "U-002"], "coverage": {"model": ["task"], "view": [], "controller": ["c_task_create"], "process": ["p_org_task_lifecycle"], "requirement": ["REQ-01"]}, "done": "REQ-01 boundary/failure 通过;happy 用例需要 c_org_node_trigger 完整实现,随 U-010 累计满足(2026-07-31 订正)。**2026-08-04 复核**:happy 用例已随 U-010/U-014/U-031 累计兑现——U-014 完整跑通端到端验收时三段 Org Graph 状态迁移首次真实串联,U-031 REQ-01~14 全量回归再次确认——不再是待兑现的推迟项,见 development-plan.md U-014/U-031 实现补充"},
    {"id": "U-010", "phase": "PH1", "sub_phase": "PH1-S1", "name": "c_org_node_trigger 完整实现(三段前向状态迁移,见 development-plan.md 2026-07-31 范围说明)", "classification": "Value Path", "depends_on": ["U-005", "U-009"], "coverage": {"model": [], "view": [], "controller": ["c_org_node_trigger"], "process": [], "requirement": []}, "done": "三个 Org Agent 分别可被触发(真实 claude --agent 调用),task.status 按 queued→planning_brd_prd_sdd→coding→validating 正确流转;重试/路由/blocked_pending_human 不在本 Unit 范围"},
    {"id": "U-011", "phase": "PH1", "sub_phase": "PH1-S2", "name": "c_work_graph_plan 实现(只规划不执行,见 development-plan.md 2026-07-31/2026-08-03 订正)", "classification": "Value Path", "depends_on": ["U-004", "U-010"], "coverage": {"model": ["artifact", "work_graph_run"], "view": [], "controller": ["c_work_graph_plan"], "process": [], "requirement": ["REQ-02"]}, "done": "graph_manifest 通过结构校验(brd/prd/sdd/benchmark 四节点+依赖链),work_graph_run(status=planning) 落地;REQ-02 happy 用例整体随 U-012/U-013 累计满足。c_artifact_write(03-C §3.7)目前没有任何 Unit 认领,是已知缺口。2026-08-03:U-042 第六次真实自举压测发现真实 LLM 输出可能完全不给 depends_on/edges(比此前已知的\"字段名不对\"更彻底),_normalize_graph_manifest 现在对 brd/prd/sdd/benchmark 四个规范 artifact_type 齐全时强制按已知的固定线性链补 depends_on,不再完全依赖 LLM 自己给对。**2026-08-04 复核**:REQ-02 happy 用例(四类 artifact 及血缘完整)已随 U-014 的 plan_documents 真实产出、并经 U-031 REQ-01~14 全量回归确认满足,\"累计满足\"不再是待兑现状态;c_artifact_write 缺口已在 U-014 补上(src/artifact_write.py),此处遗留文字仅作历史记录"},
    {"id": "U-012", "phase": "PH1", "sub_phase": "PH1-S2", "name": "c_work_graph_execute 完整实现(见 development-plan.md 2026-07-31 范围说明)", "classification": "Value Path", "depends_on": ["U-006", "U-011"], "coverage": {"model": [], "view": [], "controller": ["c_work_graph_execute"], "process": ["p_work_graph_execution", "p_usage_limit_wait"], "requirement": ["REQ-07", "REQ-14"]}, "done": "REQ-07 boundary/failure 通过(happy 需 PH2 REQ-04/05/06 就绪后累计满足);REQ-14 happy 通过。退避重试是整图级别,非逐节点;CLASSIFIER_BLOCKED 用单次调用 permission_denials≥3 近似判定。**2026-08-04 复核**:REQ-07 happy 用例已随 PH2 各 Unit 就绪、以及 U-031 用 work_graph_orchestrate.py 把 c_work_graph_plan/c_work_graph_execute/c_work_node_run 真正串联后,在 U-031 REQ-01~14 全量回归中确认满足,不再是待兑现的推迟项"},
    {"id": "U-013", "phase": "PH1", "sub_phase": "PH1-S2", "name": "c_work_node_run + git worktree 隔离(见 development-plan.md 2026-07-31 订正、2026-08-02/03 真实 bug 修复)", "classification": "Value Path", "depends_on": ["U-012"], "coverage": {"model": ["work_node_execution"], "view": [], "controller": ["c_work_node_run"], "process": [], "requirement": ["REQ-03"]}, "done": "REQ-03 boundary 通过(真实 git worktree 隔离+merge,无冲突);happy 需 c_artifact_write 落地后累计满足。2026-08-02/03:U-042 第一次真实自举压测发现 Coder 编辑 worktree 后从不 commit、merge_worktree 空操作、真实改动被 remove_worktree 静默吞掉的真实 bug,新增 ensure_worktree_committed() 兜底自动提交;第八/九次压测又发现更深一层——worktree 和主仓库共享项目身份,memory:project 写入可能直接落在主仓库检出目录而非 worktree,导致下一个节点 merge 失败,已扩展 ensure_worktree_committed() 同时兜底主仓库自身、并把 .graphlemon-worktrees/ 加入 .gitignore,全部补了真实回归测试。**第三层真实 bug(2026-08-03,U-042 第十次真实压测发现,2026-08-04 补记——development-plan.md 已有此记录但此前未同步进本字段)**:为兜住主仓库漂移新加的显式排除 pathspec `-- . ':!.graphlemon-worktrees'` 与同一次修复新增的 .gitignore 规则相互冲突——两者同时命中同一路径时 git add -A 直接报错退出(即使抑制提示文案,退出码依然非零);修复为删掉这个多余的显式排除,只依赖 .gitignore 本身即可让 git add -A 正确跳过该目录,ensure_worktree_committed() 恢复成最简单的 git add -A,测试夹具 _init_git_repo() 同步补上同一条 .gitignore 规则。**2026-08-04 复核**:REQ-03 happy 用例已随 U-014 的 c_artifact_write 落地、并经 U-031 全量回归确认满足,不再是待兑现的推迟项"},
    {"id": "U-014", "phase": "PH1", "sub_phase": "PH1-S3", "name": "贪吃蛇场景端到端验收(含补建 c_artifact_write,见 development-plan.md 2026-07-31 实现补充)", "classification": "Value Path", "depends_on": ["U-011", "U-012", "U-013"], "coverage": {"model": ["artifact"], "view": [], "controller": ["c_artifact_write"], "process": [], "requirement": []}, "done": "架构文档 §11 验收标准第 1-3 条全部达成;plan_documents(Planner 四件套+血缘)真实验证过。**2026-08-04 订正(原文\"Coder/Validator 全流程真实跑通待用户确认后执行\"已过时)**:自 2026-08-02 起用户已多次明确授权真实运行,Coder/Validator 全流程(真实写代码、真实测试、真实归因)已在 PH4/PH5 及后续自举运行中反复真实跑通——U-031/U-032 的真实验证记录、U-042 累计 13 次真实自举压测、以及 git log 中大量 `graphlemon: code_diff/test_report artifact for task <uuid>` 提交均已证实,不再是待确认执行的悬空状态"},

    {"id": "U-015", "phase": "PH2", "sub_phase": "PH2-S1", "name": "p_validator_root_cause_trace 实现", "classification": "Risk Gate", "depends_on": ["U-013"], "coverage": {"model": ["bug_record"], "view": [], "controller": ["c_bug_record_create"], "process": ["p_validator_root_cause_trace"], "requirement": ["REQ-04"]}, "done": "REQ-04 happy/boundary/failure 通过"},
    {"id": "U-016", "phase": "PH2", "sub_phase": "PH2-S1", "name": "c_org_loop_route + fast_lane/full_replan(含 close_task_done,见 development-plan.md 2026-07-31 实现补充)", "classification": "Risk Gate", "depends_on": ["U-015"], "coverage": {"model": [], "view": [], "controller": ["c_org_loop_route"], "process": [], "requirement": ["REQ-05", "REQ-09"]}, "done": "REQ-05/REQ-09 全部用例通过(含 3 轮上限 → blocked_pending_human;validating→done 通过新增 close_task_done 打通)"},
    {"id": "U-017", "phase": "PH2", "sub_phase": "PH2-S1", "name": "人为植入 bug 完整闭环验证(见 development-plan.md 2026-07-31 实现补充)", "classification": "Risk Gate", "depends_on": ["U-016"], "coverage": {"model": [], "view": [], "controller": [], "process": [], "requirement": []}, "done": "架构文档 §11 验收标准第 4 条达成:run_fix_loop 串联 U-015 判定 + U-016 路由 + 真实 Coder 修复 + 真实 Validator 复核"},
    {"id": "U-018", "phase": "PH2", "sub_phase": "PH2-S2", "name": "c_skill_update + c_skill_rollback(见 development-plan.md 2026-07-31 实现补充)", "classification": "Risk Gate", "depends_on": ["U-015"], "coverage": {"model": ["skill", "skill_iteration"], "view": [], "controller": ["c_skill_update", "c_skill_rollback"], "process": [], "requirement": ["REQ-08"]}, "done": "REQ-08 全部通过;顺带解决了 U-015 的 skill_defect 缺口(bug_record.skill_iteration_suggestion_id 由 update_skill 回填)"},
    {"id": "U-019", "phase": "PH2", "sub_phase": "PH2-S3", "name": "budget_guardrail_config + c_budget_check(见 development-plan.md 2026-07-31 实现补充)", "classification": "Risk Gate", "depends_on": ["U-012"], "coverage": {"model": ["budget_guardrail_config"], "view": [], "controller": ["c_budget_check"], "process": ["p_budget_guardrail"], "requirement": ["REQ-10"]}, "done": "REQ-10 happy/boundary 通过;boundary 复用 U-016 manual_resume,完整 c_budget_config_update UI 是 U-030 的事"},
    {"id": "U-020", "phase": "PH2", "sub_phase": "PH2-S3", "name": "p_usage_limit_wait 完整验收(见 development-plan.md 2026-07-31 实现补充)", "classification": "Risk Gate", "depends_on": ["U-012"], "coverage": {"model": [], "view": [], "controller": [], "process": ["p_usage_limit_wait"], "requirement": ["REQ-14"]}, "done": "REQ-14 全部通过(含超时兜底);补上了 opus 真实降级重试(U-013 时只做到不退避,没做到真重试)+ 之前漏测的 weekly 类型"},
    {"id": "U-021", "phase": "PH2", "sub_phase": "PH2-S4", "name": "Graph Engine 持久化 + 断点恢复(见 development-plan.md 2026-07-31 实现补充)", "classification": "Risk Gate", "depends_on": ["U-012", "U-013"], "coverage": {"model": ["work_graph_run", "work_node_execution"], "view": [], "controller": [], "process": ["p_work_graph_execution"], "requirement": ["REQ-06"]}, "done": "REQ-06 happy/boundary/failure 通过;now 默认值从 time.monotonic 改成 time.time(墙钟)以支持跨进程重启的 quota 等待续算;新增 resume_work_graph_run() 返回未完成节点列表"},

    {"id": "U-022", "phase": "PH3", "sub_phase": "PH3-S1", "name": "v_project_setup + c_pick_folder 全平台(见 development-plan.md 2026-07-31 实现补充)", "classification": "Value Path", "depends_on": ["U-007", "U-008"], "coverage": {"model": [], "view": ["v_project_setup"], "controller": ["c_pick_folder", "c_project_create"], "process": [], "requirement": ["REQ-11"]}, "done": "REQ-11 里 v_project_setup/c_pick_folder/c_project_create 部分通过;c_pick_folder 补齐 Windows/Linux;c_project_create 首次接上 HTTP 路由;REQ-11 完整 happy(含建 task)随 U-023 累计满足"},
    {"id": "U-023", "phase": "PH3", "sub_phase": "PH3-S1", "name": "v_goal_composer + v_bug_feedback(见 development-plan.md 2026-07-31 实现补充)", "classification": "Value Path", "depends_on": ["U-022"], "coverage": {"model": [], "view": ["v_goal_composer", "v_bug_feedback"], "controller": ["c_task_create", "c_bug_report_create"], "process": [], "requirement": []}, "done": "能通过 UI 创建 task 和人工 bug_record;补上 c_bug_report_create 的 project_id 必填缺口(03-C input_contract 遗漏);related_task_id 简化为文本输入,等 U-025 的 c_task_list 落地后换真下拉"},
    {"id": "U-024", "phase": "PH3", "sub_phase": "PH3-S2", "name": "c_ws_subscribe + execution_event 实时推送(最小连通版,见 development-plan.md 2026-07-31 实现补充)", "classification": "Value Path", "depends_on": ["U-012", "U-013"], "coverage": {"model": ["execution_event"], "view": [], "controller": ["c_ws_subscribe"], "process": [], "requirement": ["REQ-12"]}, "done": "推送链路本身连通,≤2 秒延迟达成;REQ-12 happy 用例通过(boundary/failure 留给 U-024.5);手写 RFC 6455 握手+帧编解码(无第三方 websockets 依赖),轮询式推送(无单一写路径可插桩),Node 原生 WebSocket 客户端验证过真实互操作性"},
    {"id": "U-024.5", "phase": "PH3", "sub_phase": "PH3-S2", "name": "REQ-12 完整验收:事件多样性联调(见 development-plan.md 2026-08-01 实现补充)", "classification": "Value Path", "depends_on": ["U-024", "U-015", "U-016", "U-018", "U-019", "U-020", "U-021"], "coverage": {"model": [], "view": [], "controller": [], "process": [], "requirement": ["REQ-12"]}, "done": "REQ-12 全部 happy/boundary/failure 用例通过;PH3 Phase 验收里的 REQ-12 以本 Unit 为准。boundary 用例(重连补齐断线期间遗漏状态)此前从未真正实现,仅 v_dashboard 有 UI banner 切换、无数据重拉——2026-08-01 于 U-031 回归审计中发现并补上:v_dashboard/v_task_board/v_task_detail(含内嵌的 v_graph_visualizer)的 connectEventSocket onStatusChange 均已在 disconnected→connected 转换时重新拉取当前快照;v_artifact_browser 不在 REQ-12 命名范围内,未改动"},
    {"id": "U-025", "phase": "PH3", "sub_phase": "PH3-S2", "name": "v_dashboard + v_task_board + v_task_detail(见 development-plan.md 2026-07-31 实现补充)", "classification": "Value Path", "depends_on": ["U-024"], "coverage": {"model": [], "view": ["v_dashboard", "v_task_board", "v_task_detail"], "controller": ["c_task_list", "c_task_get", "c_org_loop_route"], "process": [], "requirement": []}, "done": "三个页面可正常展示实时数据;补上此前无 Unit 认领的 c_task_list/c_task_get HTTP 路由,c_org_loop_route 首次接上 HTTP;v_graph_visualizer/v_log_viewer 子模块占位等 U-026/U-027"},
    {"id": "U-026", "phase": "PH3", "sub_phase": "PH3-S2", "name": "v_graph_visualizer(见 development-plan.md 2026-07-31 实现补充)", "classification": "Value Path", "depends_on": ["U-024"], "coverage": {"model": [], "view": ["v_graph_visualizer"], "controller": [], "process": [], "requirement": []}, "done": "Work Graph DAG 分层视图含 waiting_for_quota 信息态;Org Graph 层复用 v_task_detail 已有的 org-strip 面板,不重复渲染"},
    {"id": "U-027", "phase": "PH3", "sub_phase": "PH3-S3", "name": "execution_log_file + 日志查看器(见 development-plan.md 2026-07-31 实现补充)", "classification": "Value Path", "depends_on": ["U-024"], "coverage": {"model": ["execution_log_file", "log_retention_config"], "view": ["v_log_viewer"], "controller": ["c_execution_log_get", "c_ws_log_tail"], "process": ["p_log_retention_cleanup"], "requirement": ["REQ-13"]}, "done": "REQ-13 happy/boundary/failure 通过;补上此前从未存在的 append_log 写路径;顺带修了 U-024 就存在的 server_close() 并发 segfault 隐患(conn_lock 未覆盖)"},
    {"id": "U-028", "phase": "PH3", "sub_phase": "PH3-S3", "name": "v_artifact_browser(见 development-plan.md 2026-07-31 实现补充)", "classification": "Value Path", "depends_on": ["U-011"], "coverage": {"model": [], "view": ["v_artifact_browser"], "controller": ["c_artifact_get", "c_artifact_list"], "process": [], "requirement": []}, "done": "Artifact 列表+预览+血缘链可用;预览为纯文本,不做 Markdown 渲染/代码高亮(避免引入前端第三方依赖)"},
    {"id": "U-029", "phase": "PH3", "sub_phase": "PH3-S3", "name": "v_skill_library + v_skill_audit_log(见 development-plan.md 2026-07-31 实现补充)", "classification": "Value Path", "depends_on": ["U-018"], "coverage": {"model": [], "view": ["v_skill_library", "v_skill_audit_log"], "controller": ["c_skill_diff", "c_skill_list", "c_skill_get", "c_skill_rollback"], "process": [], "requirement": []}, "done": "Skill 库与变更审计日志可查看;c_skill_rollback 首次接上 HTTP(skill_repo_path 可注入,测试绝不碰真实仓库)"},
    {"id": "U-030", "phase": "PH3", "sub_phase": "PH3-S4", "name": "并发/预算/日志保留配置页(见 development-plan.md 2026-07-31 实现补充)", "classification": "Value Path", "depends_on": ["U-019", "U-021"], "coverage": {"model": ["org_concurrency_config"], "view": ["v_concurrency_settings", "v_budget_settings", "v_log_retention_settings"], "controller": ["c_concurrency_config_update", "c_budget_config_update", "c_log_retention_config_update"], "process": [], "requirement": []}, "done": "三个配置页可用且改动生效;PH3 至此全部完成"},

    {"id": "U-031", "phase": "PH4", "sub_phase": "PH4-S1", "name": "REQ-01~14 全量自动化回归(见 development-plan.md 2026-08-01/2026-08-02 实现补充)", "classification": "Risk Gate", "depends_on": ["U-014", "U-017", "U-020", "U-021", "U-022", "U-023", "U-024.5", "U-025", "U-026", "U-027", "U-028", "U-029", "U-030"], "coverage": {"model": [], "view": [], "controller": [], "process": [], "requirement": ["REQ-01", "REQ-02", "REQ-03", "REQ-04", "REQ-05", "REQ-06", "REQ-07", "REQ-08", "REQ-09", "REQ-10", "REQ-11", "REQ-12", "REQ-13", "REQ-14"]}, "done": "06 节全部 14 条 REQ 的全部用例通过一次完整回归;回归审计中发现 c_work_graph_plan/c_work_graph_execute/c_work_node_run 三个模块彼此隔离测试通过但从未被生产代码真正串联(唯一验证过的闭环 e2e_pipeline.py 绕开了三者,直接用 org_node_trigger),已按用户决策现场补上集成:新增 src/work_graph_orchestrate.py(拓扑排序 + 每节点一份独立动态工作流脚本调用 run_work_node),e2e_pipeline.py 的 plan_documents/implement_code 改为真调用 plan_work_graph→run_graph;真实 API 验证过程中发现并修复两个真实 bug(graph_manifest 的 id/node_id 字段名及 depends_on 缺失见 work_graph_plan._normalize_graph_manifest;run_work_node 缺 repo_path 导致 cwd=None)。**2026-08-02(PH5 开工前逐条复核)**:对照 06 节重新逐条核对后又发现并修复 5 处真实缺口——REQ-03 failure 缺失 'reflecting' 状态写入、REQ-05/09 的调度器场景此前从未真正测试过(U-032 建好后才补测)、REQ-06/07/14 三条 failure 共享的同一个缺口(CorruptPersistedStateError/ClassifierBlockedError/UsageLimitWaitTimeoutError 均未路由到 task.status=blocked_pending_human)、REQ-02 boundary(PRD 一致性校验)此前完全未实现现已用新的 verify_fn 机制补上、REQ-13 failure 一处测试断言过弱;全部详见 development-plan.md 对应实现补充,380 测试全绿,此时才是 06 节 REQ-01~14 真正逐条有覆盖。**2026-08-03(U-042 真实自举压测第四次尝试发现)**:`_check_prd_consistency()` 直接对 target_folder_path 调用未做 worktree 隔离,self-target 场景下会把 memory 写入落到主仓库工作区未提交状态,导致下一个节点的真实 worktree 合并失败;已改为按 05 §5.8 同样规则隔离到自己的 worktree,补充两个回归测试"},
    {"id": "U-032", "phase": "PH4", "sub_phase": "PH4-S2", "name": "多 Goal 并发 + 长时间运行稳定性压测(见 development-plan.md 2026-08-02 实现补充)", "classification": "Risk Gate", "depends_on": ["U-031"], "coverage": {"model": ["org_concurrency_config"], "view": [], "controller": [], "process": [], "requirement": ["REQ-09"]}, "done": "并发数调高后多个独立 Goal 可同时稳定运行;发现并补上一个此前从未存在的结构性缺口——04-P/01-M/REQ-09 boundary 反复假设存在的自动调度器实际从未被建过,新增 src/scheduler.py(ThreadPoolExecutor + 每线程独立 sqlite 连接,避免复刻 U-027 的共享连接锁陷阱)真正实现,并顺带补上 e2e_pipeline.run_end_to_end() 自己文档过的缺口(PASS/FAIL 后从不调用 close_task_done/run_fix_loop,卡在 validating 不动)"},
    {"id": "U-033", "phase": "PH4", "sub_phase": "PH4-S3", "name": "A-2 假设收口(见 development-plan.md 2026-08-02 实现补充)", "classification": "Risk Gate", "depends_on": ["U-004"], "coverage": {"model": [], "view": [], "controller": [], "process": [], "requirement": [], "assumption": ["A-2"]}, "done": "A-2 状态确认为 confirmed 或记录实际偏差;最终结论:维持 U-004 记录的\"部分成立\",PH1~PH4 积累的真实运行数据未暴露新偏差,偏差范围到 U-004 为止已完全摸清(Coder SOUL.md 三处实质性重写),不改判 confirmed,正式收口"},

    {"id": "U-034", "phase": "PH5", "sub_phase": "PH5-S1", "name": "01-M 扩展:deployment/deploy_health_signal + core_engine 枚举(见 development-plan.md 2026-08-02 实现补充)", "classification": "Enabler", "depends_on": ["U-001"], "coverage": {"model": ["deployment", "deploy_health_signal", "bug_record"], "view": [], "controller": [], "process": [], "requirement": []}, "done": "两张新表建表成功(共 17 张);bug_record 新枚举值向后兼容 U-015/U-018 已有测试;deployment 状态机用 01-M 1.15 完整 15 值枚举;ux_deployment_active 表达式索引强制全局单例非终态约束;bug_record.py 应用层白名单刻意未跟着放开 core_engine,classification+路由逻辑留给 U-035"},
    {"id": "U-035", "phase": "PH5", "sub_phase": "PH5-S1", "name": "self-target worktree 无条件强制 + core_engine 分类审计(见 development-plan.md 2026-08-02 实现补充)", "classification": "Risk Gate", "depends_on": ["U-013", "U-016", "U-034"], "coverage": {"model": [], "view": [], "controller": [], "process": [], "requirement": ["REQ-03"]}, "done": "self-target 时无条件走 worktree(work_graph_orchestrate.run_graph 内强制);core_engine 分类(src/core_engine_classify.py,路径规则)在 self-target 任务 PASS 收尾时记一条审计用 bug_record;且改动落地后重跑 U-013/REQ-03(worktree 隔离)现有回归用例全部通过。**2026-08-02 用户决策修正**:Deploy Supervisor 触发条件按 supervisor-auto-rollback-design.md §1 字面设计(self-target+PASS 即触发,bug_record 是旁路产物不是前提),而非 03-C/04-P 字面文本要求的\"先有 core_engine bug_record\"——后者会让从不产生 bug_record 的 goal 型自我改进任务永远触发不了 Deploy Supervisor,已用 AskUserQuestion 与用户确认此订正。c_org_loop_route 未改动(fast_lane/full_replan 是 FAIL 路径重试路由,与此处 PASS 路径的蓝绿触发正交),deployment 行创建仍是 U-037 的范围,不在本 Unit 提前做"},
    {"id": "U-036", "phase": "PH5", "sub_phase": "PH5-S2", "name": "supervisor/isolation 补齐单测 + Deploy Supervisor 进程骨架(见 development-plan.md 2026-08-02 实现补充)", "classification": "Enabler", "depends_on": [], "coverage": {"model": [], "view": [], "controller": [], "process": [], "requirement": []}, "done": "四模块各有 test_*.py(供 python3 -m unittest discover -s supervisor/isolation 运行,52 测试全绿);Deploy Supervisor 骨架(supervisor/deploy_supervisor.py)独立进程可启停(真实子进程验证,非 mock),不受 Live/Candidate 崩溃影响;本 Unit 只做进程生命周期骨架,不含任何真实部署决策逻辑(U-037+ 的 poll_fn 挂载点)"},
    {"id": "U-037", "phase": "PH5", "sub_phase": "PH5-S2", "name": "c_deploy_supervisor_stage(见 development-plan.md 2026-08-02/03 实现补充)", "classification": "Risk Gate", "depends_on": ["U-034", "U-036"], "coverage": {"model": ["deployment"], "view": [], "controller": ["c_deploy_supervisor_stage"], "process": [], "requirement": []}, "done": "能生成 deployment 记录并拉起监听临时端口、连一次性 DB 副本的候选进程(supervisor/deploy_stage.py,真实 git worktree + 真实子进程验证过);顺带补上 deployment.candidate_instance_dir 缺字段 + backend_server.py 首个 CLI 入口。2026-08-03:U-042 第三次真实自举压测发现 _copy_prod_db() 没有处理 prod_db_path 首次不存在的引导期场景(真实 FileNotFoundError),已修复为自动新建带 schema 的空库并补测试"},
    {"id": "U-038", "phase": "PH5", "sub_phase": "PH5-S2", "name": "c_deploy_supervisor_health_check(见 development-plan.md 2026-08-02/03 实现补充)", "classification": "Risk Gate", "depends_on": ["U-037"], "coverage": {"model": ["deploy_health_signal"], "view": [], "controller": ["c_deploy_supervisor_health_check"], "process": [], "requirement": []}, "done": "process_alive/http_health/canary_task 三项检查全过 -> health_check_passed;任一失败 -> health_check_failed 且 Live 未受影响(supervisor/deploy_health_check.py,真实 HTTP+真实 project/task 创建验证过);backend_server.py 新增 GET /api/health(真查一次 SELECT 1,不只是进程存活)。2026-08-03:U-042 第七/十一次真实压测均卡在 http_health(进程已存活但端口还没真正开始监听,ECONNREFUSED 立即触发、原实现单次尝试不重试),已跟用户确认不违反 03-C\"不重试\"策略后,改成和 process_alive 一样轮询等待端口就绪,真实非 2xx 响应仍立即失败"},
    {"id": "U-039", "phase": "PH5", "sub_phase": "PH5-S2", "name": "c_deploy_supervisor_cutover(见 development-plan.md 2026-08-02 实现补充)", "classification": "Risk Gate", "depends_on": ["U-038"], "coverage": {"model": ["deployment"], "view": [], "controller": ["c_deploy_supervisor_cutover"], "process": [], "requirement": []}, "done": "健康检查通过后完成真实切换(supervisor/deploy_cutover.py,真实进程停止+重启验证过);在途 work_node_execution 重启后可恢复(复用既有 REQ-06 机制);previous_instance_dir 保留至监控窗口结束;新增 LIVE_PORT=8420 常量(05 §5.9 缺的一个字段);真实测试发现并修复 deploy_supervisor.is_alive() 的僵尸进程判活缺陷(新增 reap_if_exited())"},
    {"id": "U-040", "phase": "PH5", "sub_phase": "PH5-S3", "name": "c_deploy_supervisor_monitor(见 development-plan.md 2026-08-02 实现补充)", "classification": "Risk Gate", "depends_on": ["U-039"], "coverage": {"model": ["deploy_health_signal"], "view": [], "controller": ["c_deploy_supervisor_monitor"], "process": [], "requirement": []}, "done": "四类信号采样正常(supervisor/deploy_monitor.py);validator_approval_rate 偏离基线阈值时触发 anomaly_detected;approve 占比算法基于对 scheduler.finish_task_lifecycle 真实代码逻辑的核实(PASS 从不产生 bug_record,FAIL 必然产生),非字面 SDD 定义"},
    {"id": "U-041", "phase": "PH5", "sub_phase": "PH5-S3", "name": "c_deploy_supervisor_rollback(见 development-plan.md 2026-08-02/03 实现补充)", "classification": "Risk Gate", "depends_on": ["U-038", "U-040"], "coverage": {"model": ["deployment"], "view": [], "controller": ["c_deploy_supervisor_rollback"], "process": [], "requirement": []}, "done": "回滚路径 A/B 各跑通一次(supervisor/deploy_rollback.py,真实进程+真实 git 仓库验证);旧版本也起不来时正确终态到 blocked_pending_human(真实场景验证,非假设);git revert 冲突有明确处理(真实构造冲突历史验证过,含 --abort 清理)。2026-08-03:U-042 第七次真实压测第一次真正走到 health_check 环节,发现 rollback_path_a 从未清理候选的 git worktree 检出目录(永久留在磁盘+git worktree list),已修复并补真实回归测试"},
    {"id": "U-042", "phase": "PH5", "sub_phase": "PH5-S3", "name": "自举闭环端到端验收(见 development-plan.md 2026-08-02 实现补充)", "classification": "Risk Gate", "depends_on": ["U-035", "U-041"], "coverage": {"model": [], "view": [], "controller": [], "process": [], "requirement": []}, "done": "真实复现 self-development-feasibility.md 9 步场景,全程无需人工评审代码内容(supervisor/self_hosting_e2e.py 编排层已建好);真实双实例 E2E 用例(RUN_REAL_SELF_HOSTING_E2E=1,独立于常规 RUN_REAL_AGENT_E2E 的单独环境变量)默认跳过,需显式环境变量开启且需额外用户确认才真正执行;日常回归只跑 mock 版本(6 个编排逻辑测试,已跑通)。**2026-08-04 复核(development-plan.md 2026-08-03\"真实压测\"记录未同步进本字段,现补上)**:截至 2026-08-03 已累计执行 13 次真实自举压测(用户逐次明确授权),依次发现并修复 9 个此前完全未知的真实缺口(具体条目分散记录在 U-011/U-013/U-031/U-037/U-038/U-041 各自 done 字段中);第 13 次真实压测第一次真正走完 task→plan→code→merge→classify→stage→health_check→真实 cutover 全链路,仅因监控窗口使用真实生产参数(24 小时/10 个任务)而未能在交互式会话内等到 finalized 终态——run_self_hosting_closed_loop() 已补上 monitor_window_hours/monitor_min_task_count 两个可覆盖旋钮以便后续压测拿到 finalized。这不再是\"编排层已建好、真实场景默认不跑\"的静态描述,而是已经过 13 轮真实验证、非常接近完整闭环的状态"},
    {"id": "U-043", "phase": "PH5", "sub_phase": "PH5-S4", "name": "控制台展示 deployment 状态与健康信号(见 development-plan.md 2026-08-02 实现补充)", "classification": "Value Path", "depends_on": ["U-024", "U-040"], "coverage": {"model": [], "view": ["v_deployment_status"], "controller": ["c_deployment_list", "c_deployment_current", "c_deployment_get"], "process": [], "requirement": []}, "done": "能看到当前 deployment 状态机所处状态与最近一次健康信号采样结果;02-V 从未定义过这个视图(PH5 后加),DOM/class 约定沿用现有页面;真实服务器 + urllib 验证过全部三条新路由"},

    {"id": "U-044", "phase": "PH5+", "sub_phase": "用户直接请求的控制台功能扩展", "name": "v_project_list + v_goal_list CRUD(development-plan.md 第 5 节,2026-08-03 新增,2026-08-04 补记:此前 unit_matrix.json 无对应条目)", "classification": "Value Path", "depends_on": ["U-022", "U-025"], "coverage": {"model": ["project", "task"], "view": ["v_project_list", "v_goal_list"], "controller": ["c_project_list", "c_project_get", "c_project_update", "c_project_delete", "c_task_list"], "process": [], "requirement": []}, "done": "项目列表增删改查(DELETE 语义是软删除,status=archived,因 project_id 被大量外键引用)+ 任务列表排序(白名单校验列名)/编辑目标文本/删除(仅 status=queued 时允许,TaskNotEditableError/409 防止破坏已产出 artifact 的审计可追溯性)全部可用;真实运行的服务器 + curl 端到端验证过全部新增接口,含发现并修复的一个真实 bug(delete_task() 需同事务内先删该任务自己的 execution_event 行,否则真实创建的任务会因外键约束报 IntegrityError);src/test_project_query.py(12 用例)+ test_task_query.py/test_backend_server.py 新增真实 HTTP 路由测试类,474 个测试全绿。**本 Unit 由 Claude Code 直接实现,未经 Planner/Coder/Validator 自举闭环**——development-plan.md 第 5 节记录了原因:当时 implement_code() 只用写死的单节点 graph_manifest,不具备按视图/模块拆分执行的能力,两个新页面+6 个新接口这个规模用一次不可拆分的 Coder 会话去做风险不可控。git log 7c720ab \"Add v_project_list and v_goal_list CRUD (user-requested scope expansion)\" 确认已交付"},
    {"id": "U-045", "phase": "PH5+", "sub_phase": "用户直接请求的控制台功能扩展", "name": "v_task_detail/v_dashboard 开始/暂停/停止任务执行控制(development-plan.md 第 5.1 节,2026-08-03 新增,2026-08-04 补记:此前 unit_matrix.json 无对应条目)", "classification": "Value Path", "depends_on": ["U-025", "U-032", "U-044"], "coverage": {"model": ["task"], "view": ["v_task_detail", "v_dashboard"], "controller": ["c_task_execute", "c_task_pause", "c_task_stop"], "process": [], "requirement": []}, "done": "queued 任务可从控制台手动触发执行;Pause/Stop 为软停止(不做真进程 kill,正在跑的调用自然跑完),复用既有的 blocked_pending_human + blocked_reason=user_paused/user_stopped 而非新增 task.status 枚举值,manual_resume 恢复时按 blocked_reason 自动重新 spawn 后台执行线程(而不只是翻状态字段);根因是 03-C/04-P 全文假设有常驻调度器自动唤起任务,但 src/scheduler.py(U-032)只造了函数,从未被常驻进程持续调用,因此从未设计过\"人工点击开始\"的按钮,这次是补上这个真实缺口;真实运行的服务器 + curl 端到端验证过 /execute、/pause、/stop 全部状态转移;src/task_execution.py 新增 14 个用例 + test_backend_server.py 新增 8 个真实 HTTP 路由用例,496 个测试全绿。本 Unit 同样由 Claude Code 直接实现,原因同 U-044。git log add263a \"v_task_detail/v_dashboard: Start/Pause/Stop task execution controls\" 确认已交付"}
  ],
  "classification_summary": {
    "Value Path": 19,
    "Risk Gate": 18,
    "Enabler": 10,
    "_2026-08-04_note": "Value Path 17→19:新增 U-044/U-045(development-plan.md 第 5/5.1 节的用户直接请求控制台功能扩展),此前未在 unit_matrix.json 中反映。总 Unit 数 45→47"
  },
  "critical_path": ["U-001", "U-002", "U-004", "U-004.5", "U-005", "U-006", "U-010", "U-011", "U-012", "U-013", "U-014"],
  "ph5_critical_path": ["U-034", "U-035", "U-036", "U-037", "U-038", "U-039", "U-040", "U-041", "U-042"]
}