Pearl OS Infrastructure — Canonical Config (2026-05-11)
Status: DEFINITIVE (source of truth for all sessions) Last updated: 2026-05-11T23:50:00Z Updated by: opencode/ext-agent (sandshrew) + MjF Applies to: all agents, all sessions, all surfaces (CLI, sessions, probes)
Devices
Pi 4 (relik-pi4)
- Tailscale IP: 100.120.38.37
- Tailscale name: relik-pi4
- Tailscale version: 1.96.4
- Tailscale SSH: ENABLED (admin console toggle ON)
- OS: Debian 13 (trixie), Linux 6.12.75+rpt-rpi-v8, aarch64
- User: mehdifarah (key-based auth + Tailscale SSH)
- RAM: 4GB (3.1GB available)
- Disk: 29GB SD (18GB free)
Canonical SSH:
ssh mehdifarah@relik-pi4 # Tailscale SSH (preferred — no password)
ssh mehdifarah@100.120.38.37 # Tailscale IP (always works)
Game surface venv: /home/mehdifarah/game-surface-venv/
Installed: langgraph 1.1.10, fastapi 0.136.1, uvicorn 0.46.0, requests 2.32.3
Docker containers: d3-tui-pi-teams-proto (pi-teams + LLM wiki), from-forgejo (Forgejo on port 3001, not configured — web UI shows install page)
RG40XXV (knulli-1)
- Tailscale IP: 100.119.202.114
- Tailscale name: knulli-1
- Tailscale version: 1.96.4 (updated from 1.76.1 on 2026-05-11)
- Tailscale SSH: ENABLED (via scheduled nohup — survives reboots)
- OS: KNULLI (Linux 4.9.170, Buildroot, aarch64)
- User: root (password
linux, Tailscale SSH preferred) - MagicDNS short hostnames: NOT SUPPORTED (KNULLI Connection Manager overwrites /etc/resolv.conf) — use IPs
- Display: 640×480
- Gamepad: /dev/input/js0
- Python: 3.12.8, pygame 2.5.2, requests 2.32.3
Canonical SSH:
ssh root@100.119.202.114 # Tailscale SSH (preferred — no password, no sshpass)
ssh root@relik-pi4 # from Pi only (both on tailnet)
Tailscale binary: /userdata/tailscale_1.96.4_arm64/
Tailscale startup: /userdata/system/custom.sh (symlinks at boot)
Tailscale state: /userdata/system/tailscale/tailscaled.state
Mac (mehdis-macbook-air-2)
- Tailscale IP: 100.93.138.108
- Tailscale name: mehdis-macbook-air-2
- Tailscale SSH: confirmed working to Pi
Wiring Between Pi and RG
| Metric | Value |
|---|---|
| Ping Pi↔RG | 3-5ms steady state, 0% packet loss |
| HTTP roundtrip RG→Pi | 16ms avg (POST /ping) |
| State fetch (36 nodes + 3 units) | 18ms, 5.9KB payload |
| Invoke (0.8s mock agent) | 839ms total, 39ms HTTP overhead |
| Polling interval | 100ms (10 polls/sec — imperceptible at 16ms latency) |
| HTTP framework | FastAPI + uvicorn on Pi |
| HTTP client | Python requests on RG |
| State serialization | JSON, <50KB even with full history |
| Hostname resolution | Use IPs — MagicDNS short names blocked by KNULLI |
What Sessions Must Use
SSH
# Pi:
ssh mehdifarah@relik-pi4
# RG:
ssh root@100.119.202.114
No passwords. No sshpass. No ConnectTimeout. Tailscale SSH handles everything.
HTTP (game surface)
# From RG to Pi:
requests.get("http://100.120.38.37:8000/state")
requests.post("http://100.120.38.37:8000/invoke", json={...})
# From Pi to RG:
# Same pattern, reversed IP
Pi venv
ssh mehdifarah@relik-pi4
cd /home/mehdifarah
source game-surface-venv/bin/activate
# langgraph, fastapi, uvicorn, requests all available
What Sessions Must NOT Do
- Do NOT use
sshpass -pfor RG — Tailscale SSH is enabled - Do NOT use
ConnectTimeout=60— no longer needed - Do NOT use
192.168.1.28(local IP) — use Tailscale IP - Do NOT use
ssh mehdifarah@100.120.38.37— use hostnamerelik-pi4 - Do NOT use MagicDNS short hostnames on RG — they don't resolve
- Do NOT pip install system-wide on Pi — use the venv
- Do NOT expect Forgejo web UI at port 3001 — it's not configured
Wiki Depot
LLM wiki: /workcell/llm-wiki/ inside d3-tui-pi-teams-proto Docker container
Forgejo repo: ssh://mehdifarah@relik-pi4:/home/mehdifarah/git/langgraph-game-surface.git
Pearl Brain: query for infrastructure canonical config or tailscale setup