Thu Oct 22 02:00:36 UTC 2026 23673c96f8937d7c18a5c323daa78c4537d9c697 SOURCE FIDELITY: git diff 8acbefefc5 -- apps/server/src/mcp/toolkits/orchestrator/tools.ts packages/provider-core/src/server/orchestrationInstructions.ts WORKSPACE DEPENDENCY: /tmp/issue19821-red-evidence/packages/provider-core COMMAND: vp test run apps/server/src/mcp/toolkits/orchestrator/tools.test.ts apps/server/src/provider/CodexDeveloperInstructions.test.ts note: You are running `vp test` as a Vite+ built-in command. If you meant to run the test npm script, use `vpr test` instead. RUN v5.0.5 /tmp/issue19821-red-evidence ❯ |t3| src/mcp/toolkits/orchestrator/tools.test.ts (2 tests | 1 failed) 90ms × separates independent review rounds from same-conversation follow-ups 75ms ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ FAIL |t3| src/mcp/toolkits/orchestrator/tools.test.ts > separates independent review rounds from same-conversation follow-ups AssertionError: instructions: expected '\n\n## T3 Code orchestration\n\nThe `…' to match /independent review rounds?/i - Expected: /independent review rounds?/i + Received: " ## T3 Code orchestration The `t3-code` MCP server provides app-owned orchestration. Treat these concepts distinctly: - A delegated task/subagent is child work owned by the current thread. Use `orchestrator_capabilities` to discover the current provider/model IDs from the same live catalog as the composer, including configured custom models. It lists a short set of models per provider; pass `search` to find others. Do not treat a native tool's model list as the full list of available subagent models. Prefer native subagent tools for same-provider work only when they support the chosen model and no model options are requested or inherited. Use `delegate_task` with that provider instance and model when native tools cannot, including for same-provider work. Also use `delegate_task` for cross-provider or explicitly T3-owned child tasks. For a child task that needs a separate checkout, use `delegate_task` with `isolation:\"worktree\"` across any provider or model. It starts from the parent local commit and runs project setup; uncommitted edits are not copied. Retain each returned `taskId`, and use `task_status` or `task_cancel` to manage it. The returned `childThreadId` is backing storage for the subagent, not the target for starting another delegated review round. - `t3_thread_launch` and `create_threads` create ordinary top-level T3 conversations. 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. - `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. ### Choose the workspace before starting a new thread For independent implementation or a PR stack in its own worktree, use `t3_thread_launch` with an explicit `workspaceStrategy`. It creates or selects the workspace, binds the new thread to it, and prepares it before the agent starts. Put the task in `message`, not `prompt`: - New worktree: `{\"title\":\"UI cleanup\",\"workspaceStrategy\":{\"type\":\"worktree\",\"baseRef\":\"feature/base\",\"branch\":\"feature/ui-cleanup\",\"startFromOrigin\":false},\"message\":\"Implement the cleanup and open a PR against feature/base.\"}` - Existing worktree: `{\"title\":\"Continue cleanup\",\"workspaceStrategy\":{\"type\":\"existing_worktree\",\"worktreePath\":\"/absolute/path/to/worktree\",\"branch\":\"feature/ui-cleanup\"},\"message\":\"Continue the cleanup.\"}` - Project's main checkout: `workspaceStrategy:{\"type\":\"root\"}`. Omitting workspaceStrategy also selects root; it does not inherit the caller's worktree. For stacked work, set `baseRef` to the intended parent branch and `startFromOrigin:false` to use its local commits. Use `startFromOrigin:true` when you intend to fetch the base branch's remote and start from it. Uncommitted edits are not copied. Use `t3_worktree_list` to discover existing checkout paths. Project, model selection, and modes inherit unless supplied; a launched thread may not run with broader modes than yours. `t3_thread_launch` is the single-thread launch tool. Use `create_threads` only for a batch of threads intentionally sharing the caller's checkout: it always inherits the caller's project, branch, and worktree and has no workspace override. Asking an agent to run `git worktree add` or `cd` in its prompt does not update T3's thread binding. Select the workspace in the launch call instead. `t3_worktree_handoff` moves the calling thread, not another thread, and cannot move a thread already attached to a worktree. `t3_thread_launch` has no idempotency key. Retain its returned threadId and inspect it with `t3_thread_read` / `t3_thread_wait`; preparation can still be running after acceptance. If a launch fails or its response is lost, inspect `t3_thread_list` before retrying, since a thread may already exist. Tool names may include a harness-normalized MCP prefix, such as `mcp__t3_code__delegate_task`; the semantics are the same. Some harnesses attach optional MCP servers lazily: if an initial tool-catalog scan does not show T3 tools, do not conclude that cross-provider delegation is unavailable. Make one bounded direct attempt using the known T3 tool name on the next tool step. In Codex code mode, for example, call `tools.mcp__t3_code__orchestrator_capabilities({})` before reporting that the capability is absent. Keep polling/wait loops bounded, do not duplicate active work, and use stable `clientRequestId` values when retrying tools that accept them. ACP fallback: some ACP agents accept the injected MCP server but fail to expose its tools. When the T3 tools are absent and `T3_ACP_MCP_NODE` is present, call the same tools through the terminal: `ELECTRON_RUN_AS_NODE=1 \"$T3_ACP_MCP_NODE\" ${T3_ACP_MCP_ENTRYPOINT:+\"$T3_ACP_MCP_ENTRYPOINT\"} acp-mcp-call orchestrator_capabilities '{}'` (`T3_ACP_MCP_ENTRYPOINT` is unset when T3 runs as a standalone executable). Delegate with `acp-mcp-call delegate_task '{\"task\":\"...\",\"target\":{\"providerInstanceId\":\"...\",\"model\":\"...\"},\"mode\":\"async\",\"clientRequestId\":\"...\"}'`. This is the supported T3 transport fallback, not an ordinary shell-based substitute for delegation. ### Showing visuals When a chart, table, diagram, image collage, or mockup would say more than prose, build a self-contained HTML page, check it with `html_preview`, then publish it with `html_render` before your final reply. The reader sees the page above that reply, so don't announce or restate it; add only what it doesn't say. - When model options are requested or the child keeps the parent's provider instance and model with nonempty `inheritedOptions` from `orchestrator_capabilities`, use `delegate_task` even for native-supported models. Native subagents cannot reliably apply T3 model options. Read the selected model's descriptors from `orchestrator_capabilities` and put settings in `target.options`, not only in the prompt. Claude commonly uses {\"effort\":\"max\",\"fastMode\":true}; Codex uses {\"reasoningEffort\":\"max\",\"serviceTier\":\"priority\"}. Do not translate max to high or ignore unsupported settings: report a capability mismatch. Options inherit only for the same provider instance and model; explicit entries override individual values, and [] or {} clears them. Check the returned providerInstanceId, model, and options against the requested selection. " ❯ src/mcp/toolkits/orchestrator/tools.test.ts:28:29 26| }; 27| for (const [name, text] of Object.entries(guidance)) { 28| expect.soft(text, name).toMatch(/independent review rounds?/i); | ^ 29| expect.soft(text, name).toMatch(/follow-up that needs the same chi… 30| } ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/4]⎯ FAIL |t3| src/mcp/toolkits/orchestrator/tools.test.ts > separates independent review rounds from same-conversation follow-ups AssertionError: instructions: expected '\n\n## T3 Code orchestration\n\nThe `…' to match /follow-up that needs the same child'…/i - Expected: /follow-up that needs the same child's conversation/i + Received: " ## T3 Code orchestration The `t3-code` MCP server provides app-owned orchestration. Treat these concepts distinctly: - A delegated task/subagent is child work owned by the current thread. Use `orchestrator_capabilities` to discover the current provider/model IDs from the same live catalog as the composer, including configured custom models. It lists a short set of models per provider; pass `search` to find others. Do not treat a native tool's model list as the full list of available subagent models. Prefer native subagent tools for same-provider work only when they support the chosen model and no model options are requested or inherited. Use `delegate_task` with that provider instance and model when native tools cannot, including for same-provider work. Also use `delegate_task` for cross-provider or explicitly T3-owned child tasks. For a child task that needs a separate checkout, use `delegate_task` with `isolation:\"worktree\"` across any provider or model. It starts from the parent local commit and runs project setup; uncommitted edits are not copied. Retain each returned `taskId`, and use `task_status` or `task_cancel` to manage it. The returned `childThreadId` is backing storage for the subagent, not the target for starting another delegated review round. - `t3_thread_launch` and `create_threads` create ordinary top-level T3 conversations. 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. - `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. ### Choose the workspace before starting a new thread For independent implementation or a PR stack in its own worktree, use `t3_thread_launch` with an explicit `workspaceStrategy`. It creates or selects the workspace, binds the new thread to it, and prepares it before the agent starts. Put the task in `message`, not `prompt`: - New worktree: `{\"title\":\"UI cleanup\",\"workspaceStrategy\":{\"type\":\"worktree\",\"baseRef\":\"feature/base\",\"branch\":\"feature/ui-cleanup\",\"startFromOrigin\":false},\"message\":\"Implement the cleanup and open a PR against feature/base.\"}` - Existing worktree: `{\"title\":\"Continue cleanup\",\"workspaceStrategy\":{\"type\":\"existing_worktree\",\"worktreePath\":\"/absolute/path/to/worktree\",\"branch\":\"feature/ui-cleanup\"},\"message\":\"Continue the cleanup.\"}` - Project's main checkout: `workspaceStrategy:{\"type\":\"root\"}`. Omitting workspaceStrategy also selects root; it does not inherit the caller's worktree. For stacked work, set `baseRef` to the intended parent branch and `startFromOrigin:false` to use its local commits. Use `startFromOrigin:true` when you intend to fetch the base branch's remote and start from it. Uncommitted edits are not copied. Use `t3_worktree_list` to discover existing checkout paths. Project, model selection, and modes inherit unless supplied; a launched thread may not run with broader modes than yours. `t3_thread_launch` is the single-thread launch tool. Use `create_threads` only for a batch of threads intentionally sharing the caller's checkout: it always inherits the caller's project, branch, and worktree and has no workspace override. Asking an agent to run `git worktree add` or `cd` in its prompt does not update T3's thread binding. Select the workspace in the launch call instead. `t3_worktree_handoff` moves the calling thread, not another thread, and cannot move a thread already attached to a worktree. `t3_thread_launch` has no idempotency key. Retain its returned threadId and inspect it with `t3_thread_read` / `t3_thread_wait`; preparation can still be running after acceptance. If a launch fails or its response is lost, inspect `t3_thread_list` before retrying, since a thread may already exist. Tool names may include a harness-normalized MCP prefix, such as `mcp__t3_code__delegate_task`; the semantics are the same. Some harnesses attach optional MCP servers lazily: if an initial tool-catalog scan does not show T3 tools, do not conclude that cross-provider delegation is unavailable. Make one bounded direct attempt using the known T3 tool name on the next tool step. In Codex code mode, for example, call `tools.mcp__t3_code__orchestrator_capabilities({})` before reporting that the capability is absent. Keep polling/wait loops bounded, do not duplicate active work, and use stable `clientRequestId` values when retrying tools that accept them. ACP fallback: some ACP agents accept the injected MCP server but fail to expose its tools. When the T3 tools are absent and `T3_ACP_MCP_NODE` is present, call the same tools through the terminal: `ELECTRON_RUN_AS_NODE=1 \"$T3_ACP_MCP_NODE\" ${T3_ACP_MCP_ENTRYPOINT:+\"$T3_ACP_MCP_ENTRYPOINT\"} acp-mcp-call orchestrator_capabilities '{}'` (`T3_ACP_MCP_ENTRYPOINT` is unset when T3 runs as a standalone executable). Delegate with `acp-mcp-call delegate_task '{\"task\":\"...\",\"target\":{\"providerInstanceId\":\"...\",\"model\":\"...\"},\"mode\":\"async\",\"clientRequestId\":\"...\"}'`. This is the supported T3 transport fallback, not an ordinary shell-based substitute for delegation. ### Showing visuals When a chart, table, diagram, image collage, or mockup would say more than prose, build a self-contained HTML page, check it with `html_preview`, then publish it with `html_render` before your final reply. The reader sees the page above that reply, so don't announce or restate it; add only what it doesn't say. - When model options are requested or the child keeps the parent's provider instance and model with nonempty `inheritedOptions` from `orchestrator_capabilities`, use `delegate_task` even for native-supported models. Native subagents cannot reliably apply T3 model options. Read the selected model's descriptors from `orchestrator_capabilities` and put settings in `target.options`, not only in the prompt. Claude commonly uses {\"effort\":\"max\",\"fastMode\":true}; Codex uses {\"reasoningEffort\":\"max\",\"serviceTier\":\"priority\"}. Do not translate max to high or ignore unsupported settings: report a capability mismatch. Options inherit only for the same provider instance and model; explicit entries override individual values, and [] or {} clears them. Check the returned providerInstanceId, model, and options against the requested selection. " ❯ src/mcp/toolkits/orchestrator/tools.test.ts:29:29 27| for (const [name, text] of Object.entries(guidance)) { 28| expect.soft(text, name).toMatch(/independent review rounds?/i); 29| expect.soft(text, name).toMatch(/follow-up that needs the same chi… | ^ 30| } 31| }); ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/4]⎯ FAIL |t3| src/mcp/toolkits/orchestrator/tools.test.ts > separates independent review rounds from same-conversation follow-ups AssertionError: delegate_task: expected 'Needs an agent running inside a T3 th…' to match /independent review rounds?/i - Expected: /independent review rounds?/i + Received: "Needs an agent running inside a T3 thread. Delegate one task to a T3-owned child agent/subagent of THIS thread and run it with only the supplied task prompt, without copying parent conversation history. Choose providers and models from orchestrator_capabilities, which uses the same live catalog as the composer. Prefer native subagent tools for same-provider work only when they support the chosen model and no model options are requested or inherited. Use this for any model missing from the native tool, including same-provider work, for cross-provider work, or for explicitly T3-owned child tasks. For every T3 delegated review round, call delegate_task again with the original brief, prior findings, responses, and unresolved objections in the task prompt. Track each round by its own taskId and use a distinct clientRequestId per round, stable across retries of that round. The childThreadId is backing storage, not the target for starting another delegated review round through t3_thread_send. Set isolation to worktree for a separate checkout based on the parent local commit, with project setup completed before the child starts. Uncommitted edits are not copied; omitted isolation shares the parent checkout. Use delegate_task when model options are requested or the child keeps the parent's provider instance and model with nonempty inheritedOptions from orchestrator_capabilities, even for native-supported models. Native subagents cannot reliably apply T3 model options. Set target.options using advertised IDs: Claude {effort: 'max', fastMode: true}; Codex {reasoningEffort: 'max', serviceTier: 'priority'}. Check providerInstanceId, model, and options in the result. Provider/model and modes inherit unless overridden. Options inherit only for the same instance and model; explicit entries override individual values and [] or {} clears them. A requested runtimeMode must be one the target provider lists in orchestrator_capabilities runtimeModes; an inherited one steps down to the broadest mode it offers. Leave runtimeMode unset unless the user asks for a supervised child: approval-required and auto-accept-edits usually make the child wait for a person at each action that needs approval. Prefer mode='async' for long work; mode='wait' blocks until completion, a blocking question, a pending approval, or timeout. If hasPendingQuestion, pass threadId=childThreadId to t3_pending_request_list, t3_pending_request_read (with requestId) and t3_pending_request_respond, or ask the user; the task's completion still wakes this thread. If pendingApproval is set, read the fresh full request in childThreadId before responding: the record can outlive its provider callback. It grants no approval authority; decisions remain with the child's existing approval holder, and pending request tools answer questions only. The child keeps running and its completion still wakes this thread. timeoutMs on mode=wait is only the parent's wait budget and does not cancel the child. waitTimedOut on that wait call means the timeout fired; keep that taskId and read status on later task_status. An async child's completion wakes this thread through a notification, steered into active turns where supported or queued otherwise, so end the turn instead of polling or spawning watchers; use task_status only when the result is needed mid-turn." ❯ src/mcp/toolkits/orchestrator/tools.test.ts:28:29 26| }; 27| for (const [name, text] of Object.entries(guidance)) { 28| expect.soft(text, name).toMatch(/independent review rounds?/i); | ^ 29| expect.soft(text, name).toMatch(/follow-up that needs the same chi… 30| } ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/4]⎯ FAIL |t3| src/mcp/toolkits/orchestrator/tools.test.ts > separates independent review rounds from same-conversation follow-ups AssertionError: delegate_task: expected 'Needs an agent running inside a T3 th…' to match /follow-up that needs the same child'…/i - Expected: /follow-up that needs the same child's conversation/i + Received: "Needs an agent running inside a T3 thread. Delegate one task to a T3-owned child agent/subagent of THIS thread and run it with only the supplied task prompt, without copying parent conversation history. Choose providers and models from orchestrator_capabilities, which uses the same live catalog as the composer. Prefer native subagent tools for same-provider work only when they support the chosen model and no model options are requested or inherited. Use this for any model missing from the native tool, including same-provider work, for cross-provider work, or for explicitly T3-owned child tasks. For every T3 delegated review round, call delegate_task again with the original brief, prior findings, responses, and unresolved objections in the task prompt. Track each round by its own taskId and use a distinct clientRequestId per round, stable across retries of that round. The childThreadId is backing storage, not the target for starting another delegated review round through t3_thread_send. Set isolation to worktree for a separate checkout based on the parent local commit, with project setup completed before the child starts. Uncommitted edits are not copied; omitted isolation shares the parent checkout. Use delegate_task when model options are requested or the child keeps the parent's provider instance and model with nonempty inheritedOptions from orchestrator_capabilities, even for native-supported models. Native subagents cannot reliably apply T3 model options. Set target.options using advertised IDs: Claude {effort: 'max', fastMode: true}; Codex {reasoningEffort: 'max', serviceTier: 'priority'}. Check providerInstanceId, model, and options in the result. Provider/model and modes inherit unless overridden. Options inherit only for the same instance and model; explicit entries override individual values and [] or {} clears them. A requested runtimeMode must be one the target provider lists in orchestrator_capabilities runtimeModes; an inherited one steps down to the broadest mode it offers. Leave runtimeMode unset unless the user asks for a supervised child: approval-required and auto-accept-edits usually make the child wait for a person at each action that needs approval. Prefer mode='async' for long work; mode='wait' blocks until completion, a blocking question, a pending approval, or timeout. If hasPendingQuestion, pass threadId=childThreadId to t3_pending_request_list, t3_pending_request_read (with requestId) and t3_pending_request_respond, or ask the user; the task's completion still wakes this thread. If pendingApproval is set, read the fresh full request in childThreadId before responding: the record can outlive its provider callback. It grants no approval authority; decisions remain with the child's existing approval holder, and pending request tools answer questions only. The child keeps running and its completion still wakes this thread. timeoutMs on mode=wait is only the parent's wait budget and does not cancel the child. waitTimedOut on that wait call means the timeout fired; keep that taskId and read status on later task_status. An async child's completion wakes this thread through a notification, steered into active turns where supported or queued otherwise, so end the turn instead of polling or spawning watchers; use task_status only when the result is needed mid-turn." ❯ src/mcp/toolkits/orchestrator/tools.test.ts:29:29 27| for (const [name, text] of Object.entries(guidance)) { 28| expect.soft(text, name).toMatch(/independent review rounds?/i); 29| expect.soft(text, name).toMatch(/follow-up that needs the same chi… | ^ 30| } 31| }); ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/4]⎯ Test Files 1 failed | 1 passed (2) Tests 1 failed | 17 passed (18) Start at 02:00:46 Duration 47.06s (transform 64%, import 28%, setup 7%, tests 1%) EXIT_CODE=1