# Handon

> Use at the start of a session to orient to outstanding work — scans for HANDOFF.yaml (or HANDOFF.md) files, triages items by priority, and acts according to risk level without asking for approval on P1/P2 work.

- Skill: `89jobrien/handon` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add 89jobrien/handon`
- Raw SKILL.md: https://api.skillmd.com/api/skills/89jobrien/handon/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: 89jobrien (https://skillmd.com/u/89jobrien)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/89jobrien/handon

---


# handon — Session-Start Handoff Reader

## Overview

Scan the current directory tree for handoff files, parse items by priority, and act:

| Priority | Action                                                                            |
| -------- | --------------------------------------------------------------------------------- |
| P0       | Validate current state immediately. Report to user. Ask before touching anything. |
| P1       | Execute autonomously. Stop only if scope expands or something unexpected happens. |
| P2       | Delegate to subagents. Cap at 5 concurrent.                                       |

`handon` should use HANDOFF YAML plus `handoff-db`/SQLite only. Do not call `doob` here;
`valerie` is the only skill that should touch `doob` or GitHub issue sync. Treat `items` as
transient open-work context and `log` as durable completed-work history.

## Steps

### 0. Load local config

Look for `.ctx/handoff.<repo>.config.toml` in the repo root (where `<repo>` is the directory
name). If found, read it and make all `[vars]` entries available as session variables for the
remainder of this skill's execution. If absent, continue — config is optional.

If the file does not exist but `.ctx/handoff.<repo>.config.toml.example` does, note it once:
"No local config found. Copy `.ctx/handoff.<repo>.config.toml.example` to
`.ctx/handoff.<repo>.config.toml` and fill in your values."

Do not error or stop if config is missing.

### 1. Find handoff file

```bash
handoff-detect          # returns path if exists, expected path + exit 2 if not
```

- Exit 0 → file exists, path printed — read it
- Exit 2 → file missing, expected path printed — offer to create via `/atelier:handoff`
- Exit 1 → not in a git repo — report and stop

If `handoff-detect` is not on PATH, fall back to globbing `.ctx/` for `HANDOFF.*.yaml`.

If invoked from a workspace root (e.g. `~/dev`) with no `.git`, sweep subdirs for
`HANDOFF.*.*.yaml` files instead.

If only a legacy `HANDOFF.md` exists at repo root, read it as freeform. Do not convert unless
asked.

### 2. Run preflight script if present

Before reading state and HANDOFF files manually, check for a `.ctx/scripts/preflight.rs` at the
repo root:

```bash
test -f .ctx/scripts/preflight.rs && rxx .ctx/scripts/preflight.rs
```

If it exists and `rxx` is on PATH, run it. Its output covers branch, git status, recent history,
tracked files, and full `.ctx/HANDOFF*` content — skip steps 2a and 3 entirely and proceed
directly to step 4 using the displayed HANDOFF content.

If the script is absent or `rxx` is not on PATH, continue with the manual steps below.

### 2a. Read .ctx/HANDOFF.<name>.<base>.state.yaml

After locating the HANDOFF file, derive the state file path by appending `.state` before `.yaml`
(e.g. `HANDOFF.atelier.atelier.yaml` → `HANDOFF.atelier.atelier.state.yaml`). Read it if it
exists. Extract `branch`, `build`, `tests`, `notes`, `touched_files` and surface them in the
triage header:

```
## Handoff Triage — <path/to/repo>

Branch: <branch> | Build: <build> | Tests: <tests>
<notes if non-null>
Recently touched: <touched_files as comma-separated list, omit if absent>
```

If the file is absent, omit the state line rather than guessing.

### 3. Pull latest state from SQLite

Before parsing the local file, check the local SQLite database for status overrides written
outside this session (e.g. by another tool or a manual update):

```bash
handoff-db query --project <project> 2>/dev/null
```

For each row returned, if the SQLite `status` differs from the YAML `status`, prefer SQLite and
update the in-memory copy before triaging. Do not write back to HANDOFF.yaml here — that happens
in step 9.

If the script is not found or `sqlite3` is not on PATH, skip and continue with the local file.

### 4. Review on wake

Before triaging by priority, scan all items for unreviewed `human-edit` entries — any `extra`
entry with `type: human-edit` and no `reviewed` field (or `reviewed` is absent).

Surface these first, regardless of item priority:

```
## Review on Wake

- [id] "[title]" — human edited `<field>` → `<value>` on <date>
  <note if present>
```

Do not act on these items automatically. Present to user and wait for acknowledgement before
proceeding to P0 triage. After the user acknowledges, note which items were reviewed —
`/atelier:handoff` will stamp `reviewed: <today>` on those entries at session end.

### 5. Parse items

From `HANDOFF.yaml`: read `items` list directly. Filter to `status: open` or `status: blocked`.
Apply any SQLite overrides from step 3 before triaging.

From `HANDOFF.md`: read the "Known Gaps", "Next Up", "Parked", or "Remaining Work" sections.
Infer priority:

- P0: "broken", "fails", "blocked", "urgent", "security"
- P1: specific file + known fix mentioned
- P2: everything else that's safe

### 6. Triage P0 items

For each P0:

1. Run relevant validation (`cargo check`, `git status`, test run)
2. Report finding to user with current state
3. Ask for go/no-go before acting

Do not proceed to P1/P2 until all P0s are acknowledged by user.

### 7. Execute P1 items

Work through each open P1 without asking. Stop and surface to user when:

- Scope expands beyond what the item described
- Tests fail unexpectedly (not the known failure)
- More than 3 files need changing beyond what was described
- Any destructive operation would be needed

### 8. Delegate P2 items

Dispatch one subagent per P2 item (cap 5 concurrent). Each subagent must:

- Receive explicit `--allowedTools` list
- Verify `git status` is clean before starting
- Commit its own changes
- Report back with result

### 9. Report and update

After all work:

```
## Handoff Triage — <path/to/repo>

P0:
  - [id] [name] "[title]" → [state found] → [action / question]

P1:
  - [id] [name] "[title]" → done | blocked: <reason>

P2:
  - [id] [name] "[title]" → delegated | skipped: <reason>
```

Then update `HANDOFF.yaml`:

- Remove any item that was completed or closed upstream so `items` only carry open context
- Add `log` entry for this session (one-liner, prepend to list)
- Upsert remaining open/blocked items to SQLite via `handoff-db.sh upsert` (see handoff skill step 6)
- Commit: `git add .ctx/HANDOFF.<project>.*.yaml && git commit -m "docs: update handoff"`

## Edge Cases

**No handoff file found:** Report "No HANDOFF.yaml found in `<path>`." Offer to create one via
`/atelier:handoff`.

**HANDOFF.md only:** Read it, triage as normal, note at end: "Consider migrating to HANDOFF.yaml
for structured triage."

**All items done or parked:** Report clean state, no action needed. Closed items should be
pruned from `items` on the next write; `log` remains as history.

**Blocked item:** Do not attempt. Report the blocker to user verbatim from the `description`
field.

## Additional Resources

- **`references/triage-patterns.md`** — priority classification guide, P0 validation
  sequence, P1 autonomous execution rules, P2 subagent dispatch template, multi-repo sweep,
  human-edit review patterns, SQLite conflict resolution, blocked item handling

