handoff
Skill3 starsChanged 10 days agoMITView on GitHub
Park the current session for a fresh one — capture the failure trail (typed rejections + next intent) so the next session resumes with full context. Use when the user types /handoff, says 'park this session', wants to 'park work for a fresh session', or asks to 'hand off this task' or 'checkpoint this session'.
191 other projects use a version of this.
Adopted by
Most recently taken up by
- xiaoxiaosrm/dsh-mattpocock-skillstheir own version, first seen Nov 8, 2026
- ethosagent/ethostheir own version, first seen Nov 8, 2026
- dsifry/metaswarmtheir own version, first seen Nov 8, 2026
- glebis/claude-skillstheir own version, first seen Nov 8, 2026
- domengabrovsek/agent-configtheir own version, first seen Nov 8, 2026
- domengabrovsek/claudetheir own version, first seen Nov 8, 2026
Used with
Projects with it also use decision-mapping, setup-ts-deep-modules and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
FabienDehopreSkilldecision-mapping
Turn a loose idea into a sequenced map of investigation tickets, then drive them to resolution one at a time.
Also in 8 projects that use this
liufeng1976Skillsetup-ts-deep-modules
Wire dependency-cruiser into a TypeScript repo so each package is a deep module — implementation hidden in subfolders, reachable only through its entry-point files. User-invoked.
Also in 42 projects that use this
AWSSkillto-questionnaire
Turn a decision you can't fully answer into a questionnaire for someone else to fill in.
Also in 93 projects that use this
GoogleSkillask-matt
Ask which skill or flow fits your situation. A router over the skills in this repo.
Also in 87 projects that use this
RoentekSkillloop-me
Grill me about specs for the workflows I want to build, within this workspace.
Also in 51 projects that use this
LesaniSkillwriting-beats
Shape an article as a journey of beats, choose-your-own-adventure style. The user picks a starting beat from the raw material, you write only that beat, then offer options for where to pivot next, beat by beat, until the article reaches a natural end. Use when the user has raw material and wants to assemble it as a narrative rather than an argument.
Also in 54 projects that use this
Other versions191 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 191
- mattpocock/skills★ 309ksame name
- QuivrHQ/quivr★ 40ksame name
- The-Vibe-Company/quivr★ 40ksame name
- GreyDGL/PentestGPT★ 16ksame name
- ykdojo/claude-code-tips★ 10ksame name
- ArcReel/ArcReel★ 6.3ksame name
- vinvcn/mattpocock-skills-zh-CN★ 5.5ksame name
- withcoral/coral★ 4.9ksame name
- epicenter-md/epicenter★ 4.8ksame name
- EpicenterHQ/epicenter★ 4.8ksame name
181 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository36 other files it gives its agents.
- agent-statsSkill
- aristotle-deconstructorSkill
- babysit-prsSkill
- briefingSkill
- code-auditorSkill
- core-editSkill
- create-jira-ticketSkill
- create-tech-specSkill
- cyrus-tdd-engineerSkill
- doctorSkill
- dotfiles-syncSkill
- forgeSkill
- google-docsSkill
- google-driveSkill
- grill-meSkill
- lessons-reviewSkill
- mermaid-diagramsSkill
- metrics-emitSkill
- obligationsSkill
- optimus-plannerSkill
- overlay-initSkill
- performance-reviewSkill
- pr-create-from-commitsSkill
- ranger-reviewerSkill
- record-demoSkill
- review-contextSkill
- review-respondSkill
- scout-reviewerSkill
- self-evaluateSkill
- smart-compactSkill
- smart-statuslineSkill
- swarm-retroSkill
- team-leadSkill
- ticket-pickupSkill
- ticket-swarmSkill
- to-prdSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
13 rules. 0 are common, 9 are distinctive, and 4 are very specific to this project.
0
Common
Most of the 172 edited versions we read keep these.
9
Distinctive
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 31
If either git call fails (no git repo), or if the branch is empty or detached HEAD, abort with:
- Very specific: line 45
Create the handoff/ subdirectory if it does not exist.
- Distinctive: line 51
Before any rejection enters the typed queue, apply this filter for each item the user wants to record:
- Distinctive: line 53
Ask: *"Is there a specific artifact this rejects against, or is this a meta-lesson about how to approach problems in general?"*
- Very specific: line 55
If meta — route to ~/.claude/tasks/<project>/lessons.md using the existing Signs format (~/.claude/_shared/lessons-signs-format.md).
- Distinctive: line 56
If specific — continue to the rejection-collection loop below.
- Distinctive: line 70
Check the target path (Section B).
- Distinctive: line 94
Run the write-time validator (Section G): predicate non-empty, kind recognized, anchor non-empty, untyped-fraction check.
- Distinctive: line 120
After the approval gate has succeeded and the artifact (and optional obligation) are written, emit this final directive to the user:
- Very specific: line 149
When in doubt, prefer goal-conditional — it surfaces to the user instead of silently gating.
- Distinctive: line 208
Use Section A. If either fails (not in a git repo, detached HEAD), no-op silently.
- Distinctive: line 212
Read the handoff file. Parse the YAML frontmatter.
- Very specific: line 272
After the read half runs, the artifact is not auto-deleted.
“Common” is measured: kept by at least 6 in 10 of the 172 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Overview
Two halves of equal importance. The write half (user-invocable) captures the failure trail — typed rejections with re-verification predicates and an immediate next intent — and writes them to a branch-scoped artifact. The read half (session-start auto-detect) reads that artifact on the next session for the same branch, evaluates each rejection's predicate, and surfaces the results before any agent dispatch.
Branch name is the universal task key. The artifact survives a context boundary without duplicating signal that git already provides.
A. Resolve project and task-key
Resolve <project> as:
basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)"Resolve <task-key> as the current branch name:
git branch --show-currentSlug-safe the branch name by replacing / with -.
If either git call fails (no git repo), or if the branch is empty or detached HEAD, abort with:
Cannot write a handoff: no git branch resolvable. Run from inside a git repo on a named branch.B. Storage path
~/.claude/tasks/<project>/handoff/<task-key>.mdCreate the handoff/ subdirectory if it does not exist. Permissions inherit from the user umask. One handoff per task-key at any moment.
C. Pre-queue meta-lesson filter
Before any rejection enters the typed queue, apply this filter for each item the user wants to record:
Ask: "Is there a specific artifact this rejects against, or is this a meta-lesson about how to approach problems in general?"
- If meta — route to
~/.claude/tasks/<project>/lessons.mdusing the existing Signs format (~/.claude/_shared/lessons-signs-format.md). Do not enqueue in the handoff queue. Show the routing decision to the user so they can override. - If specific — continue to the rejection-collection loop below.
The user sees the routing decision and can override it.
D. Write flow
Step 1 — Verify git state
Resolve <project> and <task-key> (Section A). Abort cleanly on failure.
Step 2 — Check for an existing handoff
Check the target path (Section B). If a file already exists, present three options:
append— add new rejections to the existing listoverwrite— replace the artifact entirely (warn that prior content will be lost)abort— stop without writing
Step 3 — Immediate next intent
Prompt for immediate next intent — one short statement. Required; do not proceed without it.
Step 4 — Active goal
Prompt for active goal — optional. If the user says "skip" or "trivially recoverable from PR", omit this field from the artifact.
Step 5 — Rejection-collection loop
For each rejection the user wants to record:
- Apply the pre-queue meta-lesson filter (Section C). If meta → route to
lessons.md, do not enqueue. - Apply the classification tie-break rule (Section F): when the rejection cites selection criteria as a soft preference ("smaller is preferred"), default to
goal-conditional. When expressed as a hard invariant ("must not exceed K files"), default tostructural. - Type-tag the rejection as one of:
structural | contractual | empirical-local | empirical-external | goal-conditional | untyped. Theuntypedkind is the pressure valve when classification genuinely fails; warn ifuntyped > 1/3of the total. - Author the
predicatefield per the predicate grammar (Section E). Must be non-empty. - Author the
anchorfield (the concrete artifact the predicate checks against — a file path, function signature, dependency name+version, etc.). Must be non-empty. - Author the
fallbackfield — default:"drop and surface to user". - Run the write-time validator (Section G): predicate non-empty, kind recognized, anchor non-empty, untyped-fraction check. Warn on findings; do not block.
Step 6 — Approval gate
Render the proposed handoff artifact in full. Gate on user approval:
y— accept and writee— edit a fieldx— abort without writing
Step 7 — Atomic write
On approval, write the artifact atomically: write to <task-key>.md.tmp, then rename to <task-key>.md. This prevents a half-written artifact from being read by a concurrent session.
Step 8 — Paired obligation (optional)
Offer to create a paired obligation that watches the branch/PR for external motion. The user opts in explicitly. If yes, invoke the existing obligations create flow with a sensible default (gh_query on the PR if one exists, otherwise a time-based reminder).
Step 9 — Completion summary and auto-clear
Print:
Handoff written: ~/.claude/tasks/<project>/handoff/<task-key>.md (N rejections, intent captured).After the approval gate has succeeded and the artifact (and optional obligation) are written, emit this final directive to the user:
Run `/clear` to start a fresh session — the handoff will surface automatically on the next session for this branch.The skill does not silently invoke /clear. It instructs the user with a single, unambiguous final line. The clear happens only after the approval gate — this is the gate-before-clear safety property.
E. Predicate grammar
Six rejection kinds form a closed enumeration. Each kind has an anchor (what is checked against), a predicate shape (what a writable predicate looks like for that kind), and example predicates.
| # | Kind | Anchor | Predicate shape | Example predicates |
| 1 | structural | A type, invariant, or schema declaration at a specific file:line | "<invariant statement> still holds in <anchor-path>" | "grep -q 'final class Foo' src/Foo.php" ; "the Bar interface still exposes execute(): void at lib/Bar.ts" |
| 2 | contractual | A function signature, API spec, or interface declaration | "<signature> unchanged at <anchor>" | "grep -qF 'function render(Context $ctx): string' src/Renderer.php" ; "the GET /v1/items endpoint still accepts &filter[status] per docs/api.md" |
| 3 | empirical-local | A specific file's behavior at a location (test outcome, observable output, error string) | "<observable> at <anchor> still <expected>" | "grep -q 'throws NullPointerException' tests/RendererTest.php" ; "the line 'preview returns null' in CampaignPreviewController.php:142 is still present" |
| 4 | empirical-external | A dependency at a pinned version, or an external service contract | "<dep> still at version <V>" or "<external-system> still <contract>" | "grep -q '\"react\": \"18\\.' package.json" ; "composer.lock pins guzzlehttp/guzzle to 7.5.x" |
| 5 | goal-conditional | The user's stated goal at write-time | "user still wants <P>" | "user still prefers the smaller blast-radius approach" ; "user still wants to avoid touching the legacy Foo subsystem" |
| 6 | untyped | None — the producer could not classify | "<freeform claim>" | "approach X felt wrong but I can't articulate why" |
Goal-conditional predicates always evaluate to cannot-evaluate automatically — they exist so the next session asks the user before assuming. Untyped predicates are always surfaced as cannot-evaluate.
Tie-break rule:
- Selection-criteria rejections expressed as soft preferences ("smaller blast radius is preferred", "fewer files is better") →
goal-conditional. - Selection-criteria rejections expressed as hard invariants ("blast radius must not exceed K files", "no new dependencies allowed") →
structural. - When in doubt, prefer
goal-conditional— it surfaces to the user instead of silently gating.
Low-information predicate flag:
A predicate that is trivially always-true (literal true, or a tautology) is flagged at write time with low_info: true in the rejection's YAML record. The evaluator still runs it, but the read half does not let it gate the session — shown as "noted but not gating" in the surface block.
F. Validator rules
Each rule is a warning that surfaces to the user during the write flow, not a blocking error.
- Predicate non-empty — every rejection must have a non-empty
predicate:field. Empty → warn: "Rejection {N} has no predicate. It will be marked cannot-evaluate on every read and surfaced unconditionally. Recommend authoring one." - Kind in closed enumeration —
kind:must be one of the six valid values. Unrecognized kind → warn and offer to re-classify. If user insists, force-coerce tountyped. - Anchor non-empty —
anchor:must be non-empty. Empty → warn: "Rejection {N} has no anchor. The evaluator has no idea what to check against. Recommend authoring one (e.g., a file path, a function signature, a dependency name+version)." - Untyped overflow — if
untyped / total > 1/3, warn: "{X} of {Y} rejections are untyped. That's a signal the closed enumeration isn't matching what you're trying to capture. Consider re-classifying." - Low-information predicate flag — if a predicate is trivially always-true (e.g., literal
true, or"user still wants improvements"), mark the rejection with an internallow_info: truefield. The read half shows it as "noted but not gating."
G. Read half — session-start auto-trigger
The read half is not user-invocable. It runs at session start (including after /clear), before any user message is processed, via the SessionStart hook in ~/.claude/settings.json.
Trigger: On every new session, resolve <project> and <task-key> via the same git convention as the write half (Section A), then check ~/.claude/tasks/<project>/handoff/<task-key>.md. If present, run the read flow (Section H) and prepend the surfaced result to the first agent response.
Implementation: .claude/hooks/handoff-read.py, installed by install.sh as a symlink at ~/.claude/hooks/handoff-read.py. The script reads the JSON hook payload from stdin (for cwd), executes the read flow, and prints the Section I surface block to stdout — Claude Code captures stdout as session context.
Required ~/.claude/settings.json entry. Overlays may ship this in their .claude/settings.json.template for fresh-install convenience, but lib-mcp-config.sh only copies the template when ~/.claude/settings.json does not already exist, so pre-existing installs (including any overlay's main user) must add the block manually:
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume|clear",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/handoff-read.py",
"timeout": 5
}
]
}
]
}The matcher deliberately omits compact — surfacing a handoff mid-task is intrusive. The script no-ops silently when not in a git repo, on detached HEAD, or when no handoff file exists for the current branch.
H. Read flow
Step 1 — Resolve project and task-key
Use Section A. If either fails (not in a git repo, detached HEAD), no-op silently. Detached HEAD is treated the same as no branch.
Step 2 — Parse the handoff file
Read the handoff file. Parse the YAML frontmatter. If parse fails → surface a warning:
Handoff file at <path> is malformed; skipping. Inspect manually.Continue with no gating set.
Step 3 — Evaluate predicates (bounded)
For each rejection in the frontmatter rejections: list, evaluate the predicate with these bounds:
- Time budget: 2 seconds per predicate. If exceeded →
cannot-evaluate. - Tool budget: at most 1 file read, 1 grep, or 1
gh/gitshell call per predicate. If a predicate requires more →cannot-evaluate. - Predicates that require running tests, building, or executing arbitrary code →
cannot-evaluateimmediately. goal-conditionalpredicates → alwayscannot-evaluate(surface to user by design).untypedpredicates → alwayscannot-evaluate.
Step 4 — Partition the rejection list
holds— predicate evaluated true. Added to the gating set for the new session.fails— predicate evaluated false (the anchor moved). Dropped from the gating set; surfaced as "ground may have shifted."cannot-evaluate— predicate could not be evaluated within budget, wasgoal-conditional, or wasuntyped. Dropped from the gating set; surfaced to the user.
Step 5 — Surface block
Print the following before any agent response (Section I for format).
I. Surface block format
Open handoff detected for <task-key> (written <timestamp>).
Immediate next intent:
<intent>
Active goal:
<goal — or "(omitted; recoverable from PR/ticket)">
Holding (these gate this session — do not re-try without a stated reason):
[<kind>] <claim>
[<kind>] <claim>
... (N holding)
Ground may have shifted (you may want to reconsider):
[<kind>] <claim>
reason: predicate failed — <one-line evaluator note>
[<kind>] <claim>
reason: cannot-evaluate — <one-line: timeout / out-of-budget / untyped>
... (M surfaced)
-> Proceeding. To re-examine the handoff later, read ~/.claude/tasks/<project>/handoff/<task-key>.mdJ. Lifecycle and cleanup
After the read half runs, the artifact is not auto-deleted. It persists across subsequent sessions on the same branch until the user explicitly closes it via /handoff close.
/handoff close sub-command
Marks the handoff as resolved by renaming:
<task-key>.md → <task-key>.md.closed-<timestamp>This preserves the audit trail in the same directory. No new content is authored.
Deletion on branch deletion is not automated in v1.
K. Artifact schema
The handoff file is Markdown with YAML frontmatter. The frontmatter holds the machine-readable fields; the Markdown body is reserved for narrative scratch (not consumed by the evaluator).
---
task_key: <branch-slug>
project: <project>
written: <ISO 8601 timestamp>
intent: <immediate next intent>
goal: <active goal or null>
rejections:
- kind: structural
claim: <claim text>
anchor: <file path or identifier>
predicate: <grep -q '...' path/to/file>
fallback: drop and surface to user
- kind: goal-conditional
claim: <claim text>
anchor: null
predicate: user still wants <P>
fallback: drop and surface to user
---
<!-- Narrative scratch — not consumed by the evaluator -->Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

