Skip to content

fix(server): tell parents when a delegated task is waiting for input - #13343

Open
saphid wants to merge 1 commit into
pingdotgg:t3code/codex-turn-mappingfrom
saphid:fix/v2-subagent-blocked-reports
Open

saphid wants to merge 1 commit into
pingdotgg:t3code/codex-turn-mappingfrom
saphid:fix/v2-subagent-blocked-reports

Conversation

@saphid

@saphid saphid commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

What Changed

When a delegated child asks a question or needs an approval, its parent now hears about it.

The server watches for new pending runtime requests. When one lands on an app-owned delegated child (one created by delegate_task), it queues a notice on the parent thread with three pieces of information:

  • Which task: the task ID, plus a timeline notification such as "Load test lane is waiting for an answer to a question".
  • What it's blocked on: a question, an approval (with its kind), or a sign-in.
  • How to act: a question can be read and answered with t3_pending_request_read and t3_pending_request_respond, using the child thread ID and request ID given in the notice. Approvals and sign-in need the user.

The child is not marked finished and no result is published. Its final result still arrives through the normal completion delivery when it ends.

The notice is server-owned, like a completion delivery, so it follows the same rules:

  • Dedup: one notice per request. The command ID includes the request ID, so a repeated update for the same request does not queue a second notice.
  • Race safety: eligibility is checked under the parent lock. No notice is queued for a finished task, a task the parent has dropped, or an archived or deleted parent.
  • Stop: pressing Stop on the parent cancels every queued notice, so none can start a new parent turn after a Stop.
  • Dropping the task: task_cancel, reading the task's final result, and the existing cohort disposal (Queue Remove, archive, delete) cancel the queued notices for those tasks.

Web and mobile already render notification items from their summary, so there is no client change.

Why

A delegated child that asked a question just waited. Its run stayed running, so the parent was never woken, and once the parent's own turn ended nobody would answer. The parent could only find out by polling task_status. We saw a child waiting on a question after its parent's turn had already finished, with nothing that would ever answer it.

This is one of a few focused fixes to make sure a parent learns when a child stops. #13938 fixed results that were never delivered, and #13345 covers children stopped by restart recovery.

Known limits:

  • If the request is answered before the parent's queued notice runs, the notice is not withdrawn. Its text says the request may already be resolved.
  • Requests that were already pending when the server starts are not replayed.

Tests

DelegatedCompletionDelivery.test.ts: new test "tells the parent once when its child blocks on a request". It waits on persisted parent events and checks:

  • the notification and the wording for questions and for approvals
  • that a repeated request update does not queue a second notice
  • that the child stays running and no result is published
  • that task_cancel cancels that task's queued notices
  • that Stop cancels a queued notice from a task spawned by an earlier parent turn

On t3code/codex-turn-mapping the test times out waiting for the notice. Removing the dedup, the task_cancel cancellation, or the Stop cancellation each makes it fail.

47 tests pass in DelegatedCompletionDelivery, OrchestratorMcpToolkit.integration, SteeringCompletion.integration, RuntimeRequestService, ProviderEventIngestor, ThreadDeletion, OrchestratorMcpService, and ProviderTurnControlService. Server typecheck is clean.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes (no UI change; the notice uses the existing notification row)
  • I included a video for animation/interaction changes (no UI change)

This change was made by Claude Opus 5.5 with Claude Code and reviewed by GPT-6 Astra with Codex.

🤖 Generated with Claude Code

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 24, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This adds an always-on server-side notification and scheduling path between delegated child and parent threads, including new cancellation barriers for Stop and task disposal. The change affects production orchestration behavior and can trigger additional parent processing, beyond a small isolated fix.

No code changes detected at 151c43a. Prior analysis still applies.

You can add or adjust custom eligibility rules. Learn more.

Comment thread apps/server/src/orchestration-v2/Orchestrator.ts
@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch 3 times, most recently from fe4f6ad to 87c67bd Compare September 25, 2026 05:55
@saphid
saphid force-pushed the fix/v2-subagent-blocked-reports branch from 8b259bc to 151c43a Compare September 25, 2026 07:34
A delegated child that asked a question or needed an approval simply
waited. Its run stayed running, so the parent was never woken, and once
the parent's own turn ended nobody would answer. The parent could only
find out by polling task_status.

When an app-owned child records a pending runtime request, queue a
notice on the parent: which task is blocked, on what, and how to act
(questions can be answered with t3_pending_request_respond; approvals
and sign-in need the user). The child keeps running and its result is
still delivered when it finishes. The command id is per request, so a
repeated update for the same request does not queue a second notice.

The notice is server-owned like a completion delivery, so the same
barriers apply: eligibility is checked under the parent lock, Stop
cancels queued notices, and task_cancel, acknowledgement, and cohort
disposal cancel the notices for their tasks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@saphid
saphid force-pushed the fix/v2-subagent-blocked-reports branch from 151c43a to 742dcc0 Compare September 27, 2026 23:32

This branch has not been deployed

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

Labels

size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant