fix(orchestrator): 拆解未批准前冻结子任务——父任务 plan_review/analyzing 期间子任务不可领取

修复 bug:auto-approved 项目里 planner 拆解后子任务立即被领取执行,而父任务还在
plan_review 等人审批,导致拆解若被驳回则子任务已白跑。claimable 加闸:子任务的父任务
处于 plan_review(待审拆解)或 analyzing(拆解中)时冻结,批准(decomposed)后放行。
仅冻结这两态,不影响 todo-sync 等其它带 parentId 的流程。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-29 10:57:24 +08:00
parent f5ea32a600
commit 3780f1c064
2 changed files with 22 additions and 0 deletions
+17
View File
@@ -415,6 +415,23 @@ test('claimable 纳入 analyzinghard 任务派 planner-decompose', () => {
store.close();
});
test('子任务在父任务 plan_review 期间不可领取,拆解批准(decomposed)后放行', () => {
const { store, projectId } = setup('auto-approved');
const parent = store.createTask({ projectId, title: 'epic', complexity: 'hard' }); // → analyzing
const child = store.createTask({ projectId, parentId: parent.id, title: 'sub', complexity: 'easy' }); // → ready
store.transition(parent.id, 'plan_review', { by: 'test' }); // 模拟拆解完成待审
const state = freshState();
const { deps } = mockDeps(state);
const orch = createOrchestrator(store, noopLog, deps);
orch.claimTick();
assert.equal(state.spawned.length, 0, '父任务 plan_review(拆解待审)期间,子任务不应被领取');
store.transition(parent.id, 'decomposed', { by: 'test' }); // 批准拆解
orch.claimTick();
assert.equal(state.spawned.length, 1, '拆解批准后子任务放行可领取');
assert.equal(store.listRuns(child.id).length, 1, '被领取的是该子任务');
store.close();
});
test('auto-easy 不做规划:medium(speccing) 不被领取', () => {
const { store, projectId } = setup('auto-easy');
const t = store.createTask({ projectId, title: 'feat', complexity: 'medium' }); // → speccing