test(tasks): fence the background integration test on an idle owner

The rewritten test tolerated the interleaving where a fast command
settles before the running turn's next pre-step claim. The notice is
then folded into a step whose scripted reply is final, the turn closes
with an empty next-step inbox, and the collection entries are never
reached — a real timeout, not a tolerated ordering.

The command now blocks on a sentinel the test creates only after the
agent has gone idle, so the wake is the only path that can deliver the
notice, and the test asserts exactly two turns.

Also apply the review's smaller points: key the wake budget by Agent
rather than object, register the budget-refill listener only under
wakeup delivery, pin the schema default and rejection like
reportDelivery does, record the retirement-window stranding as a Known
Limitation, and cross-link the partial supersession both ways.
This commit is contained in:
Yichen Jiang
2026-08-11 20:39:04 +08:00
parent 75b26988dc
commit fa349202c7
9 changed files with 59 additions and 25 deletions
@@ -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: 16cbd7ee3772edfb237f269a972217b8a6ad51a3
2026-08-11-background-task-completion-wakes-an-idle-owner.zh.md: a09f8e9c99b3ca2e516c3e0de4727d4bce3008d6
2026-08-11-background-task-completion-wakes-an-idle-owner.md: cbebf1fbe82d47db4ba6e39b318d2e8ed8d89e17
2026-08-11-background-task-completion-wakes-an-idle-owner.zh.md: b5f3cdd594b04370dcfe99d83775f34ab8b8115c
@@ -10,6 +10,8 @@ English | [中文](2026-08-11-background-task-completion-wakes-an-idle-owner.zh.
The gap was recorded as a limitation rather than reasoned about, so the fallback was `task_output(wait: true)` — the blocking wait the same prompt discourages.
This supersedes one fact of the [background-task runtime decision](../architecture/2026-06-20-generic-long-running-tool-runtime.md) — that completion never wakes an idle owner — and adds teardown as a `reported` setter. That note keeps every other task-runtime decision and is updated in place rather than replaced.
The delivery machinery was never the obstacle. `Agent.send(message, target, wakeup)` has covered the `target` × `wakeup` matrix since the [unified send decision](../architecture/2026-07-22-unified-send-and-coalesced-user-messages.md), and `wakeDriver()` already handles idle, maintenance, and cancelled-converging phases. The missing piece was the policy choice of which lane a completion takes, plus the bound that choice needs.
## Decision
@@ -10,6 +10,8 @@ Status: implemented
这个缺口被记为一条限制,而不是被推敲过,于是退路成了 `task_output(wait: true)`——同一段提示词并不鼓励的阻塞等待。
本决策取代[后台任务运行时决策](../architecture/2026-06-20-generic-long-running-tool-runtime.md)中的一条事实——完成永不唤醒空闲所有者——并把 teardown 加为 `reported` 的置位方。那份 note 仍拥有其余全部任务运行时决策,因此就地更新而非替换。
交付机制从来不是障碍。自[统一 send 决策](../architecture/2026-07-22-unified-send-and-coalesced-user-messages.md)起,`Agent.send(message, target, wakeup)` 就覆盖了 `target` × `wakeup` 矩阵,`wakeDriver()` 也已经处理 idle、maintenance 和已取消未收敛三种相位。缺的是「一次完成走哪条通道」这一策略选择,以及该选择所需的界。
## 决策