Skip to content
Back to skills

Issueops Merge

ASecurity

Use for "머지해줘", "PR 머지하고 정리", "merge the PR" on a completed IssueOps cycle: previews checks with `issueops remote merge-pr`, merges pinned to the completed head, deletes the remote branch, hands off to issueops-cleanup.

  • 6 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
ai-agentsbashgit

Works with

  • mcp

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned November 7, 2026

npx -y skills add m16khb-org/issueops --skill issueops-merge --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Issueops Merge?

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

Security grade badge for Issueops Merge
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/m16khb-org-issueops-merge/badge)](https://www.skillsdirectory.com/skills/m16khb-org-issueops-merge)

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: issueops-merge
description: 'Use for "머지해줘", "PR 머지하고 정리", "merge the PR" on a completed IssueOps cycle: previews checks with `issueops remote merge-pr`, merges pinned to the completed head, deletes the remote branch, hands off to issueops-cleanup.'
---

# IssueOps Merge

이 스킬은 **완료된 사이클의 PR/MR 하나를 머지하고 정리 단계로 넘기는 일**을 맡는다.
워크트리 세션이 `execution complete`까지 끝낸 뒤, 개발자가 PR을 확인하고 메인
세션에서 부르는 단계다.

- 전체 흐름과 단계 판별: [`issueops`](../issueops/SKILL.md)
- 직전 단계: [`issueops-complete`](../issueops-complete/SKILL.md)
- 다음 단계: [`issueops-cleanup`](../issueops-cleanup/SKILL.md)
- 원격 쓰기 절차: [`issueops-remote-write`](../issueops-remote-write/SKILL.md)

이 스킬이 하지 않는 일은 다음과 같다.

- `execution complete`를 대신 기록하지 않는다. 워크트리 세션의 몫이다.
- 코드를 고치지 않는다. 고칠 일이 생기면 사이클을 다시 열어 워크트리 세션에 넘긴다.
- 워크트리·로컬 브랜치 삭제와 이슈 종료는 `issueops-cleanup`이 맡는다.
- `gh pr merge`, `glab mr merge`, `--admin`, 자동 머지를 직접 쓰지 않는다.

## 흐름

```mermaid
flowchart LR
  a["이슈·PR 번호"] --> b["IssueOps ID 찾기"]
  b --> c{"next = done?"}
  c -->|아니오| x["멈춤: 워크트리 세션이 끝나지 않음"]
  c -->|예| d["merge-pr 미리보기"]
  d --> e{"차단 사유?"}
  e -->|있음| r["복구 표에 따라 처리"]
  r --> d
  e -->|없음| f["확인 ①: 머지 + 원격 브랜치 삭제"]
  f --> g["merge-pr --confirm"]
  g --> h["cleanup remote-branch"]
  h --> i["issueops-cleanup (확인 ②)"]
```

## 1 대상 찾기

사용자가 이슈 번호나 PR 번호를 준다. `issueops list`의 `issue_url`과
`remote_artifact_url`에서 번호가 맞는 사이클을 고른다.

```bash
issueops list --repo "$PWD" --json
```

- 이슈 번호는 `issue_url`의 `/issues/<n>`과 맞춘다.
- PR 번호는 `remote_artifact_url`의 `/pull/<n>`(GitHub)이나
  `/merge_requests/<n>`(GitLab)과 맞춘다.
- 맞는 사이클이 없거나 둘 이상이면 후보를 보여 주고 사용자에게 묻는다. 제목으로 추측하지 않는다.

## 2 진입 게이트

```bash
issueops next --id "$ISSUEOPS_ID" --json
```

`stage.key`가 `done`이어야 한다. `pr.create`나 `pr.complete`, 또는 lease가 active인
상태라면 워크트리 세션이 아직 끝나지 않은 것이다. 이때는 멈추고 그 사실을 보고한다.
살아 있는 홀더의 lease를 가져오지 않는다.

## 프로젝트 문서 확인

머지와 원격 브랜치 삭제는 되돌리기 어렵다. 미리보기 전에 `.issueops/CAUTIONS.md` 색인을
읽고(없으면 열지 않고 "파일 없음"으로 적는다), `project_docs_route`(MCP를 쓸 수 없으면 `issueops project route-docs --repo "$PWD"
--task "<작업 요약>" --json`)에 "PR 머지와 원격 브랜치 삭제" 같은 작업 요약을 넣어 머지·브랜치·
정리에 관한 `cautions/`·`adr/` 기록을 고른다. `.issueops/VCS.md`가 있으면 provider별 머지
방식과 제약을 거기서 확인한다. 확인 ①에서 사용자에게 보여 줄 때 해당되는 주의사항을
문서 경로와 함께 적는다.

## 3 미리보기

사용자가 PR 리뷰 반영을 함께 요청했으면 미리보기 전에 [`review-agent-feedback`](../review-agent-feedback/SKILL.md)으로
지적마다 판정한다. 반영할 지적은 `references/blocker-recovery.md`의 **코드 결함** 갈래(reseed)로 고친 뒤 미리보기를 다시 한다.

```bash
issueops remote merge-pr --id "$ISSUEOPS_ID" --json
```

기본 방식은 `squash`다. 사용자가 다른 방식을 원할 때만 `--method merge` 또는
`--method rebase`를 붙인다. GitLab은 프로젝트 설정이 merge commit과 fast-forward를
정하므로 `rebase`를 받지 않는다. squash는 PR 제목을 커밋 제목으로 쓰므로, 저장소가 정한
커밋 제목 형식과 PR 제목이 다르면 머지 전에 사용자에게 알린다.

응답에서 다음 값을 사용자에게 보여 준다.

| 항목 | 필드 |
|---|---|
| PR/MR | `url`, `state`, `draft`, `base_branch` |
| 체크 | `checks`, `failing_checks`, `pending_checks` |
| head | `head_oid`와 `expected_head_oid`(completion이 봉인한 head) |
| 차단 사유 | `blockers[].code`, `blockers[].message` |

`ok: true`이고 `blockers`가 비어 있으면 4단계로 간다. `already_merged: true`면 이미
머지된 것이므로 5단계로 간다.

## 차단 사유별 복구

`merge-pr`는 차단 사유가 하나라도 있으면 `--confirm`을 거부하고 아무것도 바꾸지 않는다.
사유마다 되돌아갈 길이 정해져 있다.

| code | 뜻 | 복구 |
|---|---|---|
| `checks_pending` | CI가 아직 돈다 | 기다린 뒤 3단계 미리보기를 다시 실행한다. 상태는 바뀌지 않는다 |
| `checks_failing` | CI가 실패했다 | 일시적 실패인지 코드 결함인지 사용자와 정한다(아래 복구 절차) |
| `head_mismatch` | completion 뒤에 커밋이 더 올라갔다 | 검증되지 않은 head다. 사이클을 다시 연다 |
| `merge_conflict` | base와 충돌한다 | base를 먼저 동기화한 뒤 사이클을 다시 연다 |
| `merge_blocked` | 리뷰 승인이나 브랜치 보호가 막는다. 변경 요청(`CHANGES_REQUESTED`·`requested_changes`)도 여기다 | 지적을 반영해야 하면 아래 복구 절차의 **코드 결함** 갈래로 사이클을 다시 연다. 반영 뒤에도 리뷰어가 provider에서 재승인하거나 dismiss해야 풀린다. 사람이 해결한 뒤 미리보기를 다시 실행한다. `--admin`으로 우회하지 않는다 |
| `base_mismatch` | provider가 PR 대상 브랜치를 바꿨다(쌓은 부모 브랜치가 머지·삭제됨) | 메시지의 `branch retarget`으로 새 base를 기록하고 `merge_conflict`와 같은 동기화 경로를 밟는다 |
| `pr_not_open` | PR/MR이 닫혔다 | 멈춘다. 폐기할지는 사용자가 정하고 [`issueops-abandon`](../issueops-abandon/SKILL.md)이 맡는다. 재오픈은 [재오픈 조건](references/blocker-recovery.md#닫힌-prmr-재오픈)을 따른다 |

`checks_failing`·`head_mismatch`·`merge_conflict`·`base_mismatch`·`merge_blocked`의 복구 절차(일시적 실패 재실행, reseed로 사이클 다시 열기,
base 동기화)는 [차단 사유별 복구 절차](references/blocker-recovery.md)(`issueops-merge/references/blocker-recovery.md`)를 읽고 따른다.

## 4 확인 경계

차단 사유가 없을 때 한 번의 확인으로 머지와 원격 브랜치 삭제를 함께 받는다.

```text
PR <URL>(head <head_oid 앞 10자>, 체크 <checks>)을
<draft면 "draft에서 해제하고 "><method> 방식으로 <base_branch>에 머지하고,
머지 뒤 원격 브랜치 <branch>(OID <head_oid 앞 10자>)를 삭제할까요?
주의사항: <프로젝트 문서 확인에서 고른 항목마다 "문서 경로: 해당 문장 인용", 없으면 "대조한 문서 <경로 목록>, 해당 없음">
워크트리·로컬 브랜치 정리와 이슈 종료는 다음 단계에서 따로 확인합니다.
```

가장 최근 사용자 메시지가 이 대상을 확인해야 한다. 일반적인 "머지해" 요청은 미리보기까지만
허락한 것으로 본다.

예외: 원래 요청이 승인 문장 안에서 **이 사이클의 PR merge**를 명시했고(예: "PR을 만들어 merge하고 정리까지,
merge는 승인함") 그 뒤 사용자 메시지가 범위를 줄이거나 멈추라고 하지 않았으면, 그 승인이 확인을 대신한다.
조건은 모두 맞아야 한다. 미리보기 PR URL·base가 record와 같다. head가 completion head와 같다. `blockers`가
비어 있다(`checks_pending`·`merge_blocked` 포함). 머지 방식이 요청이나 저장소 관례와 맞는다. draft
해제는 같은 승인 문장이 PR 생성과 merge를 함께 다루거나, 이미 있는 PR을 record의 PR과 일치하는 번호(같은
저장소)나 URL로 지목해 그 PR의 merge를 명시해 승인했을 때만 포함한다. 지목한 PR이 record와 다르거나 저장소가
모호하면 다시 확인받는다. "ready로 바꿔"·"검토 요청"만으로는 merge 승인이 아니다. 그 요청은
`issueops remote mark-ready --id "$ISSUEOPS_ID" --json`(preview) 뒤 `--confirm`으로 draft만 해제한다. 원격 브랜치 삭제는 그 승인이 정리까지
포함하고 원격 OID가 completion head와 같을 때만 함께 한다. 이 경우 6단계의 비교 기준은 completion head다.
그렇지 않으면 머지는 진행하고, 원격 브랜치 삭제는 6단계에서 대상을 보여 주고 따로 확인받는다. 확인을 생략해도 위 확인 문구(`주의사항:` 줄 포함)는 출력해 기록으로
남긴다. 하나라도 다르거나 판단할 수 없으면 대상을 보여 주고 다시 확인을 받는다.

## 5 머지

```bash
issueops remote merge-pr --id "$ISSUEOPS_ID" --method squash --confirm --json
```

미리보기와 같은 `--method`를 쓴다. `ok: true`, `merged: true`를 요구한다. `marked_ready`는
draft를 해제했는지, `merge_commit_oid`는 base에 생긴 커밋을 알려 준다.

- 명령이 `merge-pr refused`로 끝나면 그 사이 상태가 바뀐 것이다. 3단계로 돌아간다.
- `merge was not verified`로 끝나면 머지가 대기열에 들어갔거나 provider가 아직
  반영하지 않은 것이다. 같은 명령을 반복하지 말고 잠시 뒤 미리보기로 상태를 읽는다.
  `already_merged: true`가 나오면 성공으로 이어 간다.
- confirm이 출력 없이 끝나면(호출 프로세스 종료, exit 137 등) 위와 같이 다룬다. 다시 confirm하지
  않고 미리보기를 읽는다. `already_merged: true`와 `merge_commit_oid`가 머지 증거다.

## 6 원격 브랜치 삭제

```bash
issueops cleanup remote-branch --id "$ISSUEOPS_ID" --preview --json
```

미리보기의 `branch`와 `remote_oid`가 4단계에서 확인받은 브랜치·OID와 같아야 한다.
다르면 멈추고 새 대상으로 다시 확인받는다. 같으면 미리보기가 돌려준 `next_command`를
그대로 실행한다. 형식은 다음과 같다.

```text
issueops cleanup remote-branch --id "$ISSUEOPS_ID" --apply --confirm --fingerprint "$FINGERPRINT" --json
```

`deleted: true` 또는 `already_absent: true`를 요구한다. `git push origin --delete`를
직접 쓰지 않는다.

## 7 정리로 넘기기

[`issueops-cleanup`](../issueops-cleanup/SKILL.md)을 같은 ID로 이어서 실행한다. cleanup은
워크트리·로컬 브랜치 삭제와 이슈 종료를 위해 자체 미리보기와 확인 ②를 따로 받는다.
원격 브랜치는 6단계에서 지웠으므로 `--keep-remote-branch`는 쓰지 않는다.

## 완료 보고

| 항목 | 근거 |
|---|---|
| 사이클 | IssueOps ID, 이슈 URL |
| 머지 | PR/MR URL, 방식, `merge_commit_oid`, draft 해제 여부 |
| 원격 브랜치 | `cleanup remote-branch`의 `deleted` 또는 `already_absent` |
| 다음 단계 | `issueops-cleanup` 진행 결과 또는 대기 중인 확인 |
| 복구 | 차단 사유가 있었다면 code와 선택한 복구 경로 |

## 나쁜 예

| 나쁜 행동 | 문제 |
|---|---|
| `gh pr merge --squash --delete-branch` 직접 실행 | head 고정과 머지 확인이 빠진다. 다른 워크트리가 base를 체크아웃하고 있으면 로컬 정리 단계에서 실패한다 |
| `checks_failing`인데 `--admin`이나 자동 머지로 넘김 | 실패한 코드가 base에 들어간다 |
| `head_mismatch`를 무시하고 머지 | completion이 검증하지 않은 커밋이 들어간다 |
| 체크 실패를 메인 세션에서 직접 고쳐 push | lease 없이 사이클 브랜치를 바꾼다. reseed로 워크트리 세션에 넘긴다 |
| `stage.key`가 `pr.complete`인데 머지 | completion이 없어 `merge-pr`가 거부한다. 워크트리 세션을 기다린다 |
| `merge was not verified` 뒤 confirm 반복 | 대기열에 들어간 머지를 두 번 요청한다. 미리보기로 상태를 읽는다 |
| 원격 브랜치를 `git push origin --delete`로 삭제 | fingerprint와 감사 기록을 우회한다 |
| 머지 확인 하나로 워크트리와 이슈까지 정리 | cleanup의 fingerprint는 이슈를 닫은 뒤 새로 발급된다. 확인 ②를 따로 받는다 |

Files in this skill

  • SKILL.md12.2 KB
  • agents/openai.yaml820 B
  • references/blocker-recovery.md4.1 KB

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.