두 축 리뷰: HEAD와 사용자가 제공한 고정 지점 간의 차이점
- 표준(Standards): 코드가 이 저장소의 문서화된 코딩 표준을 따르는가?
- 명세(Spec): 코드가 원래의 이슈/명세를 충실히 구현하는가?
두 축은 병렬 서브 에이전트로 실행되어 서로의 컨텍스트를 오염시키지 않으며, 이후 이 스킬이 결과를 종합합니다.
이슈 트래커가 제공되어 있어야 합니다. 그렇지 않다면 사용자에게 /setup-matt-pocock-skills를 실행하라고 알리세요.
프로세스
1. 고정 지점 설정
사용자가 말한 고정 지점(커밋 SHA, 브랜치 이름, 태그, main, HEAD~5 등)을 그대로 사용합니다. 지정하지 않았다면 요청하세요.
diff 명령어를 한 번 캡처합니다: git diff <fixed-point>...HEAD (세 점 표기법으로, merge-base와 비교). 또한 git log <fixed-point>..HEAD --oneline을 통해 커밋 목록을 기록합니다.
더 진행하기 전에, 고정 지점이 해석 가능한지(git rev-parse <fixed-point>) 확인하고 diff가 비어 있지 않은지 확인하세요. 잘못된 참조나 빈 diff는 여기서 실패해야 하며, 두 병렬 서브 에이전트 안에서 실패하면 안 됩니다.
2. 명세 소스 식별
다음 우선순위로 원래 명세를 찾습니다:
- 커밋 메시지의 이슈 참조(
#123,Closes #45, GitLab!67등) - 트래커 문서의 워크플로를 통해 가져옴. - 사용자가 인수로 전달한 경로.
- 브랜치 이름이나 기능과 일치하는
docs/,specs/, 또는.scratch/아래의 명세 파일. - 아무것도 찾을 수 없으면 사용자에게 명세 위치를 물어보세요. 만약 명세가 없다고 하면, 명세 서브 에이전트는 건너뛰고 "명세 없음"으로 보고합니다.
3. 표준 소스 식별
저장소에서 코드 작성 방식을 문서화한 모든 파일을 검색합니다. CODING_STANDARDS.md 또는 CONTRIBUTING.md가 있으면 반드시 목록에 포함되어야 합니다.
저장소가 문서화한 내용 외에도, 표준 축은 항상 아래 냄새 기준선(baseline) 을 포함합니다. 이는 저장소에 문서화된 내용이 없더라도 적용되는 고정된 Fowler 코드 냄새 세트입니다(Refactoring, 3장). 두 가지 규칙이 적용됩니다:
- 저장소가 우선합니다. 문서화된 저장소 표준이 항상 우선하며, 기준선이 플래그를 지정할 내용을 저장소 표준이 승인하면 해당 냄새를 억제합니다.
- 항상 판단의 영역입니다. 각 냄새는 명확한 위반이 아니라 레이블이 붙은 휴리스틱("가능한 Feature Envy")입니다. 여기의 다른 표준과 마찬가지로, 도구가 이미 강제하는 사항은 건너뜁니다.
각 냄새는 그것이 무엇인가 → 어떻게 수정하는가 로 구성되며, diff와 비교합니다:
- Mysterious Name: 함수, 변수, 또는 타입의 이름이 그것이 무엇을 하는지 또는 담고 있는지 드러내지 않습니다. → 이름을 바꾸세요. 정직한 이름이 떠오르지 않으면 설계가 모호한 것입니다.
- Duplicated Code: 변경 내의 여러 헝크 또는 파일에서 동일한 로직 형태가 나타납니다. → 공유된 형태를 추출하고 양쪽에서 호출하세요.
- Feature Envy: 메서드가 자신의 데이터보다 다른 객체의 데이터를 더 많이 사용합니다. → 메서드를 그것이 탐내는 데이터가 있는 객체로 이동하세요.
- Data Clumps: 동일한 몇 개의 필드나 매개변수가 계속 함께 다닙니다(탄생을 기다리는 타입). → 하나의 타입으로 묶고 그것을 전달하세요.
- Primitive Obsession: 원시 타입이나 문자열이 고유한 타입을 가져야 할 도메인 개념을 대신하고 있습니다. → 개념에 고유한 작은 타입을 부여하세요.
- Repeated Switches: 동일한 타입에 대한 동일한
switch/if-계단식이 변경 전체에 걸쳐 반복됩니다. → 다형성으로 대체하거나, 두 사이트가 공유하는 하나의 맵을 사용하세요. - Shotgun Surgery: 하나의 논리적 변경이 diff의 여러 파일에 분산된 수정을 강제합니다. → 함께 변경되는 것들을 하나의 모듈로 모으세요.
- Divergent Change: 하나의 파일이나 모듈이 여러 관련 없는 이유로 편집됩니다. → 각 모듈이 하나의 이유로만 변경되도록 분할하세요.
- Speculative Generality: 명세에 필요하지 않은 추상화, 매개변수, 또는 훅이 추가되었습니다. → 삭제하세요. 실제 필요가 나타날 때까지 인라인 처리하세요.
- Message Chains: 호출자가 의존해서는 안 되는 긴
a.b().c().d()탐색. → 첫 번째 객체의 하나의 메서드 뒤에 탐색을 숨기세요. - Middle Man: 주로 위임만 하는 클래스나 함수. → 잘라내고 실제 대상을 직접 호출하세요.
- Refused Bequest: 상속받은 것의 대부분을 무시하거나 재정의하는 서브클래스나 구현체. → 상속을 버리고 컴포지션을 사용하세요.
4. 두 서브 에이전트를 병렬로 실행
두 서브 에이전트 호출을 함께 포그라운드에서 실행하고, 그들이 반환한 보고서를 종합합니다.
표준 서브 에이전트 프롬프트는 다음을 포함해야 합니다:
- 전체 diff 명령어와 커밋 목록.
- 3단계에서 찾은 표준-소스 파일 목록, 더불어 3단계의 냄새 기준선 전문을 붙여넣기(서브 에이전트는 다른 접근 권한이 없음).
- 브리프: "파일/헝크별로 관련 있는 경우 (a) diff가 문서화된 표준을 위반하는 모든 위치를 보고하세요: 표준(파일 + 규칙)을 인용하고; (b) 발견한 기준선 냄새를 이름을 지정하고 헝크를 인용하세요. 명백한 위반과 판단 호출을 구분하세요: 문서화된 표준 위반은 명백할 수 있지만, 기준선 냄새는 항상 판단 호출이며, 문서화된 저장소 표준은 기준선을 재정의합니다. 도구가 강제하는 것은 건너뛰세요. 400단어 미만."
명세 서브 에이전트 프롬프트는 다음을 포함해야 합니다:
- diff 명령어와 커밋 목록.
- 명세의 경로 또는 가져온 내용.
- 브리프: "보고하세요: (a) 명세가 요청했지만 누락되었거나 부분적으로만 구현된 요구 사항; (b) diff에서 요청되지 않은 동작(범위 확장); (c) 구현된 것처럼 보이지만 구현이 잘못된 것처럼 보이는 요구 사항. 각 발견 사항에 대해 명세 줄을 인용하세요. 400단어 미만."
명세가 없으면 명세 서브 에이전트를 건너뛰고 최종 보고서에 이를 명시하세요.
5. 종합
두 보고서를 ## 표준(Standards) 및 ## 명세(Spec) 제목 아래에 원문 그대로 또는 가볍게 정리하여 제시하세요. 발견 사항을 병합하거나 재순위화하지 마세요. 두 축은 의도적으로 분리되어 있기 때문입니다(두 축의 이유 참조).
각 축의 총 발견 사항 수와 각 축 내의 최악의 문제(있는 경우)를 한 줄 요약으로 마무리하세요. 축 간에 단일 승자를 선택하지 마세요. 그것이 분리 목적을 무효화하는 재순위화입니다.
두 축의 이유
변경 사항은 한 축은 통과하고 다른 축은 실패할 수 있습니다:
- 모든 표준을 따르지만 잘못된 것을 구현하는 코드 → 표준 통과, 명세 실패.
- 이슈가 요청한 대로 정확히 수행하지만 프로젝트의 규칙을 위반하는 코드 → 명세 통과, 표준 실패.
별도로 보고하면 한 축이 다른 축을 가리는 것을 방지할 수 있습니다.