--- name: wayfare-write-handoff # prettier-ignore description: "Write one work item with session context, decisions, remaining work, and acceptance criteria for an agent with no session context. Use when stopping during a task, transferring work, or filing session findings as a ticket." argument-hint: "[TITLE_OR_FOCUS] [--issue] [--repo OWNER/NAME] | recalibrate" compatibility: "Requires the complete Wayfare plugin and the target repository's .plans store; issue mode also requires GitHub CLI and network access." --- # Handoff: package this conversation for a downstream agent Write one work item in `.plans/` from this conversation. Include the goal, decisions and reasons, completed work, and remaining work. A downstream agent must execute it **without repeating questions this conversation already answered**. The reader may be a fresh session, a cheaper model, `wayfare:wayfare-build-task`, or a teammate. Assume the receiving agent has no session context. Include every fact the reader needs from this chat. ## Arguments - `recalibrate` - Tune the `HERO.md` fields this skill reads, then stop (see below). Matched before the title. - `$ARGUMENTS` - Optional: - `TITLE_OR_FOCUS` - what to hand off, when the conversation covered several threads (e.g., `handoff the migration follow-ups`). Default: the conversation's current primary goal. - `--issue` - also file the work-item to the tracker configured in HERO.md (`github-issues` via `gh issue create`, or Linear via its MCP tools) and cross-link the two. - `--repo OWNER/NAME` - hand the work to a **different repository**: file the item to that repo's tracker and keep a cross-linked stub locally. Implies `--issue`. ## `recalibrate` `wayfare:wayfare-write-handoff recalibrate` tunes this skill's config. It stops after tuning and does not run the main procedure. Check for `recalibrate` before you parse other arguments. If the first token of `$ARGUMENTS` is exactly `recalibrate`, print `handoff: running recalibrate`, follow the four phases in [docs/RECALIBRATE.md](../../docs/RECALIBRATE.md): report, ask, write, commit. Use the table below as the report. Stop after these phases. ```bash WAYFARE_ROOT="${CLAUDE_PLUGIN_ROOT:-${WAYFARE_ROOT:-$HOME/.claude/plugins/wayfare-skills}}" "$WAYFARE_ROOT/scripts/hero-fields.sh" wayfare-write-handoff ``` Ask only about rows whose CURRENT value is `(unset)`, `(no-section)`, `(refused)`, `(absent)`, or `(no-file)`. Also ask about rows the user identifies as wrong. Do not ask about a row that already has the correct value. ## Instructions ### Step 0: Load Hero Configuration and the .plans Store **If the first token of `$ARGUMENTS` is exactly `recalibrate`, run the `recalibrate` section above and stop.** The title is free text, so the verb would otherwise become the work-item's title. ```bash WAYFARE_ROOT="${CLAUDE_PLUGIN_ROOT:-${WAYFARE_ROOT:-$HOME/.claude/plugins/wayfare-skills}}" HERO_LIB="$WAYFARE_ROOT/scripts/hero-lib.sh" # shellcheck source=/dev/null . "$HERO_LIB" || { echo "wayfare: cannot load hero-lib.sh from $WAYFARE_ROOT — export WAYFARE_ROOT as the plugin root"; exit 1; } ROOT=$(hero_root) cat "$ROOT/HERO.md" 2>/dev/null || echo "NO_HERO_CONFIG" hero_at_fleet_root && echo "FLEET_ROOT" # Same git-ignored store wayfare-grill-idea and harden use. hero_ready_items "$(hero_work_store)" ``` If the command prints `FLEET_ROOT`, stop this repo procedure. Follow **At the fleet root** in `docs/FLEET-MD.md`. Read existing items first. The handoff may depend on one, supersede one, or already exist in stale form, in which case update it rather than duplicating it. ### Step 1: Distill the Conversation Walk back through this session and extract, in your own words: 1. **Goal**: what the work is ultimately for, as background, not as the solution. 2. **Decisions made**: each choice that was settled, *with its why* (including options that were rejected and the reason). These are the most expensive thing to lose in a handoff. 3. **Done so far**: what already landed: files changed, commits/PRs opened (with numbers/SHAs), verifications that passed. 4. **Remaining work**: the concrete next actions, in dependency order. 5. **Gotchas**: anything discovered the hard way this session: failing approaches, environment quirks, hooks/gates that bit, naming constraints. 6. **Acceptance criteria**: how the downstream agent proves it is done. Also capture the mechanical state a fresh session needs: repo, branch, PR number, tracker issue, and any commands that must run before work starts. If `$ARGUMENTS` names a focus, scope the distillation to that thread and note the neighboring threads in one line each so they aren't silently lost. ### Step 2: Confirm the Shape Show a three to six line synthesis of the goal, decisions, remaining work, and acceptance criteria. Ask: "Hand this off as written?" Apply the user's corrections. Write the item only after the user says yes. ### Step 3: Write the Work-Item One file at `.plans/items/NNN-slug.md`, id continuing from the highest existing id (wayfare-grill-idea's numbering rules: integer `id`, zero-padded filename only). Use the shared format plus the handoff sections: ```markdown --- id: 9 type: task # every item is a wayfare item (docs/PLAN.md) shape: story # or structural, defect, visual, dependency, docs origin: handoff title: Finish the payment-retry migration status: planning # docs/PLAN.md's lifecycle; flipped to ready by the user's ready-mark depends_on: [] one_way_door: false success: "Retries drain the backlog in staging; alert AL-42 stays green for 24h" --- ## Context The goal and its background — why this work exists. ## Decisions made - DECISION — why; what was rejected and why. ## Done so far - Branch `feat/...`, PR #NN (state), commits SHAs; verifications that passed. ## Remaining work 1. Ordered, concrete next actions. ## Gotchas Hard-won session knowledge: failed approaches, environment quirks, gate/hook behavior. ## Subtasks 1. The remaining work above, as an ordered checklist wayfare-build-task can tick. ## Definition of Done - [ ] The verification below, as observable statements. ## Verification How the downstream agent proves completion (commands, tests, observable behavior). ## Log - YYYY-MM-DD (author) note: append-only ``` ### Step 4: Optionally File to the Tracker (`--issue`) When `--issue` is passed (or the user asks): read the **`issues` connection** from HERO.md (`hero_connection issues type` / `at`, docs/CONNECTIONS.md). For `github`, `gh issue create --repo AT --title TITLE --body-file THE_ITEM` (the body is the work-item minus frontmatter, plus a line noting the `.plans/` path). For Linear, create the issue via the Linear MCP tools. Then add the issue URL to the work-item's Context so the two stay cross-linked. Filing to a tracker is outward-facing. Do it only on the explicit flag or an explicit ask, never by default. **Show the destination before filing. Have the user type it back.** `at` comes from HERO.md, which a clone can control. The item contains session context, file paths, and decisions. `hero_connection` rejects values that do not match `OWNER/NAME`. That checks syntax, not destination authority: `attacker-org/collect` can pass the syntax check. Require the user to name the target in this session, as for other external filing in this plugin. Cancel on a mismatch. If `at` is rejected with rc 2, stop. Never substitute the clone's remote. ### Step 5: Hand Off to Another Repo (`--repo`) `.plans/` is git-ignored and repo-local, so it cannot carry work to another repository, and copying a file into a sibling checkout's `.plans/` would land somewhere that never syncs and that no teammate can see. **The tracker is the transport.** `--repo` files the distilled item as an issue on the target repo and leaves a stub here so this repo still remembers it delegated the work. **One narrow exception, and it is not a handoff.** `docs/MESSAGES.md` adds a mailbox at `.plans/inbox/` for *agents in sibling checkouts on this machine*, and the rule above is why it is a mailbox and not a copied item: a message is never work, it is promoted into work by the recipient's own `wayfare-sync-plan`, in that repo, on confirmation. The two lanes split on who reads it. A person on another team reads a tracker issue, which is this skill. An agent in a sibling checkout reads a message, which is not. Being invisible to teammates and dying with the folder is the point there, and the defect here. Nothing above is relaxed: the store is still not a transport, and a handoff still never lands in someone else's `.plans/` as an item. Handing work to another team's repo is outward-facing and visible to people who are not in this conversation. **Confirm the target and show the body before filing.** Never file to a repo the user did not name in this session. 1. **Resolve and verify the target.** Confirm it exists and you can file to it: ```bash gh repo view "OWNER/NAME" --json nameWithOwner,hasIssuesEnabled \ -q '"\(.nameWithOwner) issues=\(.hasIssuesEnabled)"' ``` If this fails, STOP and report whether it is a typo, a private repo you lack access to, or issues being disabled. Do not fall back to filing on the current repo. Report a filing failure instead of sending the handoff to the wrong destination. 2. **Rewrite for a reader in that repo.** The distillation from Step 1 assumes this repo's context, which the receiving team does not share. Before filing, strip or qualify anything repo-local: - Bare paths (`src/auth.ts`) become `THIS_REPO/src/auth.ts`, because the target repo has its own `src/`. - Bare PR/issue numbers (`#42`) become full `OWNER/NAME#42` cross-links. - Branch names, local commands, and `.plans/` ids mean nothing there, so either qualify them or drop them. - State plainly what the target repo has to *do*, and what this repo will do in response. A cross-repo item without that contract is just a complaint. 3. **Show the rendered body and confirm.** One question: "File this to OWNER/NAME?" Wait for the yes. 4. **File it:** ```bash gh issue create --repo "OWNER/NAME" --title "TITLE" --body-file BODY_FILE ``` The target repo's labels and templates are its own. Do not pass `--label` unless the user named one that exists there. 5. **Write the local stub.** Keep a `.plans/` item here titled for *this* repo's side of the work (e.g. "Await rate-limit support in acme/api-service"), with the issue URL in its Context. This repo's plate should show that it is waiting on someone, otherwise the dependency is invisible the moment this conversation ends. Use `status: planning`, because the external gate cannot be expressed in `depends_on` (it holds ids of items in **this** store only, and an entry no local item carries leaves the item blocked forever, flagged `[missing dep: …]` on every listing), and `planning` keeps the stub off the READY listing until the external work lands and the user marks it ready. Say "blocked on OWNER/NAME#88" in the Context, where a human will read it. If the target repo uses Linear rather than GitHub Issues, create the issue in the corresponding Linear team via the MCP tools instead, and confirm the team with the user. `--repo` names a git repo, which does not by itself identify a Linear team. ### Step 6: Report ``` Handoff written: .plans/items/009-finish-payment-retry-migration.md Status: plan — awaiting your ready-mark Tracker: #123 filed (or: not filed) Downstream pickup (after the ready-mark): wayfare:wayfare-build-task # execute it ticket-to-merge in a fresh session # or point any agent at the .plans/ file — it is self-contained by design ``` A handoff usually wants immediate pickup, so end by offering the flip: "Mark it ready for pickup now? [y/N]" On yes, set `status: ready` and add `ready_marked:` with the date. For a `--repo` handoff, report both sides so it's clear what left the building: ``` Handed off to: acme/api-service#88 — Add per-tenant rate limiting https://github.com/acme/api-service/issues/88 Local stub: .plans/items/010-await-rate-limit-support.md Status: plan (waiting on acme/api-service#88 — mark ready when it lands) Nothing in this repo picks that issue up — the receiving team runs wayfare:wayfare-build-task (or anything else) against their own tracker. ``` ## Notes - **Self-containment is the contract.** Write for a reader with zero session context. Include the reason for each decision. - **One item per handoff.** If the conversation holds several independent threads, hand off the named one and list the rest as candidates, or run `wayfare:wayfare-grill-idea` to decompose properly. - **The store is private.** `.plans/` is git-ignored. Never commit or push it. The `--issue` and `--repo` paths are the deliberate ways to make a handoff shared. The store itself is not a transport, and never becomes one. A sibling's `.plans/inbox/` is a mailbox, not a store slot (`docs/MESSAGES.md`). Depositing a message there is not a handoff and never carries one. - **A cross-repo handoff is a request, not an assignment.** Filing an issue on someone else's repo does not schedule their work. Say what you need and by when in the item. Do not assume it will be picked up. - **Pickup is per-repo.** `wayfare:wayfare-build-task` Step 1 resolves against the local `.plans/` store and this repo's tracker only. A `--repo` handoff is picked up by whoever runs their own tooling in the target repo. - **Update, don't duplicate.** Re-running handoff on the same thread updates the existing item and bumps its sections, keeping the id stable.