Skip to content

[code-review] swarm_task_complete 幂等守卫非原子:Get+Update 竞态窗口击穿 double-fire 拦截,ExpectedStatus 原语漏用 #2794

Description

@topcheer

文件和行号
internal/tool/swarm_task_tools.go:367-383

问题描述
duplicate-complete 守卫是两步非原子:先 Get 检查 Status==Completed,再无条件 Update(UpdateOptions 只传 Status)。同文件 claim 路径(#861)已示范的 ExpectedStatus 条件更新原语在 complete 路径漏用。internal/task/manager.go 的 Manager.Update 整体在 m.mu 下执行且 ExpectedStatus 检查在锁内——原子 CAS 已存在但未使用。

触发场景
两个 teammate(stale 视图)并发调用 swarm_task_complete 同一 in_progress 任务:A/B 都通过 Get 检查(竞态窗口)→ A Update 成功 → B Update 也静默成功(completed→completed 无守卫,仅刷新 UpdatedAt)→ 双发 EmitBoardUpdated 事件。B 按注释声明语义("must not silently succeed")应失败但成功了。

预期行为 vs 实际行为
预期:并发 double-fire 第二次原子失败。实际:击穿守卫静默成功(无计数器损坏,仅语义矛盾+重复事件)。

修复建议
为 Update 增加 ExpectedStatus 多态支持(或新增锁内 CompleteIf 原语,允许 pending/in_progress 两态),complete 路径改用条件更新;顺带裁决"未 claim 的 Pending 任务可直接 complete"是否合法语义。

严重程度
low(独立复核确认:真实竞态窗口、修复原语就在同文件同族、无数据损坏副作用)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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