diff --git a/apps/server/src/mcp/toolInstructions.ts b/apps/server/src/mcp/toolInstructions.ts
index 502aae43b4..7836dc87c1 100644
--- a/apps/server/src/mcp/toolInstructions.ts
+++ b/apps/server/src/mcp/toolInstructions.ts
@@ -1,6 +1,6 @@
/** Prism guidance shared by every provider runtime. */
export const T3_CODE_TOOL_USE_INSTRUCTIONS = `
Use the t3-code MCP tools for visible agent work. Delegate children with delegate_task (role and optional lane/prismRole); launch explicitly requested top-level work with t3_thread_launch. Prism chooses provider, model and effort unless the user supplies an explicit target/modelSelection. Never substitute shell agent CLIs.
-Use task_status/task_cancel for delegated tasks and t3_thread_read/t3_thread_wait/t3_thread_interrupt for ordinary threads. Each review round is a new delegate_task call with its full brief and prior findings. Use t3_pending_request_respond only within its advertised permissions.
+Use task_status/task_cancel for delegated tasks and t3_thread_read/t3_thread_wait/t3_thread_interrupt for ordinary threads. Each review round is a new delegate_task call with its full brief and prior findings. To continue the same job after a stop or a cleared blocker, t3_thread_send to its childThreadId and t3_thread_wait on it; follow-ups do not wake you. Use t3_pending_request_respond only within its advertised permissions.
Machine recovery is automatic: usage limits wait for reset; retryable provider failures receive at most one persisted retry on the same provider and model. Stop and retirement cancel recovery. Completed or silent work stays the parent's decision; optional prismRole retry/escalation requests a new kit when appropriate.
`;
diff --git a/apps/server/src/mcp/toolkits/orchestrator/tools.test.ts b/apps/server/src/mcp/toolkits/orchestrator/tools.test.ts
index e95639d308..32df33da75 100644
--- a/apps/server/src/mcp/toolkits/orchestrator/tools.test.ts
+++ b/apps/server/src/mcp/toolkits/orchestrator/tools.test.ts
@@ -24,6 +24,10 @@ describe("orchestrator MCP tool guidance", () => {
OrchestratorToolkit.tools.t3_thread_send.description ?? "",
"Do not use a delegated task's childThreadId to start another review round",
);
+ assert.include(
+ OrchestratorToolkit.tools.t3_thread_send.description ?? "",
+ "To continue the same delegated job after it stopped",
+ );
assert.include(
OrchestratorToolkit.tools.task_cancel.description ?? "",
"This includes later child-thread runs, even after the task is terminal",
diff --git a/apps/server/src/mcp/toolkits/orchestrator/tools.ts b/apps/server/src/mcp/toolkits/orchestrator/tools.ts
index 6f7f8b56d6..90789cf881 100644
--- a/apps/server/src/mcp/toolkits/orchestrator/tools.ts
+++ b/apps/server/src/mcp/toolkits/orchestrator/tools.ts
@@ -219,7 +219,7 @@ export const ThreadUpdateTool = Tool.make("t3_thread_update", {
const ThreadSendTool = Tool.make("t3_thread_send", {
description:
- "Send a message to any T3 thread in this environment. The target cannot have broader permission modes than the caller. Do not use a delegated task's childThreadId to start another review round here; use delegate_task with the full review context and a new clientRequestId for that round. Thread messages do not create a new delegated task or reopen a completed task. Spectrum transcript threads return runId=null, status=idle and delivery=transcript; they never start a provider on the transcript thread. mode='auto' starts an idle thread, steers a fully active turn, or queues behind a turn that is not yet steerable. Use queue for a separate follow-up turn, steer for an in-flight update, or restart to interrupt-and-restart the active turn. clientRequestId makes retries idempotent.",
+ "Send a message to any T3 thread in this environment. The target cannot have broader permission modes than the caller. Do not use a delegated task's childThreadId to start another review round here; use delegate_task with the full review context and a new clientRequestId for that round. To continue the same delegated job after it stopped, send here to its childThreadId and wait with t3_thread_wait; the result appears in task_status latestTerminal* and does not wake the parent. Thread messages do not create a new delegated task or reopen a completed task. Spectrum transcript threads return runId=null, status=idle and delivery=transcript; they never start a provider on the transcript thread. mode='auto' starts an idle thread, steers a fully active turn, or queues behind a turn that is not yet steerable. Use queue for a separate follow-up turn, steer for an in-flight update, or restart to interrupt-and-restart the active turn. clientRequestId makes retries idempotent.",
parameters: OrchestratorMcpThreadSendInput,
success: OrchestratorMcpThreadSendResult,
failure: OrchestratorMcpFailure,
diff --git a/apps/server/src/provider/T3OrchestrationInstructions.test.ts b/apps/server/src/provider/T3OrchestrationInstructions.test.ts
index e625e40c11..65ff11ec72 100644
--- a/apps/server/src/provider/T3OrchestrationInstructions.test.ts
+++ b/apps/server/src/provider/T3OrchestrationInstructions.test.ts
@@ -18,6 +18,8 @@ describe("T3 orchestration provider instructions", () => {
T3_CODE_ORCHESTRATION_INSTRUCTIONS,
"Do not use `t3_thread_send` on `childThreadId`",
);
+ assert.include(T3_CODE_ORCHESTRATION_INSTRUCTIONS, "To continue the same delegated job");
+ assert.include(T3_CODE_ORCHESTRATION_INSTRUCTIONS, "does not wake you");
});
it("documents structured schedules instead of JSON strings", () => {
diff --git a/apps/server/src/provider/T3OrchestrationInstructions.ts b/apps/server/src/provider/T3OrchestrationInstructions.ts
index af71b98d77..3a3100f869 100644
--- a/apps/server/src/provider/T3OrchestrationInstructions.ts
+++ b/apps/server/src/provider/T3OrchestrationInstructions.ts
@@ -9,6 +9,7 @@ The \`t3-code\` MCP server provides app-owned orchestration. Treat these concept
- A delegated task/subagent is child work owned by the current thread. Use \`delegate_task\` so Prism selects the provider, model and effort from the configured role kit and capacity. Omit \`target\` unless the user explicitly chose a provider/model; an explicit target wins over Prism. Upstream role labels map to kits: implementation/test/general to worker, review to reviewer, research/design to planner. Use optional \`lane\` for worker difficulty and \`prismRole\` for an explicit kit. Retain each returned \`taskId\`, and use \`task_status\` or \`task_cancel\` to manage it. The returned \`childThreadId\` is backing storage, not the target for starting another delegated review round. Do not start shell agent CLIs or native subagents for work that belongs in visible T3 threads.
- \`t3_thread_launch\` and \`create_threads\` create ordinary top-level T3 conversations. \`t3_thread_launch\` uses Prism and accepts optional \`prismRole\` (including dispatcher or promachos) and \`lane\`; an explicit \`modelSelection\` wins. Use them only when the user explicitly asks for separate/new/top-level threads or conversations. Never use them merely because the user said "subagent" or requested parallel delegated work.
- For every T3 delegated review round, call \`delegate_task\` again. Include the original brief, prior findings, responses, and unresolved objections in each new task prompt. Track each round by its own \`taskId\`. Use a distinct \`clientRequestId\` per round, stable across retries of that round. Do not use \`t3_thread_send\` on \`childThreadId\` to continue a delegated review.
+- To continue the same delegated job after it stopped on a blocker or question that has since been resolved (the user answered, granted access, or cleared the blocker), send the follow-up to that task's \`childThreadId\` with \`t3_thread_send\` and wait on it with \`t3_thread_wait\`; the child keeps its context. The follow-up result appears in \`task_status\` as \`latestTerminal*\` and does not wake you. Start a new \`delegate_task\` only for independent work, such as a fresh review round or a different job.
- \`schedule_task\` creates persistent recurring work in the app scheduler. Pass \`schedule\` as a structured object, never as JSON text: \`{"type":"interval","everyMs":3600000}\` for an interval, or \`{"type":"fixed_time","timeOfDay":"09:00","weekdays":[1,2,3,4,5]}\` for a wall-clock schedule, or \`{"type":"webhook"}\` to run on each request to the returned \`webhookUrl\` (the run sees the request only through \`{{body.path}}\`-style placeholders in the prompt). By default runs return to the current thread, which suits orchestrating: each trigger arrives here and you delegate or dedupe; set \`bindToCurrentThread=false\` only when the user wants a fresh thread for every run. After scheduling a timer, report the returned cadence and next run time; for a webhook, report its \`webhookUrl\`, or say T3 Connect remote access is needed if it is missing.
- When you need a secret from the user (a token, API key, or webhook signing secret), call \`request_secret\` so they enter it privately, then pass the returned \`secretRef\` to the tool that needs it, e.g. \`signature.secretRef\` on a webhook task for a sender that signs requests such as GitHub. A \`secretRef\` works once. Never ask for a secret in chat, never invent one, and never repeat one.
- To mention another thread to the user, link it as \`[title](t3-thread://v1/)\` with its exact \`threadId\`, not URL-encoded. T3 Code opens the thread in the app and shows its current title.