Commit f74725ab5d0d11ddcb6efe8b84f58a9feec45dea
1 parent
ab4631c2
fix(company): 任务收敛到终态时清掉残留的 blocked_reason
settleTaskFromRun 只写 status/finished_at,不清 blocked_reason —— 任务卡住时 noteTaskBlockedReason 写过的那句「节点 xxx 卡住(...)」会一直挂在 tasks 行上, 哪怕后来 run 真的恢复跑完转 completed。界面上因此出现「已完成」绿色状态旁边 还留着一句刺眼的红字,容易被读成还在报错。 真实复现:T-mt2r6fz0-125b 手动推过熔断点后 org run 收敛到 completed, 任务列表却仍显示 org-coder 卡住的旧归因文本。手动清了这条任务的残留数据, 代码层面在 settleTaskFromRun 的 UPDATE 里一并置 NULL——task 进终态时 「为什么卡着」这句话本来就该失效,不管进的是 completed/failed/cancelled 哪一种。 扩展了 goal-task-acceptance.test.js 里"预算耗尽→恢复→跑完"那条既有用例, 断言 blocked_reason 在完成后确实被清空。全量单测 998/998 通过。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Showing
2 changed files
with
9 additions
and
1 deletions
server/services/work-graph-db.js
| ... | ... | @@ -2024,7 +2024,7 @@ function settleTaskFromRun(taskId, runId, status) { |
| 2024 | 2024 | const now = new Date().toISOString(); |
| 2025 | 2025 | return getDb() |
| 2026 | 2026 | .prepare(` |
| 2027 | - UPDATE tasks SET status = @status, finished_at = @now, updated_at = @now | |
| 2027 | + UPDATE tasks SET status = @status, blocked_reason = NULL, finished_at = @now, updated_at = @now | |
| 2028 | 2028 | WHERE id = @id |
| 2029 | 2029 | AND current_run_id = @runId |
| 2030 | 2030 | AND status NOT IN (${TASK_TERMINAL_STATUS.map((s) => `'${s}'`).join(', ')}) | ... | ... |
server/tests/unit/goal-task-acceptance.test.js
| ... | ... | @@ -304,6 +304,9 @@ describe('27-P3C 批 1 验收(§八 4 / 5 / 6 / 10 / 11 / 12b)', () => { |
| 304 | 304 | expect(sse.transitionRun(body.runId, 'running', 'blocked', {}, { summary: '用例模拟预算耗尽' })).toBeTruthy(); |
| 305 | 305 | // task 行要看得见「卡住了」—— 这是界面上唯一的信号 |
| 306 | 306 | expect(wdb.getTask(body.taskId).status).toBe('blocked'); |
| 307 | + // 界面上那句「卡在哪」的小字(真实链路里由 describeRunBlock + noteTaskBlockedReason 写) | |
| 308 | + expect(wdb.noteTaskBlockedReason(body.taskId, body.runId, '节点 xxx 卡住(budget_exhausted)')).toBe(1); | |
| 309 | + expect(wdb.getTask(body.taskId).blocked_reason).toBeTruthy(); | |
| 307 | 310 | // 但 goal 不许收敛:挂起等人加预算 ≠ 需求失败。判 failed 会写 OKR、唤醒上级、 |
| 308 | 311 | // 并把 goal 锁进终态,人加完预算跑完也再改不回 done(缺陷 2:误报 + 白烧一轮 LLM) |
| 309 | 312 | expect(wdb.getGoal(body.goalId).status).toBe('active'); |
| ... | ... | @@ -323,6 +326,11 @@ describe('27-P3C 批 1 验收(§八 4 / 5 / 6 / 10 / 11 / 12b)', () => { |
| 323 | 326 | const task = wdb.getTask(body.taskId); |
| 324 | 327 | expect(task.status).toBe('completed'); // 修之前这里永远钉死在 blocked |
| 325 | 328 | expect(task.finished_at).toBeTruthy(); |
| 329 | + // 33 号文档同批修的另一个真实 bug:settleTaskFromRun 只写 status,不清 blocked_reason, | |
| 330 | + // 于是任务列表在「已完成」绿色状态旁边,还会一直挂着上一次卡住时留下的那句红字 | |
| 331 | + // ——真实回归任务 T-mt2r6fz0-125b 复现过(org-coder 恢复跑完后,界面仍显示 | |
| 332 | + // 「节点 org-coder 卡住(missing_required_input)」)。 | |
| 333 | + expect(task.blocked_reason).toBeNull(); | |
| 326 | 334 | expect(wdb.getGoal(body.goalId).status).toBe('done'); |
| 327 | 335 | expect(okrCalls).toEqual([{ nodeId: 'O-002.1', status: 'done' }]); |
| 328 | 336 | ... | ... |