Files
pikasTech-unidesk/docs/MDTODO/details/agentrun-runtime-reliability/R9_Task_Report.md
T

4.6 KiB
Raw Blame History

R9 任务报告:post-task 去重串线取消事故

结论

本次事故不是 AgentRun 自动控制器执行 sibling task reconcile,也不是后端按投影自动取消。

事故由两段 UniDesk 受控流程缺陷串联产生:

  1. Artificer Target create 的 idempotency key 未绑定最终 prompt/payload,且显式 --idempotency-key 可以绕过 canonical identity
  2. 外部 post-task 收尾操作按一次 dispatch 归组,并用相同 reason 人为取消三个不同 logical operation。

引入提交为 43124d01。该提交建立 Target 只读预检、完整位置上下文和自动 dispatch,整体方向符合当前规格;本次属于局部幂等实现缺陷,不满足整 PR 方向错误的语义回滚条件,因此没有回滚整个提交。

离线证据

三个被误取消 task

  • qt_d214e48f4b0d4d6e899428e2855121acpayload hash 为 e7c8bb1016fad9a2e27fb69b20c9c5c069fe13fb1632edf8c604c3a5ad79c3c3
  • qt_7c12fa9735634934a64986a1d45cfc44payload hash 为 b48d75f1d717ff36d640f67b28a44c1f016183b677680e727c3ac27a1aa1e206
  • qt_45e692244cbd42a9aa28cc9706f4a28fpayload hash 为 bccec985937e047e95b1fed23da15927f60f14d3ac36c58ac7101329487572b6

三者在 2026-07-15 09:19:0309:19:42 UTC 进入 cancelledfailure message 完全相同:

duplicate create task from one post-task dispatch; preserve qt_c94a19c6bd824551bcb7b22a51c266af

被保留的 qt_c94a19c6bd824551bcb7b22a51c266af payload hash 为 7904461ada875b99d79c4a98a0d82ba7b75bffa3e4c2524ebcb1f3e2ac2cc15f,属于 Issue #1888。该 task 随后在 2026-07-15 09:22:16 UTC 以“请求 #2170 却复用旧 #1888 input”原因取消,证明 create 幂等复用已经先发生串线。

仓库源码与 Git 历史中不存在上述 duplicate reason,也不存在按 post-task dispatch 自动扫描和取消 sibling task 的 controller。AgentRun session 事件还证明 #1888 session 自身只取消了它刚误创建且尚无 attempt 的嵌套副本,没有执行本次三项取消。

修复

scripts/src/agentrun/target-task.ts 现在生成版本化 canonical logical-operation fingerprint,绑定:

  • tenant/project
  • Aipod
  • MDTODO
  • Target
  • repository/ref
  • 绝对 targetWorkspace
  • 已核验源码提交;
  • 最终 prompt 的 SHA-256 payload hash。

同一 operation 重放生成相同 key;任一 scope 或 payload 变化都会生成不同 key。

Target create 收到显式 --idempotency-key 时,只接受与 canonical key 完全一致的值。不同 payload 复用旧 key 会在 render 和 queue mutation 前返回:

  • stageidempotency-key-conflict
  • codetarget-task-idempotency-key-conflict
  • reasonprovided-key-does-not-match-canonical-logical-operation
  • canonical fingerprint
  • payload hash
  • provided key 的不可逆 fingerprint
  • mutation=falsevaluesPrinted=false

task metadata、dry-run 和 mutation 摘要保留 logical-operation evidence,供事件和 OTel 投影读取,不打印 prompt 或 Secret。

unidesk-subagent skill 同步明确:

  • 禁止按 dispatch、时间窗口、session、标题或列表邻近关系判定重复;
  • identity 不全、投影陈旧或终态不确定时只 warning;
  • post-task cleanup 不得取消 sibling task
  • 取消只用于用户明确授权目标或同一 task/attempt 的受控终止。

验证

Target 原入口轻量验证:

git diff --check
bun test scripts/src/agentrun.test.ts --test-name-pattern 'Artificer Target'

结果:4 个测试通过,0 失败,72 个断言。fixture 覆盖 R8、R7.1、R7.2 与 #1888 四个不同 logical operation,并验证:

  • 四个 key 全部不同;
  • 同一请求重放 key 稳定;
  • prompt 变化会改变 key
  • 显式旧 key 与新 payload 冲突时返回 typed evidence,且不披露原 key。

OTel 证据边界

事故时间窗的 Tempo 搜索没有找到 queue task cancel HTTP route、task ID 或 cancel reason span。当前 AgentRun durable attempt terminal fact 可证明取消结果和 reason,但不能从 OTel 单独恢复取消调用者。

调查 trace 01fb780dc5184363fea5f8ef859c9031 仅覆盖本次 R9 只读调查命令,不作为事故调用者证据。修复后的 logical-operation evidence 已进入 task metadataPR 自动交付后应从新的正常 create/replay 原入口确认对应 span/event 投影。

本任务没有新增锁、租约、第二状态库、数据库迁移或运行面围栏;没有取消任何现存 task,没有执行 runtime patch、人工 CI/CD 或 PR merge。

关联:UniDesk #2176MDTODO R9