PR 열기
현재 브랜치에 대해 감지된 PR 플랫폼(Azure DevOps 또는 GitHub)에서 풀 리퀘스트를 엽니다. 제목과 설명은 고정된 팀 스타일이 아닌 호출 사용자의 과거 PR 작성 규칙에 맞춰 작성된 후 확인을 위해 표시됩니다. PR은 명시적인 승인 없이는 절대 생성되지 않습니다 — PR을 여는 것은 외부로 공개되는 작업입니다.
이 스킬은 백엔드에 독립적입니다. 플랫폼별 메커니즘(PR 생성, 중복 확인, 레이블, 백포트 링크)은 resources/backends/ 디렉토리의 백엔드 어댑터 참조 문서에 있으며, 티켓 링크 메커니즘은 resources/trackers/ 디렉토리의 트래커 어댑터 참조 문서에 있습니다. 스킬 본문은 플랫폼과 트래커를 감지하고, 일치하는 어댑터를 로드한 후 해당 레시피를 따릅니다. 자체적으로 az/gh 관련 필드 파싱이나 트래커별 ID/URL 파싱을 보유하지 않습니다. PR 생성 흐름의 안전 장치를 차용하지만 의도적으로 더 좁은 범위를 가집니다. 현재 브랜치를 있는 그대로 PR용으로 엽니다. (PR에 필요하므로 아직 원격에 없다면 먼저 푸시합니다.) 기본 브랜치를 병합하거나, 브랜치를 삭제하거나, 리뷰 코멘트를 분류하지 않습니다(이는 resolve-pr-comments에서 처리합니다).
0단계 — 플랫폼 + 트래커 감지, 어댑터 로드, 알림
다른 모든 작업보다 먼저, 이 실행이 대상으로 하는 백엔드와 트래커를 결정합니다:
- PR 플랫폼 —
git remote get-url origin으로부터:dev.azure.com또는*.visualstudio.com→ Azure DevOps (resources/backends/azure-devops.md).github.com→ GitHub (resources/backends/github.md).- 모호하거나 다른 호스트 → 제한 사항을 알리고 사용자에게 대상 플랫폼을 물어봅니다(추측하지 않음).
- 이슈 트래커 (우선 순위 — 첫 번째 일치가 우선):
- 명시적 설정이 우선:
.claude/pr-lifecycle.json(선택 사항, gitignore에 포함됨)이 트래커 유형을 지정하면 이를 사용합니다(그리고 Jira 기본 URL도 가져옵니다). - 그렇지 않으면 기존 티켓 참조에서 유형을 추론:
[A-Z][A-Z0-9]+-\d+→ Jira (모든 플랫폼); 숫자만 있는 이슈 참조 → GitHub Issues — 단, GitHub 원격일 때만 해당합니다. (Azure DevOps에서#<n>은 작업 항목 링크이지 GitHub 이슈가 아니므로, 숫자만으로 GitHub Issues를 의미하지 않습니다.) - 그렇지 않으면 플랫폼별 기본값: GitHub 원격 → GitHub Issues (설정 불필요); Azure DevOps 원격 → Jira.
- 티켓이 전혀 없음 → 트래커 라인을 생성하지 않음(현재와 동일).
- Jira →
resources/trackers/jira.md; GitHub Issues →resources/trackers/github-issues.md.
- 명시적 설정이 우선:
- 감지된 플랫폼과 트래커를 알립니다 — 잘못된 추측이 조용히 발생하는 것을 방지합니다.
일치하는 백엔드 및 트래커 어댑터를 로드하고 아래 단계의 플랫폼/트래커별 부분을 이들을 통해 실행합니다. 이 본문에서 유일한 백엔드 연결 지점은 어댑터를 선택하기 위해 원격 문자열을 인식하는 것입니다. 그 이상의 필드 접근은 없습니다. (어댑터 경로는 플러그인 루트 — plugins/pr-lifecycle/resources/backends/ 및 resources/trackers/ — 를 기준으로 하며, 스킬 디렉토리가 아닙니다.)
1단계 — 대상 브랜치 감지
- 저장소의 자체 기본 브랜치를 읽습니다. 절대 추정하지 마세요.
git symbolic-ref --short refs/remotes/origin/HEAD는origin/<branch>를 반환합니다. 접두사를 제거합니다. 이 참조는git clone에 의해 기록되므로,git init+git fetch로 만든 원격에는 없을 수 있습니다. 이 경우git ls-remote --symref origin HEAD로 원격에 직접 물어보십시오. 이는 읽기 전용이며 로컬 상태를 변경하지 않습니다. - 두 방법 모두 실패한 경우에만 원격에 실제로 있는
main/master중에서 선택합니다. 두 브랜치가 모두 존재하면 사용자에게 물어봅니다. 이름을 변경하는 중인 저장소는 이전 이름을 오래된 브랜치로 유지하므로, 조용히 선택하면 잘못된 대상에 대해 PR이 생성되어 2단계의 앞선 커밋 수와 3단계에서 호출자의 규칙을 학습하는 기록도 무효화됩니다. - 현재 브랜치가 릴리스 라인(예:
release/2.5)을 대상으로 하는 경우 백포트로 처리합니다(아래 백포트 형식 참조). - 올바른 대상이 실제로 모호하면 추측하지 말고 물어보십시오.
2단계 — 사전 조건 확인 (실패 시 중단 및 보고)
초안을 작성하기 전에 다음을 실행합니다. 각각은 일반적인 첫 실행 차단 요소이기 때문입니다:
- PR에 커밋이 있어야 합니다. 브랜치가 대상보다 앞서 있어야 합니다:
git fetch, 그 다음git rev-list --count origin/<target>..HEAD가 0보다 커야 합니다. - 원격에 있어야 함 — 필요 시 푸시. PR을 생성하려면 소스 브랜치가 원격에 있어야 합니다. 아직 푸시되지 않은 브랜치는 중단 사유가 아닙니다. 확인 후 open-pr은 4단계에서 생성의 일부로 이를 푸시합니다(
git push -u origin <branch>). (비대화형 모드로 실행 시 푸시하지 않고 생성하지 않습니다. — 4단계 참조.) - 중복 없음. 백엔드 어댑터의 중복 확인 레시피를 통해 이 소스에서 대상으로의 기존 열린 PR이 있는지 확인합니다. 존재한다면, 중단하고 사용자에게 이를 안내합니다. — 두 번째 PR을 열지 말고, 여기서 기존 PR을 수정하지 마십시오.
3단계 — 호출자의 규칙 학습 후 초안 작성
git config user.email (선호) 및 user.name으로 호출자를 식별한 후, 이 저장소에서 사용자의 최근 병합된 PR을 읽습니다: git log <target> --author="<email or name>" (두 형식을 모두 시도하고, 둘 다 아무것도 반환하지 않을 때만 "기록 없음"으로 처리). 지난 여러 개로부터 제목 케이싱과 설명 레이아웃(섹션으로 구분 vs 플랫 불릿 목록)을 다수결로 추론합니다. 가장 최근 커밋 날짜가 동점을 깨며, 단일 이전 PR은 직접 사용됩니다. 결과를 알립니다(K개의 과거 PR에서 학습함 또는 일치하는 기록 없음 -> 기본값 사용). 잘못된 추측이 조용히 발생하는 것을 방지합니다.
학습은 이 저장소와 이 호출자가 작성하는 방식을 다룹니다. 단순한 활자체 이상으로, 제목 케이싱, 설명 레이아웃(섹션 구분 vs 플랫 불릿 목록), 그리고 제목의 티켓 접두사 형태를 포함합니다. — 대괄호([acme-123] …), 접두사 없음(acme-123 …), Conventional Commits 유형(fix(scope): …) 또는 접두사 없음. 동일한 기록에서 형태를 읽습니다. 관찰된 PR에 티켓 접두사가 없으면 접두사를 추가하지 마십시오. 아래 기본값은 학습할 기록이 없을 때 사용하는 것이며, 다른 작업을 하는 저장소에 적용할 형식이 아닙니다.
학습은 아래 필수 콘텐츠(티켓 링크, 요약, 불릿)를 절대 삭제하거나 재정렬해서는 안 됩니다. 4번 항목의 다이어그램은 선택 사항이며, 5번 항목의 출처 푸터는 기본적으로 꺼져 있지만 출처 푸터가 옵트인된 경우 학습은 이를 마지막에 유지하고 절대 삭제하지 않아야 합니다. 이 저장소가 단일 작성자라도 학습을 이 저장소로 편향시키지 마십시오. 중요한 규칙은 스킬이 실행되는 모든 저장소에서의 호출자의 규칙입니다.
기본 형식 (대체 수단; 호출자의 학습된 규칙이 프레젠테이션을 재정의함)
제목: 트래커 어댑터에서 티켓 ID와 그 케이싱을 파생합니다:
- Jira 트래커:
[acme-xxxxx] <간결한 한 줄 요약>— 대괄호, 소문자 키(어댑터는 URL용 대문자 형식도 제공). - GitHub Issues 트래커:
#<n> <간결한 한 줄 요약>— 대괄호 형태 대신#<n>참조. - 티켓 없음: 티켓 라인을 생략하고, 이 저장소가 티켓 없는 PR의 제목을 지정하는 방식으로 제목을 지정합니다.
ad-hoc <요약>은 3단계의 기록이 복사할 대상을 전혀 제공하지 않았을 때만 대체 수단입니다. 이는 한 팀의 표식일 뿐, 사용한 적이 없는 저장소에 도입할 규칙이 아닙니다. 일반<요약>이 더 안전한 기본값입니다. - 두 개 이상의 다른 티켓 ID는 첫 번째를 조용히 선택하지 말고 어느 것을 사용할지 물어봅니다.
설명 (표준 PR):
- 티켓 링크 — 트래커 어댑터에 의해 생성됨: Jira의 경우
https://<jira_base_url>/browse/<KEY>(대문자 키); GitHub Issues의 경우#<n>(GitHub는 동일 저장소 이슈를 자동 링크). 플랫폼이 자동 링크할 수 있도록 첫 번째 줄이어야 함; 티켓이 없을 때만 전체 라인을 생략합니다. - 요약 — 한두 문장.
- 설명 — 각 개별 변경 사항당 하나의 불릿으로 동작과 간단한 이유/영향을 포함하는 불릿 목록. 파일/클래스/메서드/경로 식별자는 생략합니다. 의도를 설명하고 diff를 붙여넣지 마십시오.
- 짧은 ASCII 다이어그램, 펜스 코드 블록으로 감싸기 (선택 사항) — 그림이 리뷰어가 산문보다 변경 사항을 더 빨리 이해하게 할 때만 포함하고, 그렇지 않으면 생략합니다. 포함할 때: 실제 고정폭 구조 다이어그램(상자/화살표, 또는 작은 트리/테이블 — 산문을 다이어그램으로 위장한 것이 아님), 높은 수준으로 유지, 삼중 백틱 펜스로 감싸고, 일반 ASCII 글리프(
+ - | > v)로 그리고 Mermaid 사용 금지, 너무 넓거나 복잡한 다이어그램은 더 작은 여러 개로 나누어 하나의 읽을 수 없는 블록을 만들지 마십시오. 전체 그림 지침, 펜스/인코딩 근거 및 예시 형태:resources/diagram-guidance.md. - AI 출처 마커 (옵트인 — 기본적으로 꺼짐) — 푸터(
---구분선, 그 다음🤖 _Claude Code로 초안 작성됨._)와 4단계에서 적용되는ai-assisted레이블은 호출 요청이 PR을 AI 지원으로 표시/레이블/플래그 지정하도록 명시적으로 요청할 때만 추가됩니다(또는 명시적 옵트인 전달). 해당 표현이 없는 경우 — 모든 자동화된resolve-issue파이프라인 호출을 포함하여 이러한 표현이 없음 — 둘 다 추가하지 마십시오. 플랫폼/트래커/학습 결과와 같은 줄에 결정을 알립니다(provenance: off ("AI 지원으로 표시"라고 말하면 추가됨), 또는provenance: on (푸터 + 최선 노력 레이블)). 조용히 마커가 생략되는 것을 방지합니다. 옵트인된 경우 푸터는 모든 경로에서 마지막 요소입니다. 학습된 규칙 본문 뒤에 추가하고 학습이 이를 삭제하거나 재정렬하지 않도록 하십시오. Azure DevOps와 GitHub에서 동일하게 렌더링되며 휴대용 마커입니다. 레이블은 그와 함께하는 플랫폼 기본 배지입니다(최선 노력 — 4단계 참조). 팀이 감사를 위해 AI 공개를 의무적으로 요구해야 한다면 그때 구성 플래그로 다시 도입하십시오. 지금은 의도적으로 구축하지 않습니다.
백포트 (release/* 대상):
- 제목 (Jira 트래커):
[acme-xxxxx] [release] <요약>; (GitHub Issues 트래커):#<n> [release] <요약>. - 설명은 티켓 링크, 그 다음
cherry pick from <PR-링크>입니다. 여기서 백엔드 어댑터가 PR-링크 구문(Azure DevOps!<pr_number>, GitHub#<pr_number>— 둘 다 해당 PR에 대한 링크로 렌더링됨)을 제공합니다. 그 다음 출처가 옵트인된 경우에만 (3단계, 항목 5) AI 출처 푸터(---+🤖 _Claude Code로 초안 작성됨._). 요약 블록, 불릿 또는 다이어그램은 없습니다. 실제 리뷰는 원본 PR에서 이루어졌습니다. - 사용자에게 체리픽한 소스 PR 번호를 묻거나(또는 입력으로 받아)
<summary>에 해당 PR의 한 줄 요약을 재사용합니다. 백포트는 제목 케이싱만 학습하고 설명 레이아웃은 학습하지 않습니다.
모든 경로에서 (백포트 포함): 제목과 설명은 영어입니다. 자신의 Co-Authored-By 트레일러를 git에 추가하지 마십시오. 이는 커밋 관련 사항이지 PR 설명 관련 사항이 아니며, 이 저장소가 원하는지 여부는 이 스킬이 결정할 사항이 아니라 저장소 자체 기록(git log -n 50 --format=%b | grep -c '^Co-Authored-By')에서 관찰할 수 있는 것입니다. 기본적으로 추가하지 않습니다. 저장소의 커밋이 정기적으로 이를 수행한다면 재정의하는 대신 따르십시오. AI 출처 푸터와 ai-assisted 레이블은 다른 것이며 기본적으로 꺼져 있습니다 — 3단계(푸터)에서 설명된 명시적 옵트인과 4단계(레이블)에서 적용될 때만 추가되며, 금지된 트레일러가 아닙니다.
4단계 — 표시, 확인, 생성
초안 작성된 제목과 설명을 표시하고 사용자가 편집할 수 있도록 합니다. 그 다음:
- 독립 실행형: 사용자가 명시적으로 확인한 후에만 생성합니다. 소스 브랜치가 아직 원격에 없으면 먼저 푸시합니다(
git push -u origin <branch>). 그런 다음 백엔드 어댑터의 생성 레시피를 통해 PR을 생성합니다. 전체 설명을 임시 파일에 쓰고 인라인 문자열이 아닌 어댑터의 본문 파일 플래그로 전달합니다. 어댑터는 플랫폼의 파일 인코딩 함정(예: Azure DevOpsaz.cmdcp1252/UTF-8@<file>특이 사항)과 출처가 옵트인된 경우에만 (3단계)ai-assisted레이블이 적용되는 방법을 문서화합니다(Azure DevOps는--labels를 통해 인라인으로 태그를 생성하고, GitHub는gh pr edit --add-label로 생성 후 추가합니다.gh pr create --label은 레이블이 없으면 중단되기 때문입니다). 옵트인된 경우 레이블은 어느 쪽이든 최선 노력입니다(명시된 제한 사항 참조). 기본적으로 레이블이 적용되지 않습니다. PR URL을 반환합니다. - 확인을 받을 수 없는 경우 (비대화형으로 실행 중이거나 프롬프트할 수 없는 하위 에이전트 내부): 브랜치를 푸시하지 말고 PR을 생성하지 마십시오. 준비된 제목과 설명을 사용자가 수동으로 생성할 수 있도록 출력하고 그렇게 말합니다. 비대화형 컨텍스트에서 브라우저에서 열기 플래그(예: Azure DevOps
--open)를 사용하지 마십시오. 출처가 옵트인된 경우 출력된 설명에는 이미 푸터가 포함되어 있습니다. 사용자에게 PR을 생성할 때ai-assisted레이블을 추가하라고 말하십시오. 기본적으로(옵트인 없음) 어떤 마커도 출력되거나 언급되지 않습니다.
불변 규칙: 명시적인 인간 확인 없이는 브랜치를 푸시하거나 PR을 열지 마십시오. 둘 다 외부로 공개되는 작업입니다.
안전 장치
- 병합 충돌을 자동으로 해결하지 마십시오. 중단하고 보고하십시오.
- 브랜치를 삭제하지 마십시오.
- 명시적인 요청 없이 강제 푸시하지 마십시오.
명시된 제한 사항
- 감지된 플랫폼의 PR 도구가 없거나 인증되지 않은 경우(각 백엔드 어댑터의 사전 조건 참조 — 예: Azure DevOps의
az+azure-devops확장, GitHub의gh인증), 그렇게 말하고 준비된 제목과 설명을 수동 생성을 위해 출력하십시오. 조용히 실패하지 마십시오. - 학습된 규칙은 최선 노력입니다. 스쿼시 워크플로가 설명 본문을 남기지 않은 경우 케이싱은 여전히 커밋 제목에서 가져오고 레이아웃은 기본값으로 대체됩니다. 알림, 조용하지 않음.
- 출처 마커는 기본적으로 꺼져 있습니다 — 호출 요청이 명시적으로 옵트인하지 않는 한 푸터와 레이블이 없습니다(3단계, 항목 5). 옵트인된 경우
ai-assisted레이블은 최선 노력입니다. 플랫폼이 거부하면(임시 PR 태그를 허용하지 않는 Azure DevOps 조직 또는 아직 존재하지 않는 GitHub 레이블) 레이블을 드롭하고 푸터만으로 PR을 생성한 후(옵트인된 마커) 그렇게 말하십시오. 백엔드 어댑터는 플랫폼별 동작을 문서화합니다.