Skip to content
Back to skills

Harvest

BSecurity

Use when the user asks to clean up, sweep or harvest what was already merged — checks every worktree recorded in a manifest, removes the ones whose PR was merged, moves durable knowledge into permanent notes, deletes the ephemeral record and reports what is still in flight. Manual trigger by design; run it after merging a PR. Also for "what is still open", "which worktrees can I delete", "clean up what landed".

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 26, 2026
ai-agentsgit

Security analysis

B85/100
  • highPerforms destructive filesystem operations

Pro shows the line behind each finding and how to fix it

Scanned September 26, 2026

npx -y skills add FabianoArthur/claude-code-kitchen --skill harvest --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Harvest?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Harvest
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/fabianoarthur-harvest/badge)](https://www.skillsdirectory.com/skills/fabianoarthur-harvest)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: harvest
description: Use when the user asks to clean up, sweep or harvest what was already merged — checks every worktree recorded in a manifest, removes the ones whose PR was merged, moves durable knowledge into permanent notes, deletes the ephemeral record and reports what is still in flight. Manual trigger by design; run it after merging a PR. Also for "what is still open", "which worktrees can I delete", "clean up what landed".
---

# /harvest — sweep what was merged

```
/harvest              sweep everything recorded in a manifest
/harvest <id>         only this unit
/harvest --dry        report without deleting anything
```

**Read `../orchestrate/CORE.md` before any step.**

## Why it is manual, and will stay that way

There is no cheap event trigger for "PR merged" in a local setup. The options are polling
(cron / a scheduled cloud routine), each trigger costs a full agent round, and merges happen
a few times a day. Running `/harvest` yourself after merging is **free and instant**; paying
an agent to watch is not.

If a real webhook shows up, revisit. Until then: manual, by decision, not by omission.

---

## Step 1 — Enumerate candidates

Read the manifests at `<vault.plans>/*-manifest.md`. The worktrees listed there are the
**only** ones this skill may touch.

> **A worktree without a manifest entry is NEVER touched.** It belongs to another flow,
> another person, or predates this convention. **Report it, do not touch it.** Compare
> `git worktree list` with what is in manifests and list orphans as information.

## Step 2 — Check each candidate's merge

`<gh> pr view <branch> --json state,mergedAt,number`

`<gh>` = the adapter's `gh` field if present; otherwise plain `gh` (CORE §1). It matters
here more than anywhere: a `gh` broken by an environment variable returns HTTP 401, and
without verification **there is no cleanup** — better to delete nothing than to delete based
on a misread error.

| state | action |
|---|---|
| `MERGED` | eligible for cleanup (Step 3) |
| `OPEN` | skip, report as still in review |
| PR not found | skip and **flag** — something is out of place; do not guess |

**The merge is the gate, not the backlog status.** Closing the card is a separate human call
and can lag or lead the merge. Do not block cleanup because of it — but **report** each
card's current status in the summary, so the human sees what is pending.

`gh` unavailable → **assume nothing.** Report that it could not be verified and stop.

## Step 3 — Clean an eligible worktree

In order, and stop at any resistance:

1. `tmux has-session -t '=kitchen-<ID>' 2>/dev/null` → session alive? With the PR
   **verified MERGED** in Step 2, its work is over: `tmux kill-session -t '=kitchen-<ID>'`.
   The `=` is exact match and the quotes are mandatory — without it tmux matches by prefix
   and `kitchen-FE-2` kills `kitchen-FE-21`. Kill **before** the remove: git does NOT refuse
   to remove a clean worktree with a live process inside — without the kill an agent keeps
   running in a deleted directory. Without a verified merge: kill only if `.kitchen/done`
   exists in the worktree (the agent hibernated by contract; the context comes back with
   `claude --resume <session-id>` from the manifest row); without `done`, **do not kill** —
   there may be a conversation/adjustment in progress in there.
2. `git worktree remove <dir>` — from the main checkout. **Never `rm -rf`**: it leaves the
   worktree registered and git complains at the next `worktree add`.
   - Refused because of uncommitted changes → **stop and show the human.** A merged branch
     may still hold a draft file worth a second look. Do not force. (`.kitchen/` does not
     count: it is dispatch machinery, expected and ignored via `info/exclude`.)
3. `git branch -d <branch>` — lowercase `-d`, never `-D`. A real merge makes `-d` safe; if
   git refuses, the branch was **not** merged into the local base and you must **stop**, not
   force. (A squash-merged PR is the usual cause: fetch and fast-forward the base first; if
   git still refuses, report it and let the human decide.)
4. Before the directory disappears, look for artifacts that should not be there (build
   output, log dirs). If any, **only record it** — its owner decides.

## Step 4 — Consolidate and delete the ephemeral note

Before removing the manifest entry:

1. Does it hold a durable decision not yet in `permanent/` nor in the task doc's
   `## Outcome`? Move it there **now** (CORE §6), linking back to the order. Knowledge does
   not die with cleanup.
2. Mark the unit as harvested in the manifest.
3. Manifest with **every** unit harvested → fold what is left of durable into where it
   belongs and **delete the manifest**. An ephemeral note does not outlive its checkout.

## Step 5 — Report

One line per worktree: **cleaned** / **skipped** (why) / **flagged** (why). Then:

- what is still in flight (open PR, queued unit, `kitchen-*` tmux session still running);
- cards whose status is pending closure in the backlog;
- orphan worktrees found (information, not action);
- `kitchen-*` tmux sessions without a manifest entry (`tmux ls`) — information, not action;
- local branches merged outside this flow, if you notice them (information).

If nothing is left in flight, say it plainly ("nothing in flight — `/clear` whenever you
want"). Do **not** try to invoke `/clear`: it is a REPL reset, there is no tool for it.

## This skill does NOT

- Merge PRs or close cards — both are the human's calls.
- Touch a worktree outside a manifest.
- Force `-D` on a branch or `rm -rf` a worktree. Git's resistance is a signal, not an
  obstacle.
- Infer a merge without `gh`. No verification, no cleanup.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.