Agent Uplink

DEVELOPMENT DOCUMENTATION / FILESYSTEMS

Confined files, shared across agent frameworks.

A shared TypeScript client speaks 9P2000.L over an authenticated consumer WebSocket to a scoped filesystem export.

Framework adapters

AdapterSource exportPurpose
Files SDK@agent-tunnel/client/files-sdkObject-style operations over scoped files.
Mastra@agent-tunnel/client/mastraWorkspaceFilesystem integration.
just-bash@agent-tunnel/client/just-bashA filesystem for the in-process shell interpreter, not a remote host shell.
AI SDK@agent-tunnel/client/ai-sdkFiles API integration through the shared client.

These are export subpaths in the source package, not four independently published npm packages. The rebrand does not rename these identifiers. Use the checkout's package metadata rather than assuming a public registry release.

Provision and connect

Use examples/m6-catalog-fs.toml through the fresh-catalog workflow. Declare the export's actual case behavior using fs_case_sensitivity and grant fs:connect plus the permitted file operations. Local export capabilities can narrow access further.

A GET to /v1/devices/{device_id}/services/{service_id}/fs returns the descriptor; a WebSocket upgrade with subprotocol agent-tunnel.9p.v1 opens a 9P2000.L session. The token needs fs:connect. The binary bundle includes no filesystem consumer client; the TypeScript client is a separate source integration. The provisioning regression gate reads a generated file, not every adapter's full workflow.

Ownership and authorization

The application owns the connection. Adapters borrow it and must not change its token, endpoint, root or grant. Closing one adapter must not close another adapter's handles. Cross-user connection sharing is prohibited.

Semantic boundaries

Limits and idle sessions

The device enforces message size, outstanding tags, live fids, path bounds and traversal-entry budgets. It now closes an idle filesystem session with DEADLINE_EXCEEDED when nothing is queued or received for the descriptor's sessionIdleSeconds (default 300 seconds). Single-request and composite-operation deadlines, traversal depth and materialization limits are client-enforced parameters, not device-side guarantees against a custom client that ignores them. The filesystem queued-bytes limit remains an open design decision; bounded transport queues are a separate constraint.

Data-socket recovery

Current main fixes lost receive credit and replay/snapshot ordering during retained recovery. The relay and connector reissue cumulative receive credit on the replacement carrier; the relay retries a refused reissue from its periodic tick. Scoped real-socket filesystem recovery evidence exists on macOS and hosted Linux, and the recovery gate is registered in the M4 harness. This does not guarantee recovery from every disconnect or prove that an interrupted mutation completed.

The repository records three local M4 harness passes after the review fixes at 0e7f64c. Earlier hosted Linux probe jobs passed the full M4 harness, but that probe run failed overall in a separate gate-2 job; this is not a blanket hosted acceptance claim. Linux mount coverage and wider milestone acceptance remain open. These runtime tests were not rerun for this website review.

Diagnosing a closed session

REVERSE_CHANNEL_UNAVAILABLE means the data carrier's receiver is gone. FLOW_CONTROL_UNDELIVERABLE means an ACK, credit update or reset could not be queued on a live carrier even using reserved capacity; inspect queue diagnostics rather than assuming the device disconnected. CONTROL_CLOSED also covers data loss when recovery cannot start because control is already gone. None of these codes proves that a dispatched file mutation did not run.

Integration caveats

Files SDK needs its own matching FilesError class instance so failures keep their intended retry semantics. The pinned just-bash API includes synchronous metadata helpers that cannot perform asynchronous remote enumeration. Consult the source adapter contract before assuming complete filesystem equivalence.

Host support

Filesystem exports require a Unix device host, such as Linux or macOS. On Windows, tunnel-client config check and connect refuse an fs export with filesystem exports are unsupported on this host. Enrolling a Windows device or building a Windows binary does not enable filesystem exports.

Linux now uses the bounded per-component resolver when symlinks are enabled, enforcing the provider's 32-hop and per-target bounds. With symlinks disabled it uses openat2 where available, with a per-component fallback. This implementation change is not a blanket platform or adapter certification.

Verification scope

Four native adapters have compilation/contract evidence. The shared TypeScript client and one adapter have real relay/device socket evidence. Upstream records include Linux resolver tests and corrections after their first hosted run; full Linux race/deletion evidence, second-host acceptance and all-adapter end-to-end coverage remain separate. No host or adapter tests were rerun for this website review.

Source & review

Reviewed against cb94dc3ccbf4 on 2026-09-25. Based on docs/filesystem-api.md, docs/filesystem-adapters.md, packages/client/package.json, docs/tasks.md. Historical test evidence is not a new test run.