Repository navigation
Description
What happens
A completed delegated task wakes its parent thread as a steer, even while the parent waits on a pending request (a question or an approval). The pending-request guard never sees that steer.
At 409b1b09 (v0.1.3-lazurio.1):
apps/server/src/orchestration-v2/Orchestrator.ts:5197resolves the dispatch throughresolveMessageDispatchIntent.- Its guard (
CommandPolicy.ts:170) turnssteer_activeintoqueue_after_activewhilewaitsOnPendingRequest(projection)holds (With steer as the default (v0.1.3), any steer must queue while the turn waits on a pending question or approval #139).
- Its guard (
- Later in the same command, the durable-mailbox branch (
Orchestrator.ts:5328-5360) setsdispatchMode = { type: "steer_active", … }for a delegated completion whose tasks all havecompletionWake: "always".- That holds for every non-
waitdelegate_task(OrchestratorMcpService.ts:2225,:2287). - It applies when the session supports active steering and steering doesn't interrupt tools.
- The pending-request guard isn't applied again.
- That holds for every non-
Who is affected:
- Not Claude:
activeSteeringInterruptsTools: trueexcludes it. - Hermes over ACP is, since feat(acp): steer an agent's running turn through _lazurio/steer instead of cancelling it #141 (
provider-acp/src/server/adapter.ts:634). - Possibly any other provider that supports active steering without interrupting tools.
What it does there:
- A parent that waits on
clarifygets the wake text as a steer, and the run is projected as steered rather than queued. - In Hermes the steer only appends to the pending steer parts (
agent/interrupt_control.pysteer).clarify's wait (tools/clarify_gateway.pywait_for_response) ends only on an interrupt, so the question should stay, and the text arrives after the answer, in the same turn. That's a reading of the code, not yet observed. - Even if the question stays, the wake is reported delivered before the question is answered. That breaks the order With steer as the default (v0.1.3), any steer must queue while the turn waits on a pending question or approval #139 promises.
Not this path: Buddy's Delegace wakes. They come through t3 thread send in queue mode and pass the guard.
Expected
A delegated completion that would steer goes through the same pending-request guard: while the parent has a pending runtime request, it waits behind the turn (queue_after_active).
Suggested fix
In the durable-mailbox branch, set steer_active only when !waitsOnPendingRequest(projection), or re-apply the guard after it.
Test:
- a parent on an ACP session with active steering and a pending request, plus a
completionWake: "always"task that completes: the wake queues after the active run; - without a pending request, it steers as today.
Context
Found by the T3 Release bot's independent audit of the v0.1.4 rebuild (#144). The finding exists on main at 409b1b09 too. The fix is planned with the v0.1.5 rebuild. The stable 0.1.3-lazurio.1 ships without it, because the observable effect is limited to the cases above. Ring 0 acceptance 13 in Buddy's chat (#138) covers the Delegace path.
🤖 Generated with Claude Code
Activity
immakermatty commentedon Oct 31, 2026
Supervisor of T3 Release: the fix for this issue is already in the rebuild #152. It came from the v0.1.4 dry run (#144, finding 4 of the independent audit) and was carried through #149.
The evidence is on #152's head
0ddf6f4628cfe6e9593cd29b5d310eda8ebc982e:apps/server/src/orchestration-v2/Orchestrator.ts:5606puts!waitsOnPendingRequest(projection)on the branch that promotes a delegated completion wake tosteer_active.SteeringCompletion.integration.test.ts:1279has the case "A delegated task's completion wake steers on its own path, so it needs the guard too".steer_activeproducer against the guard. That included this T3-nativedelegate_taskwake.The issue closes once #152's head becomes
mainand the stable from it is published. Until then, the stablev0.1.3-lazurio.1(409b1b09) still has this defect. The scope correction above stands: Buddy's Delegace wakes through queue mode and is covered by #139, not by this path.