skills/handoff/SKILL.md
--- name: handoff description: Capture a live session into ONE handoff file so you can clear context and resume cleanly in a fresh session (or another worktree). The "I'm continuing elsewhere" sibling of /ro:close-session ("I'm done, nothing left"). Runs the shared /ro:session-state sweep, ensures every open loop is a GitHub issue (the durable queue), writes a single orientation file at .handoff/<ts>.md (+ latest.md), and prints the exact pickup command. `handoff status` is a read-only preview o
npx skillsauth add RonanCodes/ronan-skills skills/handoffInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
The point: spend a maxed-out session's last useful tokens turning loose conversation state into durable artefacts, then clear and start genuinely fresh. Not auto-compact (which keeps you in the same dirty context with a lossy summary). A real handoff writes state down and lets you wipe the slate.
The split with /ro:close-session:
Both run the same /ro:session-state sweep first, then diverge.
handoff status (read-only, no writes)Use when the context-watch hook nudges you, or when the user asks "should I do a handoff?". Steps:
/ro:session-state for the mechanical inventory.HANDOFF PREVIEW
loose state: <verdict from session-state>
open loops: <N> (<one-line each>)
chat-only: <N decisions not yet in any file>
est. cost: ~<N> min to capture
→ run `/ro:handoff` to write it, then clear.
No files written. This is the "is it worth it yet?" check.
handoff (default — capture and prepare to clear)Sweep. Run /ro:session-state. Carry its inventory into the file.
Gather the narrative (this is the part only this session knows):
code-reviewer, explorer, wiki-curator) so the resumed main context stays lean..ro-linear.json), ADRs/CONTEXT.md, and any Confluence/Jira/Notion. Record what you actually used; don't invent links.2b. Capability retro. Invoke /ro:capability-retro — scan this session for a tool that should exist (a manual dance that should be a skill, heavy work that should be an agent, a workflow the user described) or an existing skill/agent that needs editing. Its findings populate the file's "Skills / subagents this session wished it had" section; act on any the user approves now, defer the rest. Skip with --no-issues only if you also want to skip this.
Ensure the queue survives the file. For each open loop, the work belongs in the tracker, not just the file:
gh issue create (or /ro:write-a-prd / /ro:slice-into-issues for anything bigger), label ready-for-agent. Defer to /ro:repo-mode — work repos write local notes only, nothing leaks to the work tracker./ro:linear-* conventions.--no-issues (file-only handoff).
The handoff file then links to the issues; it does not duplicate the work list. The file is "read me first"; issues are the source of truth for work.Reconcile existing handoffs, then write ONE new file to the primary worktree's .handoff/ (not the current dir). Resolve the primary checkout so the handoff is findable from the main repo (where you usually start Claude) and survives a short-lived worktree being torn down:
PRIMARY=$(git worktree list --porcelain | sed -n '1s/^worktree //p')
PROJECT=$(basename "$PRIMARY")
mkdir -p "$PRIMARY/.handoff/archive"
# name with date + project + slug so multiple repos/threads never collide:
# "$PRIMARY/.handoff/<YYYY-MM-DD-HHMM>-<project>-<slug>.md"
Always include the project name in the filename (<date>-<project>-<slug>.md). The project name makes the pickup command self-explanatory when several handoffs exist, and stops two repos' latest.md from reading alike.
Before writing, look at the existing .handoff/*.md — there may be several from parallel sessions:
mv the old one into .handoff/archive/. Don't leave stale same-thread handoffs at the top level. (Per the way-of-working overwrite rule: open and confirm it's genuinely the same thread before archiving — never blind-clobber another session's file.)## ⚠️ Parallel handoffs (read first) note at the very top of your new file that names each other active handoff (filename + one-line goal), so neither thread is lost.latest.md (the most-recent pointer the SessionStart hook reads). When multiple active threads exist, latest.md points at the newest, and your Parallel-handoffs note carries the rest.Worktrees share one .git but have separate working dirs, so a gitignored file written in a linked worktree is invisible from the main repo and dies when that worktree is removed. Writing to the primary checkout avoids both. Be lossy on purpose: drop ancient context, keep load-bearing state. Record the branch the work is on (session-state captures it) so a main-repo resume knows where the code lives.
Ensure .handoff/ is gitignored in the primary worktree (local session state, one shared .handoff/ per repo, not committed). Pass --commit to instead commit the file on the current branch — only when the handoff must travel to another machine.
Print the pickup command + safe-to-clear banner. Always name the PROJECT and the FULL handoff filename (never just latest.md) so the command is unambiguous when several handoffs exist:
✓ Handoff written → .handoff/<YYYY-MM-DD-HHMM>-<project>-<slug>.md (also copied to latest.md)
project: <project>
• <N> open loops captured (<N> as issues: #.. #..)
• <N> chat-only decisions recorded
• parallel active handoffs: <none | filename(s)>
• archived this run: <none | filename(s)>
• safe to clear now
Resume in a fresh session with:
/ro:handoff resume .handoff/<YYYY-MM-DD-HHMM>-<project>-<slug>.md
handoff resume [<file>] — the re-entry / "pick up where we left off"The single front door for resuming work in a code repo. It first scans for all pending pickups, then orients across the standing sources.
0. Scan the pickup registry (what is waiting to be resumed in this repo). Several systems now drop a resumable artifact on disk and print a pickup command (this is a general pattern, see "The pickup pattern" below). Check each known source and list what is pending:
.handoff/*.md (non-archived, excluding latest.md)..code-review/council-*.md whose .code-review/verdict is REQUEST-CHANGES (a review waiting to be implemented). Pickup = /ro:council-review --fix --report <path>.If more than one kind of pickup is pending (e.g. a handoff AND an unimplemented council review), AskUserQuestion: "what do you want to pick up?" listing each with its one-line summary + timestamp. If the user already named one ("implement the code review feedback" → the council report; "where did we leave off" → the handoff), go straight to it. Then proceed with the matching flow (council reviews route into /ro:council-review --fix; handoffs continue below).
Orient across these sources, reconcile them, then propose the next move — never trust one alone, and degrade gracefully when one is missing:
<file> arg was given, read it. Otherwise list the non-archived .handoff/*.md (exclude latest.md and archive/). If there's just one active thread, read it. If there are SEVERAL (parallel sessions), print each as <project> — <filename> — <one-line goal> — <timestamp> and AskUserQuestion which to resume (default = newest / latest.md). Then read the chosen file: goal, state, open loops, decisions, the Context locations map, the subagent plan, and any ## ⚠️ Parallel handoffs note (so you don't lose the sibling threads). (Distinct from /pickup, which is vault-scoped; this is repo/session-scoped.)gh issue list --state open (+ recently closed for context), and the Linear board if the Context-locations map names one. Surface in-flight + ready-for-agent first.bash "${CLAUDE_PLUGIN_ROOT:-$HOME/Dev/ronan-skills}/scripts/resolve-repo.sh" LLM_WIKI) and the project's vault (from the Context-locations map or ./.ronan-skills-llm-wiki.local.json); skim its ROADMAP / recent log for project context. Use /ro:wiki or /query, not raw greps.Then:
4. Print a one-screen briefing reconciling the three (what we were doing, what's in flight, what's blocked, what's next) and flag disagreements (e.g. a handoff loop whose issue is already closed).
5. Ask (AskUserQuestion) which next action(s) to start.
6. Dispatch the right subagent per action via the Agent tool (code-reviewer / explorer / wiki-curator / general-purpose) with a tight brief drawn from the three sources. Heavy work runs in the subagent's context; the main context stays a thin router.
No handoff file? Don't bail — orient from issues + wiki alone, and say so.
The plugin's SessionStart hook (hooks/handoff-on-start.sh) checks the primary worktree for .handoff/latest.md on every new session. If one exists it surfaces the goal + timestamp and tells the agent to open by offering resume-or-new — so just launching Claude in the repo prompts you, no command or trigger phrase needed. Silent when there's no handoff. This is the conditional, plugin-delivered alternative to putting a "check the handoff folder" line in every repo's CLAUDE.md.
# Handoff — <project> — <slug> — <YYYY-MM-DD HH:MM>
## ⚠️ Parallel handoffs (read first) ← only when other active threads exist
- <other-filename.md> — <one-line goal of that thread>
## Goal
<one or two sentences>
## Current state
- done: <…>
- in-flight: <… + branch/PR>
- blocked: <… + on what>
## Context locations (where everything we touched lives — follow these for more)
- LLM wiki: vault `llm-wiki-<short>` → <key page(s)> (resolve via $LLM_WIKI_DIR)
- GitHub: <owner/repo> — open issues #.. ; PRs #..
- Linear: <team/board> — <ticket ids> (if this repo uses Linear; see .ro-linear.json)
- ADRs/docs: <docs/adr/000N-*.md, CONTEXT.md>
- Other: <Confluence / Jira / Notion / etc. if any>
## Session-state inventory
<paste the SESSION-STATE block verbatim>
## Open loops (the queue lives in the issues; this links to them)
1. <action, executable cold> → #<issue> → subagent: <name>
2. …
## Decisions made this session (not yet elsewhere)
- <decision> → durable home it should get: <ADR / CONTEXT.md / wiki / issue>
## Skills / subagents this session wished it had
- <gap> → <skill or subagent to create>
## Pickup (project: <project>)
/ro:handoff resume .handoff/<YYYY-MM-DD-HHMM>-<project>-<slug>.md
Sections 1–4 mirror the standalone meta-prompt (the one you paste into a session you can't run a skill in). "Skills / subagents wished for" is the self-improvement loop: each handoff tells you what to build before the next one.
A growing family of skills follows the same save-and-resume shape, and new ones should too:
.handoff/ for sessions, .code-review/ for council reviews, more later).claude "/ro:<skill> --resume/--fix --report <path>". The artifact is the contract; the command is the door.handoff resume step 0, so launching in a repo discovers every pending pickup across all systems and asks which to resume. Natural-language shortcuts route straight to one ("implement the code review feedback" → the council report).This means the user never has to remember where a thing was saved or how to continue it: finishing an action hands them the next command, and re-entering a repo lists everything waiting. When you build a new long-running or artifact-producing skill, give it this shape (dir + pickup command + registry entry) rather than inventing a one-off.
Keeping the main agent's context small is half the job; the other half is making clearing it safe and instant. Subagents keep the hot context lean during a session; this skill makes the cold handoff between sessions lossless where it matters and lossy where it doesn't. Together they mean you never fear /clear.
[[session-state]] — the shared mechanical sweep both this and close-session run.[[close-session]] — the "I'm done" sibling; this is the "continue later" sibling.[[snapshot-sessions]] — across-sessions safety net before a machine restart; handoff is per-session.[[pickup]] — vault-scoped session-start briefing; handoff resume is the repo/session-scoped equivalent.testing
--- name: linear-pipeline description: The Fable orchestrator for a single dispatched Linear ticket. Holds almost no context itself; it receives `--issue <ID> --detached`, decides the stage sequence, and fans out a sub-agent per stage, passing forward only each stage's artifact (never re-derived, never inlined into its own context). Step zero, before any planning or stage routing, is a boundary triage against `canon/security-boundary.md` (#199): a match tags Ronan Connolly and stops the run, no
development
--- name: in-your-face description: Capture a chat-only answer into a durable artifact (markdown + HTML, PDF when cheap) and launch it automatically so the user cannot miss it. Use when user says "in your face", "don't let me lose this", "save that answer", "make that durable", or right after answering a substantive side question (a recipe, comparison, how-to, or generated prompt) that would otherwise die with the context. category: workflow argument-hint: [--no-open] [--vault <short>] [hint of
tools
One-shot headless OpenAI Codex CLI calls for background/admin AI tasks — summaries, classification, extraction, admin glue. The default engine for anything that runs AI constantly in the background (daemon-driven, per-event), because it bills the flat ChatGPT subscription instead of Claude usage or per-token API spend, and it keeps working while Claude is rate-limited. NEVER for coding — coding stays Claude. Use when a skill or daemon needs a cheap always-on AI call, when the user says "use codex", "ask codex", "codex as backup", or when building a background summarizer/classifier into a listener or loop. Reads auth from ~/.codex/auth.json (ChatGPT account, no API key).
research
Turn a warranty rejection, repair quote, or RMA email into a cited decision brief — legal read (NL/EU consumer law), is the part user-serviceable, live part and new-unit prices, repair-vs-DIY-vs-new economics, before-you-send-it checklist, deadlines. Use when the user pastes or screenshots a repair quote, warranty rejection, "not covered" email, onderzoekskosten fee, or asks "should I repair or replace this".