# Ywc Finish Branch

> >-

- **Type:** Skill
- **Install:** `agentstack add skill-yongwoon-ywc-agent-toolkit-ywc-finish-branch`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [yongwoon](https://agentstack.voostack.com/s/yongwoon)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [yongwoon](https://github.com/yongwoon)
- **Source:** https://github.com/yongwoon/ywc-agent-toolkit/tree/main/claude-code/skills/ywc-finish-branch

## Install

```sh
agentstack add skill-yongwoon-ywc-agent-toolkit-ywc-finish-branch
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# ywc-finish-branch

**Announce at start:** "I'm using the ywc-finish-branch skill to deliver this feature branch."

Encapsulates the post-implementation delivery flow that `ywc-sequential-executor` and `ywc-parallel-executor` previously inlined separately. One feature branch, one task — given a verified branch with passing local tests, this skill takes it the rest of the way to "done": optionally creates the PR, marks it ready, waits for CI, handles automated bot reviews, merges (PR or local), runs the post-merge hard gate, moves the task directory to `completed/`, and deletes the local feature branch. Worktree-specific cleanup is intentionally **not** in scope — that stays with `ywc-parallel-executor` because the lifecycle differs.

## Rationalization Defense

When tempted to skip a step, check this table first:

| Excuse | Reality |
|---|---|
| "Step 4 (Merge) succeeded, that means we are done" | The Definition of Done has 5 conditions. Merge is condition 2 of 5. Mark Task Complete (Step 7) and branch deletion (Step 8) are equally required — skipping them silently breaks dependency resolution for downstream tasks. |
| "Post-merge verification is just running `git log` — skip it for speed" | The hard gate exists because `git merge` can silently no-op (already merged, nothing to do, fast-forward elided) and the caller cannot tell from exit code alone. Always verify. |
| "Bot review polling found 0 comments, skip the wait window" | Polling the full window is the contract. Bots can post asynchronously after CI completes; cutting short the window misses real findings. |
| "Branch was already deleted by `gh pr merge --delete-branch`, skip the local cleanup" | `--delete-branch` only removes the **remote** branch. The local copy persists and the next task's branch creation will conflict. Always run `git branch -d`. |
| "Mode flag conflict was already validated upstream, skip the check here" | This skill is a callable unit and may be invoked outside the executors. Validate flag conflicts at every entry point, not just the upstream caller. |
| "Mark Task Complete is bookkeeping — defer it for after all wave tasks merge" | `tasks/completed/` is the contract that downstream tasks read for dependency resolution. Move-then-merge ordering is forbidden by the Definition of Done; merge-then-move within the same task cycle is required. |
| "If `git merge --no-ff` reports a conflict, abort and try again" | An aborted merge loses the working state needed to debug the conflict. **Never** auto-abort — surface the conflict to the user so they can inspect it. |
| "`build-pr-title.py` exited 1 — I'll use just the slug as the title" | Exit 1 means `TASK_NUMBER` was not detected. Stop and return `NEEDS_CONTEXT` — do not construct a title without `[TASK_NUMBER]`. A title without the task number cannot be traced back to the task in the audit trail. |
| "`ywc-create-pr` generates its own title from `git log`, so `--title` is optional" | `ywc-create-pr`'s internal title generation does not know the task-number format. It silently produces a title without `[TASK_NUM]`. Always pass `--title` explicitly with `[TASK_NUMBER]` already included. |
| "CI failed twice — return BLOCKED and let the user fix it" | Before returning BLOCKED, categorize the failure type. Lint/format failures are auto-fixable without judgment. Type errors and build errors usually have a clear mechanical fix visible in the log. Only return BLOCKED when the root cause requires a design decision or all fix attempts are genuinely exhausted. |
| "CI is green, so `gh pr merge` will succeed" | A PR can be `CONFLICTING` or `BEHIND` against the base even with green CI — a sibling task or another PR merged first. Check `gh pr view --json mergeable,mergeStateStatus` before merging instead of letting `gh pr merge` fail. If the branch is merely behind, merge the base into it (never rebase — it orphans review threads) and re-verify CI; if it is a real textual conflict, surface it and return BLOCKED. See `references/pr-conflict-resolution.md`. |
| "The UL update in Step 1.5 is optional bookkeeping — skip it to save time" | The glossary is the shared vocabulary LLMs use in every subsequent prompt on this project. A branch that introduces new domain terms without updating the glossary silently pollutes downstream code generation and spec reviews. If `docs/ubiquitous-language.md` does not exist, Step 1.5 skips automatically — there is no overhead in that case. |

**Violating the letter of these rules is violating the spirit.** Delivery is the step where the user trusts the executor most — earning that trust requires honesty about partial completion.

## Arguments

| Parameter | Format | Example | Description |
|---|---|---|---|
| `--mode` | `` | `--mode local-merge` | One of `normal-pr`, `local-merge`, `draft`, `skip-ci-wait`, `per-task-pr`. See [Modes](#modes). |
| `--branch` | `feature/` | `--branch feature/000001-010-db-create-users` | The feature branch to deliver. Must already exist locally. |
| `--base-branch` | `` | `--base-branch develop` | Target branch. Default: auto-detect (`develop` > `main` > `master`). |
| `--task-name` | `` | `--task-name 000001-010-db-create-users` | Task directory name under `/`, used for the Mark Complete commit. |
| `--tasks-dir` | `` | `--tasks-dir tasks/` | Tasks directory root. Default: `tasks/`. |
| `--pr-lang` | `` | `--pr-lang ja` | PR title/description language. Default: auto-detect from CLAUDE.md / AGENTS.md / recent PRs. |
| `--bot-action` | `sequential` \| `parallel` | `--bot-action sequential` | Post-bot polling behavior. Default: `sequential` (re-run CI after bot fixes). Use `parallel` when called from a wave loop where CI does not re-gate between bot iterations. |
| `--defer-push` | flag | | Skip the push of the Mark Complete commit. Used by range-mode callers that batch pushes at the end of the range. |
| `--keep-branch` | flag | | Skip the local feature branch deletion (`git branch -d`). Used by `ywc-parallel-executor`, where the branch is checked out in a worktree at the time of merge — `git branch -d` would fail until the worktree is removed. Caller takes responsibility for the eventual `git worktree remove` + `git branch -d`. |
| `--worktree-path` | `` | `--worktree-path /abs/run-000024-010-000024-020` | Run every git operation in Steps 1 and 5–8 as `git -C  …` so the delivery acts on the run worktree's HEAD instead of the main checkout. When unset, all git commands run against the repo root (current behavior — 100% backward compatible). Passed by `ywc-sequential-executor --worktree`; worktree creation and removal stay the caller's responsibility. See [Worktree-path mode](#worktree-path-mode). |

**Mode-flag mutual exclusivity**: `--mode` is a single value; conflicts are impossible by construction. The caller is responsible for resolving ambiguity (e.g., the upstream executor's `--draft` and `--local-merge` flags must be collapsed into one `--mode` value before invoking this skill).

## Worktree-path mode

When `--worktree-path ` is set, **every git command this skill issues** — the Step 1 `git branch --list` / `git rev-parse` validations, the Step 5 merge/checkout/pull/push/branch-delete sequence, the Step 6 post-merge `git log`, the Step 7 `git check-ignore` / `git mv` / `git commit` / post-move check, and the Step 8 checkout/pull/branch-delete — runs as `git -C  …`. The delivery semantics are unchanged: CI wait, bot-review polling, the merge-readiness gate, and Mark Task Complete behave identically; only the working directory the git commands act on differs (the run worktree instead of the main checkout). `gh` commands (`gh pr ready` / `gh pr checks` / `gh pr merge` / `gh pr view`) operate on the remote PR, not a working tree, so they are unaffected by `--worktree-path`.

**HEAD invariant (per-task feature branch deletion is safe).** At the moment Step 5 runs, the run worktree's HEAD is on the **integration branch** (the worktree's permanent checkout). finish-branch creates/merges `feature/` and then checks out the integration branch *before* deleting `feature/`, so the per-task branch is never the worktree's current checkout when `git branch -d` runs. The integration branch (and the trunk base branch) is **never** a deletion target here — finish-branch only deletes the per-task `feature/`. This is why per-task branch deletion succeeds inside a worktree without needing `--keep-branch`: only a branch that is *checked out* in a worktree is undeletable, and the per-task branch is not.

## Modes

| Mode | PR? | CI wait? | Merge? | Mark Complete? | Cleanup? | Use case |
|---|---|---|---|---|---|---|
| `normal-pr` | yes (delegates to `ywc-create-pr`) | yes | yes (`gh pr merge --delete-branch`) | yes | yes (`git branch -d`) | Default upstream flow |
| `local-merge` | no | no | yes (`git merge --no-ff` + push) | yes | yes | Personal repos, fast iteration |
| `draft` | yes | no | no | **no** (task stays open until manually merged) | no | User wants PR for review without auto-merge |
| `skip-ci-wait` | yes (mark ready) | no | no | **no** | no | User merges manually after offline review |
| `per-task-pr` | yes | no (caller handles per-wave CI) | no (caller merges locally for wave progression) | no (caller marks complete in wave loop) | no | `ywc-parallel-executor` per-task PR delivery |

`per-task-pr` is the special mode used inside `ywc-parallel-executor`'s wave loop — this skill creates and pushes the PR but stops short of merging or marking complete, because wave-level orchestration handles those steps. For all other modes, this skill executes the full lifecycle.

## Definition of Done

A `--mode normal-pr` or `--mode local-merge` invocation is **done** only when all of the following have happened, in this order:

1. **Verification gate passed** (caller's responsibility — this skill does not re-run tests; the upstream executor must have completed its verification before invoking).
2. **Merge succeeded**: either the PR was merged via `gh pr merge --delete-branch` (normal-pr) or `git merge --no-ff` succeeded locally and was pushed (local-merge).
3. **Post-merge verification passed**: `git log -1 --format="%s"` on the base branch begins with `Merge branch 'feature/`.
4. **Task directory moved**: `git mv / /completed/` and the `chore: mark  as completed` commit was created.
5. **Local feature branch deleted**: `git branch -d feature/` succeeded (refuses to delete an unmerged branch — that is the safety check).

For `--mode draft` and `--mode skip-ci-wait`, conditions 2–5 are intentionally not performed; the skill's responsibility ends at PR creation (and ready-marking for `skip-ci-wait`). For `--mode per-task-pr`, only the PR creation portion runs; the caller handles the rest within the wave loop.

## Execution Steps

### Step 1: Validate Inputs

- Confirm `--branch` exists locally (`git branch --list ` returns the branch).
- Confirm `--base-branch` is reachable (`git rev-parse --verify ` succeeds).
- Confirm `--task-name` matches an entry under `/` (not under `/completed/`).
- For PR-based modes: confirm `gh auth status` succeeds.

When `--worktree-path ` is set, run the `git branch --list` and `git rev-parse` validations as `git -C  …` (see [Worktree-path mode](#worktree-path-mode)).

If any check fails, return `NEEDS_CONTEXT` with the specific missing input. Do not proceed with partial information.

### Step 1.5: Ubiquitous Language Update (optional)

Check whether `docs/ubiquitous-language.md` exists in the project root:

```bash
test -f docs/ubiquitous-language.md
```

- **Exists**: Invoke `ywc-ubiquitous-language --mode update`. This runs before PR creation so that any new domain terms introduced by this branch are captured in the glossary before the PR description is written.
- **Not exists**: Skip silently — the project has not yet established a ubiquitous language document.

`ywc-create-pr` is called in Step 2 with `--skip-ubiquitous-update` to prevent a second invocation of the same update.

### Step 2: PR Creation (PR-based modes only)

For `--mode` ∈ {`normal-pr`, `draft`, `skip-ci-wait`, `per-task-pr`}: construct the PR title per the format below, then invoke `ywc-create-pr` passing:
- `--title ""` — the `[task-number] description` string built from `--task-name` and `--pr-lang`
- `--lang ` — so the description is written in the correct language
- `--base-branch ` — the resolved target branch
- `--skip-post-ci-check` — prevents `ywc-create-pr` from running its own post-PR CI + bot check; this skill handles CI verification in Step 4
- `--skip-ubiquitous-update` — prevents `ywc-create-pr` from running the UL update a second time; Step 1.5 already ran it

`ywc-create-pr` handles security check, CI pre-push validation, push, and PR creation as a draft. Because `--title` is provided explicitly, `ywc-create-pr` will use it verbatim and skip its own title-generation step.

**PR title format**: `[] `

Run the bundled script to extract the task number and English slug without regex parsing:

```bash
python claude-code/skills/ywc-finish-branch/scripts/build-pr-title.py 
# TASK_NUMBER=000001-010
# SLUG_EN=Db Create Users Table
```

**If the script exits 1 (`TASK_NUMBER` is empty)**: stop immediately and return `NEEDS_CONTEXT` — report the task name that failed to parse. Do not construct a title with an empty task number.

For English PRs (`--pr-lang en`), use `--format title` to get the complete title directly:

```bash
python claude-code/skills/ywc-finish-branch/scripts/build-pr-title.py  --format title
# [000001-010] Db Create Users Table
```

For other languages, translate only `SLUG_EN` to `--pr-lang`, then compose: `[] `.

The script supports both task-name formats (new `000001-010-slug` and legacy `001010-slug`). Examples of final titles: `[000001-010] Create users table` (en) · `[000001-010] ユーザーテーブル作成` (ja) · `[001010] DB 사용자 테이블 생성` (ko).

**Before calling `ywc-create-pr`**: verify the constructed title string starts with `[`. If it does not, stop — the `[TASK_NUMBER]` prefix was lost somewhere in the construction. Do not call `ywc-create-pr` without a valid title.

For `--mode local-merge`: skip this step entirely. Local-merge does not produce a PR.

### Step 3: Mark PR Ready (normal-pr only)

Invoke `gh pr ready ` to convert the draft into an open PR. Skip for `--mode draft`, `--mode skip-ci-wait`, `--mode per-task-pr` (those modes leave the PR as draft or hand control back to the caller).

### Step 4: CI Verification + Bot Review Polling (normal-pr only)

> **Action required**: Read [`../references/pr-bot-polling.md`](../references/pr-bot-polling.md) now before proceeding. The 60-second initial wait, the 300-second polling window, the `BOT_COUNT` jq query, and the merge condition are all defined there. Do not implement your own polling logic without reading it first.

Run the CI wait + fix loop and the bot review polling per [../references/pr-bot-polling.md](../references/pr-bot-polling.md). The polling reference defines the canonical loop; this skill applies its `--bot-action` parameter to choose the post-bot behavior:

- `--bot-action sequential`: after `ywc-handle-pr-reviews` runs, re-run the CI verification step before re-polling. Bot fixes may trigger a new CI run that must pass before merging.
- `--bot-action parallel`: after `ywc-handle-pr-reviews` runs, re-poll without re-gating on CI. The wave loop in `ywc-parallel-executor` handles CI at the wave level.

**CI failure handling (up to 2 fix attempts per failure cycle):**

1. **Identify failing checks:**
   ```bash
   gh pr checks 
   ```

2. **Get failure logs:**
   ```bash
   # Get the most recent failed run ID for the feature branch
   gh run list --branch  \
     --json databaseId,name,conclusion \
     --jq '.[] | select(.conclusion == "failure") | .databaseId' | head -1
   gh run view  --log-failed
   ```

3. **Categorize and fix by failure type:**

   | Failure type | Fix action |
   |---|---|
   | Lint / format | Run the project's auto-fix comman

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [yongwoon](https://github.com/yongwoon)
- **Source:** [yongwoon/ywc-agent-toolkit](https://github.com/yongwoon/ywc-agent-toolkit)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-yongwoon-ywc-agent-toolkit-ywc-finish-branch
- Seller: https://agentstack.voostack.com/s/yongwoon
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
