PavlokPager¶
C# CLI that lets Claude (or anything else) page Andrew through his Pavlok wristband — vibe, beep, or zap — via the Pavlok API v5.
Built as the "phone line" for overnight autonomous missions: when Claude finishes all queued work or hits a blocker only a human can resolve, it runs an escalation ladder on the band instead of silently idling until morning.
Docs¶
- Technical architecture — C4 + sequence + state diagrams, command surface, storage, build
- How it works (plain English) — no-jargon explainer
- Security — threat model, controls, Semgrep + Codex gate results
- Testing — xUnit + Bogus suite, Stryker mutation score
- Making of — living build journal, design → now
- Project board — PP-1…PP-17 Kanban (live HTML)
How it works¶
POST https://api.pavlok.com/api/v5/stimulus/send with Authorization: Bearer <api-key> and body:
{ "stimulus": { "stimulusType": "vibe|beep|zap", "stimulusValue": 1-100 } }
Install (as a .NET global tool)¶
dotnet pack PavlokPager.csproj -c Release
dotnet tool install --global --add-source .\nupkg PavlokPager # use `update` to upgrade
Requires .NET 10 SDK. Installs command pavlok, available from any directory / new terminal (~\.dotnet\tools is on PATH by default). No Docker, no daemon — it's a fire-and-forget CLI the overnight session invokes when it needs a human.
Setup (BYO key)¶
- Get a token — either
pavlok login(below) does it for you, or grab one from the Pavlok API docs Authentication page while logged in. - Store it — pick one:
pavlok login— prompts email, then a hidden password prompt; POSTs to/api/v5/users/login, saves the returned token DPAPI-encrypted in%USERPROFILE%\.pavlok\config.json. Password is never stored or echoed.pavlok setup— hidden prompt for an existing token (or pipe it:echo $TOKEN | pavlok setup).- set the
PAVLOK_API_KEYenvironment variable (takes precedence over stored key). - Verify:
pavlok test(gentle vibe).
Secrets are never accepted as command-line arguments (they would leak into shell history and the process list). The token file and log are created owner-only (0600, directory 0700) on Linux/macOS; on Windows the token is DPAPI-encrypted to the current user. Set PAVLOK_DEBUG=1 to see raw API response bodies when troubleshooting.
Usage¶
pavlok login [email] log in (password: hidden prompt or piped stdin)
pavlok setup store a token (hidden prompt or piped stdin)
pavlok vibe|beep|zap [1-100] [--reason ""] send one stimulus (default 50)
pavlok page --reason "" [--level L] run escalation ladder (gentle|normal|urgent)
pavlok test gentle vibe to verify setup
pavlok log [-n 20] recent history
--dry-run print steps instead of sending
Escalation ladders (defaults)¶
| Level | Steps |
|---|---|
| gentle | vibe 40 → vibe 60 |
| normal | vibe 50 → beep 60 → vibe 80 → beep 80 |
| urgent | vibe 80 → beep 100 → zap 100 ×5 (max-strength zaps — what it actually takes to wake Andrew) |
Delays between steps are built in (10–45 s). Edit %USERPROFILE%\.pavlok\config.json to customize ladders, maxZap (default 100 — zaps are clamped to this), and maxPagesPer8Hours (default 3 — further page calls are refused with exit code 3 so a looping agent can't zap all night; dry-runs don't count).
Every stimulus is logged to %USERPROFILE%\.pavlok\pages.jsonl with timestamp, type, value, and reason.
Exit codes¶
0 = ok · 1 = send failed after retries · 2 = usage error · 3 = page budget refused
Security¶
The Pavlok token is the only secret this tool holds. It is never accepted as a CLI argument, never
echoed, and never stored in plaintext on Windows: pavlok setup/pavlok login DPAPI-encrypt it to
the current user (0600/0700 owner-only files on Linux/macOS, where DPAPI is unavailable). The
PAVLOK_API_KEY environment variable overrides the stored value for CI/scripted use. A hard budget
(maxPagesPer8Hours, default 3) caps how often the band can be paged, so a runaway or looping agent
can't zap all night. CI runs Semgrep (Docker) on every push with pinned-SHA Actions. Full threat
model, controls table, and scan results: docs/technical/SECURITY.md.
Claude skill¶
The pavlok-page skill (versioned here under skill/) teaches Claude when it may page (all work done / hard-blocked / critical failure), the escalation protocol (summary in chat first, one page, 15-min wait, max one escalation), and the hard budget.
Install it for Claude Code by copying it into your skills directory:
Copy-Item -Recurse skill\pavlok-page "$env:USERPROFILE\.claude\skills\pavlok-page" -Force