Dual-machine agentic coding failover system for Command Code (cmdc).
Two independent cmdc sessions — laptop + Oracle VM — sharing project memory via git-tracked context files and one-context-mcp. Switch between machines seamlessly; cmdc on the target knows exactly what you were doing.
Laptop (i7, 32GB) ←── git + Tailscale ──→ Oracle VM (ARM, 24GB)
│ │
cmdc session cmdc session
one-context-mcp one-context-mcp
VS Code (editing) Docker (testing)
code-server (web IDE)
│ │
└───────────────┬─────────────────────────┘
│
Phone (SSH via QR)
# 1. Provision Oracle VM (free tier)
# See: scripts/PHASE1-README.md
# 2. Run VM setup
scp scripts/oracle-vm-setup.sh ubuntu@<vm-ip>:~/
ssh ubuntu@<vm-ip> 'bash oracle-vm-setup.sh'
# 3. Install Tailscale on all devices
# VM: bash scripts/install-tailscale-vm.sh
# Laptop: PowerShell scripts/install-tailscale-laptop.ps1
# Phone: App Store / Google Play
# 4. Configure ACLs
# Copy scripts/tailscale-acls.json to Tailscale admin console
# 5. Harden SSH + generate keys
ssh ubuntu@<vm-ip> 'bash ~/secure-ssh.sh'
bash scripts/setup-ssh-keys.sh
# 6. Generate QR codes for phone
bash scripts/gen-ssh-qr.sh# On BOTH laptop and VM:
bash scripts/install-one-context.sh
# Verify:
cmdc mcp list | grep one-ctx
ctx status cmdc-failoverType these directly in the cmdc terminal — no shell commands needed:
| Keyphrase | Action |
|---|---|
Jarvis vm |
Sync context → hand off to VM. Shows QR/SSH command for phone. |
Jarvis pc |
Sync context → hand off to laptop. |
Jarvis laptop |
Same as "Jarvis pc" |
Jarvis switch |
Show current machine + sync status |
Jarvis who |
Who's driving right now? |
Jarvis push |
Manual sync push (no switch) |
Jarvis pull |
Manual sync pull (no switch) |
cmdc's jarvis-handoff skill handles everything — context export, git push, QR display, machine tracking.
# Start coding (laptop or VM)
bash scripts/cmdc-session-start
# Work with cmdc normally...
# When ready to switch machines, just type in cmdc:
Jarvis vm # switches to VM — shows phone SSH command
# or
Jarvis pc # switches to laptop
# From phone:
ssh oracle-vm 'bash scripts/cmdc-failover-phone'# Start cmdc with full context (on laptop or VM)
bash scripts/cmdc-session-start
# cmdc auto-reads COMMANDCODE.md + .cmdc-context/
# Uses one-context-mcp tools via MCP (ctx_get, ctx_update)
# Auto-updates context files via auto-context skill# Run test suite
bash scripts/failover-test
# Full failover from laptop → VM
# On laptop:
cmdc-sync push
# On phone → VM:
ssh oracle-vm 'bash scripts/cmdc-failover-phone'
# Back on laptop:
cmdc-sync pull && bash scripts/cmdc-session-start# On VM: full dev setup with code-server, auto-start, notifications
bash scripts/vm-setup-dev-env
# Health checks run automatically every 5 min
systemctl status cmdc-health-check.timer
# Manual health check
bash scripts/vm-health-check
bash scripts/vm-health-check --notify # With push notification
# Access code-server (web VS Code)
# http://<vm-tailscale-ip>:8080# VM auto-services (systemd timers)
# cmdc-health-check.timer — every 5 min
# cmdc-context-pull.timer — every 5 min auto-pull
# cmdc-session.service — auto-start cmdc in tmux
# Notifications via ntfy (optional)
# Set NTFY_TOPIC + NTFY_URL in vm-health-check
# Get push notifications on phone when:
# - Health issues detected
# - New context available
# - cmdc session crashed| Command | Description | Phase |
|---|---|---|
cmdc-sync push |
Export context, commit, push to git | 2 |
cmdc-sync pull |
Pull from git, import context | 2 |
cmdc-sync status |
Show sync state | 2 |
cmdc-sync flush |
Push queued offline commits | 2 |
scripts/cmdc-session-start |
Start/attach cmdc in tmux with context | 3 |
scripts/cmdc-failover-phone |
One-command phone failover to VM | 4 |
scripts/failover-test |
End-to-end test suite | 4 |
scripts/vm-setup-dev-env |
Full VM dev environment setup | 5 |
scripts/vm-health-check |
Monitor VM + cmdc health | 6 |
scripts/install-one-context.sh |
Setup one-context-mcp | 2 |
scripts/oracle-vm-setup.sh |
Fresh VM provisioning | 1 |
scripts/secure-ssh.sh |
SSH hardening | 1 |
scripts/setup-ssh-keys.sh |
Generate + distribute SSH keys | 1 |
scripts/gen-ssh-qr.sh |
Generate QR codes for phone | 1 |
COMMANDCODE.md ← cmdc's project memory (auto-read)
.cmdc-context/
├── session-summary.md ← Current task, progress
├── conversation-log.md ← Last 5 turns
├── handoff-marker.md ← Last sync info
├── active-machine ← Who's driving
└── context.json ← one-context-mcp export (auto)
.commandcode/
└── skills/auto-context/ ← cmdc skill for auto-updates
- Command Code CLI (
npm i -g command-code) - Tailscale (all devices)
- Python 3.11+ with
one-ctx(pip install one-ctx) - Node.js 22+ (for cmdc)
- tmux, git, Docker (VM)
- SSH client on phone (Termius / Prompt)
| # | Phase | Status |
|---|---|---|
| 1 | Foundation — VM, Tailscale, SSH, QR codes | ✅ Complete |
| 2 | Context Layer — one-context-mcp, git, cmdc-sync | ✅ Complete |
| 3 | cmdc Sessions — tmux, context-aware startup, auto-context skill | ✅ Complete |
| 4 | Failover — phone trigger, bidirectional sync, offline resilience | ✅ Complete |
| 5 | VM Dev Env — Docker, code-server, auto-start services | ✅ Complete |
| 6 | Monitor — health checks, ntfy notifications, systemd timers | ✅ Complete |
See specs/006-cmdc-failover/ for the full spec-kit artifacts:
spec.md— Feature specification (5 user stories, 14 functional requirements)plan.md— Implementation plan with architecture diagramstasks.md— 31 tasks across 6 phasesresearch.md— 8 research findings + decision logcontracts/context-schema.json— JSON schema for context files
- No public ports — all traffic over Tailscale WireGuard
- SSH key-only auth (ed25519), no passwords
- UFW + Fail2Ban on VM
- Tailscale ACLs restrict to SSH port 22
MIT