Repository navigation
Description
What happened
A thread in my WSL environment couldn't start a subagent on my Windows machine. Every tool that touches environment links failed with capability_denied: "This work was started from T3 Code · through a linked environment, so it cannot use this environment's links. A link paired with full access is not limited this way."
I re-paired the link with Full access, reloaded the thread and restarted T3 Code, and kept getting the same error. A new thread I started in the same environment used the link and ran the Windows subagent right away.
Diagnosis
The fence itself is intended (#16695). The problem is that a thread can never leave it, and the error message suggests a fix that only works for new threads.
- How it got fenced. An agent on the Windows host created the thread with
t3_thread_launchthrough its Windows → WSL link, which was paired withautoaccess. The WSL server stamped the thread withlinkOrigin.access: "auto". - The stamp never changes.
OrchestrationV2LinkOriginis "set when the thread is created and never changed", andlinkOriginIsFencedisaccess !== "full-access"(packages/contracts/src/orchestrationV2.ts).callerLinkOriginchecks the stamped origin first (apps/server/src/mcp/linkOrigin.ts). Onlythread.createsets it, and forks and delegated children copy it. - What it blocks. Listing or linking environments, forwarding any tool with a linked
environmentId(includingdelegate_task, throughPeerForwarding.callerLimits), and creating projects. - Why re-pairing does nothing. Re-pairing issued a new full-access auth session and left the old
autosession unrevoked, and the stamp still points at the old one. Reloading or restarting can't change a stamp stored in the database. - The UI misleads. The header says only "From T3 Code · ", and nothing says the thread is restricted. The error's last sentence reads as "re-pair to fix this". The environment's own user was typing in the thread and had no way out.
Possible directions:
- At minimum, the error should say that the limit was set when the thread started, that re-pairing only affects new threads, and that a new thread is the way out.
- Let the environment's user lift the fence from the thread header, or re-evaluate it once the same peer has been re-paired with full access.
Steps to reproduce
- On environment A (here the Windows desktop app's local server), link environment B (here a T3 server in WSL2) with access below Full, for example "Auto". Give B a working full-access link of its own (here B → A).
- In a thread on A, ask the agent to call
t3_thread_launchwithenvironmentId: <B>. - In the new thread on B, ask the agent to call
t3_environment_links, ordelegate_taskwithtarget.environmentId. It fails withcapability_denied. - On A, re-pair B with Full access. Reload the thread and restart the app, then retry step 3. You get the same error.
- Start a new thread on B from the app and retry step 3. It works.
Version
0.1.9 (the WSL server where the thread runs, and the Windows desktop app with its local server). main has no change to linkOrigin fencing since v0.1.9.
Environment
Windows 10.0.26300 host (T3 Code Desktop 0.1.9) linked to a T3 server 0.1.9 in WSL2 (Linux 6.18, Node 26.12.1). The agent in the thread was Claude (claude-opus-5-5).
Evidence
# WSL server, statev2.sqlite (read-only): the stuck thread
thread mcp:launch:d99e… created 2026-11-12T02:01:59Z createdBy=agent creationSource=mcp
linkOrigin = {"sessionId":"f514…","label":"T3 Code · <host>","access":"auto"}
# WSL server, auth_sessions with label "T3 Code · <host>"
f514… issued 2026-10-31T18:24Z [orchestration:read, orchestration:operate] revoked_at NULL
ae8c… issued 2026-11-12T04:05Z [orchestration:read, orchestration:operate, settings:write, source-control:write] revoked_at NULL <- re-pair, full access
# From the stamped thread: t3_environment_links, 6 attempts from 03:46Z to 04:11Z
# (before and after the re-pair at 04:05Z, a thread reload and an app restart)
{"_tag":"OrchestratorMcpFailure","code":"capability_denied","message":"This work was started from T3 Code · <host> through a linked environment, so it cannot use this environment's links. A link paired with full access is not limited this way."}
# t3_environment_link from the same thread:
... so it cannot change projects or environment settings. A link paired with full access is not limited this way.
# From a thread the user started on the WSL server (04:02Z and 04:12Z)
t3_environment_links -> [{"label":"<host>","status":"reachable","access":"full-access"}]
delegate_task with target.environmentId=<Windows> -> Codex child ran on Windows and completedRelated issues
#27004 is also about threads started with t3_thread_launch through a link, but its symptom is sidebar and Lineage visibility, not the fence. The fence came from #16695 (a PR). I found no existing issue about this.
Fix applied or workaround
Nothing was changed on the machine. The user continued in a new thread they started in the WSL environment. Forking the stuck thread doesn't help, because forks copy linkOrigin.
Filed by
Claude Code (claude-opus-5-5) via T3 Code triage. Posted with gh by a user without triage rights, so the via-triage label could not be set.
Activity
juliusmarminge commentedon Nov 13, 2026
This is how it is meant to work: immutable state. fork and change permission on the new session
Closing as not planned.