diff --git a/README.md b/README.md
index a98408d..52ab147 100644
--- a/README.md
+++ b/README.md
@@ -113,7 +113,7 @@ graph TB
AG[agent.Agent
loop · compaction
prompt assembly]
end
- subgraph "toolsrv (child process, 9P)"
+ subgraph "toolsrv (local: child process / remote: SSH-spawned)"
TOOLS[9P Filesystem
ctl · tools · proc/]
EXEC[Tool Scripts
· shell, reasoning_think
· file_*, lsp_*, memory_*
· gui_*, subagent_*]
end
diff --git a/doc/resources/evolution.md b/doc/resources/evolution.md
index a8cf4e2..9756bc3 100644
--- a/doc/resources/evolution.md
+++ b/doc/resources/evolution.md
@@ -1073,7 +1073,9 @@ Excludes: backends (4,229), fsedsl (1,030), tests, KDE, tools, generated code.
## Phase 20: toolsrv 9P Migration & Process Isolation (Aug 10–11)
The tool server completed its evolution from an in-process library to a
-**fully independent 9P server** running as a child process of olliesrv.
+**fully independent 9P server**. Locally it runs as a child process of
+olliesrv; for remote execution it runs on a remote host, connected via
+SSH Unix socket forwarding.
### Before
@@ -1123,13 +1125,17 @@ communicate over a socket.
Three-layer defense against orphaned toolsrv processes:
-1. **Pdeathsig** — `SysProcAttr{Pdeathsig: SIGTERM}` on local spawn. When
- olliesrv dies, the kernel terminates toolsrv immediately.
+1. **Pdeathsig** (local only) — `SysProcAttr{Pdeathsig: SIGTERM}` on local
+ spawn. When olliesrv dies, the kernel terminates toolsrv immediately.
+ For SSH-spawned toolsrv, Pdeathsig is set on the `ssh` process itself —
+ when SSH dies, the remote shell receives SIGHUP which typically cascades
+ to toolsrv.
-2. **Idle timeout** — toolsrv tracks active 9P connections. After the first
- client connects and then all connections drop, a 30s timer starts.
- If no new connection arrives, toolsrv exits cleanly. 60s startup grace
- period for the initial connection.
+2. **Idle timeout** (local + remote) — toolsrv tracks active 9P connections.
+ After the first client connects and then all connections drop, a 30s timer
+ starts. If no new connection arrives, toolsrv exits cleanly. 60s startup
+ grace period for the initial connection. This is the primary cleanup
+ mechanism for remote toolsrv where Pdeathsig doesn't apply directly.
3. **Kill-before-respawn** — `ProcessKeeper.Dial()` kills the old process
before spawning a replacement. Prevents accumulation during reconnect cycles.