# Laptop Dispatch — Windows SSH Gotchas

**Last updated:** 2026-05-10

**Correct SSH form — record verbatim:**
```
ssh -i /root/.ssh/id_hermes_ed25519 mclou@laptop-cd8df7fs "<command>"
```
- Key: `/root/.ssh/id_hermes_ed25519`
- User: `mclou` (Windows Administrator, NOT root)
- Host: `laptop-cd8df7fs` (hostname, NOT IP `100.108.207.15`)
- Port: 22 (plain SSH, NOT `tailscale ssh`)
- Flag: `-o StrictHostKeyChecking=no` suppresses host key prompts

**`tailscale ssh` does NOT work on Windows.** It returns "502 Bad Gateway". Use plain SSH via hostname.

**When port 22 times out:** laptop shows `active` on tailnet but SSH service may be down. Try plain SSH first (often still works). If it fails: Rocky runs `Restart-Service sshd` on the laptop.

## Windows path escaping (PowerShell vs CMD)

Windows paths via SSH require careful quoting. Rules:

| What | Wrong | Right |
|---|---|---|
| CMD.exe paths | `cd C:\Users\mclou\rateright-growth` | `cmd /c "cd /d C:\Users\mclou\rateright-growth"` |
| PowerShell paths | `cd C:\Users\mclou\rateright-growth` | `powershell -Command "cd 'C:\Users\mclou\rateright-growth'; <cmd>"` |
| Git with paths | `git -C 'C:\path'` | `git -C 'C:\path'` works in PowerShell, not in CMD |

**Best practice:** Use `powershell -Command` for anything that needs path resolution. Use `cmd /c` for directory listings.

### Working examples

**List a directory:**
```bash
ssh -i /root/.ssh/id_hermes_ed25519 mclou@laptop-cd8df7fs "cmd /c dir C:\Users\mclou"
```

**Check if a path exists (PowerShell):**
```bash
ssh -i /root/.ssh/id_hermes_ed25519 mclou@laptop-cd8df7fs "powershell -Command \"Test-Path 'C:\Users\mclou\rateright-growth'\""
```

**Run git commands:**
```bash
ssh -i /root/.ssh/id_hermes_ed25519 mclou@laptop-cd8df7fs "powershell -Command \"git -C 'C:\Users\mclou\rateright-growth-deploy' log --oneline -3\""
```

## .env config on laptop

The laptop's `rateright-growth-deploy/.env` does NOT have `ANTHROPIC_API_KEY` set. This causes `claude -p` to fail with "Invalid API key".

Current keys in `.env`:
- `SLACK_WEBHOOK_URL`
- `CLAWDBOT_API_KEY`

**To run Claude Code on the laptop, either:**
1. Set `ANTHROPIC_API_KEY` in the laptop's `.env` (Rocky types it manually, only needed if you want laptop-side execution)
2. Run Claude Code from the VPS instead (where the API key IS set in `.env`) — preferred for the foreseeable future

## Running Claude Code via SSH

**Works:**
```bash
ssh -i /root/.ssh/id_hermes_ed25519 mclou@laptop-cd8df7fs "powershell -Command \"cd 'C:\Users\mclou\rateright-growth-deploy'; claude -p 'hi'\""
```

**Fails (API key missing):**
```bash
ssh -i /root/.ssh/id_hermes_ed25519 mclou@laptop-cd8df7fs "powershell -Command \"cd 'C:\Users\mclou\rateright-growth-deploy'; claude -p 'do something' --dangerously-skip-permissions\""
# → "Invalid API key"
```

**For heavy Claude Code work:** do it from the VPS (where the key is set) rather than dispatching to the laptop.

## Git on laptop — credential issue

Git fetch/pull on the laptop fails with:
```
fatal: Unable to persist credentials with the 'wincredman' credential store.
```

This is a Windows credential store issue — Git can't use the Windows Credential Manager via SSH. The laptop is out of sync with origin/main.

**Workaround:** If you need to sync the laptop's vault, either:
1. Push from VPS (where git works fine) and tell Rocky to pull manually on laptop
2. Use a GitHub Personal Access Token in a `git remote set-url` command (requires the token)

## File locations on laptop

| Path | What |
|---|---|
| `C:\Users\mclou\rateright-growth-deploy` | Main vault repo — this is where the work happens |
| `C:\Users\mclou\opsman` | Local opsman workspace (old) |
| `C:\Users\mclou\lfcs-handoff` | LFCS handoff folder |
| `C:\Users\mclou\lfcs-precedent-staging` | Husse's LFCS Obsidian vault mirror — 28 jobs ingested 2026-05-10, precedent-finder corpus grew from 11→39 |
| `C:\Program Files\OpenSSH` | OpenSSH server installation |

## lfo/lfp Daemon Sessions — How They Get Auth (2026-05-10)

The daemon spawns `claude -p` sessions WITHOUT `ANTHROPIC_API_KEY` in the environment (`env: ANTHROPIC_API_KEY stripped` per daemon log). Despite this, sessions work.

**How it works:** CC on the laptop is logged in via OAuth (Max subscription, desktop session). When the daemon spawns a subprocess, it inherits the OAuth session from the desktop context. The `ANTHROPIC_API_KEY` is not needed because OAuth auth handles it.

**What this means for dispatch:**
- You can spawn lfo/lfp sessions from VPS via SSH and they work
- No API key needed on laptop
- The previous "Invalid API key" error from direct `claude -p` SSH was a different scenario (invoking CC directly without the daemon/OAuth context)

## Quick dispatch checklist

Before SSHing to laptop, confirm:
1. ✅ Using `mclou@` not `root@`
2. ✅ Using hostname `laptop-cd8df7fs` not IP `100.108.207.15`
3. ✅ Using `powershell -Command` or `cmd /c` for Windows path-based commands
4. ✅ Git work done from VPS (where credentials work), not laptop
5. ✅ Claude Code execution from VPS unless API key explicitly set on laptop