-
Notifications
You must be signed in to change notification settings - Fork 0
Data Model
handoff-mcp stores everything under a project's .handoff/ directory. You
normally never touch these files directly — the MCP tools are the supported
interface — but understanding the shape helps when reviewing or debugging.
Add
.handoff/to your.gitignore. It is local working state, not code.
.handoff/
├── config.toml # project settings (see Configuration)
├── sessions/ # one file per session
├── tasks/ # task tree (directories + files)
└── referrals/ # incoming cross-project referrals
Tasks form a hierarchy: each task is a directory, child tasks are subdirectories, and a task's status is encoded in its filename. This makes the whole tree legible at a glance.
tasks/
├── t1-implement-auth/
│ ├── _task.in_progress.json
│ ├── t1.1-design-schema/
│ │ └── _task.done.json
│ └── t1.2-write-handlers/
│ └── _task.review.json
└── t2-deploy-staging/
└── _task.blocked.json
A status change renames the file (e.g. _task.todo.json →
_task.in_progress.json); the directory name is unchanged, so child paths are
unaffected.
Statuses: todo · in_progress · review · done · blocked · skipped
Each task can carry:
-
Assignee — a team-member key (matches
[assignees.<key>]in config). -
Priority —
low/medium/high. - Labels — free-form tags.
-
Done criteria — a checklist; all items must be checked before a
donetransition. Toggle items withhandoff_check_criterion. - Links — URLs to issues, MRs, or docs.
- Notes — a markdown description.
-
Schedule —
start_date,due_date,estimate_hours,actual_hours,remaining_hours,milestone,pinned. - Dependencies — task IDs this task depends on (circular deps are rejected).
See Estimates and Capacity for how estimate_hours
feeds metrics and scheduling.
Each session is one file in sessions/, named
YYYYMMDD-HHMMSS-<slug>.<status>.json. The timestamp is the save_context time
(UTC), the slug is derived from the summary, and the suffix is the status.
Statuses: open · active · paused · closed
Status transitions are renames:
-
handoff_import_context→ creates.open.json(a planned future session). -
handoff_load_context→ activates open sessions (.open.json→.active.json). -
handoff_save_context(default) → writes handoff data, then closes the active session (.active.json→.closed.json). It does not create a new open session, and leaves other open sessions untouched. -
handoff_save_contextwithsession_status: "active"→ updates the active session in place (creating one if none exists). Use this at session start so work survives an interruption. -
handoff_save_contextwithpause_active/pause_session_id→ pauses sessions (.active.json→.paused.json) for later resumption.
When closing a session, the agent captures the handoff the next session reads:
- Summary — one line on what happened.
-
Decisions — what was decided and why, with a confidence level
(
confirmed/estimated/unverified). - Blockers — what is preventing progress.
-
Checklist — verification items for the next session (each owned by
aioruser). -
Handoff notes — categorized as
caution,context, orsuggestion(include at least onesuggestionwith a concrete next action). - References — links to files, issues, MRs, wiki pages, or URLs.
- Context pointers — specific files and line ranges to open first.
-
Git state — branch, recent commits, dirty files (captured automatically
when
auto_git_summaryis on).
Incoming cross-project referrals live in referrals/, with status in the
filename suffix (.open.json / .acknowledged.json / .resolved.json). Read
them with handoff_list_referrals (summaries) and handoff_get_referral (full
body). See Cross-Project Referrals.