new file mode 100644
index 0000000..3994bc0
@@ -0,0 +1,70 @@
+---
+visibility: public
+---
+
+# Workspace isolation
+
+## The question
+
+"When a compromised message in chat A tries to read chat B's files, what stops it?"
+
+## The answer (v1)
+
+**POSIX permissions.** Chat A's processes run as a different Unix user (`chat-<hexA>`) from chat B's (`chat-<hexB>`). Chat B's home dir is `chmod 0700` and owned by `chat-<hexB>`. Chat A's user has no read access.
+
+## What this buys us
+
+- Fast spin-up (< 1 s: `useradd`, `mkdir`, `chown`, `chmod`).
+- Tiny idle footprint (a tmux + bash — few MB).
+- Composes with cheap hardening (bubblewrap, Landlock, firejail) later.
+- Works on any Linux; no daemon.
+
+## What this does NOT buy us
+
+- Kernel-level exploits cross boundaries.
+- Shared `/tmp`, shared `/dev`, shared networking by default.
+- Shared `/proc` can expose sibling-user process info (`ps aux`).
+- Resource limits need explicit cgroups.
+
+## Minimum hardening (v1)
+
+1. `chmod 0700` on home dirs, owned by the chat user
+2. `pam_namespace` → per-user `/tmp`
+3. `iptables` `owner match` → egress allowlist per UID
+4. cgroups v2 → 256 MB RAM, 200 pids, quarter-CPU per chat
+5. No sudo for chat users; no setuid binaries in their `PATH`
+6. Restricted PATH: shims at `/usr/local/bin/picortex-shims` first, then nothing of consequence
+
+## Known gaps (documented, not fixed in v1)
+
+- A chat user can `ps aux` and see other chat users' command lines. → Fix with `hidepid=2` mount option on `/proc`.
+- Shared DNS resolver config. → Fix with per-chat `resolv.conf` via namespaces.
+- Memory pressure from one chat can evict another (page cache). → Live with it.
+
+## Stronger options (evaluated for D2)
+
+- **bubblewrap (`bwrap`)**: add to the tmux-entry wrapper; cheap, composable, solid defaults.
+- **Landlock (kernel ≥ 6.1)**: programmatic FS ACLs per-process; newer API, smaller ecosystem.
+- **nsjail**: more config knobs than bwrap; use if bwrap isn't granular enough.
+- **firejail**: friendliest defaults for interactive shells.
+- **gVisor**: overkill, kernel surface reduction but cost.
+- **Firecracker microVM per chat**: overkill but the strongest.
+
+D2 will rank these with Jacob's real threat model. Start simple; add layers empirically.
+
+## Threat model (v1)
+
+| Threat | Likelihood | Impact | Controlled by |
+|---|---|---|---|
+| Prompt injection via a group member's message causes bot to exfil Jacob's DM files | high | high | per-chat user + `0700` |
+| Prompt injection causes bot to delete chat's own files | medium | low | acceptable — files are a cache |
+| Kernel exploit from chat user | low | high | keep kernel patched; consider bwrap/Landlock |
+| Bot accidentally posts a private file to the wrong chat | medium | high | sharing bridge R7 with BridgeEvent audit |
+| Someone gets Linq webhook secret | low | very high | HMAC + replay guard; rotate secret on suspicion |
+
+## References
+
+- [Spec 001](../specs/001-workspace-isolation-linux-users.md) — concrete provisioning
+- [ADR-0002](../adrs/0002-linux-users-over-docker.md) — the Linux-users-not-Docker decision
+- `~/memory/research/openclaw-group-chat-security.md` — prior research on prompt-injection in group chats
+- D2 ticket — isolation-model comparison report
\ No newline at end of file