Commit 82368fc6d3a38e988a10509bc8526465276529a8
1 parent
7c46a2f2
docs: mark Phase 2a/2b implemented, record real findings from implementation
Updates the Phase 2 SDD and requirements doc to reflect that Phase 2a (86fc0bb) and Phase 2b (7c46a2f) are done, not just designed. Records the concrete deviations/fixes found during implementation that the original design didn't anticipate: the run_id=None bug in the artifact-reuse resume path, the missing needs_worktree=True on Coder's run_graph() call, why §2.2's index narrowing needed to move from "maybe safe after 2b" to "actually needs 2c", and the test-fixture check_same_thread=False gap concurrent merged-graph layers exposed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Showing
2 changed files
with
18 additions
and
10 deletions
docs/todo/org-graph-unification-and-universal-self-planning-requirements.md
| ... | ... | @@ -119,7 +119,7 @@ |
| 119 | 119 | - **验收**:能在(已真实复现过的)"benchmark 输出叙述文字冒充产出"场景下,在 Coder 动手之前拦住任务;崩溃后 resume 不再假设 Planner artifact 一定存在;fresh-run 也不再假设 prd/benchmark 一定存在。 |
| 120 | 120 | |
| 121 | 121 | ### Phase 2 — 全员自规划 + 合图(方案 A)+ 节点级验证 skill |
| 122 | -- **详细设计**:`docs/todo/org-graph-unification-phase2-universal-self-planning-design.md`(2026-08-08,按 §7 四条拍板结果改写)。设计阶段发现范围比原设想更大——`_GENERIC_PROMPT_TEMPLATE` 从未征集 judgment/on_fail、`run_graph()` 的 subagent_type/skill_ref 是 run 级常量不是节点级、现有 `loop_back` 是规划阶段静态声明的单一目标不支持终审失败时动态选择根因节点(新增 `on_fail.action="dynamic_loop_back"` 解决,复用 `root_cause_trace.py` 陪审团结构)——详见该文档 §1/§5。 | |
| 122 | +- **详细设计**:`docs/todo/org-graph-unification-phase2-universal-self-planning-design.md`。Phase 2a(节点级 subagent/skill 绑定 + `dynamic_loop_back`/Reflection-review/Fix-Skill,commit `86fc0bb`)+ Phase 2b(Coder 接入自规划,commit `7c46a2f`)已实现(2026-08-12);Phase 2c(Validator 接入自规划 + `org_node` 列删除 + 退休粗粒度路由)待实施。设计阶段发现范围比原设想更大——`_GENERIC_PROMPT_TEMPLATE` 从未征集 judgment/on_fail、`run_graph()` 的 subagent_type/skill_ref 是 run 级常量不是节点级、现有 `loop_back` 是规划阶段静态声明的单一目标不支持终审失败时动态选择根因节点(新增 `on_fail.action="dynamic_loop_back"` 解决,复用 `root_cause_trace.py` 陪审团结构)——详见该文档 §1/§5。 | |
| 123 | 123 | - **范围**:FR-2 + FR-3 + FR-4,按 §4/§4.1 已拍板的合图路径实现。 |
| 124 | 124 | - **产出**(按拍板后的最终形状): |
| 125 | 125 | 1. `work_graph_run.org_node` 列彻底删除(不是下沉/保留),`work_graph_run_query.py`/`work_graph_fork.py` 改造为从 `work_node_execution.subagent_type` 聚合/逐节点判断;`ux_work_graph_run_active` 收窄为 `UNIQUE(task_id)`。 | ... | ... |
docs/todo/org-graph-unification-phase2-universal-self-planning-design.md
| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | **日期**: 2026-08-08 |
| 4 | 4 | **性质**: 详细设计,对应 `docs/todo/org-graph-unification-and-universal-self-planning-requirements.md` 的 Phase 2(FR-2/FR-3/FR-4),按 §4/§4.1 已拍板的合图(方案 A)路径设计。 |
| 5 | 5 | **依赖**: 硬依赖 Phase 1(`docs/done/org-graph-unification-phase1-review-gate-design.md`)——已实现(commit `ea19c7d`,2026-08-08)。§9 接口核对清单已于 2026-08-12 逐条核对完成:三项全部吻合(`plan_and_review_documents()` 经 `_review_planner_output_with_retries()` 透传 `plan_documents()` 的 `{"run_id", "artifact_ids"}` 返回形状,含 `run_id`;`task.status` 新值确认是 `reviewing_planner_output`;`roles/planner_reviewer/role.json` 目前 `skills: ["planner-output-review", "unattended-agent-operations"]`,未预留 §7.1 新 skill 位置,Phase 2 实施时新增一行即可,不是不兼容)。 |
| 6 | -**状态**: 设计草案,Phase 1 前置条件已满足,可以开始实施。**2026-08-08 修订**:写作过程中,需求文档 §7 的四个开放问题已被用户直接拍板(详见该文档 §7 对应条目),其中两条推翻了本文档最初的设计判断——Coder/Validator 自规划改为"建议节点清单"而非完全自由(§3),`work_graph_run.org_node` 改为彻底移除而非保留(§2.1)——本版本已按拍板结果改写,不是原始草稿。**2026-08-08 追加**(同日,见需求文档新增 §3.1):FR-4 的目标被明确为"失败即进化"完整方法论(判断失败 → Reflection-review 动态诊断 → 系统性缺陷则先 Fix-Skill → 跳回执行),当时 §5 设计的 `dynamic_loop_back` 只覆盖第 1/2/4 步,第 3 步(Fix-Skill)是已知缺口。**2026-08-12 补齐**:§5 已扩写为完整四步设计(§5.4 Reflection-review 现在同时判断目标节点和缺陷性质,§5.5 新增 Fix-Skill,真实调用既有但从未真正投入使用的 `skill_update.py::update_skill()`),过程中发现两个既有事实(`skills:` frontmatter 只按名字动态加载内容、不需要重新部署;`org_level_loop.py` 的 `_ROUTE_FOR_CATEGORY` 从来没有 `skill_defect` 这个 key,`update_skill()` 在这个代码库里投产以来从未被真正调用过)——详见 §5 开头。由哪个身份执笔改 Skill 已通过 `AskUserQuestion` 确认(2026-08-12):统一用 Validator,见 §5.5。 | |
| 6 | +**状态**: Phase 2a(commit `86fc0bb`)+ Phase 2b(commit `7c46a2f`)已实现,2026-08-12。Phase 2c(Validator 接入自规划 + `org_node` 列删除 + 精确 loop_back 收口)待实施,详见 §10。**2026-08-08 修订**:写作过程中,需求文档 §7 的四个开放问题已被用户直接拍板(详见该文档 §7 对应条目),其中两条推翻了本文档最初的设计判断——Coder/Validator 自规划改为"建议节点清单"而非完全自由(§3),`work_graph_run.org_node` 改为彻底移除而非保留(§2.1)——本版本已按拍板结果改写,不是原始草稿。**2026-08-08 追加**(同日,见需求文档新增 §3.1):FR-4 的目标被明确为"失败即进化"完整方法论(判断失败 → Reflection-review 动态诊断 → 系统性缺陷则先 Fix-Skill → 跳回执行),当时 §5 设计的 `dynamic_loop_back` 只覆盖第 1/2/4 步,第 3 步(Fix-Skill)是已知缺口。**2026-08-12 补齐**:§5 已扩写为完整四步设计(§5.4 Reflection-review 现在同时判断目标节点和缺陷性质,§5.5 新增 Fix-Skill,真实调用既有但从未真正投入使用的 `skill_update.py::update_skill()`),过程中发现两个既有事实(`skills:` frontmatter 只按名字动态加载内容、不需要重新部署;`org_level_loop.py` 的 `_ROUTE_FOR_CATEGORY` 从来没有 `skill_defect` 这个 key,`update_skill()` 在这个代码库里投产以来从未被真正调用过)——详见 §5 开头。由哪个身份执笔改 Skill 已通过 `AskUserQuestion` 确认(2026-08-12):统一用 Validator,见 §5.5。 | |
| 7 | 7 | |
| 8 | 8 | --- |
| 9 | 9 | |
| ... | ... | @@ -508,14 +508,22 @@ Phase 1 阶段"复核失败先用现有 `org_level_loop.py` 粗粒度路由兜 |
| 508 | 508 | |
| 509 | 509 | ## 10. 实施顺序(拆成三个可独立验收的子阶段) |
| 510 | 510 | |
| 511 | -### Phase 2a — 引擎扩展(地基,不改任何 org 流程) | |
| 512 | -- §2.2(`ux_work_graph_run_active` 迁移)+ §4(节点级 subagent/skill/tools 绑定)+ §5(`dynamic_loop_back` 新分支)+ 对应单测。 | |
| 513 | -- 验收:一个手写的合成 graph_manifest(不经过真实 LLM 规划),节点声明不同的 `subagent_type`,运行后 `work_node_execution.subagent_type` 确实按节点区分;另一个手写 manifest 触发 `dynamic_loop_back`,验证真的能跳到候选节点之一且计数正确。 | |
| 514 | - | |
| 515 | -### Phase 2b — Coder 接入自规划 | |
| 516 | -- §3(`_GENERIC_PROMPT_TEMPLATE` 扩展)+ §2.3(`promotes_to_artifact`)+ §6(`implement_code()` 改造)。 | |
| 517 | -- 验收:一个真实 goal,Coder 自规划出多节点图(不是合成单节点),`code_diff`/`test_report` 正确落 artifact,中间节点不落。 | |
| 518 | -- 风险:`validator-test-script-narrative-output-issue.md` 记录的叙述文字复发风险在这一步首次真实暴露给 Coder,按需求文档非目标 §5.2 的要求专门验证。 | |
| 511 | +### Phase 2a — 引擎扩展(地基,不改任何 org 流程) ✅ 已实现(commit `86fc0bb`,2026-08-12) | |
| 512 | +- §4(节点级 subagent/skill/tools 绑定)+ §5(`dynamic_loop_back` 完整链路:Reflection-review + Fix-Skill)+ 对应单测。 | |
| 513 | +- **§2.2(`ux_work_graph_run_active` 迁移)实施时被推迟,没有跟这批一起做**——设计时发现 `plan_documents()`/`implement_code()` 产出的 `work_graph_run` 行在 happy path 上从来不会被标记 `'done'`(只有 Validator 自己的图会),如果现在就把索引收紧成 `UNIQUE(task_id)`,会在 Phase 2b 的追加机制真正接上**之前**就先把现有生产流程弄崩——Coder 一插自己的行就会跟还没结束的 Planner 行撞车。已重新确认要推迟到 Phase 2c(Validator 也接入追加机制、三段真正共享一个 run 之后)才安全,见 Phase 2b 状态行的第 4 条。 | |
| 514 | +- 验收:手写的合成 graph_manifest(不经过真实 LLM 规划),节点声明不同的 `subagent_type`,运行后 `work_node_execution.subagent_type` 确实按节点区分;另一个手写 manifest 触发 `dynamic_loop_back`,验证真的能跳到候选节点之一且计数正确——均已有对应单测(`src/test_work_graph_orchestrate.py`:`NodeLevelSubagentSkillTest`/`DynamicLoopBackContentErrorTest`/`DynamicLoopBackSkillDefectTest`/`TallyReflectionTest`)。 | |
| 515 | +- 实施过程中发现并修复的真实 bug:节点级 `skill_ref` 没有走 `ensure_placeholder_skill`,第一次用到新 skill_id 会撞外键约束——已在 `_run_one_node` 里补上。 | |
| 516 | +- `python3 -m unittest discover -s src`(741 tests)+ `discover -s supervisor`(126 tests)全绿。 | |
| 517 | + | |
| 518 | +### Phase 2b — Coder 接入自规划 ✅ 已实现(commit `7c46a2f`,2026-08-12) | |
| 519 | +- §3(`_generic_prompt_template` 按 org_node 扩展 + 建议目录)+ §2.3(`promotes_to_artifact`)+ §6(`implement_code()` 改造为 `plan_work_graph(..., append_to_run_id=run_id)`)。 | |
| 520 | +- 实施过程中定位并修复的、SDD 原稿没预见到的问题: | |
| 521 | + 1. **`_review_planner_output_with_retries()` 复用已有 artifact 分支硬编码 `run_id=None`**——每个真实 artifact 行本来就有真实的 `produced_by_run_id`,改成从 `sdd` artifact 读取真实 run_id,不再是 `None`(否则 Coder 在这条 resume 路径上完全没有 run 可追加)。 | |
| 522 | + 2. **`implement_code()` 从来没有真的传过 `needs_worktree=True` 给 `run_graph()`**——单节点合成图时代无害(图里只有一个节点,没有并发碰撞的可能),但自规划之后 Coder 图可能真的有并行写代码的节点,03-C §3.6 的隔离要求这次才第一次真正生效。 | |
| 523 | + 3. **`work_graph_fork.py::_reconstruct_build_prompt` 必须改成逐节点 dispatch**(原计划就在 Phase 2b 范围内,§2.1.2 已预见),否则合并图一旦真的出现 Coder 节点,fork 功能会直接报 `ForkGraphShapeUnsupportedError`。 | |
| 524 | + 4. **§2.2 索引收紧比 Phase 2a 判断的还要晚**:Phase 2a 曾判断"等 Phase 2b 落地后就能收紧",实施 Phase 2b 时发现不对——Validator 在 Phase 2c 之前仍然会给自己开一个独立的 `work_graph_run`,收紧到 `UNIQUE(task_id)` 会让 Validator 那次 INSERT 直接跟还没终结的 Planner+Coder 合并行冲突。§2.1/§2.2 已重新确认推迟到 Phase 2c(Validator 也接入追加机制之后)才安全。 | |
| 525 | +- 新发现的测试基础设施缺口(不是设计问题,是既有测试夹具没预料到并发层):合并图里"已完成的旧节点"和"刚追加的新节点"如果互不依赖,会被 `topological_layers()` 分进同一层,触发 `run_graph()` 的多节点并发路径——`test_task_execution.py`/`test_e2e_pipeline.py` 的测试连接原来没开 `check_same_thread=False`,从没触发过这条路径,现已修正(生产连接本来就是对的,`scheduler.py`/`task_execution.py` 早就用 `check_same_thread=False`,只是测试夹具没跟上)。 | |
| 526 | +- `python3 -m unittest discover -s src`(752 tests)+ `discover -s supervisor`(126 tests)全绿。 | |
| 519 | 527 | |
| 520 | 528 | ### Phase 2c — Validator 接入自规划 + 精确 loop_back 收口 |
| 521 | 529 | - Validator 侧的 §6 改造 + §7(新 skill + 退休粗粒度路由)+ §9 的核对清单。 | ... | ... |