neon-sprawl/.cursor/rules/story-end.md

62 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
description: When a Linear-tracked story is finished (merged or abandoned locally), return to main, pull, delete the local story branch
alwaysApply: true
---
# Story end (Linear)
When the user **ends story work** on a ticketed branch—phrases like “end story”, “story is merged”, “clean up branch after NEO-…”, or they confirm the PR is **merged** to `main`—run this **git** sequence so local state matches the remote default branch.
## 1. Preconditions
- **Merged:** Prefer deleting the local branch only after **`main`** on the remote includes the story (PR merged). If the PR is **not** merged, `git branch -d` will refuse; use **`git branch -D`** only when the user explicitly wants to drop unmerged work.
- **Uncommitted changes:** Stash, commit, or discard before switching branches; do not leave a dirty tree without the users choice.
## 2. Steps (run in order)
1. **`git checkout main`**
2. **`git pull origin main`** (or `git pull` if `main` already tracks `origin/main` and that is correct for this repo)
3. **`git branch -d <story-branch>`** — use the branch that was used for the issue (first path segment should be the Linear issue id, e.g. `NEO-10-move-validation`). If Git reports “not fully merged”, confirm whether **`origin/main`** already contains the story (e.g. squash merge or follow-up commits only cherry-picked to `main`). If yes, **`git branch -D <story-branch>`** is OK **only with user confirmation** so local unpushed tip is not lost by mistake.
## 2a. When `main` is push-protected
If the user asks to **push** changes that sit on **`main`** and **`git push origin main` fails** (required PR / status checks), create a branch from current `main` (e.g. `chore/…`), **`git push -u origin`** that branch, then open the PR with the **GitHub MCP** **`create_pull_request`** tool and a title keyed per [commit-and-review](commit-and-review.md) **Opening a PR when the user asks** (or give the **`pull/new/...`** URL **and** remind them to fix the title to **`NEO-123:`**). **`git reset --hard origin/main`** if you had temporarily advanced local `main` so local `main` matches remote until the PR merges.
## 3. What not to do
- Do **not** delete **`main`** or **`origin/*`**.
- Do **not** assume the remote story branch should be deleted unless the user asks (many teams keep `origin/NEO-…` for history or delete via GitHub UI).
## 4. Linear issue status
- **Do not** call Linear `save_issue` to change **state** until the user has **explicitly** chosen the target status. Typical names here are **`In Test`** or **`Done`**; use `list_issue_statuses` (Linear MCP, server **`plugin-linear-linear`**) if names differ on your team.
- If the user only says “end story” / “merge cleanup” / similar **without** naming a target status: run the **git** steps in §2, then run **§4a** (required ask) and **wait for the users choice** before updating the issue. **Never assume Done** without that confirmation.
- **Exception:** If the **same user message** already names the status (e.g. “end story, move NEO-18 to **Done**”), you may update Linear after git cleanup without a second ask.
- When Linear MCP is available, perform the update with **`save_issue`** (`id` = issue identifier, `state` = chosen status).
- If MCP is unavailable or the update fails, tell the user and ask them to update Linear manually.
### 4a. Required ask (agents — do not skip)
After §2 (and any local branch deletes that succeeded), prompt for the **Linear next state** in a way that matches **story kickoff** blocking decisions: **selectable multiple choice when the product supports it**, not only free-form prose buried after long git output.
**Preferred (Agent mode):** Use Cursors **`AskQuestion`** tool (multiple-choice) as the **first** user-facing step after git, **before** a long git dump—or put a **one-line** git summary first, then **`AskQuestion`** immediately. Example question:
- **Prompt:** `Which Linear state should we set this story to?` (name the **issue key** in the prompt if known, e.g. **NEO-25**, or ask which issue in a second question if ambiguous.)
- **Options** (adapt labels to `list_issue_statuses` for the **Neon Sprawl** team—or the issues team—if names differ):
- **`in-test`** → label **In Test**
- **`done`** → label **Done**
- **`skip`** → label **Skip — do not change Linear** (user can clarify in chat afterward)
After the user selects **`in-test`** or **`done`**, call **`save_issue`** with `state` matching that status (name or type from Linear). If they pick **`skip`**, do not call `save_issue` for state.
**Fallback (no `AskQuestion`, e.g. Ask mode):** Use the prose template: ask which **status name** and **issue key**, with **In Test** / **Done** / **Skip** spelled out.
Then give any **git** details (branch deleted, `main` ahead, etc.) **after** the question or below the choice result.
## Related
- [story-kickoff](story-kickoff.md) — start of story workflow
- [git-workflow](git-workflow.md) — branch vs `main`
- [linear-git-naming](linear-git-naming.md) — branch names
- [commit-and-review](commit-and-review.md) — push and **GitHub MCP `create_pull_request`** only when the user requests it; PR title **`NEO-*:`** prefix