# Offload Phase-3 — Post-Land Live Operations (O1–O5)

Audience: AI coding agents first.

> **For agentic workers:** REQUIRED SUB-SKILL: Use /run-plan (engine) with `cursor-only` preset. Steps run sequentially on live machines AFTER offload-phase2 code landed on `origin/main`. Full contracts inherited from `docs/plans/2026-07-20-offload-phase2.md` §Post-land operations.

**Goal:** Bring the landed Phase-2 controller + spine client package live on the laptop and debian1 fleet: shared Bearer provisioning, controller service, live `~/.claude` spine hooks, debian1 watchdog, deck E2E acceptance.

**Architecture:** Operational only — repo code is already on `origin/main`. Services run from deploy clone `$HOME/.local/share/overdeck/deploy`. Live spine hooks touch ONLY `~/.claude/lib/remote-build.mjs` (with mandatory pre-hook backup). Fail-open reporting/admission; fail-closed invalid config unless `BUILD_REMOTE_LOCAL_FALLBACK=1`.

**Prerequisite:** offload-phase2 landed (`origin/main` contains T0–T7). Phase-2 code MUST NOT be re-implemented here.

**Source of truth:** `docs/plans/2026-07-20-offload-phase2.md` §Post-land operations (O1–O5) + `docs/specs/2026-07-18-offload-control-plane-spec.md`.

---

## Wave Plan

| Wave | Tasks | Scope | Parallel? |
|------|-------|-------|-----------|
| 0 | O1 | Shared Bearer token laptop + debian1 | single |
| 1 | O2 | Controller service live on laptop | single |
| 2 | O3 | Live spine hooks in `~/.claude/lib/remote-build.mjs` | single |
| 3 | O4 | Watchdog on debian1 | single |
| 4 | O5 | Deck E2E acceptance | single |

Each task MUST complete verification before the next starts. Record outcomes (host chosen, backup path, SHA-256, pass/fail) in `docs/plans/offload-phase3-run-record.md`.

---

### Task O1: Shared Bearer provisioning

**Wave:** 0 · **Blocks:** O2, O4 · **Blocked by:** —

Read phase-2 plan §O1. Laptop source: `$HOME/.config/overdeck/token` (load-or-create, mode 0600, non-empty). Copy once to debian1 `$HOME/.config/overdeck/token` via ssh port 2222 + `~/.ssh/id_ed25519_buildbox`. Compare SHA-256 local vs remote; never print token bytes.

**Acceptance:** local token exists mode 0600; remote token exists mode 0600; `sha256sum` local == remote.

---

### Task O2: Controller service live (laptop)

**Wave:** 1 · **Blocks:** O3, O5 · **Blocked by:** O1

Read phase-2 plan §O2. Update deploy clone BEFORE deploy script: `git -C $HOME/.local/share/overdeck/deploy fetch --quiet origin` then `checkout --detach origin/main`. Run `bash $HOME/.local/share/overdeck/deploy/packaging/deploy-local.sh`. Enable `overdeck-controller.service`. Verify `/health` 200 with Bearer, 401 without.

**Acceptance:** `curl` health checks pass; deck offload panels no longer show `controller-down` within one poll cycle.

---

### Task O3: Live spine hooks

**Wave:** 2 · **Blocks:** O5 · **Blocked by:** O2

Read phase-2 plan §O3 (full contract + executable verification block). Mandatory pre-hook backup of `~/.claude/lib/remote-build.mjs`. Modify ONLY that file per manifest. Use deploy-clone spine CLI via `ft bun $HOME/.local/share/overdeck/deploy/spine/src/cli.ts`. Run full O3 verification script from phase-2 plan. Run fault scenarios sequentially on live fleet `debian1` + `debian2`.

**Acceptance:** O3 executable verification block exits 0; fault scenarios pass; controller stop/restart fail-open test passes.

---

### Task O4: Watchdog on debian1

**Wave:** 3 · **Blocks:** — · **Blocked by:** O1, O2

Read phase-2 plan §O4. Operator supplies `OVERDECK_WATCHDOG_WEBHOOK_URL` (HTTPS ntfy, never committed). Provision debian1 watchdog config mode 0600. Run `deploy-watchdog.sh` from deploy clone. Verify tunnel + watchdog units active; heartbeat through tunnel; brief tunnel stop triggers exactly one page per target.

**Acceptance:** units active; tunnel heartbeat OK; ntfy pages received on tunnel stop (exactly one per target).

---

### Task O5: End-to-end deck acceptance

**Wave:** 4 · **Blocks:** — · **Blocked by:** O2, O3

Read phase-2 plan §O5. Deck `/ci` shows live cluster + remote jobs. Select available host from `/status`. Use deck controls: `box-drain` then `box-restore`; verify spine advisory eligibility follows. Record host + outcomes in `docs/plans/offload-phase3-run-record.md`.

**Acceptance:** drain blocks dispatch; restore returns host available/eligible; run record committed.
