# Using a Handoff Session

Handoff lets a host share a short-lived remote diagnostic session without
opening inbound firewall rules or sharing machine credentials.

## Host Flow

Download `handoff.exe`, then start a session:

```powershell
.\handoff.exe new
```

The host terminal prints a view URL:

```text
https://handoff.whyknot.dev/v/n1_AbCdEfGhIjK...
```

Send that URL to the operator. The host can press Ctrl+C at any time to end
the session.

## Operator Flow

Open the view URL in a browser. The viewer shows host connection state, a
command palette, queued commands, and command results. Commands are sent through
the relay to the connected host and results stream back into the event pane.

The CLI can also open the same viewer:

```powershell
.\handoff.exe connect https://handoff.whyknot.dev/v/<token>
```

## Risky Commands

Commands that can change the host, terminate processes, control services,
flash Pico devices, or run arbitrary PowerShell are marked as risky in the
viewer. The first risky command asks the host to approve risky commands for the
remainder of that session. A denial blocks risky commands for the session.

The relay still queues only known Handoff command kinds. The host enforces the
actual local action and consent decision.

## Direct API

Mint a session:

```powershell
Invoke-RestMethod -Method Post https://handoff.whyknot.dev/api/sessions
```

Queue a command:

```powershell
$body = @{ kind = "sys.uptime" } | ConvertTo-Json -Compress
Invoke-RestMethod -Method Post `
  -Uri "https://handoff.whyknot.dev/api/sessions/<view-token>/cmd" `
  -ContentType "application/json" `
  -Body $body
```

Fetch replayed events:

```powershell
Invoke-RestMethod "https://handoff.whyknot.dev/api/sessions/<view-token>/events?since=0"
```

## Troubleshooting

| Symptom | Meaning | Next step |
|---|---|---|
| `bridge_connected: false` | No host is attached to the session. | Ask the host to run `handoff new` again and share the fresh URL. |
| `unknown view token` | The session is gone or the token is wrong. | Use the latest URL printed by the host. |
| `kind not in Handoff allowlist` | The viewer or API sent an unsupported command kind. | Check `/api/sessions/<token>/meta` for the live allowlist. |
| `413 Payload Too Large` | The command body exceeded the relay cap. | Use a smaller upload or a narrower command payload. |
| `429 Too Many Requests` | Session or mint rate limit was hit. | Back off briefly before queuing more commands. |
