fix(tasks): claim the teardown report before the producer cancel runs
A throwing producer cancel jumped to the force-fail branch before `reported` was set, so `settle()` announced an unreported completion and the default wakeup delivery started a model turn on an owner the host was already destroying — the exact failure mode marking the record reported exists to prevent. Teardown claims the report before calling the producer, because that decision does not depend on whether the producer's cancel succeeds. Also reject a `maxConsecutiveWakes` that cannot bound anything: the field exists to cap a runaway chain, and `Infinity` removed the cap while a fraction never named a turn. Correct the module JSDoc and the background-task runtime note, both of which still promised that notices never wake an idle agent.
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-11-background-task-completion-wakes-an-idle-owner.md
|
||||
2026-08-11-background-task-completion-wakes-an-idle-owner.md: e9c437814fe1b75f57e0b7470a1ba9c699532ac4
|
||||
2026-08-11-background-task-completion-wakes-an-idle-owner.zh.md: 390b576e4eacfd266d5b19d7af33cc475640f1da
|
||||
2026-08-11-background-task-completion-wakes-an-idle-owner.md: 16cbd7ee3772edfb237f269a972217b8a6ad51a3
|
||||
2026-08-11-background-task-completion-wakes-an-idle-owner.zh.md: a09f8e9c99b3ca2e516c3e0de4727d4bce3008d6
|
||||
|
||||
@@ -70,3 +70,5 @@ A spent budget is restored only by user input. An unattended agent that exhausts
|
||||
A notice pending on an idle owner under `quiet` still dies with that owner's disposal, unchanged from before: the disposal cancel clears the unclaimed inbox and the log keeps the insert/cancel pair as the record. The [settlement delivery note](2026-08-06-manager-owned-subagent-settlement-delivery.md) owns the offline-mailbox discussion this would need.
|
||||
|
||||
Whether a completion extends the running turn or opens a new one is a genuine race for short-lived tasks, so no authored transcript can hold both orders. Assembled coverage asserts the outcome; the lane choice is pinned in unit tests.
|
||||
|
||||
One microtask window survives: a settlement landing after the turn loop's last inbox check but before the driver commits its idle phase still reads `status === 'running'`, so it injects and nothing wakes. Steering would not close it either — `wakeDriver()` latches only for maintenance and post-cancel phases, not for a driver between its final check and its own retirement. Closing it needs an `agent-loop` boundary that publishes retirement before the last claim, which is a core-agent decision rather than a delivery-policy one.
|
||||
|
||||
@@ -70,3 +70,5 @@ Status: implemented
|
||||
在 `quiet` 下待领于空闲所有者的通知仍会随该所有者释放而消亡,与此前一致:释放时的取消会清空未领取的 inbox,日志保留插入/取消这一对作为记录。[结算交付 note](2026-08-06-manager-owned-subagent-settlement-delivery.md) 承载这需要的离线信箱讨论。
|
||||
|
||||
对短命任务而言,完成究竟是延长运行中的轮次还是开启新轮次是一场真实竞态,因此没有哪份编写的 transcript 能同时容纳两种顺序。组装态覆盖断言结果;通道选择由单元测试钉住。
|
||||
|
||||
还残留一个微任务窗口:结算若落在轮次循环最后一次检查 inbox 之后、driver 提交 idle 相位之前,读到的仍是 `status === 'running'`,于是走注入且无人唤醒。改用 steer 也堵不上——`wakeDriver()` 只为 maintenance 与取消后的相位设置 latch,不为「最后一次检查与自身退休之间」的 driver 设置。要堵上它需要 `agent-loop` 在最后一次领取之前就发布退休状态,那属于核心 agent 的决策,而非交付策略。
|
||||
|
||||
Reference in New Issue
Block a user