[Bug]: Agent link card can't be declined or dismissed from a client that can't manage access#26952
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/web (apps/mobile has the same gate)
Summary
When an agent asks to link a machine (t3_environment_link), a client whose session cannot manage access sees the card with no buttons at all, only "Only a session that manages access here can answer this." The card cannot be declined or dismissed from that client, so it stays pending in the thread until the thread is stopped or archived.
Steps to reproduce
- Connect a client to a T3 server with a session that lacks the permission behind
peerLinkEnvironment.answerRequest(here: a desktop client viewing a thread on a remote Linux server, not as that server's access administrator). - In a thread on that server, ask the agent to open work on another, not-yet-linked machine, so it calls
t3_environment_linkwith a hint. - Look at the link card.
Expected behavior
Any client that can see the card can at least decline it, or the card says how to clear it (for example, "Stop or archive the thread to cancel this request"). Linking itself can stay restricted to sessions that manage access.
Actual behavior
The card shows the title and reason, then only "Only a session that manages access here can answer this." No Decline button. Nothing else in the thread closes it, so the thread keeps showing pending input.
In apps/web/src/components/chat/LinkRequestCard.tsx (main @ 6d450a4284, around lines 95–152), Decline and "Choose machine…" share one gate:
| 1 | const canAnswer = useAtomValue( |
| 2 | peerLinkEnvironment.answerRequest.permissionAtom(props.environmentId), |
| 3 | ); |
| 4 | ... |
| 5 | {canAnswer ? ( /* Decline + Choose machine… */ ) : ( |
| 6 | <p>Only a session that manages access here can answer this.</p> |
| 7 | )} |
apps/mobile/src/features/threads/LinkRequestCard.tsx (lines 114–182) does the same.
Declining links nothing and grants nothing, so it probably doesn't need the same permission as accepting. If the server's answer RPC also requires it for a decline, the server side would need the same split.
Impact
Minor bug or occasional failure
Version or commit
0.1.4-nightly.20261029.3853 (server, linux-x64)
Environment
Server: Linux x64, T3 Code 0.1.4-nightly.20261029.3853. Client: T3 Code desktop app viewing a thread on that remote server. Agent: Claude Code (Claude Opus 5.5).
Logs or stack traces
None. The behavior follows from the gate above.
Workaround
Stop or archive the thread. Per #17129, either closes a pending link card as cancelled. Or open the thread from a client that manages access on that server.
Related, but not the same: #26944 (closes obsolete link cards after a matching retry succeeds; nothing was linked here) and #17129 (the feature).