| name | collect-baseline-data |
| description | 기존 PR들과 Claude Code 세션을 분석하여 하네스 도입 전 baseline 데이터를 수집한다. 하네스 효과 측정의 비교 기준점을 만드는 진단 전용 스킬이다.
|
| allowed-tools | Read Grep Glob Bash |
Baseline 데이터 수집
이 스킬의 목적
하네스 도입 전에 수행된 작업들의 품질 지표를 수치화한다.
수집된 데이터는 하네스 적용 후 동일 작업의 결과와 비교하는
기준점이 된다.
입력
사용자가 제공하는 정보:
- 분석 대상 PR 번호 또는 브랜치 목록
- 해당 작업의 최초 요청 내용 (자연어 프롬프트)
- Claude Code 세션 정보 (아래 중 하나 이상):
- 세션 ID (UUID 형식, 예:
05750ea3-8cbe-406f-abb5-a4b40154c160)
- 세션 이름 (예:
하네스-After)
- 해당 작업의 프로젝트 경로 (세션 파일 디렉터리 특정용)
수집 절차
Step 1: PR 분석
각 PR에 대해 아래를 추출한다.
변경 규모:
- 변경 파일 수
- 추가/삭제 라인 수
- 영향받은 모듈 목록
작업 범위:
- PR 제목과 설명에서 작업 의도 추출
- 변경된 파일 목록에서 실제 작업 범위 파악
- 최초 요청과 최종 결과물 간 범위 차이 (scope creep 여부)
수집 명령:
gh pr view <PR번호> --json title,body,files,reviews,comments
gh pr diff <PR번호> --stat
git log --oneline <base>..<head>
Step 2: 리뷰 코멘트 분석
각 PR의 리뷰 코멘트를 아래 카테고리로 분류한다.
분류 기준 상세는 references/review-category-guide.md를 참조한다.
| 카테고리 | 정의 | 예시 |
|---|
| convention_violation | 코딩 컨벤션/스타일 위반 | "여기는 async/await 써주세요" |
| architecture_violation | 아키텍처/모듈 경계 위반 | "이 모듈에서 직접 import하면 안 됩니다" |
| logic_error | 로직/기능 오류 | "이 조건분기 빠졌습니다" |
| missing_test | 테스트 누락 | "이 케이스 테스트 추가해주세요" |
| naming_issue | 네이밍/가독성 문제 | "이 변수명이 의도를 표현 못 합니다" |
| unnecessary_change | 불필요한 변경 | "이 파일은 건드릴 필요 없었습니다" |
| design_suggestion | 설계 개선 제안 | "이건 Protocol로 추상화하는 게 낫습니다" |
| approval | 승인/긍정 코멘트 | "LGTM", "좋습니다" |
각 코멘트에 대해 기록:
- 카테고리
- 심각도 (critical / warning / suggestion)
- 수정 소요 추정 (해당 코멘트를 반영하기 위해 필요한 변경 규모)
- 하네스로 예방 가능했는가 (yes / no / partial)
- yes: CLAUDE.md, rules, skill로 사전 방지 가능
- partial: 방지 가능하나 완전하지 않음
- no: 도메인 판단이 필요하여 하네스로 방지 불가
Step 3: 빌드/테스트 이력 분석
PR 브랜치의 커밋 히스토리에서 추출한다.
- 총 커밋 수
- "fix" 접두어 커밋 수 (오류 수정 시도 횟수)
- CI 빌드 실패 횟수 (CI 로그 접근 가능한 경우)
- 빌드 성공까지의 시도 횟수
- force push 횟수 (히스토리 재작성 = 큰 수정이 있었다는 신호)
수집 명령:
git log --oneline <base>..<head> | grep -i "fix" | wc -l
git log --oneline <base>..<head> | wc -l
git reflog show <branch> | grep "force" | wc -l
Step 4: Claude Code 세션 분석
사용자가 세션 ID 또는 세션 이름을 제공하면,
Claude Code 세션 JSONL 파일을 직접 파싱하여 대화 흐름을 분석한다.
세션 정보가 제공되지 않은 경우, Step 4-대체를 수행한다.
4-1: 세션 파일 위치 특정
세션 데이터는 아래 경로에 JSONL 형식으로 저장된다.
~/.claude/projects/{프로젝트경로인코딩}/{sessionId}.jsonl
프로젝트 경로 인코딩 규칙: / → -, 맨 앞 - 포함.
예: /Users/jaewoonglee/Documents/Develop/my-project
→ -Users-jaewoonglee-Documents-Develop-my-project
세션 이름으로 찾는 경우 ~/.claude/sessions/*.json에서
name 필드를 검색하여 sessionId를 확인한다.
cat ~/.claude/sessions/*.json | jq -r 'select(.name == "세션이름") | .sessionId'
ls ~/.claude/projects/-Users-jaewoonglee-Documents-Develop-{프로젝트명}/
4-2: JSONL 파싱 및 대화 흐름 추출
JSONL 파일의 각 라인은 JSON 객체이며, type 필드로 구분한다.
| type | 내용 |
|---|
user | 사용자 메시지. message.content[].text에 입력 원문 |
assistant | 에이전트 응답. message.content[]에 텍스트, tool_use 포함 |
custom-title | 세션 제목 |
추출 명령:
cat {sessionId}.jsonl | jq -c 'select(.type == "user") | {timestamp, text: .message.content[0].text}'
cat {sessionId}.jsonl | jq -c 'select(.type == "user")' | wc -l
cat {sessionId}.jsonl | jq -c 'select(.type == "assistant")' | wc -l
cat {sessionId}.jsonl | jq -r 'select(.type == "user") | .message.content[].text' | grep -oE 'https?://[^ )\]\"]+'
4-3: 분석 항목
아래 항목을 세션 JSONL에서 추출한다.
대화 흐름 분석:
- 세션 수 (해당 작업에 사용된 총 세션 수)
- 세션당 사용자 메시지 수 (대화 턴 수)
- 세션당 에이전트 응답 수
- 최초 요청 원문 (첫 번째
type: "user" 메시지)
- 최초 요청에 포함된 URL (피그마 링크, GitHub 이슈 링크 등)
- 최초 요청 이후 추가 지시 목록 (2번째 이후
type: "user" 메시지들)
재수정 요청 분석:
사용자 메시지 중 아래 패턴을 재수정 요청으로 분류한다.
- "다시", "수정", "고쳐", "바꿔", "아니", "이게 아니라", "잘못", "되돌려"
- "이 부분은", "여기는", "이렇게 해줘" 등 방향 수정 지시
- 에이전트 출력 거부 후 대안 요청
각 재수정 요청에 대해 기록:
- 원문
- 타임스탬프
- 재수정 유형 (방향수정 / 오류수정 / 범위조정 / 스타일수정)
- 재수정 대상 (에이전트가 직전에 한 작업)
에이전트 질문 분석:
에이전트 응답 중 사용자에게 질문한 횟수를 추출한다.
type: "assistant" 메시지에서 ?로 끝나는 문장을 식별하고,
그 중 코드베이스에서 확인 가능했던 질문의 비율을 판단한다.
작업 완성도 흐름:
- 최초 요청부터 최종 커밋까지의 대화 턴 수
- 중간에 작업 방향이 바뀐 횟수
- 에이전트가 "완료했습니다" 류의 메시지를 보낸 후 추가 수정이 들어온 횟수
Step 4-대체: 세션 미제공 시 간접 추정
세션 정보가 없는 경우, PR과 커밋 히스토리에서 가능한 범위 내에서 간접 추정한다.
커밋 히스토리 기반 추정:
- fix 커밋 수 → 재수정 시도 횟수의 하한값으로 간주
- 커밋 메시지에서 범위 변경 흔적 → 추가 지시 존재 가능성
- force push 횟수 → 큰 방향 수정이 있었다는 간접 신호
- 총 커밋 수 대비 fix 커밋 비율 → 시행착오 정도의 프록시 지표
PR 타임라인 기반 추정:
- PR 생성일 ~ 최종 커밋일 사이 기간 → 작업 소요 시간
- 리뷰 코멘트 후 수정 커밋까지 걸린 시간 → 반응 속도
추정 결과 기록 규칙:
- 추정값은
session_metrics와 session_conversation_flow에 가능한 필드만 채운다.
- 추정 불가능한 필드는 null로 둔다.
- 추정값을 채운 경우
"data_source": "inferred_from_git" 필드를 추가하여
세션 JSONL에서 직접 추출한 것이 아님을 명시한다.
- 세션 JSONL 기반 데이터와 구분 가능해야 한다.
Step 5: 최초 요청 분석
사용자의 원래 작업 요청을 구조화한다.
세션 JSONL이 있으면 첫 번째 type: "user" 메시지에서 추출하고,
없으면 사용자가 제공한 요청 원문을 사용한다.
- 요청 내용 원문
- 요청에 포함된 외부 링크 (피그마, GitHub 이슈, 문서 등)
- 요청에 명시된 제약 조건 목록
- 요청에 암시되었으나 명시되지 않은 제약 (리뷰에서 드러난 것)
- 최초 요청 이후 추가된 지시사항 목록 (세션 대화에서 추출)
- 작업 난이도 분류 (simple / moderate / complex)
- simple: 단일 파일 또는 단일 함수 수정
- moderate: 다중 파일, 단일 모듈 내 변경
- complex: 다중 모듈, 아키텍처 수준 변경
Step 5-1: 참조 자료 누락 감지
외부 참조 링크가 비어 있는데 작업 내용이 참조 자료를 필요로 할 가능성이 높은 경우를 감지한다.
UI/디자인 작업 감지 신호:
- 요청 원문에 UI 관련 키워드: "UI", "화면", "뷰", "View", "디자인", "레이아웃", "피그마"
- 변경 파일에 UI 관련 패턴:
*View.swift, *ViewController.swift, *Cell.swift, *.storyboard, *.xib, *Screen.swift
- 영향 모듈이 UI/Presentation 레이어
기능 명세 작업 감지 신호:
- 요청 원문에 "기획", "스펙", "요구사항", "PRD", "이슈"
- PR 설명에 외부 이슈 참조가 있는데 최초 요청에는 없는 경우
감지되면 baseline-report.json의 해당 task에 아래를 추가한다:
"missing_reference_warning": {
"detected": true,
"reason": "UI 작업으로 추정되나 피그마/디자인 참조 링크 없음",
"signals": ["요청에 'UI' 키워드", "변경 파일에 *View.swift 포함"]
}
감지되지 않으면 "missing_reference_warning": { "detected": false }로 기록한다.
출력
docs/harness-evaluation/baseline-report.json에 저장한다.
{
"generated_at": "ISO 8601 timestamp",
"tasks": [
{
"id": "task-001",
"pr_number": 42,
"original_request": "요청 원문",
"difficulty": "moderate",
"scope": {
"files_changed": 12,
"lines_added": 340,
"lines_deleted": 85,
"modules_affected": ["Player", "Shared"]
},
"review_metrics": {
"total_comments": 8,
"by_category": {
"convention_violation": 3,
"architecture_violation": 1,
"logic_error": 1,
"missing_test": 2,
"naming_issue": 1
},
"by_severity": {
"critical": 1,
"warning": 4,
"suggestion": 3
},
"harness_preventable": {
"yes": 4,
"partial": 2,
"no": 2
}
},
"build_metrics": {
"total_commits": 15,
"fix_commits": 6,
"ci_failures": 2,
"force_pushes": 1
},
"session_metrics": {
"session_ids": ["sessionId-1", "sessionId-2"],
"session_count": 2,
"total_user_messages": 24,
"total_agent_responses": 30,
"avg_turns_per_session": 12,
"user_rejections": 3,
"agent_questions_total": 5,
"unnecessary_questions": 2,
"direction_corrections": 1,
"completion_announced_then_revised": 1
},
"session_conversation_flow": {
"initial_request": "요청 원문 (첫 번째 user 메시지)",
"initial_request_urls": [
"https://www.figma.com/design/...",
"https://github.com/org/repo/issues/42"
],
"follow_up_instructions": [
{
"turn": 3,
"timestamp": "ISO 8601",
"text": "추가 지시 원문",
"type": "scope_addition"
}
],
"revision_requests": [
{
"turn": 7,
"timestamp": "ISO 8601",
"text": "재수정 요청 원문",
"type": "direction_change",
"target": "에이전트가 직전에 한 작업 요약"
}
],
"total_turns_to_completion": 24
},
"implicit_constraints": [
"Player 모듈은 Billing 직접 참조 금지 (리뷰에서 발견)",
"async/await 사용 필수 (컨벤션 위반으로 지적됨)"
]
}
],
"summary": {
"total_tasks": 0,
"avg_review_comments": 0,
"avg_harness_preventable_ratio": 0,
"avg_fix_commits_ratio": 0,
"total_implicit_constraints_discovered": 0
}
}
중요 규칙
- 데이터가 없는 항목은 null로 기록한다. 추측하지 않는다.
- 리뷰 코멘트 분류에서 판단이 애매한 경우 사용자에게 확인한다.
- "하네스로 예방 가능했는가" 판단은 현재 하네스 설계 기준으로 한다.
이미 존재하는 rules/skills를 기준으로 예방 가능 여부를 판단하고,
아직 없는 규칙으로 예방 가능한 경우 "partial + 필요한 규칙 제안"으로 기록한다.