session-pickup
Resume a prior session with zero loss and zero false confidence. Pairs with session-end (which
wrote the snapshot). Your job is to rehydrate and reconcile — then hand control back to the operator
at the right decision point, not to barrel ahead.
Operating principle: a handoff is a SNAPSHOT — trust, then verify
The handoff was true when written. Between then and now, things may have moved: commits landed, the
branch changed, another session advanced or abandoned the in-progress work, files were renamed. Never
resume blindly on the handoff's word — reconcile it against current reality first. This is the inverse
of session-end's "ground in artifacts": there you grounded the summary; here you ground the resume.
Step 1 — Locate the handoff
- Default: in
<primary-checkout>/.claude/handoffs/, the newest handoff whose
<!-- session-end:origin branch=… worktree=… --> stamp matches the branch you are resuming (prefer
the full handoff doc; also read its companion continuation-prompt file if one exists).
- Never take "newest" on faith when the candidates disagree. That directory is shared: it lives in
the primary checkout so handoffs survive worktree cleanup, which means concurrent sessions in different
worktrees all write into it. Picking purely by recency will hand you the handoff of whichever session
happened to finish last, and resuming another branch's work is a silent wrong start, not a visible
error. So:
- Match on the origin stamp first. An unambiguous branch match is the answer.
- If several handoffs match, or the newest does not match the current branch, or the stamp is
missing (an older handoff, written before this was stamped), do not guess. List the candidates with
their timestamp, branch, and slug, and ask which to resume.
- Resolve
<primary-checkout> the same way session-end does when it writes — with
git worktree list --porcelain | head -1 | sed 's/^worktree //', not git rev-parse --show-toplevel.
In a linked worktree those differ: --show-toplevel returns the worktree's own root, so a pickup
running in a worktree would look in an empty directory and conclude no handoff exists while the real
one sits in the primary checkout. In an ordinary clone both return the same path.
- Accept an optional arg: a path or a slug to pick a specific handoff.
- If none found: say so plainly. Offer to (a) proceed cold from a stated goal, or (b) check
chat-history-search for a prior session. Do not fabricate a handoff.
Step 2 — Read tiered (honor the handoff's own tiers; don't over-read)
Read the handoff in full first. Then read only what it marks must-read; respect its
read-on-demand list (pull those only if Step 3 or the task implicates them). Over-reading here
re-creates the exact context-bloat the handoff existed to prevent.
Step 3 — Reconcile with current reality (the safety core)
Gather and compare against the handoff:
git log --oneline -20 (+ since the handoff's date) — what landed since it was written?
git status --short and current branch — does the branch match the handoff's? Uncommitted work?
- For each artifact / in-progress item the handoff cites: does the file still exist? has it changed
since the handoff (mtime / diff)? was the "in-progress" work since committed, advanced, or abandoned?
- Re-check each open verification debt / assumption — is it still open, or was it resolved?
Produce a short drift report: unchanged (handoff still accurate) · advanced (work moved forward —
adjust the next step) · conflicts (reality contradicts the handoff — STOP and surface it). Never
silently resume past a conflicts.
Step 4 — Re-establish working state
- Rebuild the TodoWrite list from the handoff's in-progress + next-step, adjusted for any drift.
- Restate the settled constraints to HONOR and the open verification debts (carry assumptions as
assumptions — do not promote them to fact just because a prior session wrote them down).
- Note explicitly what NOT to redo (the handoff's done/settled items).
Step 5 — Orient + confirm (don't auto-execute)
Present a tight orientation: where we are · what changed since the handoff · the immediate next
action. Then:
- If the handoff's next action carries a STOP / approval gate (e.g. "deliver review findings, then
wait"), honor it — stop at that gate.
- Before any side-effecting work, confirm with the operator ("resume from here?"). For a clean
unchanged drift report and a read-only next step, you may begin immediately and say so.
Safety + quality gate
- Read-only to the repo (+ TodoWrite). Pickup orients; it does not change files or commit.
- Distinguish handoff-claims from pickup-verified in your orientation — label what you confirmed
against current state vs. what you're taking on the handoff's word.
- A
[derived] claim is an inference, not a finding. session-end tags claims it reasoned its way to
(vs. [verified] ones it observed). Never act on a [derived] claim without checking it first —
above all when it would justify "repairing" something, because the thing may be deliberate. An
untagged diagnosis in an older handoff gets the same treatment: verify, don't assume it was measured.
- A
conflicts drift finding always halts for the operator — resuming on stale state is the failure mode
this skill exists to prevent.
Complements
session-end writes the snapshot this reads. chat-history-search recovers older sessions with no
handoff file. pattern-retrospective mines many sessions; session-pickup resumes exactly one.
1---2name: session-pickup3description: Start a continued Claude Code session by rehydrating from a prior session's handoff, the inverse of session-end. Reads the latest handoff in .claude/handoffs/ and what it points to, reconciles it against current git and file state to catch drift, rebuilds the todo list, settled constraints, and open verification debts, then presents the immediate next action and confirms before acting.4---56# session-pickup78Resume a prior session with zero loss and zero false confidence. Pairs with `session-end` (which9wrote the snapshot). Your job is to rehydrate *and reconcile* — then hand control back to the operator10at the right decision point, not to barrel ahead.1112## Operating principle: a handoff is a SNAPSHOT — trust, then verify1314The handoff was true when written. Between then and now, things may have moved: commits landed, the15branch changed, another session advanced or abandoned the in-progress work, files were renamed. **Never16resume blindly on the handoff's word — reconcile it against current reality first.** This is the inverse17of session-end's "ground in artifacts": there you grounded the summary; here you ground the resume.1819## Step 1 — Locate the handoff2021- Default: in `<primary-checkout>/.claude/handoffs/`, the newest handoff **whose22 `<!-- session-end:origin branch=… worktree=… -->` stamp matches the branch you are resuming** (prefer23 the full handoff doc; also read its companion continuation-prompt file if one exists).24- **Never take "newest" on faith when the candidates disagree.** That directory is shared: it lives in25 the primary checkout so handoffs survive worktree cleanup, which means concurrent sessions in different26 worktrees all write into it. Picking purely by recency will hand you the handoff of whichever session27 happened to finish last, and resuming another branch's work is a *silent* wrong start, not a visible28 error. So:29 - Match on the origin stamp first. An unambiguous branch match is the answer.30 - If several handoffs match, or the newest does **not** match the current branch, or the stamp is31 missing (an older handoff, written before this was stamped), do not guess. List the candidates with32 their timestamp, branch, and slug, and ask which to resume.33- **Resolve `<primary-checkout>` the same way `session-end` does when it writes** — with34 `git worktree list --porcelain | head -1 | sed 's/^worktree //'`, *not* `git rev-parse --show-toplevel`.35 In a linked worktree those differ: `--show-toplevel` returns the worktree's own root, so a pickup36 running in a worktree would look in an empty directory and conclude no handoff exists while the real37 one sits in the primary checkout. In an ordinary clone both return the same path.38- Accept an optional arg: a path or a slug to pick a specific handoff.39- **If none found:** say so plainly. Offer to (a) proceed cold from a stated goal, or (b) check40 `chat-history-search` for a prior session. Do not fabricate a handoff.4142## Step 2 — Read tiered (honor the handoff's own tiers; don't over-read)4344Read the handoff in full first. Then read only what it marks **must-read**; respect its45**read-on-demand** list (pull those only if Step 3 or the task implicates them). Over-reading here46re-creates the exact context-bloat the handoff existed to prevent.4748## Step 3 — Reconcile with current reality (the safety core)4950Gather and compare against the handoff:51- `git log --oneline -20` (+ since the handoff's date) — what landed since it was written?52- `git status --short` and current branch — does the branch match the handoff's? Uncommitted work?53- For each **artifact / in-progress item** the handoff cites: does the file still exist? has it changed54 since the handoff (mtime / diff)? was the "in-progress" work since committed, advanced, or abandoned?55- Re-check each **open verification debt / assumption** — is it still open, or was it resolved?5657Produce a short **drift report**: `unchanged` (handoff still accurate) · `advanced` (work moved forward —58adjust the next step) · `conflicts` (reality contradicts the handoff — STOP and surface it). Never59silently resume past a `conflicts`.6061## Step 4 — Re-establish working state6263- Rebuild the **TodoWrite** list from the handoff's in-progress + next-step, adjusted for any drift.64- Restate the **settled constraints to HONOR** and the **open verification debts** (carry assumptions as65 assumptions — do not promote them to fact just because a prior session wrote them down).66- Note explicitly **what NOT to redo** (the handoff's done/settled items).6768## Step 5 — Orient + confirm (don't auto-execute)6970Present a tight orientation: **where we are · what changed since the handoff · the immediate next71action**. Then:72- If the handoff's next action carries a **STOP / approval gate** (e.g. "deliver review findings, then73 wait"), honor it — stop at that gate.74- Before any side-effecting work, **confirm with the operator** ("resume from here?"). For a clean75 `unchanged` drift report and a read-only next step, you may begin immediately and say so.7677## Safety + quality gate7879- **Read-only to the repo** (+ TodoWrite). Pickup orients; it does not change files or commit.80- Distinguish **handoff-claims** from **pickup-verified** in your orientation — label what you confirmed81 against current state vs. what you're taking on the handoff's word.82- **A `[derived]` claim is an inference, not a finding.** `session-end` tags claims it reasoned its way to83 (vs. `[verified]` ones it observed). Never act on a `[derived]` claim without checking it first —84 above all when it would justify "repairing" something, because the thing may be deliberate. An85 *untagged* diagnosis in an older handoff gets the same treatment: verify, don't assume it was measured.86- A `conflicts` drift finding always halts for the operator — resuming on stale state is the failure mode87 this skill exists to prevent.8889## Complements90`session-end` writes the snapshot this reads. `chat-history-search` recovers older sessions with no91handoff file. `pattern-retrospective` mines many sessions; `session-pickup` resumes exactly one.