Skip to content

t1k:handoff

FieldValue
Modulet1k-extended
Version2.14.3
Effortmedium
Tools

Keywords: context, handoff, restore, resume, save, session, transfer

/t1k:handoff
save|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 first

Save Location — Resolution Order (MANDATORY)

Section titled “Save Location — Resolution Order (MANDATORY)”

The skill picks the FIRST matching location:

  1. Active plan dir → {active-plan-dir}/HANDOFF.md (PRIMARY, project-scoped)
    • Active plan = most recently modified plans/*/ dir containing a plan.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
  2. 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
  3. Global handoffs dir → $HOME/.claude/handoffs/{date}-{slug}.md (LAST RESORT — requires --global OR 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.

SubcommandAction
saveCapture current state to the first matching location above
save --globalForce save to $HOME/.claude/handoffs/{date}-{slug}.md
resumeLoad latest handoff from any of the 3 locations (newest wins)
listShow all handoffs across all 3 locations, sorted newest first
resume {date-slug}Load a specific handoff by its date-slug identifier
# Handoff — {date} {time}
Generated by: t1k:handoff save
Location: {active-plan-dir}/HANDOFF.md | .claude/handoffs/{date}-{slug}.md | $HOME/.claude/handoffs/{date}-{slug}.md
## 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 Steps
1. {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}
  1. Call TaskList to get current task statuses.
  2. Run git status --short and git log --oneline -3 for git state.
  3. Resolve save location:
    • If --global flag → 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 a plan.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.
  4. Synthesize key decisions from recent conversation (last 20 exchanges mentioning architecture, choice, decided, rejected).
  5. Ensure the parent dir exists before writing: mkdir -p "$(dirname <save-path>)" (Bash). The resolved target ({plan-dir}/HANDOFF.md, .claude/handoffs/, or $HOME/.claude/handoffs/) may not exist yet — Write fails on a missing parent dir. If mkdir -p fails, fall back to $HOME/.claude/handoffs/{YYMMDD}-{slug}.md (its parent is created the same way).
  6. Write the markdown file; include the final Location: line in the header so future resume can find it unambiguously.
  7. Report: saved to {absolute-path} ({chosen-scope}), summary of what was captured.

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).

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:

  1. If a date-slug is given: search each of the 3 locations for a matching filename and load.
  2. Else (no argument): collect newest file from each of the 3 locations; pick overall newest by mtime.
  3. Read the handoff markdown file.
  4. First text output MUST begin with this block (not preceded by any prose, corrections, or tool-call narration):
    [Handoff loaded: {absolute-path}]
    Resuming session from {date}. Context:
    Then include a concise summary of Active Plan / current phase / last merged work / git state pulled from the handoff. Omitting the [Handoff loaded: ...] line means the workflow did not run — self-correct by emitting it on the next turn.
  5. Suggest the next step from the “Next Steps” section.
  6. 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).

Failure mode to avoid (real 2026-04-24 incident)

Section titled “Failure mode to avoid (real 2026-04-24 incident)”
User: /model ... /t1k-handoff resume the activeplan
└─ skill invoked, but local-command-caveat from /model
was in the same turn
AI (wrong): [stays silent, then answers the next follow-up question
"what is the active plan" in prose]
AI (right): [Handoff loaded: /abs/path/HANDOFF.md]
Resuming session from 2026-04-24. Context: ...

The caveat on /model applies to /model output only. The skill’s Act as directed by the skill line is an explicit override.

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 scopes

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.

LocationCommitted to repo?
{plan-dir}/HANDOFF.mdYES — travels with the plan, survives branch/worktree deletion
.claude/handoffs/{date}-{slug}.mdYES — commit handoffs so they survive branch switches and show up in code review
$HOME/.claude/handoffs/{date}-{slug}.mdN/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.

  • Session state dependency: save works 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 -2 suffix. Plan-scoped saves overwrite HANDOFF.md (use git log for 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: The CLI installer’s global-path-transformer.ts rewrites .claude/$HOME/.claude/ for globally-installed skill copies. The companion PR in theonekit-cli adds this skill to the transformer’s skip list so the project-scoped paths above survive installation. If you see $HOME/ rewrites in the user-scope SKILL.md, pull the latest CLI release.

These rules harden the handoff against the three classic memory anti-patterns flagged in architecture review Round 5:

Hard cap: 32 KB per HANDOFF.md. Past that, the file blows the parent context and the resume becomes lossy. 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 a HANDOFF-{N}.md continuation file. The chain index is recorded in HANDOFF.md frontmatter as continuation: 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)”

The current 30-day mtime sweep on date-slug handoffs is documented as a feature but is actually a scheduled-expiry anti-pattern: future-you may want a 60-day-old context and find it gone. Mitigation:

  • Default behavior remains 30-day archival (low risk, most users don’t keep context that long).
  • 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”

Synthesizing key decisions from the last 20 AI turns regardless of topic relevance produces noisy handoffs (e.g., 12 turns about CI debugging plus 8 turns about the actual feature). Required 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.md headers, 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.

Triggers on: handoff, hand off, transition, context transfer, session save, session resume, save progress, resume session, where did I leave off, switch sessions