# VantagePost remediation: agent runbook

Dashboard: https://vp.micahberkley.com
This page: https://vp.micahberkley.com/agents (raw: https://vp.micahberkley.com/RESUME.md)

You are fixing the 78-issue QA list for VantagePost (repo deepstation/vantagepost).
The dashboard is the single source of truth for what to do next, who is doing it
and where each item stopped. Read this whole page before touching code.

## 1. If you were interrupted (or are new): resume in 4 steps

1. Pick a stable agent name for yourself and keep it for the whole session,
   for example `claude-<session id>` or `codex-<run id>`.
2. Ask the dashboard what to do:

       curl -s "https://vp.micahberkley.com/api/next?agent=<your name>"

   It returns, in this order of priority:
   - an item you already hold a live lease on (you were interrupted; continue it),
   - an item whose PR needs a fix (CI failing, conflicts, changes requested, wrong base),
   - a paused item (an earlier agent's lease expired; its branch is kept),
   - the next ready item by wave and order.
   `resuming: true` means work already exists. Read `item.resume`: the branch,
   ticket, PR and last note tell you exactly where it stopped. Also read the
   item's history: `curl -s https://vp.micahberkley.com/api/items/<code>`.
3. Claim it (this takes a 30-minute lease):

       curl -s -X POST https://vp.micahberkley.com/api/items/<code>/claim \
         -H "Authorization: Bearer $(cat ~/.config/vantagepost/remediation-dashboard-token)" \
         -H 'content-type: application/json' -d '{"agent":"<your name>"}'

   A 409 means someone else holds it or it is blocked. Go back to step 2.
4. If `resume.branch` is set: `git fetch origin && git checkout <branch>` and
   continue from the last note. Otherwise start fresh (section 3).

## 2. While you work

- Heartbeat at least every 10 minutes, with a one-line note of where you are.
  Without it the lease expires after 30 minutes and the item goes back to the queue
  for another agent to resume:

      curl -s -X POST https://vp.micahberkley.com/api/items/<code>/heartbeat -H "Authorization: Bearer $TOKEN" \
        -H 'content-type: application/json' -d '{"agent":"<name>","note":"tests written; implementing the gate"}'

- Register what you create the moment it exists, so a successor can find it:

      curl -s -X POST https://vp.micahberkley.com/api/items/<code>/progress -H "Authorization: Bearer $TOKEN" \
        -H 'content-type: application/json' -d '{"agent":"<name>","ticket":"VP-1234","branch":"micah/vp-1234-slug","pr":701,"note":"PR open"}'

- After every `git push`, trigger a sync so the board updates at once:

      curl -s -X POST https://vp.micahberkley.com/api/sync -H "Authorization: Bearer $TOKEN"

- Stopping before you are done? Leave a note and release:

      curl -s -X POST https://vp.micahberkley.com/api/items/<code>/release -H "Authorization: Bearer $TOKEN" \
        -H 'content-type: application/json' -d '{"agent":"<name>","note":"half done: gate in place, social part left"}'

- Found something that is not part of your item? Do not fold it in. Add it:

      curl -s -X POST https://vp.micahberkley.com/api/items -H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' \
        -d '{"agent":"<name>","code":"S4","title":"...","rootCause":"...","fix":"...","wave":5}'

## 3. How to do an item (the team's delivery cadence)

1. Read the brief from `/api/next` or `/api/items/<code>`: issues, root cause, fix,
   acceptance and the evidence file (file:line for both branches).
   Re-check the evidence against the current code first; it was written 2026-10-19.
2. Linear ticket first: team VP, project VantagePost, plain English, bugs titled
   `BUG: <what the user sees>`. Search for an existing ticket before creating one.
   Register it with `/progress`.
3. Branch from `release/v0.1.7` using the ticket's branch name (`micah/vp-NNN-slug`).
   Register it with `/progress`.
4. Implement with tests. Then have a second agent review it before the PR.
5. Open the PR into `release/v0.1.7`. The body uses Before / After / Receipts /
   Merge order, and must contain the line `Remediation: RMD-<code>` (for example
   `Remediation: RMD-A1`). That line is how the sync links your PR.
6. Register the PR with `/progress`, trigger `/api/sync`, release your lease.
   The sync now tracks CI, conflicts and reviews. If the item turns "needs fix",
   `/api/next` hands it back to whoever comes next.
7. Micah merges. The sync sees the merge and marks the item merged; dependents unblock.
8. Verification (V1, or per item when asked): check on staging, send Micah
   screenshots, then `POST /api/items/<code>/verify` with a note of what you checked.

## 4. Hard rules

- Base is `release/v0.1.7`. NEVER open, retarget or merge a PR into `main`, even if a ticket says main.
- Never merge. Micah merges.
- `gh auth switch --user TheAIMogul` before any `gh` command.
- No `Co-Authored-By` trailers, no "Generated with Claude Code" footers.
- Do not run `bun run build` or `bun run dev` unless Micah says so. Do not read `.env*` files.
- Schema changes only through Drizzle: edit `lib/db/schema.ts`, `bun run db:generate`. Never edit an existing migration. No raw SQL writes.
- System presets change only in `lib/prompt-templates/system-presets.ts` plus the seed script.
- Tests with a worker cap: `--maxWorkers=2`. One heavy job at a time on this machine.
- No temp files in the repo; use your scratchpad.
- No paid DataForSEO calls for testing without asking Micah.
- Only edit Linear tickets Micah created or owns. No account names or login details in tickets.
- Items marked `decision` stay blocked until Micah decides. Do not guess his answer.
  When he decides, record it: `POST /api/decisions/DEC-n` with `{"agent":"<name>","answer":"<his words>"}`.

## 5. Statuses

| Status | Meaning |
|---|---|
| blocked | waiting on another item's merge or one of Micah's decisions |
| ready | nobody has started; pick it up |
| claimed | an agent holds the lease, no branch yet |
| in_progress | an agent holds the lease and a branch exists |
| paused | the lease expired; the branch is kept; resume it |
| in_review | PR open, nothing wrong |
| needs_fix | PR has failing CI, conflicts, requested changes or the wrong base |
| merged | PR merged into release/v0.1.7 (R0: main has 0 commits release lacks) |
| verified | checked on staging, with a note |

## 6. How the dashboard heals itself

- Every status is derived from facts on each write (deps, decisions, lease, PR), never hand-set.
- The sync runs every 2 minutes (Cloudflare Cron Trigger) and on every agent sync call.
  A backup alarm inside the board fires if no sync has run for 5 minutes, and the open
  page triggers one itself when it sees the sync is late.
- Expired leases return items to the queue with their branch kept.
- Closed-unmerged PRs and deleted branches are cleared, with an event.
- If GitHub fails, the last good data stays on screen with a red "failing" pill.

## 7. Tokens

- Agent token (writes): `~/.config/vantagepost/remediation-dashboard-token` on Micah's Mac;
  on Cloudflare it is the Worker secret `AGENT_TOKEN`.
  Never print it, never put it in a ticket, PR or file in the repo.
- Reads (`/api/next`, `/api/items/<code>`, the page) need no token.

## 8. The service itself

Code: `~/dev/vantagepost-remediation-dashboard` (README.md has deploy steps).
Cloudflare Worker `vantagepost-remediation-dashboard` (account Micahberkley@gmail.com),
state in the Durable Object `BoardDO`.
