jj workspaces over the network
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs: reframe server as infrastructure, clarify deployment model

+69 -55
+6 -5
AGENTS.md
··· 18 18 binary (which embeds jj-cli with a custom tandem backend) to read and write 19 19 objects over Cap'n Proto RPC. 20 20 21 - The server is the **point of origin** — it's where git operations happen 22 - (`jj git push`, `jj git fetch`, `gh pr create`). The orchestrator/teamlead 23 - runs these on the server to ship code upstream. The tandem server is the source 24 - of truth, with GitHub as a mirror. 21 + The server is the **point of origin** — it typically runs on a VM/VPS as a 22 + long-running service. It's where git operations happen (`jj git push`, 23 + `jj git fetch`, `gh pr create`). The orchestrator/teamlead runs these on the 24 + server to ship code upstream. The tandem server is the source of truth, with 25 + GitHub as a mirror. 25 26 26 27 ## Installation 27 28 ··· 119 120 120 121 See `docs/design-docs/workflow.md` for the full picture. Summary: 121 122 122 - 1. **Orchestrator** sets up server: `tandem serve --listen 0.0.0.0:13013 --repo /srv/project` 123 + 1. **Orchestrator** sets up server on a VM/VPS: `tandem serve --listen 0.0.0.0:13013 --repo /srv/project` 123 124 2. **Agents** init workspaces: `tandem init --tandem-server=host:13013 ~/work/project` 124 125 3. **Agents** use stock jj commands: write files, `tandem new -m "feat: add auth"`, etc. 125 126 4. **Agents** see each other's files: `tandem cat -r <other-commit> src/auth.rs`
+3
ARCHITECTURE.md
··· 17 17 ## Core model 18 18 19 19 - Server hosts a **normal jj+git colocated repo** (uses jj's Git backend) 20 + - Server is a **long-running service**, typically on a VM/VPS — it holds the canonical repo. If lost without backups, the data is gone (unless mirrored to GitHub via `jj git push`). 20 21 - Client keeps **working copy local** (real files on disk) 21 22 - Client store calls are remote via Cap'n Proto RPC 22 23 - Backend/OpStore/OpHeadsStore trait implementations route to server ··· 81 82 - `jj git fetch` — pull upstream changes into the server's repo 82 83 - `jj git push` — push agents' work to GitHub 83 84 - `gh pr create` — create PRs from the server 85 + 86 + The server needs git credentials (SSH keys or tokens) for GitHub access. 84 87 85 88 Agents never touch git. The server is the single point of contact with 86 89 the outside world. The orchestrator SSHes to the server (or runs commands
+52 -42
README.md
··· 13 13 ``` 14 14 15 15 tandem is a single binary that embeds [jj](https://jj-vcs.com). The server 16 - hosts a jj+git repo. Agents on remote machines get transparent read/write 17 - access over Cap'n Proto RPC. Every stock jj command works — `log`, `new`, 18 - `diff`, `file show`, `bookmark`, `describe` — because tandem implements 19 - jj-lib's `Backend`, `OpStore`, and `OpHeadsStore` traits as RPC stubs. 16 + hosts a jj+git repo — typically on a VM or VPS as a long-running service. 17 + Agents on remote machines get transparent read/write access over Cap'n Proto 18 + RPC. Every stock jj command works — `log`, `new`, `diff`, `file show`, 19 + `bookmark`, `describe` — because tandem implements jj-lib's `Backend`, 20 + `OpStore`, and `OpHeadsStore` traits as RPC stubs. 20 21 21 22 ## Why 22 23 ··· 105 106 tandem serve --listen 0.0.0.0:13013 --repo ~/project 106 107 ``` 107 108 109 + For production use, run this on a VM/VPS — see [Deployment setups](#deployment-setups) below. 110 + 108 111 ### Connect agents 109 112 110 113 ```bash ··· 159 162 160 163 ## Deployment setups 161 164 162 - ### Local: multiple terminals 165 + ### Local: multiple terminals (for testing) 163 166 164 - The simplest setup. Server and agents on the same machine, different 165 - directories. 167 + The simplest setup for trying tandem out. Server and agents on the same 168 + machine, different directories. Not how you'd run it for real work — see 169 + Remote machines below. 166 170 167 171 ```bash 168 172 # Terminal 1 — server ··· 177 181 cd /tmp/agent-b && tandem log # sees agent A's commit 178 182 ``` 179 183 180 - Good for trying things out. No network setup, no containers. 184 + ### Remote machines: sprites.dev / exe.dev / SSH 185 + 186 + The typical production setup. Server on a VPS/VM, agents on separate machines. 187 + 188 + ```bash 189 + # VPS — server 190 + tandem serve --listen 0.0.0.0:13013 --repo /srv/project 191 + 192 + # Machine A — agent A (e.g. sprites.dev sandbox) 193 + # Copy the binary over, or build on the remote machine 194 + scp target/release/tandem agent-a-host:/usr/local/bin/ 195 + ssh agent-a-host 196 + export TANDEM_SERVER=server-host:13013 197 + tandem init ~/work 198 + cd ~/work 199 + # ... write code, commit with tandem new ... 200 + 201 + # Machine B — agent B (e.g. exe.dev VM) 202 + scp target/release/tandem agent-b-host:/usr/local/bin/ 203 + ssh agent-b-host 204 + export TANDEM_SERVER=server-host:13013 205 + tandem init --workspace=agent-b ~/work 206 + cd ~/work 207 + tandem log # sees agent A's commits 208 + tandem file show -r <change-id> src/auth.rs # reads agent A's files 209 + ``` 210 + 211 + Requirements: 212 + - Server port (default 13013) must be reachable from agent machines 213 + - No TLS yet — use SSH tunnels or VPN for untrusted networks 214 + - The `tandem` binary is ~30MB, statically linkable, no runtime deps 181 215 182 216 ### Docker: 3 agents on a shared network 183 217 ··· 228 262 This simulates cross-machine communication. Each container has its own 229 263 filesystem, its own network identity, and connects to the server by DNS name. 230 264 Tested — see `qa/v1/cross-machine-report.md`. 231 - 232 - ### Remote machines: sprites.dev / exe.dev / SSH 233 - 234 - Server on one machine, agents on others. 235 - 236 - ```bash 237 - # Machine 1 — server (your laptop, a VPS, etc.) 238 - tandem serve --listen 0.0.0.0:13013 --repo ~/project 239 - 240 - # Machine 2 — agent A (e.g. sprites.dev sandbox) 241 - # Copy the binary over, or build on the remote machine 242 - scp target/release/tandem agent-a-host:/usr/local/bin/ 243 - ssh agent-a-host 244 - export TANDEM_SERVER=server-host:13013 245 - tandem init ~/work 246 - cd ~/work 247 - # ... write code, commit with tandem new ... 248 - 249 - # Machine 3 — agent B (e.g. exe.dev VM) 250 - scp target/release/tandem agent-b-host:/usr/local/bin/ 251 - ssh agent-b-host 252 - export TANDEM_SERVER=server-host:13013 253 - tandem init --workspace=agent-b ~/work 254 - cd ~/work 255 - tandem log # sees agent A's commits 256 - tandem file show -r <change-id> src/auth.rs # reads agent A's files 257 - ``` 258 - 259 - Requirements: 260 - - Server port (default 13013) must be reachable from agent machines 261 - - No TLS yet — use a tunnel (e.g. `ssh -L`) for untrusted networks 262 - - The `tandem` binary is ~30MB, statically linkable, no runtime deps 263 265 264 266 ### Claude Code: multi-agent with tandem 265 267 ··· 391 393 392 394 ## Known limitations 393 395 394 - - **No TLS** — connections are plaintext. Use SSH tunnels for untrusted networks. 395 - - **No auth** — anyone who can reach the port can read/write the repo. 396 + - **No TLS** — connections are plaintext. For production on a VPS, use SSH tunnels (`ssh -L`) or a VPN. 397 + - **No auth** — anyone who can reach the port can read/write the repo. On a VPS, firewall the port and use SSH tunnels for access. 396 398 - **No static binary yet** — requires glibc 2.39+. Use matching distro or build locally. 397 399 - **fsmonitor conflict** — if your jj config has `fsmonitor.backend = "watchman"`, 398 400 pass `--config=fsmonitor.backend=none` to tandem commands. 399 401 - **Description-based revsets** — `description(exact:"...")` may not work for 400 402 cross-workspace queries. Use change IDs from `tandem log` instead. 403 + 404 + ## Running in production 405 + 406 + - **Back up the server repo directory** — it's the source of truth. If lost without backups, data is gone (unless mirrored to GitHub via `jj git push`). 407 + - **Use a process manager** (systemd, supervisord, etc.) to keep `tandem serve` running. 408 + - **Git credentials on the server** — the server needs SSH keys or tokens for `jj git push` / `jj git fetch` to GitHub. 409 + - **Monitor disk space** — all agent objects (files, trees, commits) land on the server. 410 + - **Firewall the port** — no auth means network-level access control is your only defense. SSH tunnels or VPN. 401 411 402 412 ## Project structure 403 413
+8 -8
docs/design-docs/workflow.md
··· 9 9 ## Roles 10 10 11 11 **Server (point of origin):** 12 + - Runs on a VM/VPS as a persistent service 12 13 - Hosts the canonical jj+git repo 13 14 - Runs `tandem serve` 14 15 - Is where git operations happen (`jj git push`, `jj git fetch`, `gh pr create`) ··· 25 26 ### 1. Setup 26 27 27 28 ```bash 28 - # On the server 29 + # On the server (typically a VM/VPS) 29 30 mkdir /srv/project && cd /srv/project 30 31 jj git init 31 32 jj git remote add origin git@github.com:org/project.git ··· 89 90 outside world. It's where the orchestrator makes decisions about what 90 91 ships and what doesn't. 91 92 92 - ## Future: tandem as source of truth 93 + ## Tandem as source of truth 93 94 94 - The architecture supports a future where the tandem server is THE canonical 95 - store, and GitHub is just a mirror: 95 + The tandem server is the canonical store. GitHub is a mirror. 96 96 97 - - Tandem server holds the complete history 97 + - The server holds the complete history — all agent objects live there 98 98 - `jj git push` mirrors to GitHub for CI, code review, external visibility 99 99 - Other teams interact via GitHub as usual 100 - - But the agents and orchestrator work entirely through tandem 100 + - Agents and the orchestrator work entirely through tandem 101 101 102 - No architecture change is needed — it's the same code, just a different 103 - trust model. The server already has everything. 102 + Back up the server repo directory. If it's lost without backups, the data 103 + is gone (unless you've been pushing to GitHub regularly).