Repository navigation
Conversation
Contributor
ApprovabilityVerdict: Needs Human Approval Macroscope's review found this PR requires human approval — This change adds durable remote-launch recovery and cancellation state across orchestration, shared contracts, peer authorization, and web/mobile clients, altering production execution and OAuth-link behavior. The cross-component state-machine and authentication impact are substantial enough to require human review. You can add or adjust custom eligibility rules. Learn more. |
When the task's run on the linked environment ended, the follower completed the task with that run's reply, even while the thread there still waited on its own subagents, background tasks or a completion delivery that would wake it for the real answer. A local task waits for that work and takes its result from the run that answered after it. t3_thread_wait takes an optional untilDelegatedWorkSettled. With it, the wait also blocks until delegatedTaskProgress reports result_available for the thread, waking on task, provider-thread and run updates, and reports that result run as resultRun. The follower passes it and reads the result from resultRun. Both fields are optional: an older peer ignores the input and answers as before, and the follower then falls back to the launched run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…there Stop on a parent skipped a remote task that already had its result, so follow-up work on its thread in the linked environment (a message sent there with t3_thread_send, or a run that started after the result) kept running. A local child is stopped on every Stop, result or not, and cancelling a finished remote task already stops its thread there. Stop now records the owed stop with an internal delegated_task.remote.stop command: it sets remoteChild.stoppedThere to false and counts the stop, leaving the status, result and completion delivery alone. The follower, restarted from the live event tail or by the startup scan, sends that stop under a key per count and records it as "stopped"; a "ran-out" report never clears it. One follower runs per task, and a request while it runs makes it look once more. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es keep the cause delegate_task with environmentId launched in the linked project's checkout even when isolation "worktree" was asked for. A worktree there would branch from a commit this checkout has and the other may not, so the call is refused before launching, pointing at t3_thread_launch with a worktree workspaceStrategy. Recording the task or its cancellation no longer builds the caller's message from the dispatch error; the cause goes to the log and the caller gets a fixed message. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
delegate_task to a linked environment launches an ordinary thread there, marked delegatedFrom, so a client connected to both machines listed it in the sidebar as well as in the parent's lineage panel. Its approvals and questions also never reached the parent here. Lists now treat such a thread as a subagent when the client also lists the thread that delegated it: the web sidebar and its project ordering, mobile's thread lists, and notifications leave it out. A parent here is flagged, and shows the "subagent needs input" banner, when the task or one of its own subagents there asks. A task whose parent the client cannot list (that machine switched off, or the parent gone) stays listed on its own, so its work is never out of reach. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
juliusmarminge
force-pushed
the
t3code/peer/remote-delegate
branch
from
October 18, 2026 06:16
0d787b3 to
3dfeca1
Compare
delegate_task to a linked environment launches an ordinary thread there, marked delegatedFrom, so a client connected to both machines listed it in the sidebar as well as in the parent's lineage panel. Its approvals and questions also never reached the parent here. Lists now treat such a thread as a subagent when the client also lists the thread that delegated it: the web sidebar and its project ordering, mobile's thread lists, and notifications leave it out. A parent here is flagged, and shows the "subagent needs input" banner, when the task or one of its own subagents there asks. A task whose parent the client cannot list (that machine switched off, or the parent gone) stays listed on its own, so its work is never out of reach. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
juliusmarminge
force-pushed
the
t3code/peer/remote-delegate
branch
from
October 18, 2026 06:25
3dfeca1 to
17e26cb
Compare
A link's T3-Mode-Limit caps the modes of what it starts, but within those modes it could still steer the user's own threads or change this environment's projects and settings. Work a link starts is now fenced to that link. The linking side registers its OAuth client with the t3code-peer-link software id; the receiving side signs that into the session's claims. Every thread such a session launches carries an immutable linkOrigin, and so do the subagents, forks and create_threads it derives. A client's own thread.create cannot set one. In the shared access declarations, a linked caller may change only threads of the same link, and may not use writesEnvironment tools (projects, settings), schedule tasks, or change scheduled tasks. Reads are not fenced. Setup scripts are skipped for stamped threads in ProjectSetupScriptRunner, which every path that runs them goes through. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Settings → Connections gains a Linked environments section, shown when the server supports peer links and the session may manage access: each link with whether it answers, its access, and a warning in its last five days, plus a Link dialog (address, pairing code, access) and Forget. Mobile lists a connected environment's links under Connections. A thread a linked environment started shows "From <label>" next to its title on web, and in the thread subtitle on mobile. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
An environment can now sign in to another one's /mcp as an outside agent, with a pairing code from that environment, without a browser. It drives the peer's existing MCP OAuth flow server-side, keeps the token in the server secret store and the rest in peer_environment_links (migration 059). The peer lists the link as "T3 Code · <label>" in Connections, where it can be revoked. The token is only ever sent to an address whose descriptor answers as the linked environment. PeerMcpClient calls the peer's tools and carries the caller's limits in T3-Mode-Limit on every request. Linking refuses this environment itself and peers that cannot honour that header. `t3 environment link|list|unlink` and the peerLinks.* RPCs manage links. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
delegate_task takes target.environmentId (and optionally target.projectId). The child then runs as an ordinary thread in the linked environment, launched through the link with a key derived from the caller's clientRequestId, in the project there with this thread's repository unless one is named. The parent here records the task with delegated_task.remote.request: its node, subagent row and turn item, with remoteChild instead of a local child thread. RemoteDelegation follows the thread there and completes the task with delegated_task.remote.complete, which reuses the parent half of a local finalize, so the parent wakes as it would for a local child. Open remote tasks are followed again at startup. A revoked or expired link fails the task with that reason; any other error backs off, up to five minutes. task_status and mode=wait answer from the row, task_cancel interrupts the thread there and completes the task as cancelled, and restart recovery no longer treats a remote task as abandoned provider work. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
An agent can now work on a linked environment's threads through the same T3 MCP tools. t3_project_list, orchestrator_capabilities, t3_thread_launch, t3_thread_list, t3_thread_read, t3_thread_send, t3_thread_wait and t3_thread_interrupt take an optional environmentId; t3_environment_links lists the links. Each tool's own access declaration still runs here first, so a read-only or ended caller is refused before anything leaves. The forwarded call carries the caller's modes in T3-Mode-Limit, and the linked environment holds it to those and the link's access. Retry keys are hashed with the caller's namespace, since every caller here shares the link's one session there. A forwarded wait goes out in pieces of at most 50 s so no route drops it idle. A remote launch cannot carry attachments yet. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Read failed-run activity and prefer that run's error over an earlier assistant reply. Keep successful replies unchanged and retrieve long errors in full without taking diagnostics from a later run. Add failed-run, pagination, run-isolation and successful-recovery regressions for the existing review on pingdotgg#16719. Implemented with GPT-6.1-Sol through Codex in T3 Code on behalf of Lenoridev.
When the task's run on the linked environment ended, the follower completed the task with that run's reply, even while the thread there still waited on its own subagents, background tasks or a completion delivery that would wake it for the real answer. A local task waits for that work and takes its result from the run that answered after it. t3_thread_wait takes an optional untilDelegatedWorkSettled. With it, the wait also blocks until delegatedTaskProgress reports result_available for the thread, waking on task, provider-thread and run updates, and reports that result run as resultRun. The follower passes it and reads the result from resultRun. Both fields are optional: an older peer ignores the input and answers as before, and the follower then falls back to the launched run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…there Stop on a parent skipped a remote task that already had its result, so follow-up work on its thread in the linked environment (a message sent there with t3_thread_send, or a run that started after the result) kept running. A local child is stopped on every Stop, result or not, and cancelling a finished remote task already stops its thread there. Stop now records the owed stop with an internal delegated_task.remote.stop command: it sets remoteChild.stoppedThere to false and counts the stop, leaving the status, result and completion delivery alone. The follower, restarted from the live event tail or by the startup scan, sends that stop under a key per count and records it as "stopped"; a "ran-out" report never clears it. One follower runs per task, and a request while it runs makes it look once more. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es keep the cause delegate_task with environmentId launched in the linked project's checkout even when isolation "worktree" was asked for. A worktree there would branch from a commit this checkout has and the other may not, so the call is refused before launching, pointing at t3_thread_launch with a worktree workspaceStrategy. Recording the task or its cancellation no longer builds the caller's message from the dispatch error; the cause goes to the log and the caller gets a fixed message. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
delegate_task to a linked environment launches an ordinary thread there, marked delegatedFrom, so a client connected to both machines listed it in the sidebar as well as in the parent's lineage panel. Its approvals and questions also never reached the parent here. Lists now treat such a thread as a subagent when the client also lists the thread that delegated it: the web sidebar and its project ordering, mobile's thread lists, and notifications leave it out. A parent here is flagged, and shows the "subagent needs input" banner, when the task or one of its own subagents there asks. A task whose parent the client cannot list (that machine switched off, or the parent gone) stays listed on its own, so its work is never out of reach. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
juliusmarminge
force-pushed
the
t3code/peer/remote-delegate
branch
from
October 18, 2026 06:28
17e26cb to
198c585
Compare
An OAuth client on /mcp is capped by the access it was approved with. When another environment calls on behalf of one of its agents, that agent may run under narrower modes, and the target has no way to know. /mcp now reads `T3-Mode-Limit: <runtimeMode>/<interactionMode>` from OAuth clients and caps the request at the narrower of the two. The header can only narrow: a broader one changes nothing, and a malformed one is refused with 400. The client's interaction mode can now be capped too; before, it was always default. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A launch had no retry key, so an agent (or another environment calling on its behalf) that lost the response could only guess whether the thread was created, and a retry started a second one. t3_thread_launch now takes an optional clientRequestId. The command, thread and message ids derive from the caller and the key, and the launch service already replays a command it accepted, so a retry returns the first thread. Without a key every launch is new, as before. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
An environment can now sign in to another one's /mcp as an outside agent, with a pairing code from that environment, without a browser. It drives the peer's existing MCP OAuth flow server-side, keeps the token in the server secret store and the rest in peer_environment_links (migration 059). The peer lists the link as "T3 Code · <label>" in Connections, where it can be revoked. The token is only ever sent to an address whose descriptor answers as the linked environment. PeerMcpClient calls the peer's tools and carries the caller's limits in T3-Mode-Limit on every request. Linking refuses this environment itself and peers that cannot honour that header. `t3 environment link|list|unlink` and the peerLinks.* RPCs manage links. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
An agent can now work on a linked environment's threads through the same T3 MCP tools. t3_project_list, orchestrator_capabilities, t3_thread_launch, t3_thread_list, t3_thread_read, t3_thread_send, t3_thread_wait and t3_thread_interrupt take an optional environmentId; t3_environment_links lists the links. Each tool's own access declaration still runs here first, so a read-only or ended caller is refused before anything leaves. The forwarded call carries the caller's modes in T3-Mode-Limit, and the linked environment holds it to those and the link's access. Retry keys are hashed with the caller's namespace, since every caller here shares the link's one session there. A forwarded wait goes out in pieces of at most 50 s so no route drops it idle. A remote launch cannot carry attachments yet. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
t3_project_create and t3_project_clone take environmentId, so an agent can bring a repository to a machine before launching or delegating work there. Both still need full access here, and the linked environment holds the call to the link's access. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s a linked environment Forwarding was wired tool by tool, so only the first eleven tools took environmentId. It now lives in McpToolAccess.toLayer: a tool whose parameters take OrchestratorMcpEnvironmentTarget runs in the linked environment it names once its declaration has checked the caller here. The local handler never sees environmentId. Tools that act as the calling thread itself cannot take one, and the layer refuses to build if they do. Queues, pending requests, thread settings and organizing, forks and merge-backs, scheduled tasks, pull requests, worktree refs, project read/update/delete and environment preferences now reach a link too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A link's T3-Mode-Limit caps the modes of what it starts, but within those modes it could still steer the user's own threads or change this environment's projects and settings. Work a link starts is now fenced to that link. The linking side registers its OAuth client with the t3code-peer-link software id; the receiving side signs that into the session's claims. Every thread such a session launches carries an immutable linkOrigin, and so do the subagents, forks and create_threads it derives. A client's own thread.create cannot set one. In the shared access declarations, a linked caller may change only threads of the same link, and may not use writesEnvironment tools (projects, settings), schedule tasks, or change scheduled tasks. Reads are not fenced. Setup scripts are skipped for stamped threads in ProjectSetupScriptRunner, which every path that runs them goes through. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A fleet host provisions machines by having an agent clone a repository there and register it, which the fence refused as a change to the environment. Adding a project leaves everything already there as it was, so linked work may create and clone projects with full access; it still cannot change or delete existing ones, settings, or scheduled tasks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A link's agents run as the receiving environment's user, so at full access the fence only ever stopped T3's own tools, never what the agent could do. It also kept a host from driving machines it fully trusts: answering a pending question or steering a thread the user started there, updating a project, or running the project's setup script in a worktree it launched. The stamp now records the access the link was paired with, and only a link below full access is fenced. Its work still carries linkOrigin, so clients keep showing where it came from. Stamps from before access was recorded stay fenced. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Settings → Connections gains a Linked environments section, shown when the server supports peer links and the session may manage access: each link with whether it answers, its access, and a warning in its last five days, plus a Link dialog (address, pairing code, access) and Forget. Mobile lists a connected environment's links under Connections. A thread a linked environment started shows "From <label>" next to its title on web, and in the thread subtitle on mobile. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
delegate_task takes target.environmentId (and optionally target.projectId). The child then runs as an ordinary thread in the linked environment, launched through the link with a key derived from the caller's clientRequestId, in the project there with this thread's repository unless one is named. The parent here records the task with delegated_task.remote.request: its node, subagent row and turn item, with remoteChild instead of a local child thread. RemoteDelegation follows the thread there and completes the task with delegated_task.remote.complete, which reuses the parent half of a local finalize, so the parent wakes as it would for a local child. Open remote tasks are followed again at startup. A revoked or expired link fails the task with that reason; any other error backs off, up to five minutes. task_status and mode=wait answer from the row, task_cancel interrupts the thread there and completes the task as cancelled, and restart recovery no longer treats a remote task as abandoned provider work. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Read failed-run activity and prefer that run's error over an earlier assistant reply. Keep successful replies unchanged and retrieve long errors in full without taking diagnostics from a later run. Add failed-run, pagination, run-isolation and successful-recovery regressions for the existing review on pingdotgg#16719. Implemented with GPT-6.1-Sol through Codex in T3 Code on behalf of Lenoridev.
When the task's run on the linked environment ended, the follower completed the task with that run's reply, even while the thread there still waited on its own subagents, background tasks or a completion delivery that would wake it for the real answer. A local task waits for that work and takes its result from the run that answered after it. t3_thread_wait takes an optional untilDelegatedWorkSettled. With it, the wait also blocks until delegatedTaskProgress reports result_available for the thread, waking on task, provider-thread and run updates, and reports that result run as resultRun. The follower passes it and reads the result from resultRun. Both fields are optional: an older peer ignores the input and answers as before, and the follower then falls back to the launched run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…there Stop on a parent skipped a remote task that already had its result, so follow-up work on its thread in the linked environment (a message sent there with t3_thread_send, or a run that started after the result) kept running. A local child is stopped on every Stop, result or not, and cancelling a finished remote task already stops its thread there. Stop now records the owed stop with an internal delegated_task.remote.stop command: it sets remoteChild.stoppedThere to false and counts the stop, leaving the status, result and completion delivery alone. The follower, restarted from the live event tail or by the startup scan, sends that stop under a key per count and records it as "stopped"; a "ran-out" report never clears it. One follower runs per task, and a request while it runs makes it look once more. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es keep the cause delegate_task with environmentId launched in the linked project's checkout even when isolation "worktree" was asked for. A worktree there would branch from a commit this checkout has and the other may not, so the call is refused before launching, pointing at t3_thread_launch with a worktree workspaceStrategy. Recording the task or its cancellation no longer builds the caller's message from the dispatch error; the cause goes to the log and the caller gets a fixed message. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
delegate_task to a linked environment launches an ordinary thread there, marked delegatedFrom, so a client connected to both machines listed it in the sidebar as well as in the parent's lineage panel. Its approvals and questions also never reached the parent here. Lists now treat such a thread as a subagent when the client also lists the thread that delegated it: the web sidebar and its project ordering, mobile's thread lists, and notifications leave it out. A parent here is flagged, and shows the "subagent needs input" banner, when the task or one of its own subagents there asks. A task whose parent the client cannot list (that machine switched off, or the parent gone) stays listed on its own, so its work is never out of reach. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RemoteDelegation.start resumes every open remote task at once, and each follower read its parent's whole subagent list to find one task, then held it across a wait of up to ten minutes. A parent with 1,441 tasks (35 MB of payload) and 122 open ones made every restart decode ~170k records and hold 8 GB, so the server ran out of heap seconds after starting and crash-looped. getThreadRecords now takes a subagentIds filter. Followers, and task_status waits that re-read on every parent subagent.updated, read just their task. Against a copy of the affected database the startup fan-out drops from 8.2 GB retained over 21.6 s to 8 MB over 61 ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
juliusmarminge
force-pushed
the
t3code/peer/remote-delegate
branch
from
October 27, 2026 19:53
ac028c0 to
8aefc97
Compare
juliusmarminge
force-pushed
the
t3code/peer/remote-delegate
branch
from
October 27, 2026 20:49
8aefc97 to
b7b14bf
Compare
17 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A remote
delegate_taskchild can start before the source environment records its task. If the source stops or loses the accepted launch response, that child can keep running without a source task to recover, follow or stop. Retrying manually with the original key narrows this gap but does not recover work after an unattended source restart.Change
Summary
Persist the source task and resolved launch inputs before sending the launch. Mark the start under the parent dispatch lock, then attach the destination receipt to that existing task. Startup recovery replays the original namespace/key without requiring the parent's launching run to remain active.
The stored launch identity also identifies the original OAuth grant generation, without storing credentials. A replacement link cannot turn recovery into a second child. Forwarding rechecks current authority; refusal records launch uncertainty explicitly. Pending cancellation avoids launching known-unsent work and reconciles already-accepted work using the captured Stop generation.
The shared contracts represent a remote task before its thread ID is known. Web and mobile keep that task identifiable as remote, show Launching, and disable opening it until attachment. These client changes are required by the pending state; workspace selection, Home, remote questions and approval notices remain separate.
Scope and approval
Fixes #17051, the launch/record defect and recovery approach documented by @juliusmarminge. This is a focused reliability follow-up to #16719. The PR targets
t3code/peer/remote-delegate, refreshed ontob7b14bfdd858c359c8f4f541d5227f3d7a8d6051on October 27. The normal two-parent merge retains both histories; only the 16 recovery files differ from that target. This latest refresh preserves the target restack without changing any of those recovery files.This publishes the existing tested offer, refreshed onto the current feature branch. The issue's October 22 maintainer triage leaves the MCP result/restart contract for manual review. This branch-targeted PR remains proposed for review and can be applied/restacked by the stack owner. It does not imply approval to merge or a change to the rest of the stack.
Verification
Evidence
On the October 27 target
8aefc971a6, retaining the regression and restoring only the target'sRemoteDelegation.tsreproduces the defect: after destination acceptance, the source has zero tasks instead of one. Restoring the recovery implementation passes the same regression, including rebuilding the source runtime against the same SQLite database after response loss and an ended parent run, then recovering exactly one task and destination thread with the original identity. The latest target retains this sameRemoteDelegation.tssource byte for byte; this refresh reuses that red proof and runs the recovery regression again as part of the server suite.At refresh
c812fd58e9, 116 tests pass in six focused server files on Node 26.12.1 with the target's pinned Vite+ 1.4.0 and TypeScript drop-in 0.8.0. These cover RemoteDelegation, RemoteDelegatedTask, ThreadLaunchService, PeerLinks, PeerForwarding and ThreadManagementService. The target changed provider start/control behavior but left the recovery files unchanged, so this pass focuses on server compatibility.Scoped server, web and mobile types pass, as does the contracts package typecheck. The server scope also includes the forwarding test that failed in earlier target CI. Changed-file formatting and lint pass without findings.
The required
vp run check:changed b7b14bfdd8attempt passed formatting, lint and generated GraphQL validation. With one CPU and bounded memory, its broader scans did not finish within three minutes, so the owned process group was stopped. The aggregate command and its remaining knip/type/test stages are incomplete, not passed. The focused tests and types above ran separately. Current-head upstream CI remains pending.The tests exercise accepted-response loss and runtime rebuild, never-sent intents, pending cancellation/Stop generations, reduced/revoked/replaced authority, duplicate and mismatched attachments, destination receipt replay and existing forwarding. They use source SQLite/orchestration and loopback HTTP/MCP/OAuth with modeled destination/provider services, plus the destination ThreadLaunchService receipt test. They do not establish provider or physical-host acceptance.
UI evidence
The images are the previously captured isolated web-client comparison from October 11: the same synthetic pending task rendered by original UI
d79fdd537cand the original recovery contribution. They demonstrate Running versus Launching and pending navigation handling; they are historical captures, not a fresh client pass on this PR head. The original backend did not produce the synthetic pending record. Mobile card regressions passed at the earlier8d8833d3b4refresh; this refresh checks mobile types. No native mobile, real-provider, OS-process restart, two-physical-host or T3 Connect acceptance is claimed.Merge danger
Door: one-way while source tasks are awaiting destination attachment. Complete or cancel pending launches before downgrading to a version that requires every remote task to already have a thread ID.
Blast radius: orchestration. The change affects remote launch recovery, link authority checks, cancellation and the display of pending remote tasks. The tests do not establish acceptance on physical hosts or every provider.
Written with GPT-6.1-Sol through the Codex harness in T3 Code, on behalf of Lenoridev.