handoff
How to Install
Claude Code:
git clone --depth 1 https://github.com/davepoon/buildwithclaude.git && cp buildwithclaude/plugins/origin/skills/handoff ~/.claude/skills/handoff -r---
name: handoff
description: >
End-of-session ritual. Captures decisions, lessons, gotchas, and open
threads. Writes a narrative session log to ~/.origin/sessions/ and stores
granular memories via Origin MCP. Previews any unconfirmed captures from
the current session before closing. Invoked as `/handoff`.
allowed-tools: ["Bash", "mcp__plugin_origin_origin__capture", "mcp__plugin_origin_origin__list_pending"]
---
# /handoff
End-of-session debrief. Three artifacts each pass:
1. **Granular MCP captures** — one per decision/lesson/gotcha (DB authoritative).
2. **Session log md** — narrative thread at `~/.origin/sessions/-.md`.
3. **Project status md + json** — current goals + last-handoff timestamp at `~/.origin/sessions/_status/`.
These are orthogonal: captures are queryable atoms, session log is the
narrative thread, status file lets the next session see where we left off.
## Steps
### 1. Detect project + last handoff time
```
Bash: cd_repo=$(git -C "$PWD" rev-parse --show-toplevel 2>/dev/null); echo "${cd_repo:-no-git}"
```
- If output is a path → use the basename as `` (e.g. `origin`).
- If `no-git` → use the cwd basename. Skip git steps below; rely entirely
on conversation context.
Read `~/.origin/sessions/_status/handoff-.json` for `lastHandoff`
timestamp (ISO-8601). If file missing, default to "12 hours ago".
### 1.5 Pending-captures preview
After establishing ``, call:
```
list_pending(limit=50)
```
The MCP returns memory rows with `source_id`, `content`, `created_at`, and
other metadata. Convert `lastHandoff` (ISO-8601 string, e.g.
`2026-05-13T22:50:00Z`) to a Unix epoch seconds integer before filtering:
```
Bash: date -j -f %Y-%m-%dT%H:%M:%SZ "$lastHandoff" +%s
```
Or in your scripting language of choice (Python's `datetime.fromisoformat`,
JavaScript's `Date.parse`, etc.). Save the result as `lastHandoffEpoch`.
Then filter the response rows: keep where `row.created_at >= lastHandoffEpoch`.
These are captures this session produced that the quality gate left unconfirmed
(untrusted-source captures).
If the filtered list is empty, say nothing. Proceed to Step 2.
If non-empty, render a preview block once, before the existing capture flow:
```
Pending captures this session ( total, top 3 shown):
1. mem_xyz789 "..." (untrusted source: )
2. ...
Default: proceed (captures stay pending). Opt in by running
`/review captures` before re-invoking /handoff if you want to walk them.
```
Do NOT prompt for per-item action inline. The user proceeds with /handoff
regardless; the preview is informational only.
### 2. Gather session context (parallel, only if git repo)
```
Bash: git -C log --oneline --since=
Bash: git -C status --short
Bash: git -C diff --stat HEAD~5..HEAD 2>/dev/null
Bash: git -C worktree list
```
Capture output. Use it alongside conversation history to infer what
happened. If not a git repo, skip — conversation context is the source.
### 3. Infer, do not ask
Synthesize silently from git output + conversation. Categorize each item
into user-facing groups. Each maps to a daemon `memory_type` for the
capture call:
| Display label | daemon memory_type | What belongs here |
|---|---|---|
| Decisions | `decision` | architectural choice, tool/pattern selection (with WHY) |
| Lessons | `lesson` | root cause discovered, workaround found, technical insight |
| Insights | `gotcha` | unexpected behavior, debugging discovery, sharp edge |
| Corrections | `preference` | user pushed back, corrected approach or assumption |
| Facts | `fact` | durable project/people/tool fact worth persisting |
Non-memory items (not stored, session-log only):
- **Open threads** — started but not finished, blockers.
Skip purely mechanical facts already in git (file paths, function names,
config values). The commit log preserves those.
### 4. MCP captures (one per item)
For each non-trivial item, call with the mapped `memory_type`:
```
capture(content="", memory_type="")
```
Atomic: one decision per call. Don't merge multiple items into one
memory. The daemon dedups against existing knowledge, so re-storing
known facts is a no-op.
Only surface items to the user BEFORE storing if they meet one of these
bars:
- Contradicts an existing memory (recall returned a conflicting fact).
- Marks a critical incident, irreversible action, or production change.
- You are uncertain whether the item is durable vs transient.
Otherwise just store and report counts at the end.
### 5. Write session log
Bash heredoc to `~/.origin/sessions/-.md`:
```markdown
# Session —
**Project:**
**Range:** →
## Accomplished
- -
## Decisions
-
## Lessons & Gotchas
-
## Open Threads
-
## Captures stored
-
## Git summary
```
`` = kebab-case 2-4 word summary (`session-handoff-md-writer`).
### 6. Update project status
Overwrite `~/.origin/sessions/_status/.md`:
```markdown
# — Current Status
## Last session ()
-
## Active
- - (added
)
- (added ) (gated: )
## Backlog
- - (added
)
```
Single file per project. New session overwrites — this is the *current*
state, not a log.
**Two sections, not one flat list:** `## Active` and `## Backlog` separate
the two types of tasks that get mixed otherwise. Active = fresh signal
worth picking next. Backlog = older parked items, kept for reference but
not in the "what next?" frame.
**Date stamp every bullet** with `(added )`. Use today's date
when adding a new item; preserve the original date when carrying an item
forward. Dates make age visible at a glance and avoid relative-time drift.
**Gated items stay inline-tagged** with `(gated: )` — no separate
section. The tag tells the reader why it can't move yet; the bullet stays
in whichever section reflects its recency.
**Promotion / demotion rules:**
- New item this session → `## Active` with today's date
- Item in `## Active` that wasn't touched this session AND wasn't touched
the prior session → demote to `## Backlog` (keep original date)
- Item in `## Backlog` that work resumed on → promote back to `## Active`
(keep original date — staleness is a property of the work, not the
bullet text)
### 7. Write timestamp
Overwrite `~/.origin/sessions/_status/handoff-.json`:
```json
{
"lastHandoff": "",
"project": "",
"summary": ""
}
```
Per-project file prevents parallel sessions from clobbering each other.
### 8. Auto-commit ~/.origin/
After writing the files above, snapshot the change so the user can `git
log` their memory's life timeline. Defensive — silent skip if `git` is
missing or `~/.origin/` is not a repo yet.
```
Bash: git -C ~/.origin add -A && \
git -C ~/.origin -c user.name=Origin -c [email protected] \
commit --quiet -m "session: " 2>/dev/null || \
(sleep 1 && git -C ~/.origin add -A && \
git -C ~/.origin -c user.name=Origin -c [email protected] \
commit --quiet -m "session: " 2>/dev/null) || true
```
The retry handles index.lock races — the daemon may be writing to
`~/.origin/` at the same moment (auto-commit from captures). One-second
wait is enough for the daemon to release the lock.
### 9. Confirm
Print one summary block with captures grouped by display label:
```
Handoff stored.
Decisions: (brief list)
Lessons: (brief list)
Insights: (brief list)
Corrections: (brief list)
Facts: (brief list)
Session: ~/.origin/sessions/
Status: ~/.origin/sessions/_status/.md
Git: session:
```
Show each label only if non-empty. List items as short phrases, not
full sentences — the session log has the details.
## When to use
- "Wrapping up", "let's call it", "we're done".
- Session about to close and useful state would otherwise be lost.
## When NOT to use
- Mid-flow capture during work → use `/capture` (single memory).
- Search / lookup → use `/recall`.
- One-off chat with no decisions or lessons — captures alone are enough.
## Notes on the three artifact classes
- **Memories** (MCP captures) live in the daemon DB only. Confirmation flips
a `stability` flag — they never get exported to md.
- **Pages** are wiki-style syntheses written to `~/.origin/pages/` by the
daemon when `/distill` runs. Citations link back to source memory ids.
- **Sessions** (this skill) live only at `~/.origin/sessions/`. They are
the narrative axis: chronological, not topical. Browse them as a
changelog of your work.
Details
| Category | Coding → debug |
| Source | davepoon/buildwithclaude |
| SKILL.md | View on GitHub → |
| Repo Stars | ★ 3.1K |
| Est. per Skill | 21 (shared across 142 skills from this repo) |
| Difficulty | Intermediate |
| Risk Level | Safe |
Related Skills
swiftui-expert-skill
SwiftUI Expert Skill When to Use You are building, reviewing, or refactoring SwiftUI code and need c
app-store-changelog
App Store Changelog Overview Generate a comprehensive, user-facing changelog from git history since
writing-skills
Writing Skills (Excellence) Dispatcher for skill creation excellence. Use the decision tree below to
docx-official
DOCX creation, editing, and analysis Overview A user may ask you to create, edit, or analyze the con
Works Well With
Skills from the same repository — often designed to work together
.Claude Plugin
{"name":"marketplace.json","path":".claude-plugin/marketplace.json","sha":"20a6f60ee1d9980002f14900b
Ag2 Agent Builder
{"name":"plugin.json","path":"plugins/ag2-agent-builder/.claude-plugin/plugin.json","sha":"46bd820c0
Agent Triforce
{"name":"plugin.json","path":"plugins/agent-triforce/.claude-plugin/plugin.json","sha":"feb952271078