Skip to content

TaskCompleted hook 会拦截合法的 TaskUpdate completed 状态更新 #18

@cuipengcx90

Description

@cuipengcx90

背景

在 Claude Code + hello2cc 插件环境下,我使用任务面板跟踪实际开发工作。

实际场景中,代码修改、验证、构建都已经完成,但在调用 TaskUpdate(status=completed) 将任务标记为完成时,任务状态没有成功切换为 completed,而是仍然停留在 pending / in_progress

这会导致:

  • 实际工作状态与 task board 状态不一致
  • UI 看起来像任务没有完成
  • 后续继续使用任务面板时容易产生误导

现象

在尝试将任务标记为 completed 时,hook 会返回类似错误:

  • Task description should include completion evidence such as tests, validation, exact paths, or another acceptance check.
  • Task description is too short. Include the intended deliverable, scope, and completion evidence.

然后本次状态更新被拒绝,任务不会进入 completed。

复现步骤

  1. 创建一个普通任务
  2. 完成实际代码工作,并且已经通过验证(例如构建通过)
  3. 调用 TaskUpdate,将任务状态设置为 completed
  4. 如果 description 不满足 hook 当前要求的格式,状态更新会被拦截

实际结果

  • 工作已经完成
  • 验证也已经通过
  • 但任务面板仍显示为未完成

期望结果

  • 当任务已经完成,并且状态更新是合法的,任务应能被正常标记为 completed
  • task board 应与真实开发状态保持一致
  • task description 的质量检查不应导致 task 状态同步失败到这种程度

根因分析

问题来源于 hello2cc 插件的 task lifecycle hook。

1. task-lifecycle.mjs 使用 fail-closed 方式硬拦截

文件:scripts/task-lifecycle.mjs

逻辑大致为:

const feedback = validateTaskDefinition(payload);
if (feedback) {
  process.stderr.write(`${feedback} ...`);
  process.exit(2);
}

只要校验返回 feedback,就直接 exit 2,从而阻断任务完成状态更新。

2. task-quality.mjs 对非创建事件统一要求 completion evidence

文件:scripts/lib/task-quality.mjs

export function taskRequiresCompletionEvidence(hookEventName) {
  return normalizeHookEventName(hookEventName) !== 'TaskCreated';
}

这意味着除了 TaskCreated 之外,其他 task 生命周期事件都会进入“需要完成证据”的严格模式。

这个判断过于宽泛,导致 task 的状态流转被 description 格式强耦合。

为什么这是个问题

这不是单纯的“校验严格”,而是一个实际的工作流 / UX 问题:

  1. 真实工作已经完成
  2. 验证已经完成
  3. 任务状态却无法同步为 completed
  4. task board 与实际代码状态发生漂移

这会削弱任务面板作为真实状态来源的可信度。

影响

  • task board 可能长期显示错误状态
  • 用户会误以为某些任务仍未完成
  • agent / 用户后续继续基于 task board 做判断时,容易产生偏差
  • 实际完成的工作需要为了通过 hook 而反复修改 description,增加不必要的摩擦

建议修复方向

建议任选其一或组合处理:

方案 A:只对真正的完成事件启用严格 completion evidence 校验

不要把“所有非 TaskCreated 事件”都视为需要完成证据。

方案 B:把这类校验从 hard block 改为 warning

即使 description 不够理想,也不要直接阻止 TaskUpdate(status=completed) 成功。

方案 C:降低校验脆弱度

如果仍要阻断完成状态,建议减少对 description 格式的敏感度,不要因为文本组织方式问题就导致状态无法同步。

环境信息

  • Claude Code
  • hello2cc 插件启用
  • 使用任务面板进行开发任务跟踪
  • 在实际代码工作和验证已完成后调用 TaskUpdate(status=completed)

补充说明

我这边原本已经完成了实际前端任务,但因为 hook 拦截,task board 里仍然显示部分任务为 pending / in_progress,这就是本 issue 的直接触发场景。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions