Session Handoff
세션 간 작업 인수인계 도구. 컨텍스트가 차서 다른 세션·디바이스에서 이어가야 할 때, 자기완결 텍스트 한 장으로 작업 환경과 다음 STEP을 넘긴다.
왜?
긴 작업이 한 세션에서 안 끝나거나 컨텍스트가 차서 새 세션을 열 때, 다음 세션의 Claude(또는 본인)가 5분 안에 환경 복구 + 작업 재개할 수 있어야 한다. 핸드오프는 이를 위한 표준 텍스트 메모.
특징:
- 멀티 디바이스 동기화 — 맥미니에서 저장한 핸드오프를 맥북·iPhone Claude Code 세션에서 즉시 회수
- 7일 자동 purge — 서버 측 TTL. 영구 보존 필요 시 메모리 또는 dev doc 으로 이전
- 시각 단위 다중 저장 — 같은 날 같은 토픽 여러 번 저장 가능 (HHMM 접미사)
도구
| Tool | 용도 |
|---|---|
handoff_save | 핸드오프 생성/덮어쓰기 |
handoff_get | 단일 핸드오프 본문 회수 |
handoff_list | 최근 핸드오프 목록 (옵션: 프로젝트 필터) |
⚠️ handoff_list / handoff_get 호출 시 7일 지난 핸드오프 자동 purge 가 같이 실행됨 (side effect). 자동화 에이전트는 destructive 한 maintenance call 로 취급.
저장 (Save)
mcp__ainote__handoff_save({
project: "sample-app", // 영문 소문자 + 숫자 + 하이픈만
topic: "login-flow",
content: "<자기완결 본문>",
date: "2026-05-13", // optional, 생략 시 서버 today
time: "1555" // optional, HHMM (KST). 같은 날 다중 저장 시 접미사
})저장 경로: handoffs/{project}-{topic}-[{HHMM}-]{YYYY-MM-DD}.txt
작성 원칙:
- 자기완결: 다음 세션은 이전 대화 메시지를 못 봄. 파일 하나만으로 환경 복구
- 사실만: "잘 동작" 대신 "BUILD SUCCESSFUL" 같은 검증 가능한 표현
- 절대 경로 + 줄 번호 명시 → 다음 세션이
grep/Read즉시 가능 - 다음 STEP 은 명령 단위 ("테스트 작성" X → "
/path/X.kt작성, 케이스 A/B/C" O) - 알려진 함정 필수 — 이번 세션에서 부딪힌 빌드/타입/import 함정은 재발 가능성 큼
- 비밀값 평문 금지 — "ENV 의 X (1Password 'sample-app' 항목)" 식으로 참조만
Frontmatter (v2)
content 본문 맨 앞에 YAML frontmatter 를 두면, 서버가 저장 시 자동 파싱해 file_indices.frontmatter 에 인덱싱한다. handoff_list 는 이 필드로 본문을 받지 않고 서버사이드 필터링을 한다. frontmatter 없는 v1 평문 핸드오프도 그대로 동작한다 (필터 지정 시에만 제외됨).
---
project: sample-app # 슬러그 (영문 소문자+숫자+하이픈)
topic: login-flow
title: "로그인 플로우 포팅" # 사람·LLM 식별용, 한국어 OK
session_date: "2026-05-23"
status: in_progress # in_progress | paused | completed | blocked
has_blockers: false
task_type: feature # feature | bugfix | refactor | research | ops
tags: [auth, oauth, mobile]
---
# SUMMARY
...서버가 필터링하는 필드 (handoff_list 인자):
| 필드 | 필터 |
|---|---|
status | status: "in_progress" 등 — v1(frontmatter 없음) 은 필터 지정 시 제외 |
has_blockers | true / false |
task_type | feature / bugfix / refactor / research / ops |
tags | 배열 AND 매치 — 준 태그를 모두 가진 항목만 (예: ['auth','mobile']) |
필터 외에도 handoff_list 응답 각 항목에는 title·priority·session_time· handoff_version 등이 본문 없이 실려 온다 (목록 훑기용). 필터 대상은 위 4개다.
참조 자동첨부 (클라이언트)
Claude Code session-handoff 스킬은 저장 직전 본문에서 plan/memory/skill 파일 참조를 감지해 vault 에 함께 push 하고, frontmatter 에 {vault_path, git_sha, local_path} 로 기록한다 — 다음 세션이 그 파일들을 sha 대조로 복원. 이 자동첨부는 클라이언트(스킬) 동작이며 서버 도구가 강제하는 것은 아니다.
referenced_plans:
- vault_path: global/planning/{proj}/{plan}.md
git_sha: b0959e68
local_path: ~/{proj}/.planning/{plan}.md
referenced_memory: [ ... ] # 동일 형식
referenced_skills: [ ... ] # 동일 형식Environment sidecar (핸드오프 환경 분리)
프로젝트의 안정 환경 사실(테스트 계정 참조, 에뮬레이터/시뮬레이터 셋업, 빌드 커맨드, 반복 함정)을 핸드오프마다 다시 쓰지 않고 vault 의 한 파일로 분리한다. 핸드오프의 ENVIRONMENT 섹션은 "이번 세션 delta + 치명 정보 1줄" 로 줄고, 안정 사실은 sidecar 가 정본이 된다.
- 정본 위치:
global/planning/environments/{proj}.md- ⚠️
handoffs/아래에 두지 말 것 — 핸드오프 TTL(7일) purge 가handoffs/전체를 재귀로 쓸어가므로 sidecar 도 소멸한다.global/planning/은 TTL 이 없다.
- ⚠️
- 핸드오프에서 참조: frontmatter 에 sha 를 박아 버전을 고정한다.
environment_ref:
vault_path: global/planning/environments/{proj}.md
git_sha: <sidecar 의 content SHA1 — 서버가 sync_list/sync_pull 로 주는 git_sha>⚠️ 여기서 git_sha 는 vault 가 저장하는 content SHA1 (Digest::SHA1.hexdigest(content)) 이지 git blob-object hash 가 아니다. 클라이언트는 같은 계산(sha1(content))으로 네트워크 없이 얻을 수 있다.
- resolution 은 클라이언트가 수행:
/r복구(또는 handoff CLI)가 위 ref 를 읽어 sidecar 를 가져온다. 로컬 캐시의 content SHA1 이git_sha와 일치하면 네트워크 0회로 캐시를 쓰고, 다르면 그 파일만 한 번 pull 해서 갱신한다. 가져오기에 실패하거나 오프라인이면 환경 정보만 degrade 되고 핸드오프 본문 복구는 절대 막히지 않는다. (서버는 sidecar 를 일반 vault 파일로 저장·인덱싱할 뿐,environment_ref를 해석하지는 않는다.) - 자기완결 유지: sidecar 를 못 받는 상황을 대비해 핸드오프 본문에 치명 정보 1줄 요약은 항상 남긴다.
복구 (Restore) — 시간대 cluster 가져오기
여러 프로젝트를 같은 시간대에 몰아서 저장한 경우 (예: 오전에 5개), 하나만 회수하면 인접 핸드오프를 놓칠 위험이 있다. 복구 모드는 최근 cluster + 직전 cluster 의 메타데이터를 묶어 보여줘서 빠뜨림 없이 작업을 재개하도록 돕는다.
알고리즘
handoff_list({limit: 50})호출 (응답은updated_at내림차순)- Cluster 탐지 (gap 기반):
- 기본
GAP_THRESHOLD = 30분 - 인접 항목 간 gap 계산.
gap ≤ 30분→ 같은 cluster, 초과 시 break
- 기본
- 반환 범위: 최신 cluster + 직전 cluster 1개 (빠진 것 확인용)
- 출력: cluster 별 표 (HHMM KST / project / topic) — 본문은 fetch 하지 않음
- 사용자가 선택 시 단일 메시지에서 병렬
handoff_get호출
출력 예시
## Cluster 1 — 2026-05-19 08:18~08:36 KST (5건, 18분 span)
| 시각 | project / topic |
|---|---|
| 08:36 | tennis / bracket-share-button-universal-links-0830 |
| 08:35 | refra / v2-deploy-step1-done-0834 |
| 08:30 | krx / listing-phase-10-complete-0830 |
| 08:24 | krx / listing-testflight-build2-uploaded-0824 |
| 08:18 | tennis / bracket-predict-feature-0818 |
## Cluster 2 (직전) — 2026-05-19 00:16~00:30 KST (2건)
| 00:30 | ainote / web-logout-cookie-fix-0030 |
| 00:16 | tennis / bracket-predict-feature-0016 |옵션
- "오전만"/"오후만" → KST hour 필터 (06~12 / 12~18)
- "프로젝트 X 만" → project/topic 필터 후 cluster
- "이전 cluster 더" → 직전 1개 → 2~3개로 확장
- "본문 전부 펴줘" → cluster 내 모든 항목 병렬 fetch
구현
별도 MCP tool 없이 기존 handoff_list + 클라이언트의 in-conversation cluster 추론으로 처리. Claude Code 사용자는 session-handoff 스킬의 §복구 섹션 알고리즘 자동 발동.
Claude Code 트리거 예시
저장:
- "이어서 다른 세션", "핸드오프 만들어", "다음 세션 넘기기"
- "바탕화면에 핸드오프 만들어" (Desktop fallback)
복구:
- "오전 핸드오프 복구해줘", "최근 핸드오프 복구"
- "이어서 작업 가져와", "오늘 작업한 거 묶어서 보여줘"
안티패턴
- ❌ "잘 진행됨" 같은 측정 불가 표현
- ❌ 절대 경로 없이 "feature/auth 의 XXX" — 다음 세션이 못 찾음
- ❌ STEP 에 "테스트 추가" 같은 추상적 한 줄
- ❌ 비밀값 평문 포함
- ❌ project/topic 슬러그에 한글·이모지·공백 (slugify 가 비-ASCII 를
-로 변환) - ❌ 복구 시 메타데이터 없이 곧바로 모든 본문 fetch (토큰 낭비)
- ❌ cluster 경계 무시하고 임의로 N개 자름