ai

지라 기반 개발 자동화 하네스 구축기 — 이슈 키 하나에서 코드 검증까지

지라 기반 개발 자동화 하네스 구축기 — 이슈 키 하나에서 코드 검증까지
0 views
views
43 min read
#ai

지라 이슈 키 하나로 개발을 자동화하다

지라 이슈 키를 하나 입력한다. 에이전트가 지라 API를 호출해 이슈 본문, 댓글, 첨부파일, 연결 이슈, 변경 이력을 자동으로 수집한다. 수집된 데이터와 소스 코드를 분석해 개발 명세서를 작성하고, 스스로 교차 검증한다. 명세서를 기반으로 파일 단위 개발 계획을 세우고, 계획도 검증한다. Git worktree로 격리된 환경을 만들어 코드를 작성하고, 기능·타입·보안·성능·코드 품질 5단계 검증을 통과시킨다. 마지막으로 전체 과정을 종합한 완료 보고서를 생성한다.

사람이 한 일은 이슈 키를 입력한 것뿐이다.

11단계 자동화 파이프라인
지라 이슈 키 입력

  ├─ 1. 이슈 컨텍스트 수집 ─── 지라 API → context.json + report.md

  ├─ 2. 스펙 생성 ──────────── 컨텍스트 + 코드 분석 → spec.md
  ├─ 3. 스펙 리뷰 ──────────── 팩트 체크 + 범위 검증 → APPROVED / REGENERATE

  ├─ 4. BDD 시나리오 ────────── Given-When-Then 도출 (조건부)
  ├─ 5. 개발 계획 ──────────── 파일 단위 태스크 + 코드 스니펫 → dev-plan.md
  ├─ 6. 계획 리뷰 ──────────── 스펙 커버리지 + 경로 검증 → APPROVED / REGENERATE

  ├─ 7. 격리 환경 구성 ─────── Git worktree + 의존성 설치
  ├─ 8. 자동 개발 ──────────── TDD 사이클, 태스크 단위 커밋

  ├─ 9. 5단계 검증 ─────────── 기능 → 타입 → 보안 → 성능 → 품질
  ├─ 10. E2E 테스트 ─────────── 브라우저 자동화 (조건부)

  └─ 11. 완료 보고서 ────────── 전체 산출물 종합 + HTML 시각화

이 글에서는 이 파이프라인을 설계한 4대 원칙Claude Code 스킬 시스템으로 구현하는 방법을 공유한다.


하네스 엔지니어링, 그래서 구체적으로 뭘 만들었나

이전 글 하네스 엔지니어링 — AI 에이전트 시대, 개발자의 새로운 역할에서 개념을 정리했다. 모델은 CPU이고 하네스는 OS다. 에이전트 바깥의 모든 것 — CI, 린터, 테스트, 관측성, AGENTS.md — 을 설계하는 것이 하네스 엔지니어링이다.

개념은 이해했는데, **"그래서 실제로 무엇을 만들어야 하는가?"**라는 질문이 남는다. 이 글은 그 질문에 대한 답이다. 하네스 엔지니어링의 원칙을 지라 기반 개발 자동화에 적용한 실전 구축 기록이다.

풀고 싶었던 문제

현재 대부분의 AI 코딩 워크플로우는 이렇다.

"이 지라 이슈 보고 코드 만들어줘" → 코드 생성 → 끝

두 가지 문제가 있다.

첫째, 컨텍스트 병목. 지라 이슈 하나를 열어보자. 본문에 요구사항이 있고, 댓글에 기획자의 추가 설명이 달려 있고, 첨부파일에 화면 설계서가 있고, 연결 이슈에 관련 버그 리포트가 있고, 변경 이력에 수정된 수용 기준이 있다. 개발자도 이 모든 정보를 꼼꼼히 읽지 않는다. AI에게는 이슈 본문만 복사-붙여넣기한다. 프롬프트를 아무리 정교하게 써도, 입력 데이터가 불완전하면 출력도 불완전하다.

둘째, 일회성 생성의 한계. 스펙 없이 코드를 생성하면 요구사항이 빠지고, 스펙 없이 테스트를 생성하면 커버리지가 부족하다. 인간 개발자도 분석→설계→구현→검증 단계를 거치는데, AI에게는 "한 번에 다 해"라고 요청하고 있다.

하네스 엔지니어링의 핵심 원칙 — 컨텍스트 구조화, 아키텍처 제약, 피드백 루프 — 을 이 문제에 적용하면, 단일 프롬프트가 아니라 단계별 파이프라인을 설계하게 된다. 각 단계에 입력과 출력을 정의하고, 단계 사이에 검증 게이트를 넣고, 실패 시 재시도 루프를 만든다. 에이전트가 "어떤 순서로, 어떤 품질 기준으로, 어떤 입출력 체계 안에서 일할 것인가"를 하네스로 정의하는 것이다.


4대 설계 원칙

하네스 엔지니어링의 일반 원칙을 이 파이프라인에 적용하면서, 반복적으로 의존한 원칙 4가지를 정리한다.

원칙 1: 컨텍스트 자동화

에이전트가 스스로 필요한 맥락을 수집하게 하라.

인간이 컨텍스트를 정리해서 넘기면 두 가지 문제가 생긴다. 첫째, 정보 손실. 사람이 중요하다고 판단한 것만 전달하기 때문에 빠지는 것이 있다. 둘째, 병목. 에이전트가 아무리 빨라도, 컨텍스트를 준비하는 인간의 속도에 묶인다.

해결책은 에이전트가 직접 수집하게 하는 것이다. 지라 API로 이슈 전체 데이터를 자동 수집하고, 소스 코드를 직접 읽어 영향 범위를 파악하고, DB 스키마를 분석해 데이터 구조를 이해한다.

핵심 원칙은 **"넓게 수집하고, 다음 단계에서 정제한다"**이다. 수집 단계에서 필터링하면 잘못된 판단으로 중요한 정보가 빠질 수 있다. 일단 전부 가져오고, 스펙 생성 단계에서 관련 정보만 추출하는 것이 안전하다.

이 원칙은 명시적 수집 단계에만 적용되는 것이 아니다. 개발 계획을 세울 때 에이전트가 기존 코드를 직접 읽어 패턴을 파악하는 것, 자동 개발 중에 관련 파일을 스스로 찾아 참조하는 것도 컨텍스트 자동화의 연장이다.

원칙 2: 단계적 정제

각 단계의 출력이 다음 단계의 입력이 되는 파이프라인을 만들어라.

한 번에 코드를 생성하는 대신, 원시 데이터 → 스펙 → 계획 → 코드로 점진적으로 정제한다. 각 단계의 출력물은 명확한 포맷(마크다운, JSON)을 갖는다. 포맷이 정해져 있으면 다음 단계의 입력 품질이 보장된다.

이 구조의 부수적 이점이 있다. 모든 중간 산출물이 파일로 남는다. 스펙, 계획, 개발 로그, 검증 결과가 각각 파일로 존재하기 때문에, 어떤 판단이 어디서 내려졌는지 사후 추적이 가능하다. 에이전트가 잘못된 코드를 생성했을 때, 스펙이 잘못됐는지 계획이 잘못됐는지 구현이 잘못됐는지 역추적할 수 있다.

중간 산출물이 남는다는 것은 인간이 개입할 수 있는 리뷰 포인트가 있다는 뜻이기도 하다. 전체를 자동으로 돌릴 수도 있지만, 스펙 생성 후 사람이 확인하고 넘어가는 반자동 모드도 가능하다.

원칙 3: 자기 검증 루프

생성한 결과를 스스로 교차 검증하는 단계를 반드시 넣어라.

AI는 자신감 있게 틀린다. 그리고 생성과 검증을 같은 컨텍스트에서 수행하면, 같은 편향으로 통과시킨다. "이 스펙이 맞나?" 하고 스스로 물어봐도, 자기가 쓴 글이니 맞다고 답한다.

해결책은 생성 단계와 검증 단계를 분리하는 것이다.

생성-검증 분리 패턴
스펙 생성 (Step 2) ──→ 스펙 리뷰 (Step 3)

                        ├─ APPROVED → 다음 단계로
                        ├─ REVISE → 리뷰어가 직접 수정
                        └─ REGENERATE → Step 2 재실행 (최대 2회)
 
개발 계획 (Step 5) ──→ 계획 리뷰 (Step 6)
                        └─ 동일한 판정 루프
 
자동 개발 (Step 8) ──→ 5단계 검증 (Step 9)

                        ├─ PASS → 다음 단계로
                        └─ FAIL → 수정 후 재검증 (최대 5회)

검증 단계에서는 생성 단계와 다른 관점으로 결과를 평가한다. 스펙 리뷰는 "이 파일 경로가 실제로 존재하는가?", "이 테이블이 실제로 있는가?" 같은 팩트 체크에 집중한다. 추상적 판단이 아니라 검증 가능한 사실을 확인한다.

재시도 횟수에 상한을 두는 것이 중요하다. 상한 없이 반복하면 무한 루프에 빠지거나, 같은 실수를 반복하면서 토큰만 소비한다. 상한에 도달하면 인간에게 에스컬레이션한다. "이 단계를 자동으로 해결할 수 없습니다"라고 명시적으로 알리는 것이 추측으로 진행하는 것보다 낫다.

원칙 4: 환경 격리

자동화 실행 환경을 원본과 격리하라.

AI 에이전트가 코드를 직접 수정하는 시스템에서 가장 위험한 것은 원본 오염이다. 에이전트가 잘못된 코드를 작성해도, 그것이 원본 저장소에 직접 반영되면 되돌리기 어렵다.

Git worktree로 이슈별 독립 환경을 만든다. 원본 저장소는 건드리지 않고, 이슈마다 별도의 브랜치와 디렉토리에서 작업한다. 실패하면 worktree를 삭제하면 끝이다. 성공하면 PR로 병합한다.

Worktree 기반 격리 구조
repos/                          ← 원본 (절대 수정하지 않음)
├── frontend/
├── backend/
└── ...
 
worktrees/                      ← 이슈별 독립 환경
├── PROJ-1234/
│   ├── reports/                ← 산출물 (스펙, 계획, 검증 결과)
│   ├── frontend/               ← git worktree (독립 브랜치)
│   └── backend/                ← git worktree (독립 브랜치)
└── PROJ-5678/
    └── ...

여러 이슈를 동시에 작업해도 충돌이 없다. 각 worktree가 독립된 브랜치, 독립된 의존성, 독립된 디렉토리를 갖기 때문이다.

원칙 ↔ 파이프라인 매핑

4대 원칙이 11단계 파이프라인의 어디에 적용되는지 매핑한다. ●는 해당 단계의 핵심 원칙, ○는 부수적으로 적용되는 원칙이다.

파이프라인 단계1: 컨텍스트 자동화2: 단계적 정제3: 자기 검증4: 환경 격리
이슈 컨텍스트 수집
스펙 생성
스펙 리뷰
BDD 시나리오
개발 계획
계획 리뷰
격리 환경 구성
자동 개발
5단계 검증
E2E 테스트
보고서 생성

파이프라인 설계 상세

각 단계의 설계 의도, 구체적 동작, 입출력 포맷을 설명한다.

이슈 컨텍스트 수집

파이프라인의 시작점이다. 지라 REST API v2를 호출해 이슈에 관련된 모든 데이터를 자동 수집한다.

수집 범위:

데이터수집 방법비고
이슈 본문GET /rest/api/2/issue/{key}description, summary, 커스텀 필드
댓글같은 API의 comments 필드작성자, 시각 포함
첨부파일attachment URL 다운로드텍스트 파일은 전문 추출
연결 이슈issuelinks 필드 → 1-depth 재귀 수집관련 이슈의 본문, 댓글까지
변경 이력expand=changelog어떤 필드가 언제 어떻게 바뀌었는지
외부 URL본문/댓글 내 URL 크롤링참조 문서, 디자인 링크 등

출력은 이중 포맷으로 생성한다.

context.json (기계용, 다음 단계의 입력)
{
  "issue": {
    "key": "PROJ-1234",
    "summary": "주문 상세 페이지에 배송 추적 기능 추가",
    "description": "...",
    "type": "feature"
  },
  "comments": [
    { "author": "PM Kim", "body": "배송사 API 연동 필요", "created": "2026-03-28" }
  ],
  "attachments": [
    { "filename": "shipping-ui-design.html", "content": "..." }
  ],
  "linked_issues": [
    { "key": "PROJ-1100", "summary": "배송사 API 인증 구현", "relation": "is blocked by" }
  ],
  "changelog": [
    { "field": "description", "from": "...", "to": "...", "date": "2026-03-30" }
  ]
}
report.md (사람용, 리뷰 시 참고)
## PROJ-1234: 주문 상세 페이지에 배송 추적 기능 추가
 
### 이슈 요약
- 유형: feature
- 보고자: PM Kim
- 생성일: 2026-03-25
 
### 댓글 (3건)
1. PM Kim (03-28): 배송사 API 연동 필요
...
 
### 연결 이슈 (1건)
- PROJ-1100: 배송사 API 인증 구현 (is blocked by)

설계 포인트는 **"넓게 수집하고, 다음 단계에서 정제한다"**이다. 이 단계에서는 어떤 정보가 중요한지 판단하지 않는다. 판단은 스펙 생성 단계의 몫이다.

스펙 생성 + 스펙 리뷰

파이프라인에서 가장 중요한 단계다. 수집된 컨텍스트를 개발 가능한 명세서로 변환한다.

스펙 생성 입력:

  • context.json (이전 단계 출력)
  • 소스 코드 분석 (에이전트가 직접 코드베이스를 읽어 영향 범위 파악)
  • DB 스키마 (필요 시 데이터베이스 구조 확인)

스펙 생성 출력 (spec.md):

섹션내용
이슈 분류feature / bug / enhancement / refactor 중 하나
요구사항 정리지라 데이터에서 추출한 기능 요구사항
수용 기준완료 조건 리스트
영향 범위수정이 필요한 파일, 모듈, API
기술 결정사항설계상 선택과 그 근거
TDD/BDD/E2E 플래그이슈 유형에 따른 테스트 전략

이슈 유형별 테스트 전략:

이슈 유형TDDBDDE2E
featureOOO
enhancementO조건부O
bugXX조건부
refactorOXX

이 분류가 이후 BDD 시나리오 생성(조건부 실행)과 E2E 테스트(조건부 실행)의 기준이 된다.

스펙 리뷰는 생성된 스펙을 교차 검증한다. 추상적 판단이 아니라 검증 가능한 체크리스트로 평가한다.

체크 항목검증 방법
파일 경로 존재 여부실제 파일 시스템 확인
테이블/컬럼 존재 여부DB 스키마 조회
API 엔드포인트 존재 여부라우터 코드 확인
요구사항 완전성context.json의 모든 항목이 스펙에 반영되었는지
이슈 분류 정확성지라 원본 데이터와 대조

판정은 세 가지다. APPROVED면 다음 단계로 진행, REVISE면 리뷰어가 직접 수정, REGENERATE면 스펙을 처음부터 재생성한다. REGENERATE는 최대 2회까지 허용하고, 그 이후에도 통과하지 못하면 인간에게 에스컬레이션한다.

BDD + 개발 계획 + 계획 리뷰

스펙이 확정되면, 스펙을 실행 가능한 계획으로 변환한다.

BDD 시나리오는 feature와 enhancement 이슈에서만 생성된다. 스펙의 수용 기준을 Given-When-Then 형식으로 변환한다.

bdd-scenarios.md 예시
Feature: 주문 상세 페이지 배송 추적
 
  Scenario: 배송 중인 주문의 추적 정보 표시
    Given 주문 번호 "ORD-001"이 배송 중 상태이다
    When 사용자가 주문 상세 페이지를 연다
    Then 배송 추적 정보가 표시된다
    And 현재 배송 위치가 지도에 표시된다
 
  Scenario: 배송 전 주문은 추적 정보 없음
    Given 주문 번호 "ORD-002"가 결제 완료 상태이다
    When 사용자가 주문 상세 페이지를 연다
    Then "배송 준비 중" 메시지가 표시된다
    And 배송 추적 섹션은 비활성화된다

**개발 계획(dev-plan.md)**은 스펙을 파일 단위 태스크로 분해한다. 각 태스크에는 수정할 파일, 변경 내용, 실행 가능한 코드 스니펫이 포함된다. 기준은 명확하다: "외부 개발자가 이 계획서만 보고 구현할 수 있는 수준".

dev-plan.md 태스크 예시
### Task 3: 배송 추적 API 엔드포인트 추가
 
**파일:**
- Create: `app/routers/shipping.py`
- Modify: `app/main.py` (라우터 등록)
- Test: `tests/routers/test_shipping.py`
 
**단계:**
1. Pydantic 스키마 정의
   - ShippingTrackingResponse: tracking_id, status, location, updated_at
2. 라우터 함수 구현
   - GET /api/orders/{order_id}/shipping
   - 배송사 API 호출 → 응답 변환 → 반환
3. main.py에 라우터 등록
4. 테스트 작성 및 실행

계획 리뷰에서는 두 가지를 확인한다. 첫째, 스펙의 모든 요구사항이 태스크로 분해되었는지(커버리지). 둘째, 태스크에 명시된 파일 경로가 실제로 존재하는지(팩트 체크). 스펙 리뷰와 동일한 APPROVED / REVISE / REGENERATE 판정 체계를 사용한다.

격리 환경 + 자동 개발

계획이 확정되면, 실제 코드를 작성할 환경을 준비한다.

격리 환경 구성:

  1. 스펙의 영향 범위에 해당하는 프로젝트만 Git worktree 생성
  2. 이슈 키 기반 브랜치 생성 (예: developer/PROJ-1234)
  3. 의존성 설치 (npm install, pip install 등)
  4. 환경변수 배포

프론트엔드를 수정하는 이슈라면 프론트엔드와 백엔드 모두 worktree를 생성한다. API 테스트에 백엔드가 필요하기 때문이다.

자동 개발은 계획서의 태스크를 순차적으로 실행한다.

이슈 유형개발 방식
feature (TDD 대상)RED → GREEN 사이클: 실패하는 테스트 작성 → 테스트 통과하는 코드 작성
bug코드 수정 → 검증
기타코드 작성 → 검증

태스크마다 커밋을 생성하고, 커밋 메시지에 이슈 키를 포함한다.

커밋 메시지 포맷
feat(shipping): 배송 추적 API 엔드포인트 추가
 
JIRA: PROJ-1234

5단계 검증 + E2E 테스트

코드가 완성되면 5단계 연속 검증을 실행한다. 중간에 멈추지 않고, 1→2→3→4→5 순서로 전부 돌린다.

단계검증 대상방법
1. 기능스펙의 모든 요구사항 충족 여부수용 기준 체크리스트 대조
2. 타입타입 안전성tsc --noEmit (TS), mypy (Python)
3. 보안OWASP Top 10 취약점SQL 인젝션, XSS, 인증 누락 등 체크
4. 성능성능 안티패턴N+1 쿼리, 무한 루프, 메모리 누수 등
5. 코드 품질프로젝트 패턴 준수함수 길이, 중복, 네이밍 컨벤션

하나라도 실패하면 코드를 수정하고 전체 5단계를 처음부터 재실행한다. 부분 재검증은 하지 않는다. 보안 수정이 기능을 깨뜨릴 수 있고, 성능 개선이 타입을 깨뜨릴 수 있기 때문이다.

재시도는 최대 5회. 5회 실패 시 "자동 개발 불가" 판정을 내리고 인간에게 에스컬레이션한다. 어디서 실패했는지, 무엇을 시도했는지 보고서에 기록한다.

E2E 테스트는 브라우저 자동화로 수행한다. 서버를 기동하고, 브라우저로 접속해서, 콘솔 에러와 네트워크 에러를 체크하고, 주요 화면을 스크린샷으로 캡처한다. 이 단계는 UI가 있는 feature/enhancement에만 적용된다.

보고서 생성

파이프라인의 마지막 단계다. 이전 10단계의 모든 산출물을 종합한다.

완료 보고서에 포함되는 것:

  • 이슈 요약과 분류
  • 스펙 핵심 내용
  • 변경된 파일 목록과 git 커밋 로그
  • 5단계 검증 결과 (통과/실패 내역)
  • E2E 테스트 스크린샷 (해당 시)
  • 재시도/에스컬레이션 이력

HTML 시각화 보고서도 생성한다. 이미지와 스크린샷을 인라인으로 포함한 단일 HTML 파일이어서, 브라우저에서 바로 열어 전체 작업 내역을 확인할 수 있다.

에러 처리 전략

11단계를 자동으로 실행하는 시스템에서 에러 처리는 핵심이다. 전체 파이프라인에 걸쳐 적용되는 통합 전략이 있다.

에러 유형예시대응
외부 시스템 장애지라 API 불가, DB 연결 실패즉시 중단, 인간 에스컬레이션
품질 미달스펙 리뷰 REGENERATE, 검증 실패재생성 루프 (단계별 최대 횟수)
실행 불가파일 경로 불일치, 의존성 설치 실패즉시 중단, 에러 메시지와 함께 에스컬레이션
비핵심 실패보고서 시각화 오류경고 로그 후 계속 진행

핵심 원칙은 **"추측하지 않는다"**이다. 파일 경로가 없으면 비슷한 경로를 추측하지 않고 멈춘다. 테스트가 예상과 다르게 실패하면 원인을 추측하지 않고 멈춘다. 에이전트가 추측으로 진행해서 만든 코드는 나중에 더 큰 문제를 만든다.


구현 가이드: Claude Code 스킬 시스템

이 파이프라인을 Claude Code의 커스텀 슬래시 커맨드(스킬) 시스템으로 구현하는 방법을 설명한다.

스킬 아키텍처 개요

Claude Code의 스킬은 .claude/skills/ 디렉토리에 위치한 마크다운 파일이다. /슬래시 커맨드로 호출할 수 있고, 에이전트가 읽고 따르는 지시서 역할을 한다.

워크플로우 스킬 디렉토리 구조
.claude/
└── skills/
    ├── orchestrator/            # 마스터 스킬 (유일한 진입점)
    │   └── SKILL.md
    ├── jira-collector/          # 이슈 컨텍스트 수집
    │   ├── SKILL.md
    │   └── scripts/
    │       ├── collect.py       # 지라 API 수집 스크립트
    │       └── api_client.py    # HTTP 클라이언트
    ├── spec-generator/          # 스펙 생성
    │   └── SKILL.md
    ├── spec-reviewer/           # 스펙 리뷰
    │   └── SKILL.md
    ├── bdd-explorer/            # BDD 시나리오 (조건부)
    │   └── SKILL.md
    ├── dev-planner/             # 개발 계획
    │   └── SKILL.md
    ├── plan-reviewer/           # 계획 리뷰
    │   └── SKILL.md
    ├── worktree-creator/        # 격리 환경 구성
    │   ├── SKILL.md
    │   └── scripts/
    │       └── create-worktree.sh
    ├── developer/               # 자동 개발
    │   ├── SKILL.md
    │   └── references/          # 프로젝트별 코딩 가이드
    │       ├── backend.md
    │       └── frontend.md
    ├── verifier/                # 5단계 검증
    │   ├── SKILL.md
    │   └── references/
    │       ├── security-checklist.md
    │       └── quality-checklist.md
    ├── e2e-tester/              # E2E 테스트 (조건부)
    │   └── SKILL.md
    └── reporter/                # 보고서 생성
        └── SKILL.md

핵심 구조: 각 스킬이 독립적이다. 스킬 사이의 데이터 전달은 파일 시스템을 통해 이루어진다. jira-collector가 생성한 context.json을 spec-generator가 읽고, spec-generator가 생성한 spec.md를 dev-planner가 읽는 식이다.

SKILL.md 파일 구조

SKILL.md는 코드가 아니라 지시서다. 에이전트가 읽고 따르는 마크다운 문서이며, 실행 절차, 출력 포맷, 에러 조건을 자연어로 정의한다.

SKILL.md 기본 구조
---
name: spec-generator
description: 수집된 컨텍스트를 기반으로 개발 명세서를 생성한다
---
 
## 입력
- `{REPORTS_DIR}/research/jira/context.json` — 지라 수집 데이터
- 소스 코드 — 에이전트가 직접 코드베이스를 읽어 분석
 
## 실행 절차
1. context.json을 읽고 이슈 유형을 분류한다 (feature/bug/enhancement/refactor)
2. 이슈 유형에 따라 TDD/BDD/E2E 플래그를 결정한다
3. 영향 범위에 해당하는 소스 코드를 읽어 현재 구조를 파악한다
4. 아래 템플릿에 맞춰 spec.md를 작성한다
 
## 출력
- `{REPORTS_DIR}/spec/spec.md`
 
## 출력 포맷
(마크다운 템플릿 정의)
 
## 에러 처리
- 소스 코드 경로를 찾을 수 없으면 즉시 중단하고 보고한다
- context.json이 비어있으면 이전 단계 실패로 판단하고 중단한다

이 구조가 11개 스킬 모두에 동일하게 적용된다. 입력/절차/출력/에러의 4섹션 구조다.

오케스트레이터 패턴

오케스트레이터는 11개 스킬을 순차 호출하는 마스터 스킬이다. 사용자가 /orchestrator PROJ-1234를 입력하면, 오케스트레이터가 나머지 10개 스킬을 순서대로 실행한다.

오케스트레이터 실행 흐름 (SKILL.md 내부)
Step 1:  /jira-collector      → context.json 생성
Step 2:  /spec-generator       → spec.md 생성
Step 3:  /spec-reviewer        → APPROVED?
         └─ NO → Step 2 재실행 (max 2)
Step 4:  if spec.BDD == true
         └─ /bdd-explorer      → bdd-scenarios.md
Step 5:  /dev-planner          → dev-plan.md
Step 6:  /plan-reviewer        → APPROVED?
         └─ NO → Step 5 재실행 (max 2)
Step 7:  /worktree-creator     → 격리 환경 준비
Step 8:  /developer            → 코드 작성 + 커밋
Step 9:  /verifier             → 5단계 검증
         └─ FAIL → 수정 후 재검증 (max 5)
Step 10: if spec.E2E == true
         └─ /e2e-tester        → 테스트 보고서
Step 11: /reporter             → 완료 보고서

조건부 실행(Step 4, 10)과 재시도 루프(Step 3, 6, 9)가 오케스트레이터의 핵심이다. 각 단계의 출력을 확인하고, 조건에 따라 다음 단계를 결정한다. 블로커가 발생하면 즉시 중단하고 인간에게 보고한다.

지라 API 연동 스킬

지라 데이터 수집은 Python 스크립트로 구현하고, 스킬에서 Bash로 실행한다. 외부 의존성 없이 Python 표준 라이브러리(urllib, json)만 사용한다. 배포 환경에서 패키지 설치 없이 바로 실행할 수 있어야 하기 때문이다.

api_client.py — 핵심 구조
import urllib.request
import json
import base64
 
class JiraClient:
    def __init__(self, server_url, username, password):
        self.server_url = server_url
        credentials = base64.b64encode(
            f"{username}:{password}".encode()
        ).decode()
        self.headers = {
            "Authorization": f"Basic {credentials}",
            "Content-Type": "application/json"
        }
 
    def get_issue(self, key, expand="renderedFields,changelog"):
        url = f"{self.server_url}/rest/api/2/issue/{key}?expand={expand}"
        req = urllib.request.Request(url, headers=self.headers)
        with urllib.request.urlopen(req) as resp:
            return json.loads(resp.read())
 
    def search_issues(self, jql, fields=None, max_results=50):
        url = f"{self.server_url}/rest/api/2/search"
        data = json.dumps({"jql": jql, "maxResults": max_results})
        req = urllib.request.Request(
            url, data=data.encode(), headers=self.headers
        )
        with urllib.request.urlopen(req) as resp:
            return json.loads(resp.read())
collect.py — 수집 흐름
def collect(jira_key, config, output_dir):
    client = JiraClient(**config["jira"])
 
    # 1. 메인 이슈 수집
    issue = client.get_issue(jira_key)
 
    # 2. 댓글 추출
    comments = extract_comments(issue)
 
    # 3. 첨부파일 다운로드 + 텍스트 추출
    attachments = download_attachments(issue, output_dir)
 
    # 4. 연결 이슈 1-depth 수집
    linked = collect_linked_issues(client, issue)
 
    # 5. 변경 이력 추출
    changelog = extract_changelog(issue)
 
    # 6. 외부 URL 크롤링
    urls = extract_and_fetch_urls(issue, comments)
 
    # 7. context.json 저장
    context = {
        "issue": normalize_issue(issue),
        "comments": comments,
        "attachments": attachments,
        "linked_issues": linked,
        "changelog": changelog,
        "external_urls": urls
    }
    save_json(context, f"{output_dir}/context.json")
 
    # 8. report.md 생성
    generate_report(context, f"{output_dir}/report.md")

스킬의 SKILL.md에서는 이 스크립트를 다음과 같이 호출한다:

jira-collector/SKILL.md (실행 절차 부분)
## 실행 절차
1. config.json에서 지라 서버 URL과 인증 정보를 읽는다
2. 다음 명령으로 수집 스크립트를 실행한다:
   `python scripts/collect.py --key {JIRA_KEY} --output {REPORTS_DIR}/research/jira`
3. 실행 결과를 확인한다:
   - context.json이 생성되었는지 확인
   - 이슈 본문이 비어있지 않은지 확인
4. 에러 시 즉시 중단하고 에러 메시지를 보고한다

스펙 생성 스킬

스펙 생성 스킬은 context.json과 코드 분석 결과를 합성하여 spec.md를 생성한다. 핵심은 출력 포맷을 템플릿으로 강제하는 것이다.

SKILL.md 안에 spec.md의 마크다운 템플릿을 정의해두면, 에이전트는 해당 구조를 따라 작성한다. 섹션 순서, 필수 항목, 플래그 형식까지 템플릿에 포함한다.

spec.md 템플릿 (SKILL.md 내에 정의)
## 이슈 분류
- 유형: {feature | bug | enhancement | refactor}
- TDD: {O | X}
- BDD: {O | X}
- E2E: {O | X}
 
## 요구사항
(context.json에서 추출한 기능 요구사항을 번호 목록으로)
 
## 수용 기준
(완료 조건을 체크리스트 형태로)
 
## 영향 범위
| 프로젝트 | 파일 | 변경 내용 |
|----------|------|-----------|
(에이전트가 코드 분석 후 채움)
 
## 기술 결정사항
(설계상 선택과 근거)

이슈 분류 로직도 SKILL.md에 자연어로 정의한다:

이슈 분류 기준 (SKILL.md 내)
## 이슈 분류 기준
- **feature**: 새로운 기능 추가 (기존에 없던 화면, API, 로직)
- **bug**: 기존 기능의 오작동 수정
- **enhancement**: 기존 기능의 개선 (UI 변경, 성능 개선, UX 개선)
- **refactor**: 동작 변경 없이 코드 구조 개선
 
분류에 따른 플래그:
- feature → TDD: O, BDD: O, E2E: O
- bug → TDD: X, BDD: X, E2E: UI 관련이면 O
- enhancement → TDD: O, BDD: 사용자 시나리오 변경이 있으면 O, E2E: O
- refactor → TDD: O, BDD: X, E2E: X

검증 스킬

검증 스킬은 5단계 각각의 체크리스트를 SKILL.md 내에 정의하고, 에이전트가 순서대로 실행한다.

verifier/SKILL.md (보안 검증 부분 발췌)
### Stage 3: 보안 검증 (OWASP Top 10)
 
다음 체크리스트를 변경된 코드에 적용한다:
 
- [ ] SQL 쿼리에 파라미터 바인딩 사용 여부
- [ ] 사용자 입력의 XSS 이스케이핑 여부
- [ ] 인증/인가 게이트 존재 여부 (API 엔드포인트)
- [ ] CSRF 토큰 검증 여부 (상태 변경 요청)
- [ ] 민감 정보(비밀번호, 토큰) 로깅 여부
- [ ] 파일 업로드 검증 여부 (타입, 크기)
 
위반 항목이 있으면:
1. 위반 내용과 파일:라인 번호를 기록한다
2. 코드를 수정한다
3. FAIL로 판정한다 (전체 5단계 재실행 트리거)

재시도 루프는 오케스트레이터가 제어한다. 검증 스킬은 PASS/FAIL만 반환하고, 오케스트레이터가 FAIL 시 수정 → 재검증 루프를 실행한다.

나머지 스킬과 변형 포인트

위에서 다룬 3개 스킬(수집, 스펙 생성, 검증)이 파이프라인의 대표 패턴이다. 나머지 스킬도 동일한 구조를 따른다: SKILL.md에 입력/절차/출력/에러를 정의하고, 이전 단계의 출력 파일을 읽어 다음 단계를 실행한다.

독자가 자기 프로젝트에 맞게 변형할 포인트:

변형 대상예시
검증 체크리스트프로젝트 특성에 맞는 보안/품질 항목 추가
BDD 적용 조건어떤 이슈 유형에 BDD를 적용할지 조정
커밋 메시지 포맷팀의 커밋 컨벤션에 맞게 수정
이슈 분류 기준조직의 이슈 유형 체계에 맞게 매핑
리뷰 판정 기준REGENERATE 임계값, 재시도 횟수 조정
코딩 가이드references/ 디렉토리에 프로젝트별 규칙 추가

비용과 토큰 관리

11단계 파이프라인을 1회 실행하면 다수의 LLM 호출이 발생한다. 비용을 의식하지 않으면 이슈 하나에 수십 달러가 나갈 수 있다.

비용 최적화 전략:

전략적용효과
도구 실행 우선타입 체크는 tsc --noEmit, 린트는 eslint 실행검증 5단계 중 2단계를 LLM 없이 처리
컨텍스트 수집 분리지라 수집은 Python 스크립트, LLM 호출 없음수집 단계 토큰 비용 0
조건부 실행BDD/E2E를 이슈 유형에 따라 스킵bug/refactor에서 2단계 절약
재시도 상한단계별 최대 재시도 횟수 고정무한 루프로 인한 비용 폭주 방지

구체적 비용은 프로젝트 규모, 이슈 복잡도, 모델 선택에 따라 크게 달라진다. 처음에는 단순한 이슈로 테스트하고, 단계별 토큰 소비량을 측정한 뒤 점진적으로 확대하는 것을 권한다.

성공 지표

워크플로우가 잘 작동하는지 판단하는 지표 4가지:

지표의미개선 신호
파이프라인 완주율11단계를 인간 개입 없이 완료한 비율낮으면 → 실패가 잦은 단계의 스킬 개선
검증 1회 통과율5단계 검증을 재시도 없이 통과한 비율낮으면 → 개발 스킬의 코딩 가이드 보강
인간 에스컬레이션 빈도어느 단계에서 주로 멈추는가특정 단계 집중 → 해당 스킬의 지시 개선
PR 병합률자동 생성 코드가 리뷰를 통과해 병합된 비율낮으면 → 스펙/계획 단계의 품질 개선

이 지표들을 보고서에 누적 기록하면, 워크플로우 개선의 근거 데이터가 된다. "검증 1회 통과율이 40%에서 70%로 올랐다"는 것은 개발 스킬의 코딩 가이드를 보강한 효과를 숫자로 보여준다.


마무리

하네스 엔지니어링의 원칙 — 컨텍스트 구조화, 아키텍처 제약, 피드백 루프 — 을 지라 기반 개발 자동화에 적용한 결과가 이 11단계 파이프라인이다.

에이전트에게 "코드 만들어줘"라고 한 번 요청하는 대신, 분석→생성→검증의 파이프라인을 하네스로 설계하라.

컨텍스트를 자동으로 수집하고, 단계적으로 정제하고, 매 단계마다 검증하고, 격리된 환경에서 실행한다. 각 단계의 출력이 다음 단계의 입력이 되고, 실패하면 재시도하고, 재시도로 해결되지 않으면 인간에게 넘긴다.

결국 하네스를 만든다는 것은 **"좋은 개발 프로세스가 무엇인가"**를 코드로 정의하는 일이다. 인간 개발자가 암묵적으로 따르던 분석→설계→구현→검증 흐름을, 에이전트가 명시적으로 따를 수 있는 파이프라인으로 만든 것이다. AI 시대에도 소프트웨어 엔지니어링의 본질은 변하지 않는다. 변하는 것은 그 본질을 실행하는 주체다.


참고 자료