| name | rai-story-close |
| description | Merge story branch to dev and update tracking. Use after story review. |
| allowed-tools | ["Read","Edit","Write","Grep","Glob","Bash(rai:*)","Bash(git:*)"] |
| license | MIT |
| metadata | {"raise.work_cycle":"story","raise.frequency":"per-story","raise.fase":"8","raise.prerequisites":"story-review","raise.next":"","raise.gate":"","raise.adaptable":"true","raise.version":"3.0.0","raise.visibility":"public","raise.inputs":"- retrospective_md: file_path, required, previous_skill\n- tests_passing: boolean, required, cli\n- dev_branch: string, required, config\n","raise.outputs":"- merge_commit: string, git\n"} |
Story Close
Purpose
Complete a story by verifying the retrospective, merging locally to the development branch, and updating epic tracking. Remote push and merge requests happen at epic level (see /rai-epic-close).
Mastery Levels (ShuHaRi)
- Shu: Follow all steps, verify retrospective, merge locally, update epic
- Ha: Skip epic update for standalone stories
- Ri: Integrate with CI/CD pipelines, automate cleanup workflows
Context
When to use: After /rai-story-review retrospective is complete. Story is verified and tests pass.
When to skip: Story abandoned (document why, delete branch without merge, update epic as "Abandoned").
Inputs: Completed retrospective, passing test suite, story branch ready for merge.
Branch config: Read branches.development from .raise/manifest.yaml for {dev_branch}. Default: main.
Steps
Step 1: Verify Retrospective & All Gates
RETRO="work/epics/e{N}-{name}/stories/{story_id}-retrospective.md"
[ -f "$RETRO" ] && echo "✓ Retrospective" || echo "ERROR: Run /rai-story-review first"
Run all four gates before pushing. Resolve commands from .raise/manifest.yaml or use defaults (see /rai-story-implement Step 3 for the full table):
- Tests —
project.test_command or language default
- Lint —
project.lint_command or language default
- Format —
project.format_command or language default (e.g. uv run ruff format --check src/ tests/)
- Type check —
project.type_check_command or language default (e.g. uv run pyright)
| Condition | Action |
|---|
| Retro exists + all 4 gates green | Continue |
| Retro missing | Run /rai-story-review first — no exceptions |
| Any gate failing | Fix before push — CI will reject the same errors |
Check for structural drift: if this story added modules or changed directory structure, update module docs in governance/architecture/modules/ before closing.
Retrospective exists. All four gates pass (test, lint, format, types). No undocumented structural changes.
Step 2: Verify Clean Working Tree
git status --short
| Condition | Action |
|---|
| Working tree clean | Continue to merge |
| Uncommitted changes from this story | Commit them before merge — artifacts must not be orphaned |
| Unrelated changes | Stash or commit separately with chore: prefix |
NEVER merge with uncommitted story artifacts. Files created during design, plan, or implementation that aren't committed will be silently lost or orphaned on the target branch.
`git status` shows clean working tree (or only unrelated files explicitly acknowledged).
Step 3: Merge Locally to Dev
Merge the story branch into {dev_branch} locally with --no-ff to preserve story history:
git checkout {dev_branch}
git merge story/s{N}.{M}/{slug} --no-ff -m "Merge branch 'story/s{N}.{M}/{slug}' into {dev_branch}
S{N}.{M}: {story-name} — {1-line summary}
Tracker: {JIRA_KEY} / E{N}"
Remote push and merge requests are handled at epic level during /rai-epic-close.
| Condition | Action |
|---|
| Merge succeeds | Continue to Step 4 |
| Merge conflicts | Resolve on story branch first, then retry merge |
Story merged to `{dev_branch}` locally via `--no-ff`.
Step 4: Update Epic Scope
Mark story complete in work/epics/e{N}-{name}/scope.md:
- Check the story checkbox:
- [x] S{N}.{M} {name} ✓
- Update progress tracking table (status, actual time, velocity)
Epic scope reflects story completion.
Step 5: Local Cleanup
Delete the local story branch (already merged to {dev_branch}):
git branch -d story/s{N}.{M}/{slug}
Local story branch deleted.
Step 6: Update Backlog
If the story has a backlog ticket: rai backlog transition {story_key} done
| Condition | Action |
|---|
| Transition succeeds | Continue |
| Transition fails | Log warning and continue — backlog errors are non-blocking for lifecycle |
| No ticket | Skip backlog transition |
Backlog updated.
Adapter not configured or transition fails → log and continue. Backlog sync is best-effort; it must never block story close.
Output
| Item | Destination |
|---|
| Local merge | {story_branch} merged to {dev_branch} via --no-ff |
| Epic update | work/epics/e{N}-{name}/scope.md |
| Branch cleanup | Local story branch deleted |
| Backlog update | via rai backlog transition (best-effort) |
| Remote push + MR | Deferred to /rai-epic-close |
Scope Constraints (CRITICAL)
Close is a merge-only operation. The following are explicitly forbidden:
- NEVER edit source code, skill files, config, or governance docs — close does not "fix" things
- NEVER create "fix" or "refactor" commits — if something looks wrong, report it; do not repair it
- NEVER delete directories, worktrees, or files outside the story branch — close only deletes the merged story branch
- NEVER revert or modify commits already on
{dev_branch} — prior story work is settled
- NEVER rationalize unauthorized changes — "this field looks wrong" is not a close concern
Conflict resolution: When merge conflicts occur, resolve ONLY the conflicting hunks using the mechanical merge strategy (accept both sides where possible, prefer story branch for story-owned files). Do NOT use conflicts as an opportunity to audit or "correct" surrounding code.
Allowed writes during close (exhaustive list):
work/epics/e{N}-{name}/scope.md — update progress tracking only
- Merge commit message
- Signal/backlog CLI calls (side-effect only)
Anything not on this list is out of scope. If you believe something needs fixing, return it as a finding — do not act on it.
Quality Checklist
References
- Previous:
/rai-story-review
- Complement:
/rai-story-start
- Epic scope:
work/epics/e{N}-{name}/scope.md