ship-it
Wrap up a finished round of work — verify README and CHANGELOG are current, cut a version if warranted, move completed task files into the completed/ folder…
Skill by tbeack
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/tbeack-ship-it
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: productivity
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/ship-it
Tools it pre-approves 26
From allowed-tools in SKILL.md: the agent may use these without asking you each time.
Bash(gitworktree:*),-C:*),merge:*),merge-base:*),add:*),commit:*),branch:*),mv:*),rev-parse:*),checkout:*),push:*),
Show 14 more
pull:*),status:*),log:*),remote:*),ls-remote:*),Bash(ghprcreate:*),view:*),list:*),fetch:*),tag:*),diff:*),Bash(date:*)
What's inside
- Skill name
ship-it- Description
- Wrap up a finished round of work — verify README and CHANGELOG are current, cut a version if warranted, move completed task files into the completed/ folder, then create a feature branch if needed, commit, push, and open a PR. Run after `/fsad-harness:do-task` has marked one or more tasks done. Takes no arguments.
- License
- MIT
- Allowed tools
- Bash(git, worktree:*),, Bash(git, -C:*),, Bash(git, merge:*),, Bash(git, merge-base:*),, Bash(git, add:*),, Bash(git, commit:*),, Bash(git, branch:*),, Bash(git, mv:*),, Bash(git, rev-parse:*),, Bash(git, checkout:*),, Bash(git, push:*),, Bash(git, pull:*),, Bash(git, status:*),, Bash(git, log:*),, Bash(git, remote:*),, Bash(git, ls-remote:*),, Bash(gh, pr, create:*),, Bash(gh, pr, view:*),, Bash(gh, pr, list:*),, Bash(git, fetch:*),, Bash(git, tag:*),, Bash(git, diff:*),, Bash(date:*)
- Instructions
- 266 lines in SKILL.md · view on GitHub
Before installing
- Pre-approves some shell commands
Agent Skills spec issues
- name: missing
Files (1)
- SKILL.md
SKILL.md (first lines)
# fsad-harness:ship-it — wrap up and ship
You run five sequential phases to close out a batch of completed work: pre-merge branch guard (Step 0.4), worktree merge (Step 0.5), pre-flight audits — README/CHANGELOG/version/completed-task cleanup (Step 1), commit + push + PR (Step 2), and verify-shipped (Step 3). Do not skip phases or reorder them.
"Shipped" means all three of the following verifiable predicates hold — not that a phase list was walked:
1. **Remote-HEAD parity** — the pushed branch's remote SHA (`git ls-remote`) equals local `HEAD`.
2. **PR existence** — `gh pr view` confirms a PR exists for this branch and targets the default branch.
3. **Version-string consistency** — every file in `cfg.version_files` carries the identical new version string (when a version was cut).
Step 3 (Verify shipped) checks all three explicitly before the skill reports success — see that step for details.
## Asking the user
This rule covers every question this skill asks the user: a confirmation, a choice, a missing value, a numbered decision list, or a stop-and-ask. It applies even where a later step says "ask the user" or "ask exactly once". The user may watch the decisions pane rather than the chat, so a question that only goes to chat can go unanswered.
- **When `mcp__decision-tracker__decision` is in your tool list** (loaded, or named as a deferred tool; load a deferred one with `ToolSearch` first), log each question before you ask it:
1. Call it with `action: "open"`, the question (ending in `?`), and `options` when the answers are a closed set. Set `required: false` when the work can go on without an answer. A numbered list of questions opens one decision per item. Keep each returned `id`.
2. Ask the question in chat as this skill says. The open call does not replace the chat question.
3. When the user answers, in chat or as a `Decision Dn: <answer>` message from the plugin, call the tool with `action: "close"`, the `id` and the answer.
4. When the change the answer asked for is in place, call it with `action: "implement"`, the `id` and a `path:line`.
- **When the tool is absent**, ask in chat only.
- An `AskUserQuestion` call is logged on its own. Do not open it again.
- This rule changes where a question is logged. It does not change when this skill asks, or how many times.
## Step 0 — Detect the project
1. Determine the current working directory.
2. Read `${CLAUDE_PLUGIN_ROOT}/skills/add-task/add-task-projects.yaml`.
3. Match cwd against each project's `match_paths` (expand `~`). Prefer the longest (most specific) match if multiple match.
4. If a project matches, refer to its entry as `cfg` and the resolved project root as `project_root`. Proceed.
5. If **no project matches**:
- Tell the user the project is not registered.
- Suggest running `/fsad-harness:add-task` from the project to register it.
- Stop.
## Step 0.2 — Skill routing
Resolve which skill should actually ship this work for `cfg`'s project:
1. `desired_skill` = `cfg.skills.ship` (if set) → else the YAML's top-level `defaults.skills.ship` (if set) → else `"fsad-harness:ship-it"`.
2. If `desired_skill` differs from `"fsad-harness:ship-it"`: invoke the `Skill` tool with that skill name, passing `$ARGUMENTS` unchanged, and **stop** — none of this skill's remaining steps run in this invocation.
3. Otherwise continue to Step 0.4.
## Step 0.4 — Pre-merge branch guard
Step 0.5 merges worktree branches into whatever branch is currently checked out, with no branch awareness of its own. If that happens to be `main`/`master`, the merge commit lands directly on the default branch — before Step 2.0's branch guard ever runs. This step closes that gap by moving off the default branch first, whenever a merge is about to happen.
1. Run `git worktree list --porcelain` from `project_root`. Parse the output to get all worktrees (each block starts with `worktree <path>`), then filter out the main worktree — the one whose path equals `project_root`.
2. If **no additional worktrees** exist: skip this step entirely and proceed to Step 0.5 (which will independently reach the same conclusion and pass through to Step 1).
3. If additional worktrees exist, check the current branch: `git rev-parse --abbrev-ref HEAD`.
- **Not `main`/`master`**: already off the default branch — proceed to Step 0.5.
- **Is `main`/`master`**: a merge is about to happen and must not land here.
- Propose a branch name that does **not** depend on a version string (the version isn't cut until Step 1b):
- If the worktree branch names encode task IDs (e.g. `worktree-task-tbs-070` → `tbs-070`), suggest `task/{task-ids}` — joining multiple IDs with `+` when merging more than one worktree (e.g. `task/tbs-070+tbs-071`).
- Otherwise, suggest `ship/{YYYY-MM-DD}` using today's date (`date +%F`).
- Ask the user: "About to merge {N} worktree branch(es) while on `{main|master}` — create and switch to `{branch}` first? (y/n or type a different name)"
- On confirmation: run `git checkout -b {branch}`.
- If declined: stop here. Do not proceed to Step 0.5 — merging while on the default branch is the exact failure this step exists to prevent.
4. Proceed to Step 0.5.
## Step 0.5 — Merge pending worktrees
This step must never run while `HEAD` is the default branch (`main`/`master`) — Step 0.4 ensures that by branching off first whenever a merge is pending. The merge itself cannot simply be deferred to run *after* Step 2.0's branch guard instead: Step 1's audits (README/CHANGELOG/completed-task checks) read the post-merge tree, so the merge must still happen before those audits — just off the default branch rather than on it.
**Main-tree writeback reconciliation.** `fsad-harness:do-task` (Step 5h) and `fsad-harness:add-task` write to the *main* tree even when their session runs inside a worktree: `todo.md` gets `[x]` marks and new bullets, and a task-detail file may be edited in place. At merge time these main-tree edits are therefore **expected to be uncommitted** — they are not a sign of a dirty tree that must be cleaned first. Meanwhile the worktree branch may carry new task-detail files whose bullets already sit in the main-tree `todo.md`, or a `todo.md` edit of its own. Reconcile as follows:
- **Leave the main-tree `todo.md` / task-file edits in the working tree** — do not stash, discard, or "clean up" them before merging. They are staged by name together with the merge result in Step 2.2 and land in the same commit batch.
- If `git merge` refuses to start because a file the branch touches is also modified in the main tree (typically `todo.md`), commit the main-tree edit first — `git add "{cfg.todo_file}" && git commit -m "todo: mark {IDs} done"` — then re-run the merge. Committing, not stashing, is the only accepted way to clear this.
- **`todo.md` conflict → keep both sides.** When the merge conflicts in `todo.md`, the correct resolution is almost always the union: keep every bullet from both sides, deduplicate any bullet that appears on both (keeping the `- [x]` form if either side has it), and order the bullets by task ID. Never drop a bullet to make the conflict go away.
- A task-detail file arriving from the branch whose bullet is already in the main-tree `todo.md` is the normal case, not a conflict — nothing to reconcile.
1. Run `git worktree list --porcelain` from `project_root`. Parse the output to get all worktrees (each block starts with `worktree <path>`).
2. Filter out the main worktree — the one whose path equals `project_root`.
3. If **no additional worktrees** exist: skip this step entirely and proceed to Step 1.
4. If additional worktrees exist:
- List them for the user: path and branch name (the `branch` field from the porcelain output), plus each branch's uncommitted-changes status (`git -C <path> status --porcelain`, summarized as "clean" or "N uncommitted files").
- **Stop and ask for explicit confirmation** before touching anything:
> "About to merge {N} worktree branch(es) into `{project_root}`: {list}. For each: commit any uncommitted changes, `git merge --no-ff <branch>`, verify the merge landed, then force-remove the worktree and delete the branch. Proceed? (y/n)"
- If the user declines: stop here. Do not modify or remove any worktree. Report which worktrees remain pending.
- On confirmation, for each worktree in order:
a. Check for uncommitted changes: `git -C <path> status --porcelain`. If any are present, commit them: `git -C <path> add -A && git -C <path> commit -m "<branch-name>: parallel do-task changes"`.
b. Merge the branch into the main worktree: `git merge --no-ff <branch>`.
c. If the merge produces a conflict: **stop immediately**. Tell the user which file(s) conflict and provide these resolution steps:
1. Open each conflicting file and locate the conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`).
2. Edit the file to keep the correct content and remove all conflict markers. For `{cfg.todo_file}`, apply the keep-both rule above: union of both sides' bullets, `- [x]` wins over `- [ ]` for the same ID, sorted by task ID.
3. Stage each resolved file: `git add <file>`.
4. Complete the merge commit: `git commit`.
5. Re-run `fsad-harness:ship-it` to continue from where it left off.
Do not proceed to Step 1. Do not remove the worktree — it may still hold the only copy of unmerged work.
d. **Verify the merge landed before removing anything**: run `git merge-base --is-ancestor <branch> HEAD`. Exit code `0` means the branch tip is now reachable from `HEAD` — the merge is confirmed in the main tree.
- If this check **fails** (non-zero exit): **stop immediately**. Do not remove the worktree or delete the branch — the merge did not land as expected and the worktree is the only safe copy of that work. Report the branch name and ask the user how to proceed.
- If this check **passes**: only now remove the worktree (`git worktree remove --force <path>`) and delete the branch (`git branch -d <branch>`).
5. After all worktrees are merged, verified, and removed: tell the user "Worktrees merged." and proceed to Step 1.
## Step 1 — Pre-flight audits (run concurrently)
### 1.0 — Does versioning apply to this project?
Decide this **before** dispatching the audits, because it determines whether Audit B and Step 1b run at all. Set `versioning = off` if **either** of the following holds:
- `cfg.version_scheme` is explicitly `none` (or the YAML null forms `null` / `~`). This is different from the key being **absent** — an absent key still runs Audit B and falls through to the "No `version_scheme` configured" prompt in 1b.
- The CHANGELOG file does not exist on disk. Resolve `changelog_path` = `{project_root}/{cfg.changelog_file}` if `cfg.changelog_file` is set, else `{project_root}/CHANGELOG.md`; every later reference to the CHANGELOG in this skill means this path.
When `versioning = off`:
- Tell the user **once**, naming the reason that applied: "Versioning skipped for this project — `version_scheme: none`." or "Versioning skipped for this project — no CHANGELOG at `{changelog_path}`." Do not mention it again in later steps.
- **Skip Audit B and Step 1b entirely.** Run only Audits A, C, and D.
- **Do not create a CHANGELOG, do not invent or propose a version, and do not touch `cfg.version_files`.** A project without versioning ships as a plain commit + PR; Step 2.0 then names the branch `task/…` or `ship/…`, Step 2.1 item 1 and item 3 are skipped, and Step 3 predicate 3 is not applicable.
Otherwise (`versioning = on`) run all four audits below.
These checks are read-only and independent of each other — none needs another's output. Dispatch them as concurrent subagents (or, if subagents aren't available in the current context, run the read passes back-to-back with no dependency ordering between them) rather than sequentially:
- **Audit A — README ↔ skills-table consistency:** List all subdirectories in `{project_root}/skills/` (each is a skill). Read `{project_root}/README.md`. For every skill directory, check a corresponding row exists in the README skills table (match on directory name). Report any skills missing from the README.
- **Audit B — CHANGELOG/version derivation:** Read `{changelog_path}`. Find the `## [Unreleased]` section and collect everything between that heading and the next `## [` heading (the pending content). Read `cfg.version_scheme` and `cfg.version_files`; if set, read the first file in the list and extract the current version string (JSON `"version"` field, README version-table row, or HTML `<title>`). Report: pending CHANGELOG content (or "empty"), current version scheme, and current version string.
- **Audit C — completed-task cross-reference:** Scan `{project_root}/{cfg.task_dir}/` for files matching the task filename pattern (e.g. `task-tbs-NNN.md`) not already inside `completed/`. For each, look up the corresponding identifier in `cfg.todo_file`: `- [x]` → candidate to move; `- [ ]` or not found → leave in place. For each candidate, also list its AC status file (the same path with `.md` replaced by `.acs.json`) when one exists, so it moves with the task file. Report the candidate list.
- **Audit D — skill frontmatter parse:** If `{project_root}/scripts/check-frontmatter.sh` exists, run it with no arguments and report its `BAD:` lines and exit code. If the script does not exist, report "not applicable".From tbeack/fsad_playbook, MIT.
More from tbeack/fsad_playbook
- 0.626score
sec-review-fixes
tbeack
Companion to `sec-review-team`.
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
plan
tbeack
Guide the user through planning a significant project, a large epic/initiative spanning multiple epics, or a codebase refactor.
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
set-context
tbeack
Gather codebase and initiative context before planning starts — runs a graphify build or query when graphify is available locally, falls back to a manual repo…
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
code-review-team
tbeack
Run a multi-agent code review TEAM over a codebase diff or path.
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
init
tbeack
Initialize a new project with a standard directory structure, template files, and a git repository.
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
next
tbeack
Pick the next open task from the current project's todo file and invoke `/fsad-harness:do-task` with that task ID.
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
playbook-assistant
tbeack
Answer "how do I…" questions about FSAD strategies and practices using only the content already in the FSAD Playbook — no external knowledge.
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
prd
tbeack
Guide the user through writing a Product Requirements Document or feature spec.
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
sec-review-team
tbeack
Run a multi-agent security review TEAM over a codebase or recent diff.
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
plan-review
tbeack
Run a detailed, adversarial multi-agent review of an implementation plan — a GitHub PR, a branch, or a planning document — against the baseline spec, ADR, or…
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
ac
tbeack
Verify acceptance criteria for a task.
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
add-task
tbeack
Add a new task to any of your local projects.
SkillAFreshness: A★ 8Claude Code +9
Signals
- Stars
- 8
- Forks
- 4
- Open issues
- 0
- Last commit (this folder)
- Oct 7, 2026 (21 days ago)
- Last release
- May 18, 2026 (5 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/tbeack/fsad_playbook
- Website
- fsad-playbook.vercel.app
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
Same skill elsewhere
Copies of this SKILL.md published by others; search shows only one of them.
More from tbeack
- 0.626score
set-context
tbeack
Gather codebase and initiative context before planning starts — runs a graphify build or query when graphify is available locally, falls back to a manual repo…
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
sec-review-fixes
tbeack
Companion to `sec-review-team`.
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
plan
tbeack
Guide the user through planning a significant project, a large epic/initiative spanning multiple epics, or a codebase refactor.
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
add-task
tbeack
Add a new task to any of your local projects.
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
next
tbeack
Pick the next open task from the current project's todo file and invoke `/fsad-harness:do-task` with that task ID.
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
init
tbeack
Initialize a new project with a standard directory structure, template files, and a git repository.
SkillAFreshness: A★ 8Claude Code +9
Cite this page
ship-it skill. Agent Mart. https://agentmart.dev/skills/tbeack-ship-it (last updated 2026-10-24)