t1k:handoff
| Field | Value |
|---|---|
| Module | t1k-extended |
| Version | 3.5.0 |
| Effort | medium |
| Tools | — |
Keywords: context, handoff, restore, resume, save, session, transfer
How to invoke
Section titled “How to invoke”/t1k:handoffsave|resume|list [date-slug|--global]TheOneKit Handoff — Session Context Transfer
Section titled “TheOneKit Handoff — Session Context Transfer”Capture structured session context for handoff between sessions or developers. Extends the session state system with a human-readable markdown export.
Pre-flight Step 0 — Fuzzy plan/path arg resolution (MANDATORY)
Section titled “Pre-flight Step 0 — Fuzzy plan/path arg resolution (MANDATORY)”If the user provides a fuzzy plan/path/phase arg (e.g. chaosforge-demo, plans/chaosforge-demo, phase-3), an empty arg, or natural-language ref like “active plan” / “current plan” / “this plan”, run the Fuzzy Plan / Path Resolution Protocol at skills/t1k-cook/references/fuzzy-plan-resolution.md BEFORE bail. Skill MUST NOT emit “no path matching” / “exact path required” until that protocol has been applied and Step 6 reached.
/t1k:handoff save # Save to active plan dir → project .claude/handoffs/ → $HOME (fallback chain)/t1k:handoff save --global # Force save to $HOME/.claude/handoffs/ (no-project sessions)/t1k:handoff resume # Load latest handoff (same fallback chain)/t1k:handoff resume 260325-auth # Load specific handoff by date-slug (fuzzy match — see Pre-flight Step 0)/t1k:handoff list # Show available handoffs with timestamps, sorted newest firstDelegation (MANDATORY — never run inline from a lead/main session)
Section titled “Delegation (MANDATORY — never run inline from a lead/main session)”save / resume / list are executed by the t1k-handoff-manager sub-agent, not inline by whichever session invoked /t1k:handoff. If you are the main/lead session (or any agent that is not itself t1k-handoff-manager):
- Spawn
t1k-handoff-manager(subagent_type: "t1k-handoff-manager", task indescription:permodules/t1k-orchestration/rules/agent-name-is-identity.md),run_in_background: true. - Do not ask for approval first. A save/resume/list request — whether an explicit user ask, a
[t1k:context-budget pct=NN handoff=due]frame, or an auto-compact suggestion the lead has already decided to act on — is itself sufficient authorization (same standing-approval pattern asauto-sync-back-when-enabled.md). Asking “want me to save a handoff?” when the trigger already answers that question is the violation this section closes. - Brief with findings, not payload (
modules/t1k-orchestration/rules/lean-brief-pointer-not-payload.md): put what only the lead knows — what shipped this session, what was verified, what’s still open, the active plan path — in the spawn prompt as a short list. The agent owns the mechanics: git-state gathering, task-list read, file write, the<HARD-GATE-HANDOFF-*>guard-script steps, commit. Never paste transcript excerpts or full file bodies into the brief. - Gate any context-destroying step on the agent’s report. If the save precedes a
/compact,t1k session roll, or/clear(thecontext-budget-handoff.md“land and roll” case), the background spawn does not excuse skipping the wait — hold at that point (completing the landing sequence is not “starting anything new”) untilt1k-handoff-managerreports itssaved to {absolute-path} ({chosen-scope})line, THEN roll. Rolling before that confirmation arrives can lose the very context the handoff exists to preserve.resumeis the same: the loaded context is only useful if it lands before the session continues, so treat its report as a blocking prerequisite too. - Relay the agent’s report verbatim —
saved to .../[Handoff loaded: ...]— do not paraphrase or omit it.
Exception: if you were spawned specifically to run this skill (you ARE t1k-handoff-manager), execute the workflow below directly — do not recurse-spawn yourself.
Save Location — Resolution Order (MANDATORY)
Section titled “Save Location — Resolution Order (MANDATORY)”The skill picks the FIRST matching location:
- Active plan dir →
{active-plan-dir}/HANDOFF.md(PRIMARY, project-scoped)- Active plan = most recently modified
plans/*/dir containing aplan.md - One HANDOFF.md per plan — subsequent saves overwrite (git history preserves older versions)
- This is the preferred location for any session with a plan — keeps handoff next to the work
- Active plan = most recently modified
- Project handoffs dir →
.claude/handoffs/{date}-{slug}.md(FALLBACK when no active plan but a project is in scope)- Scopes to the current project; multiple handoffs accumulate here
- Global handoffs dir →
$HOME/.claude/handoffs/{date}-{slug}.md(LAST RESORT — requires--globalOR no project context)- For sessions not associated with any project
Rationale (per project memory feedback_handoff_location): project handoffs belong in the project so they travel with the plan, survive worktree deletion, and show up in code review. User-scope is explicit opt-in only.
Subcommands
Section titled “Subcommands”| Subcommand | Action |
|---|---|
save | Capture current state to the first matching location above |
save --global | Force save to $HOME/.claude/handoffs/{date}-{slug}.md |
resume | Load latest handoff from any of the 3 locations (newest wins) |
list | Show all handoffs across all 3 locations, sorted newest first |
resume {date-slug} | Load a specific handoff by its date-slug identifier |
Handoff Document Structure
Section titled “Handoff Document Structure”# Handoff — {date} {time}as-of: {YYYY-MM-DD} @ {8-char git HEAD}Generated by: t1k:handoff saveLocation: {active-plan-dir}/HANDOFF.md | .claude/handoffs/{date}-{slug}.md | $HOME/.claude/handoffs/{date}-{slug}.md
> **"Progress", "Blockers" and "Next Steps" are dated claims — they describe the session> at the `as-of` commit, not now.** They go false the moment anything lands. Before trusting> them after any later merge/commit, re-check against current `HEAD` (or read the intervening> commits via `git log {as-of}..HEAD`).
## Active Plan- Path: plans/{timestamp}-{slug}/- Current phase: Phase N — {phase name}- Phase status: {in_progress|blocked|pending}
## Progress### Completed Tasks- [x] Task description
### In Progress- [ ] Task description (owner: {agent})
### Blocked- [ ] Task description — Blocker: {reason}
## Key Decisions Made- {architectural or design decision with context}
## Blockers- {blocker description} — context: {why it's blocked, what's needed to unblock}
## Next Steps1. {highest priority action}2. {second priority}3. {third priority}
## Git State- Branch: {branch name}- Last commit: {hash} {message}- Dirty files: {list or "none"}- Uncommitted changes: {summary or "none"}
## Session Notes{any freeform notes from the session worth preserving}save Workflow
Section titled “save Workflow”(Run by t1k-handoff-manager per the “Delegation” section above.)
- Call
TaskListto get current task statuses. - Run
git status --short,git log --oneline -3, andgit rev-parse --short HEADfor git state. Record the short SHA in the template’sas-of:line (with the ISO date) so resume can later tell what commit the volatile sections describe. - Resolve save location:
- If
--globalflag → use$HOME/.claude/handoffs/{YYMMDD}-{slug}.md. - Else: find the most recently modified
plans/*/dir (relative to current working directory or the project root) that contains aplan.md. If found → save to{plan-dir}/HANDOFF.md. - Else: if a
.claude/dir exists in project scope → save to.claude/handoffs/{YYMMDD}-{slug}.md. - Else (global-only mode, no project) → save to
$HOME/.claude/handoffs/{YYMMDD}-{slug}.md.
- If
- Synthesize key decisions from recent conversation (last 20 exchanges mentioning architecture, choice, decided, rejected).
- Write the markdown file to the
OK <path>returned in step 5; include the finalLocation:line in the header so futureresumecan find it unambiguously.
- Report:
saved to {absolute-path} ({chosen-scope}), summary of what was captured. The{absolute-path}MUST be the path the step 7verifyreturnedOKfor — never a path you only intended to write.
Slug is auto-generated from the active plan name or current task, lowercased, max 30 chars. Not used when saving to {plan-dir}/HANDOFF.md (filename is fixed).
The three <HARD-GATE-HANDOFF-*> blocks above are machine-readable contracts (see rules/workflow-gates.md): steps 5, 7 and 8 MUST go through scripts/handoff-save-guard.cjs, never a hand-rolled mkdir -p / test -f / sentinel write (those were the prose steps that got skipped in #536 and #527, producing false “saved” claims with no file on disk).
resume Workflow
Section titled “resume Workflow”(Run by t1k-handoff-manager per the “Delegation” section above.)
MANDATORY EXECUTION. The resume workflow MUST run on every /t1k:handoff resume invocation and produce output in the exact format of step 4. The AI MUST NOT:
- Switch into conversational Q&A mode just because another local command (
/model,/fast,/clear, etc.) arrived in the same turn. - Defer the resume to a later turn while waiting for a follow-up user message.
- Treat
<local-command-caveat>blocks as silencing the skill — those caveats apply to the command that emitted them, not to a skill invocation in the same turn. Skill invocations are direct instructions and MUST be executed. - Read files one-by-one in prose before emitting the
[Handoff loaded: ...]block.
Steps:
- If a date-slug is given: search each of the 3 locations for a matching filename and load.
- Else (no argument): collect newest file from each of the 3 locations; pick overall newest by mtime.
- Read the handoff markdown file.
- First text output MUST begin with this block (not preceded by any prose, corrections, or tool-call narration):
Then include a concise summary of Active Plan / current phase / last merged work / git state pulled from the handoff. Omitting the[Handoff loaded: {absolute-path}]Resuming session from {date}. Context:
[Handoff loaded: ...]line means the workflow did not run — self-correct by emitting it on the next turn. - Suggest the next step from the “Next Steps” section.
- Check if the listed active plan still exists — warn if not found (missing
plan.md, deleted plan dir, or references to files on disk that no longer exist). - Compare the handoff’s
as-ofSHA (header/frontmatter, if present) against currentHEAD:- If the handoff carries an
as-ofandgit rev-parse HEADdiffers from it, surface the intervening commits (git log --oneline {as-of}..HEAD) so the resumer treats “Progress” / “Blockers” / “Next Steps” as claims about the recorded commit, not about now. - If the handoff has no
as-ofyet (saved before this field existed), simply note that its volatile sections are of unknown freshness — do not guess a date on its behalf. - Never auto-rewrite the handoff’s sections on resume; the document is deliberately a dated artifact. The fix is making the date legible, not making the file self-updating.
- If the handoff carries an
A <local-command-caveat> from an unrelated command in the same turn (e.g. /model) does NOT
silence this skill — the workflow above still MUST run. Incident + worked example:
references/incidents.md § “resume silently skipped mid-turn”.
list Workflow
Section titled “list Workflow”Output newest-first, grouped by scope:
Available handoffs:
PLAN-SCOPED plans/260325-auth-implementation/HANDOFF.md (2 days ago) Phase 3 — Auth API
PROJECT-SCOPED (.claude/handoffs/) 260323-database-schema.md (4 days ago) Phase 2 — DB Models
GLOBAL ($HOME/.claude/handoffs/) 260320-project-kickoff.md (7 days ago) Phase 1 — Setup
Use: /t1k:handoff resume 260325-auth-implementation /t1k:handoff resume # for the latest across all scopesAuto-Cleanup
Section titled “Auto-Cleanup”Only applies to the two date-slug directories (.claude/handoffs/, $HOME/.claude/handoffs/). Plan-scoped HANDOFF.md files are NEVER auto-cleaned — they travel with the plan.
On each save, check for handoffs older than 30 days in the two date-slug dirs:
- Move them to
{dir}/archive/ - Log:
Archived N handoffs older than 30 days → {dir}/archive/
Do NOT delete — archive only.
Commit Policy
Section titled “Commit Policy”| Location | Committed to repo? |
|---|---|
{plan-dir}/HANDOFF.md | YES — travels with the plan, survives branch/worktree deletion |
.claude/handoffs/{date}-{slug}.md | YES — commit handoffs so they survive branch switches and show up in code review |
$HOME/.claude/handoffs/{date}-{slug}.md | N/A (outside any repo) |
Do NOT add .claude/handoffs/ to .gitignore. Handoffs are session context worth preserving in git history. If an existing repo already has .claude/handoffs/ in its .gitignore, remove that entry on first save and stage the removal alongside the handoff file.
Gotchas
Section titled “Gotchas”- Inline execution by the lead is the bug, not a shortcut. Delegate per “Delegation (MANDATORY)” above — never save inline from the lead. Incident: references/incidents.md § “Lead ran the save inline instead of delegating”.
- Session state dependency:
saveworks best with the session-state-manager hook active. Without it, git state and task list are still captured but session history context is shallower. - Slug collisions: If two date-slug saves happen on the same day with the same plan, the second appends
-2suffix. Plan-scoped saves overwriteHANDOFF.md(usegit logfor older versions). - Large conversation history: Only synthesize decisions from the last 20 AI turns — do not dump full history.
- resume doesn’t restore tool state: It provides context text only — the AI must re-read relevant files itself.
- CLI path-transformer skip-list: the project-scoped paths above survive global-install rewriting because this skill is on the CLI’s skip list. Detail: references/incidents.md § “CLI global-install path-transformer skip-list”.
- Save guard is deterministic, not prose: parent-dir creation, post-write verification and the resume sentinel run through
scripts/handoff-save-guard.cjs(prepare/verify/sentinel), NOT hand-rolledmkdir -p/test -f/ file writes.prepareandverifyexit 2 on failure so a missing/empty file can never be reported as “saved” (#536). Resolve the script via the SKILL.md dir; when globally installed it lives at$HOME/.claude/skills/t1k-handoff/scripts/handoff-save-guard.cjs. - Resume sentinel is single-consumption and gitignored: the
sentinelsubcommand drops one small JSON file in the handoffs dir (path owned byhooks/lib/context-budget.cjs— never hardcode it). SessionStart consumes it exactly once, so a stale sentinel cannot re-inject on every start. Only that one file is gitignored — the handoffs themselves are committed on purpose (see § Commit Policy). Unlike the other two subcommands it always exits 0; aSKIPline means no resume hint was recorded, not that the save failed.
Memory Anti-Pattern Guards (E9)
Section titled “Memory Anti-Pattern Guards (E9)”These rules harden the handoff against three classic memory anti-patterns flagged in architecture review Round 5. Why each guard exists: references/memory-guard-rationale.md.
A. HANDOFF.md size cap
Section titled “A. HANDOFF.md size cap”Hard cap: 32 KB per HANDOFF.md. Enforcement:
- Before writing, count
Buffer.byteLength(content, 'utf8'). - If
> 32_768, the skill MUST refuse to write the full content; instead, write a 16 KB head-summary and chain to aHANDOFF-{N}.mdcontinuation file. The chain index is recorded inHANDOFF.mdfrontmatter ascontinuation: HANDOFF-2.md. - Resume reads the head + walks the continuation chain only when explicitly requested.
B. 30-day archival = scheduled expiry (red flag)
Section titled “B. 30-day archival = scheduled expiry (red flag)”- Default behavior remains 30-day archival on date-slug handoffs.
- BUT: archival is a soft-move to
~/.claude/.handoff-trash/{date-slug}.md, never a hard delete. Trash retention is bounded by quota (max 200 entries, FIFO), not date. - Resume looks in
.handoff-trash/if the primary path is missing, with a “found in trash, move back?” prompt. - Plan-scoped HANDOFF.md is NEVER archived (already documented; this rule formalizes it).
C. “Last 20 exchanges” without relevance gate
Section titled “C. “Last 20 exchanges” without relevance gate”- For each candidate turn, the skill MUST score it for relevance to the active plan/task before including. Score signals: keyword overlap with
plan.mdheaders, presence of decision-marker phrases (decided,chose,rejected,architecture,risk,gotcha), commit messages from that turn’s window. - Turns scoring below threshold (default
0.3) are filtered out. - The skill records “filtered N/20 turns” in the saved HANDOFF.md so the resumer knows the synthesis was selective, not exhaustive.
Auto-Activation Keywords
Section titled “Auto-Activation Keywords”Triggers on: handoff, hand off, transition, context transfer, session save, session resume, save progress, resume session, where did I leave off, switch sessions