Skip to content

Data Model

alphaelements edited this page Jun 27, 2026 · 1 revision

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

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).
  • Prioritylow / medium / high.
  • Labels — free-form tags.
  • Done criteria — a checklist; all items must be checked before a done transition. Toggle items with handoff_check_criterion.
  • Links — URLs to issues, MRs, or docs.
  • Notes — a markdown description.
  • Schedulestart_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.

Sessions

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_context with session_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_context with pause_active / pause_session_id → pauses sessions (.active.json.paused.json) for later resumption.

What a session records

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 ai or user).
  • Handoff notes — categorized as caution, context, or suggestion (include at least one suggestion with 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_summary is on).

Referrals

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.

Clone this wiki locally