SuperAPI AI Directory

handoff

Office & productivity

View repository

Updated 10-15 09:44

About this skill

handoff — Session-End Handoff Writer

Overview

HANDOFF.yaml is split in two: items are the committed short-lived context layer for still-open work, while log is the durable one-line history of finished work. GitHub issues, reconciled through valerie and doob, are the active-work source of truth. Non-Valerie skills should use the local SQLite database via handoff-db plus HANDOFF YAML, never doob directly. The scripted bridge from HANDOFF into the backlog is handoff-reconcile; use that instead of reconstructing doob commands by hand. Project state (build, tests, branch) lives separately in .ctx/HANDOFF.<name>.<base>.state.yaml — generated, never committed. A rendered reference doc is also written to .ctx/HANDOFF.md.

See references/schema.md for the full YAML schema, immutability rules, priority guide, and file layout.

File Discovery

Use handoff-detect to resolve the HANDOFF.yaml path if available:

handoff-detect          # returns path if exists, expected path + exit 2 if not
handoff-detect --name   # expected filename only (e.g. HANDOFF.devkit.devkit.yaml)
handoff-detect --root   # repo root
handoff-detect --project # project name

If handoff-detect is not on PATH, fall back to globbing the repo root for HANDOFF.*.yaml.

Legacy fallback (read-only): if no HANDOFF.yaml exists and a HANDOFF.md exists at repo root, read it as freeform. Do not convert unless asked.

Steps

1. Get current state

git branch --show-current
git log --oneline -5
cargo check 2>&1 | tail -3   # or language equivalent
cargo test 2>&1 | tail -5

2. Read existing HANDOFF.yaml and .ctx/HANDOFF...state.yaml (if present)

3. Update HANDOFF.yaml

items — apply immutability rules (see references/schema.md):

  • New gap → append with new id
  • Completed or closed upstream → remove the item from items after recording the outcome in log
  • Blocked → set status: blocked, append extra entry with type: blocker
  • Do NOT edit title, description, priority, or files on existing items
  • Do NOT retain done or parked items in committed items

human-edit acknowledgement — for any extra entry with type: human-edit and no reviewed field that was surfaced by handon this session, add reviewed: <today> to that entry.

log — prepend a new entry (newest first). This section is durable, not transient. Required fields and formats:

  • date: ISO 8601 datetime at session end — date +%Y%m%d.%H%M%S — never a bare date
  • session: increment from the previous log entry's session value (start at 1 if no prior log)
  • claude_session_id: capture from $CLAUDE_SESSION_ID env var if set; omit the field if unset
  • summary: one line, past tense
  • commits: use {sha, branch} object form for each commit — never bare hash strings:
    commits:
      - sha: abc1234
        branch: main
    

updated — set to current UTC datetime: date +%Y%m%d.%H%M%S.

4. Write HANDOFF.yaml

Emit clean YAML. No anchors, no aliases.

5. Write .ctx/HANDOFF...state.yaml

Create .ctx/ if it does not exist. Overwrite completely with current state from step 1.

Populate touched_files from files changed in commits since the session started. If session boundary is unclear, use files changed since the last log entry date in HANDOFF.yaml:

git diff --name-only $(git log --format="%H" --since="<last-log-date>" | tail -1)..HEAD

Omit the field if empty.

6. Sync to SQLite

Run handoff-db (available on PATH via the plugin's bin/):

handoff-db upsert --project <project> --handoff <path-to-HANDOFF.yaml>

If the script is not found or exits non-zero, skip and note it in output.

Do not call doob from this skill. valerie owns doob and GitHub issue sync.

6b. Reconcile open HANDOFF items into the backlog

Run the scripted Valerie bridge:

handoff-reconcile sync --project <project> --handoff <path-to-HANDOFF.yaml>

This is required. A handoff update is not complete until every open or blocked HANDOFF item has been reconciled into the configured doob backend through this command. Do not recreate this flow with ad hoc doob todo add / doob todo list commands unless you are debugging the reconciler itself.

If the script is not found or exits non-zero, stop and report the failure instead of silently continuing.

7. Generate .ctx/HANDOFF.md and .ctx/HANDOVER.md

Run the helper script to write both rendered docs in one step:

generate-ctx-docs \
  --handoff <path-to-HANDOFF.yaml> \
  --state   <path-to-HANDOFF.state.yaml> \
  --ctx     <repo-root>/.ctx

generate-ctx-docs is available on PATH via the plugin's bin/. It prefers nu if present and falls back to POSIX sh. Both files are overwritten completely.

HANDOFF.md — combined reference doc:

  • Header: project, updated timestamp, branch/build/tests from state file
  • Items table sorted P0 → P2, open before blocked
  • Log: last 5 entries only

HANDOVER.md — static ASCII dependency/flow diagram:

  • Item flow with [ ] open / [!] blocked / [x] done symbols
  • depends_on shown inline when present
  • Recent sessions (last 5 log entries)

If the helper is not found or exits non-zero, fall back to writing .ctx/HANDOFF.md inline using the Write tool (template from the previous step format). Skip HANDOVER.md in that case and note the failure.

8. Ensure .gitignore covers .ctx/

Verify .gitignore has:

.ctx/*
!.ctx/HANDOFF.*.yaml
.ctx/HANDOFF.*.state.yaml

Add or update if not present. This pattern ignores all .ctx/ contents except HANDOFF files.

9. Migration preflight

Before writing, check if the HANDOFF file is still at the repo root. If so, migrate it first:

migrate-handoff <repo-root> <old-root-path>

Then stage the rename and continue with the new .ctx/ path.

10. Commit

git add <path-to-HANDOFF.yaml> .gitignore
git commit -m "docs: update handoff"

Stage only the durable HANDOFF file under .ctx/ plus any .gitignore update required for the managed block. Never stage .ctx/HANDOFF.*.state.yaml, .ctx/HANDOFF.md, or .ctx/HANDOVER.md.

Creating from Scratch

Bootstrap from git context:

git log --oneline -10
git status

Populate log from recent commits. Leave items empty or with one P1 if there's an obvious open next step. Do not backfill closed work into items, but do preserve durable log history. Write .ctx/HANDOFF.<name>.<base>.state.yaml from actual build/test output.

Place the new HANDOFF file at .ctx/HANDOFF.<name>.<base>.yaml where <name> is the package/crate name from the nearest manifest and <base> is the repo root dir name. Use handoff-detect --name to get the correct filename.

Legacy HANDOFF.md

If HANDOFF.md exists at repo root and HANDOFF.yaml does not: read it as freeform context, do not auto-convert. Note that a HANDOFF.yaml could be created.