# Filesystem Every native session serves 9P2000 on a Unix socket. Pane shells receive `PARDES_9P` (socket path) and `PARDES_PANE` (pane serial). The socket is `$XDG_RUNTIME_DIR/pardes-9p-.sock`, or lives under `~/.local/state/pardes` when XDG_RUNTIME_DIR is unset. Detached sessions use their session name; `--9p=` overrides it. A `pardes ` launched from a pane forwards Look to that pane over 9P. `--nested` opens a separate editor and disables forwarding from its pane shells; its 9P service stays available. Look resolves the OS filesystem first, then the editor's virtual filesystem. Explicit paths bypass that search: | Editor path | Meaning | 9P server path | |---|---|---| | `/n/os/proc/self` | OS filesystem | `/os/proc/self` | | `/n/self/pane/2/body` | pane 2's text | `/self/pane/2/body` | | `/virtual/src/pardes.zig` | source embedded in this build | `/self/src/pardes.zig` | | `/n/peer/self/pane/2/body` | another session's text | peer's `/self/pane/2/body` | `--mount=peer=work` mounts the named session `work`; the dial can also be an absolute socket path, `unix!/path`, `tcp!IP!port`, or `quic!IP!port`. At runtime, use `Mount peer dial` and `Unmount peer`. There are eight named mounts; `os` and `self` are reserved. Unmount refuses mounts still used by a pane, its working directory, or a pending Save. Mounts are saved in dumps. Save uses the file's original mount. `pardes --9p-tcp='tcp!127.0.0.1!5640'` adds a TCP listener alongside the Unix socket. Build with `-Dquic=true` and system OpenSSL 3.6+ to enable QUIC; `--9p-quic='quic!127.0.0.1!5641'` adds its listener. Both accept numeric IPv4/IPv6 addresses, not DNS names. Listener port zero chooses a free port; `/self/listeners` reports all active dial addresses. All connections have session access, including `os`. TCP is unencrypted. QUIC uses an ephemeral TLS identity without peer verification or login. It carries 9P2000 on one bidirectional stream with ALPN `pardes-9p`. The four application connection slots are shared across transports; OpenSSL's internal buffers are separate, dynamically allocated memory. [Plan9port's client](https://9fans.github.io/plan9port/man/man1/9p.html) can drive Unix or TCP without a kernel mount: ```sh 9p -n -a "unix!$PARDES_9P" read self/index 9p -n -a 'tcp!127.0.0.1!5640' read self/index ``` For [Linux v9fs](https://www.kernel.org/doc/html/latest/filesystems/9p.html), use `version=9p2000,cache=none,access=any` and `trans=unix`, or `trans=tcp` with `port=5640`. Set `uname`, `dfltuid`, and `dfltgid` for the local user. Leave `aname` empty: the mount root contains `os` and `self`. The opt-in [Linux v9fs experiment](v9fs.md) tests a kernel mount in a separate subprocess namespace (`zig build v9fs-test`, requiring explicit mount authorization). Neither 9P2000.u nor 9P2000.L is implemented. Existing Plan9port/v9fs clients need a userspace bridge for QUIC. The server root contains `os` and `self`. Under `self`, `index` lists panes, `README` explains the interface. `new/` lists its creation endpoints and another `README`; listing, walking and statting entries do not create panes. Opening `new/ctl` creates a pane and returns its serial, and `pane/` contains `body`, `tag`, `ctl`, `addr`, `data`, `event`, and selection files. Terminal panes additionally have `pty/{ctl,status,data}`. `EffectCode ` lists the current backend's embedded implementation files under `/virtual`; Look opens their full source. `self/screen` returns JSON with `cols`, `rows`, `cursor`, a `styles` table, and row-major `cells` of `[grapheme, style_index]`. Each open freezes one frame until close, including across multiple reads. The independent client can inspect it directly with `Client(socket_path).screen()`. A terminal `body` freezes its history on the first read of each open handle; later reads use the same bytes while output continues. Close and reopen for newer history, or read `pty/data` for the live stream. Screen and terminal-body snapshots share 32 handle slots, released on close or disconnect. Writing `body` appends; opening it with truncation replaces its contents. `addr` selects a range and `data` replaces that range. `ctl` accepts `name`, `look `, `get`, `put`, `del`, and `delete`. Look resolves from that pane without editing its body or tag. Holding `event` open redirects the pane's Look and Exec clicks to that client; writing a record back performs the action. This is a control filesystem, not a complete POSIX export. Native filenames may contain up to 255 bytes. Existing regular OS files support read, write, and truncation to zero; protocol create, remove, rename, and other metadata changes are refused. Ownership, permissions, and timestamps are synthetic. Zero-length truncation accepts the accompanying `mtime` hint sent by Linux v9fs; the hint is not stored. Standalone timestamp changes remain refused. `zig build fs-test` drives real sessions using the independent Python client in `test/ninep.py`. `zig build 9p-test` checks the freestanding wire protocol; `zig build fs-bench` measures filesystem transactions in the core. `zig build fs-test quic-test -Dquic=true` also exercises QUIC mounts and I/O.