website: claim-mission — 개인 미션을 받아 끝까지 미는 스킬
멋사 경희대 사이트 프로젝트의 팀 협업 하네스에, 팀원이 "나한테 할당된 미션 수행하자" 한 마디만 하면 리서치부터 PR 생성, 미션 마감까지 자동으로 굴러가는 claim-mission 스킬을 추가한 PR입니다.
요약
이 PR은 2026년 7월 11일 하루 만에 작성되고 병합됐습니다. 716줄을 추가하고 4줄을 지운, 규모로 보면 작지 않은 변경인데도 커밋은 하나뿐이었어요. 처음부터 설계를 다 잡고 한 번에 밀어 넣은 셈입니다.
핵심은 이거예요. 팀원 입장에서는 "내 미션 하자"라고만 말하면, 뒤에서 신원 확인 → 배정된 미션 조회 → 리서치 → 계획 → 구현 → QA → PR 생성 → 미션 닫기까지 알아서 진행됩니다. gh 명령어도, PAT 토큰도, 프로젝트 보드 좌표도 전부 스크립트 뒤에 숨겨져서 사용자는 볼 필요가 없어요.
배경 및 목적
PR 본문에 이 스킬을 만든 이유가 꽤 명확하게 적혀 있습니다. 지금까지는 사람이 이슈를 읽고, 내용을 복사해서 AI에게 붙여넣고, 그제서야 일을 시작하는 흐름이었을 거예요. 이슈 찾기, 복붙, 보드에서 착수 표시로 옮기기 — 이런 건 전부 기계가 대신할 수 있는 배관(plumbing)이라는 문제의식이 출발점입니다.
여기서 나오는 게 human-in-the-loop과 human-on-the-loop의 구분이에요. 사람을 매 단계마다 끼워 넣으면 사람이 병목이 됩니다. 그래서 사람은 루프 안이 아니라 루프 위에 있어야 한다는 게 이 PR의 설계 철학이에요. 리서치 → 계획 → 구현 → QA는 AI가 자율적으로 돌리고, 사람은 딱 두 지점에서만 브레이크를 밟습니다. 방향이 맞는지 확인하는 지점(RP 게이트)과 결과가 맞는지 확인하는 지점(IQ 게이트)이요.
그리고 미션은 연 사람이 닫는다는 원칙도 눈에 띕니다. 시작부터 끝까지 한 사람이 책임지는 구조를 만든 거죠.
구현 내용
전체 흐름 (SKILL.md)
.claude/skills/claim-mission/SKILL.md가 이 PR의 뼈대입니다. Step 0부터 Step 4까지 순서가 고정돼 있어요.
- Step 0 — 신원 확인:
check-identity.sh로 레포 루트의.identity.local.yml을 읽어 GitHub handle과 PAT가 유효한지 검증합니다. - Step 0-a — 로컬 토큰 자동 발견: 신원이 없으면 바로 인터뷰로 가지 않고,
discover-token.sh로 이 머신에 이미 있는 토큰(주로gh로그인)을 먼저 찾습니다. 초보자에게 PAT를 새로 만들라고 하기 전에 마찰을 없애려는 의도예요. - Step 0-b — 인터뷰: 그래도 토큰이 없으면 그때 처음으로 PAT 발급 과정을 단계별로 안내합니다.
pm/roster.yml에서 handle이 있는 멤버만 골라 신원을 확정하고,repo+project스코프로 토큰을 만들게 안내해요. - Step 1 — 내 미션 가져오기:
fetch-my-mission.sh로 자신에게 assign된 이슈를 가져옵니다. 0개면 아직 배정이 안 됐다고 안내, 여러 개면 골라 진행합니다. - Step 2 — 착수:
start-mission.sh로 보드 카드를 Todo에서 In Progress로 옮깁니다. - Step 3 — R→P→[RP게이트]→I→Q→[IQ게이트]: 리서치와 계획은 자율로 진행하고, 각 게이트에서는 "리뷰포인트를 집는다 → 권장 답을 준다 → 확인만 받는다" 형식으로 사람에게 열린 질문 없이 예/아니오만 받도록 설계했습니다.
- Step 4 — 마감:
create-pr.sh로 PR을 올리고,close-mission.sh로 보드 카드를 Done으로 옮기고 이슈를 닫습니다.
스크립트들
배관 역할을 하는 스크립트가 꽤 여럿인데, 그중 몇 개를 보면 이 PR이 보안에 상당히 신경 쓴 걸 알 수 있습니다.
check-identity.sh는 PAT를 파싱할 때 python3의 최소 YAML 파서로 값을 읽되, 절대 stdout이나 에러 메시지에 토큰 값을 노출하지 않습니다.
read_key() { python3 -c "
import sys
d={}
for line in open('$ID_FILE'):
line=line.rstrip('\n')
if ':' not in line: continue
k,v=line.split(':',1)
d[k.strip()]=v.strip().strip('\"').strip(\"'\")
print(d.get('$1',''))
"; }
discover-token.sh도 마찬가지로, gh auth token이나 git credential, 흔한 로컬 파일에서 토큰 패턴을 긁어모으되 후보 배열에만 담고 절대 출력하지 않습니다. 검증에 성공한 첫 토큰만 .identity.local.yml에 씁니다.
create-pr.sh는 push할 때 토큰이 URL이나 명령 인자에 남지 않도록 임시 GIT_ASKPASS 스크립트를 만들어 권한 600으로 쓰고 push가 끝나면 바로 지웁니다.
ASKPASS=$(mktemp)
chmod 600 "$ASKPASS"
printf '#!/bin/sh\necho "%s"\n' "ASKPASS"
chmod 700 "$ASKPASS"
GIT_ASKPASS="BRANCH"
rm -f "$ASKPASS"
close-mission.sh는 프로젝트 보드의 Status 필드 옵션 ID(Todo/In Progress/Done)를 하드코딩해두고, 이슈 번호로 보드 아이템을 찾아 Done으로 옮긴 뒤 이슈를 닫으면서 마감 코멘트를 답니다.
기술적 의사결정
가장 눈에 띄는 결정은 게이트를 "PM 보고"가 아니라 "미션을 채간 사람 본인의 셀프 검토"로 설계한 부분입니다. PR 본문에서도 강조하듯, 사람은 맥락이 없는 상태로 미션을 받게 되니 매 게이트에서 AI가 리뷰포인트를 대신 짚어주고, 권장 판단까지 제시한 다음 "이거 맞아요?" 하나만 확인받는 구조를 택했어요. 열린 질문을 던지지 말라는 지침도 명시적으로 박아뒀습니다. 초보자가 판단 부담 없이 확인만 하면 되도록 만든 설계입니다.
인증 방식도 개인 PAT를 로컬의 gitignore된 파일(.identity.local.yml)에 두고, 팀 정보는 pm/roster.yml이라는 별도 명부에서 handle로 파생시키는 방식을 택했습니다. 개인 비밀 정보와 팀 공유 정보를 분리한 거죠.
라우팅 기준으로는 GitHub의 assignee 필드를 그대로 쓰고, 미션임을 구분하는 태그는 roadmap + 팀 라벨 조합으로 잡았습니다. 별도의 인프라 없이 GitHub 네이티브 기능만으로 미션 발주-수령 체계를 구현한 셈입니다.
배운 점 및 개선점
이 PR은 한 커밋으로 완성된 형태라 시행착오의 흔적은 드러나지 않지만, 스크립트 하나하나에 실패 케이스별 exit code와 안내 메시지를 세세하게 박아둔 걸 보면 미리 여러 실패 시나리오(PAT 만료, 스코프 부족, handle 불일치, 보드 접근 실패 등)를 염두에 두고 설계한 것으로 보입니다.
개인적으로 이 구조에서 인상 깊었던 건 "AI가 실행자, 사람은 검토·결정자"라는 역할 분리를 실제 코드 레벨(게이트 하드 스톱, PAT 비노출, 열린 질문 금지 등)로 강제했다는 점이에요. 철학을 문서로만 남기지 않고 스크립트의 exit code와 SKILL.md의 절차로 못 박아둔 게 이 PR의 핵심 가치인 것 같습니다.
다만 fine-grained 토큰의 경우 스코프 헤더가 비어 와서 project 권한 여부를 판정할 수 없다는 한계가 코드 주석에도 명시돼 있어요. 이 부분과, 보드의 Status 옵션 ID를 스크립트에 하드코딩해둔 부분은 보드 구조가 바뀌면 함께 고쳐야 한다는 점에서 앞으로 개선 여지가 있어 보입니다.