---
name: apt:resume
description: "Restore context from a paused session, an agent handoff, or recover from a crash"
apt-skill-version: {{APT_VERSION}}
stage: resume
intent: capture
when_to_use: "The user is returning to paused work, picking up an agent-to-agent handoff, or recovering from a crash and needs to restore context from CONTINUE artifacts, HANDOFF artifacts, or the active-task state."
user_invocable: true
internal: false
spawns_agent: false
agent_name: null
task_context: none
default_execution_mode: auto
execution_modes:
  - auto
  - step
allowed-tools: "Bash, Read, Grep, Glob, Write, Edit, Task"
argument-hint: "apt:resume [task-id]"
gates: []
---
<objective>
Restore context and continue work after a session break — whether it was a graceful pause (CONTINUE files exist), an agent-to-agent handoff (HANDOFF files exist, written by `/apt:handoff`), or a crash/disconnect (no CONTINUE/HANDOFF but state.json has an active task). Supports multiple resumable sessions of mixed type — shows all and lets the user pick which to resume.
</objective>

<your_environment>
- **Working directory:** The project root (where you were invoked)
- **apt-tools path:** `node packages/framework/bin/apt-tools.mjs` or the locally installed `apt-tools` binary
- **Constitution:** Read `AGENTS.md` in the project root if it exists
- **Pause index:** `.aperant/CONTINUE_INDEX.md` (human-pause sessions written by `/apt:pause`)
- **Handoff index:** `.aperant/HANDOFFS_INDEX.md` (agent-to-agent handoffs written by `/apt:handoff`)
- **Legacy handoff:** `.aperant/CONTINUE.md` (pre-v2 single-file format, migrate if found)
- **State:** `.aperant/state.json` (always exists if initialized)
- **Cross-agent team signal:** `.aperant/team-status/{agent-id}.json` records (gitignored, TTL-expired) are the canonical "who's working on what" surface; `state.active_tasks` is this agent's local view.
- **Task-level worktree isolation:** after selecting a session, check `state.active_tasks[taskId].worktree_path`. If present, restore the working directory by prefixing subsequent Bash calls with `cd {worktree_path} &&` (or pass it as spawned-agent `cwd`). `apt-tools` commands still take the main repo as `<project-dir>`. Task artifacts (`.aperant/tasks/{id}/`) are shared through the main repo.
</your_environment>

<process>

## 1. Discover Resumable Sessions

Each discovered session is tagged with a **type** — `pause` (human stopped, `CONTINUE.md`) or `handoff` (agent transferred work, `HANDOFF.md`) — and tracked alongside its location. Scan both surfaces; do not assume only one exists.

### 1a. Check for pause index
Read `.aperant/CONTINUE_INDEX.md` if it exists — primary source for `type=pause` sessions.

### 1b. Check for handoff index
Read `.aperant/HANDOFFS_INDEX.md` if it exists — primary source for `type=handoff` sessions (agent-to-agent transfers from `/apt:handoff`).

### 1c. Check for legacy CONTINUE.md
If `.aperant/CONTINUE.md` exists (pre-v2 format), treat it as one paused session. Migrate it after resume:
- Move it to the appropriate task dir or `.aperant/paused/` location
- Add it to `CONTINUE_INDEX.md`

### 1d. Scan for task-level CONTINUE and HANDOFF files
As a fallback, scan for files that might not be in either index:
```bash
find .aperant/tasks/*/CONTINUE.md .aperant/paused/*/CONTINUE.md 2>/dev/null
find .aperant/tasks/*/handoffs/*/HANDOFF.md .aperant/handoffs/*/HANDOFF.md 2>/dev/null
```

### 1e. Check state.json for active tasks
```bash
node packages/framework/bin/apt-tools.mjs health-check .
node packages/framework/bin/apt-tools.mjs task list .
```

Combine all sources into a unified list of resumable sessions, each carrying `{ type, path, branch, focus_or_task, date, suggested_receiver? }`.

## 2. Present Sessions

### If multiple resumable sessions found:

Render handoffs FIRST (agent dropped work in your lap = higher urgency than human-paused work). Tag each row with `[pause]` or `[handoff]`.

```
Resumable Sessions
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  1. [handoff] Finish MCP token rotation wiring
     Branch: feat/mcp-rotation | Handed off: 2026-05-22 14:30
     Sender: Claude Opus 4.7 / Claude Code → Receiver: any agent
     → .aperant/handoffs/handoff-20260522-1430-finish-mcp-token-rotation/HANDOFF.md

  2. [pause] Chat UI Polish + Sidebar Redesign
     Branch: closing-phase-4 | Paused: 2026-04-13
     Progress: 6/9 items done
     → .aperant/paused/paused-20260413-chat-ui-polish/CONTINUE.md

  3. [pause] Onboarding State Unification
     Branch: feat/onboarding-sync | Paused: 2026-04-13
     Progress: executing subtask 3/5
     → .aperant/tasks/task-20260413-onboarding-sync/CONTINUE.md

Which session to resume? (number, or "all" to see full context for each)
```

Wait for user selection before proceeding.

### If one resumable session found:
Proceed directly to Step 3 with that session.

### If no resumable sessions but active tasks in state.json:
Follow crash recovery flow (Step 4).

### If nothing found:
```
No paused sessions, handoffs, or active tasks found.

→ Start something new: /apt "describe your task"
```

## 3. Resume Selected Session

Branch on `type`:

### 3a. type=pause — read CONTINUE.md
Extract:
- **Task description** — What was being worked on
- **Branch** — Which branch to be on
- **Decisions made** — Context that must not be lost
- **Remaining work** — What still needs to be done
- **Current state** — Pipeline stage, progress
- **Next steps** — Ordered list of what to do next

### 3b. type=handoff — read HANDOFF.md
Extract the handoff-specific fields:
- **Focus For The Receiver** — the load-bearing paragraph; this drives the immediate next action
- **Sender / Suggested receiver** — model + CLI hints (warn if the current agent is a poor fit, e.g. handoff suggested Codex for a heavy refactor and the receiver is a small model)
- **Existing Artifacts** — open each referenced path/URL into context BEFORE acting
- **Decisions Made (do NOT relitigate)** — treat as locked context
- **Uncommitted changes** — handoffs do NOT stash; verify the listed files still exist in the working tree with `git status --short` and reconcile if drift occurred since the handoff was written
- **External state the receiver must check** — verify each item (dev server running, PR open, MCP session live) before resuming
- **Suggested Skills** — use as the next-action recommendation

### Check Branch
```bash
git branch --show-current
```
If not on expected branch: suggest `git checkout {expected-branch}`

### Restore Stashed Work (pause only)
For `type=pause` ONLY — if CONTINUE.md indicates stashed changes, find and pop the matching stash:
```bash
git stash list | grep "apt-pause: {task description}"
```
`type=handoff` never stashes; skip this step for handoffs.

### Present Context Summary
Display all key context from the artifact, then suggest the next action based on pipeline stage (pause) or Focus + Suggested Skills (handoff).

### Clean Up After Resume
After user confirms they have context:
- Remove the resumed artifact file (`CONTINUE.md` or `HANDOFF.md`)
- Remove its row from the matching index (`CONTINUE_INDEX.md` or `HANDOFFS_INDEX.md`)
- If the index is now empty, delete it

## 4. Crash Recovery (no CONTINUE, stale active_tasks)

This is the hard path — the session ended ungracefully.

### Step 1: Run Health Check

Parse `health-check` output for issues:

**Stale locks:**
```bash
node packages/framework/bin/apt-tools.mjs lock cleanup .
```
Report: "Cleaned up {N} stale lock(s) from interrupted execution."

**Orphaned events:**
Report which subtasks were claimed but never completed. These need re-execution or manual resolution.

**Dirty working tree:**
```bash
git status --porcelain
```
If uncommitted changes exist, present options:
- "Commit these changes" — they may be partial work from the interrupted subtask
- "Stash them" — save for later, continue with clean tree
- "Discard them" — dangerous, only if the user confirms

### Step 2: Reconstruct Context from State

Read state.json `active_tasks` and the plan artifacts for each:
- `.aperant/tasks/{task-id}/implementation_plan.json` — find completed vs pending subtasks
- `.aperant/tasks/{task-id}/spec.md` — original requirements

### Step 3: Present Recovery Summary

```
Crash Recovery
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Task: {description}
Track: {track} | Phase: {phase}
Progress: {completed}/{total} subtasks
Last activity: {relative_time} ago

Recovery actions taken:
  {✓ Cleaned N stale locks | No stale locks}
  {✓ Found N orphaned events | No orphaned events}
  {⚠ N uncommitted files — awaiting your decision | Working tree clean}

Completed subtasks:
  1. ✓ {subtask-1}
  2. ✓ {subtask-2}

Remaining subtasks:
  3. ○ {subtask-3} {← interrupted here, if orphaned event found}
  4. ○ {subtask-4}

→ Recommended: continue executing from subtask 3
  Also: re-plan remaining work | verify what's done so far | start fresh
```

### Step 4: Route

| Situation | Action |
|-----------|--------|
| Execution was interrupted mid-subtask | Resume from the interrupted subtask |
| Execution completed but verify didn't run | Run apt:verify |
| Plan exists but execution never started | Run apt:execute |
| Only context exists (discuss done, no plan) | Run apt:plan |

</process>
