# feat\(web,mobile\): linked environments in Connections · PR \#16698 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/16698)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: open

Source repository: pingdotgg/t3code

Source branch: t3code/peer/links-ui

Target branch: t3code/peer/link-origin

Head commit: f580fefde9a4e31cfd5ff263ea43b0d392601b31

[Discussion and reviews](https://git.cafe/pingdotgg/t3code/pull/16698)

[Commits](https://git.cafe/pingdotgg/t3code/pull/16698/commits?format=markdown)

[Files changed](https://git.cafe/pingdotgg/t3code/pull/16698/diffs?format=markdown)

## Description

---

Linked environments were available through the server stack but had no Connections UI. This layer adds web pairing and confirmed local forgetting, a mobile read-only list, and thread-origin labels on both clients.

Preserves @juliusmarminge's original work in [#16698](https://github.com/pingdotgg/t3code/pull/16698), with maintainer fixes on top. It remains based on `t3code/peer/link-origin` at [37b2d54670](https://github.com/pingdotgg/t3code/commit/37b2d54670e57295c132f3e30d1c04580796dc13); **that prerequisite must land first**. Main lacks its peer-link contracts and models. No parent branch was changed or flattened.

The UI selects every connected, readable host advertising peer-link support, including remote-only hosts. Older servers receive no unsupported list request. Link and Forget use the shared destination-scoped `access:write` command guards and server authorization. Cancel and other idle close requests reset address, pairing code and access; pending operations guard closing and disable the controls. Restricted-access guidance now matches the parent's fence rules. Mobile excludes disconnected catalog entries and advances expiry while focused and on resume.

Forget removes the local link; revoking its authorized client on the peer is a separate action. Reachability and membership are query-time snapshots, refreshed after this client's mutations and normal query remounts. This does not add continuous remote health polling; local expiry labels still advance.

### Verification

Reviewed head: [e9ed401dc1](https://github.com/pingdotgg/t3code/commit/e9ed401dc19afc3df3f994d56d2dd9a687870315).

- PR-touched tests: **82 cases / 3 files → 78 / 2**, preserving all 76 parent cases. PR-added cases **6 → 2**: a real command/query lifecycle with destination permission changes and list invalidation, plus remote-only Settings search. Deleted four isolated helper assertions and replaced the permission table. Six controlled regressions failed the intended assertions.
- **108 tests / 4 files passed**, including the parent peer service and server authorization suites. Scoped typechecks passed for web, mobile, client-runtime, contracts and server. All 18 changed TypeScript paths passed lint (nine existing warnings on untouched lines); all 20 changed paths passed formatting.
- Two independent whole-layer review rounds each used GPT-6 Sol and Claude Opus 5.5. The final round found no required changes. The optional polling request was declined because each list probes every peer, and this UI promises snapshots rather than continuous remote health.
- Actual Linux browser against **two isolated real servers**: OAuth pairing with Supervised access, persisted linked row and reachability probe, Cancel/reopen reset, Settings search, and confirmed Forget with immediate list refresh. The remote authorized-client session remained after Forget, verified separately through the peer CLI.
- Actual bearer sessions, HTTP WebSocket tickets and server RPC: read-only credentials can list but both mutations fail with `access:write` authorization errors. Write credentials reach the service. [Sanitized observations and boundaries](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a7b4fd5b319e06eb/16698-live-proof.json).

### Evidence

Matched Connections captures use the same data, viewport (1280×1000) and scroll position. Before serves the **verbatim base ConnectionsSettings component** through a Vite load override; other modules and the real backend remain at the reviewed head. This is a component baseline, not a full base checkout.

| Before | After |
| --- | --- |
| ![Before: Connections without linked-environment controls](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/df8622668732e482/16698-before-connections.png) | ![After: Connections includes linked environments](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/2d70a9773aa513cb/16698-after-empty.png) |

Real pairing produced this reachable link:

![After: real paired environment with Supervised access and local Forget](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/4438e40fb5d4e961/16698-after-linked.png)

[Cancel/reset recording](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/6f89513a3886d39c/16698-cancel-reset-final.mp4) — enter dummy address/code, select Full access, cancel, reopen blank with Supervised restored.

[Forget confirmation recording](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/01fe3ac957f878aa/16698-forget.mp4) — shows the reachable row and local-versus-remote revocation guidance. The subsequent empty list and unchanged remote session were checked separately.

The origin label below uses a **projection-only fixture on an idle isolated thread**, written with the server stopped. It proves presentation of supplied origin metadata, not production linked-agent attribution.

![After: thread displays supplied linked-environment origin](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a8f1a35fd1cf2282/16698-origin-fixture.png)

### Remaining human gates

Prerequisite landing, current-head CI and human approval remain required. Current-head Macroscope Correctness succeeded (10 changed code objects, no findings); Approvability is **NEUTRAL / Needs Human Approval** for the cross-machine workflow and authorization scope. PR Size and Vouch succeeded. GitHub currently reports mergeability unknown and retains a stale synthetic merge ref whose parents match neither this head nor base; the CI workflow has not started for this head. This is an outstanding GitHub merge-ref/CI gate, not a passing CI result. Native iOS/Android, Electron desktop, macOS/Windows, production T3 Connect relay and tunnel paths were not run on this headless Linux host. Multiple connected hosts, grant changes while open, pending-close behavior and unreachable/failing/expired rows were source-reviewed rather than driven live. Actual linked-agent thread attribution still needs an integrated pass. This PR is unmerged.

Tests: GPT-6 Astra via Codex. Implementation and integration: GPT-6.1 Sol via Codex. Independent reviews: GPT-6 Sol via Codex and Claude Opus 5.5 via Claude Code.

