앞선 글에서 리뷰를 세 번 통과하고도 남은 버그를 적었다. 세 개의 PR은 diff만 보면 각각 자기 티켓 안에서 타당했지만, 변경이 적용되는 범위를 함께 놓고 보자 문제가 드러났다.
버그는 고쳤다. 하지만 수정하고 끝내면 다음 리뷰에서도 같은 방식으로 놓칠 수 있었다. 그래서 당시 문제를 찾는 데 사용한 판단 과정을 정리하고, 다음 작업에서 다시 실행할 수 있는 작은 리뷰 도구로 남겨보기로 했다.
버그를 고친 뒤 남은 질문
앞 글에 리뷰 질문 다섯 개를 적었다.
- 이 줄은 몇 군데에 적용되나
- 티켓의 범위와 diff의 실제 영향 범위가 같은가
- 이 조건의 이름이 맞나 —
isWebview인가isFullscreen인가 - 이 수정은 문제를 고치는가, 화면에서 가리기만 하는가
- 새 술어를 만들었다면 옛 소비처도 함께 확인했는가
이 질문들을 다음 리뷰에서 매번 떠올릴 수 있으면 같은 유형의 문제를 더 빨리 발견할 수 있다. 처음에는 다섯 개를 모두 자동으로 판정하고 싶었다. 그러나 실제로 대보니 기계가 답할 수 있는 것과 사람이 판단해야 하는 것이 섞여 있었다.
소비처 수는 코드에서 직접 셀 수 있다. 변경된 파일에서 export한 심볼을 몇 곳이 사용하는지,
공용 기본 스타일이나 전역 셀렉터처럼 소비처가 끌 수 없는 변경인지, CSS 변수 override나
!important, 전역 defaults 대입처럼 값을 덮는 코드가 있는지는 저장소 검색 규칙으로 일관되게
찾을 수 있다.
반면 티켓의 의도와 실제 영향 범위가 다른 것이 실수인지 의도인지는 코드만 보고 확정할 수 없다.
isWebview와 isFullscreen은 둘 다 유효한 boolean이고, 어느 조건이 맞는지는 제품이 실제로
어떻게 열리는지를 알아야 한다. 옛 소비처도 목록으로 찾을 수는 있지만, 새 술어로 옮겨야 하는지는
제품 계약을 알아야 판단할 수 있다.
그래서 스크립트는 소비처 수와 위험 신호를 찾고, 나머지는 리뷰어가 확인할 질문으로 남기도록 했다.
판정에 코드 밖의 계약이 필요하면 자동으로 결론 내리지 않는다. 신호를 찾고, 사람이 판단할 자리까지 안내한다.
도구가 하는 일은 리뷰어를 대신하는 것이 아니라, 리뷰어가 확인해야 할 자리로 데려가는 것이다.
판단 과정을 작은 도구로 옮겼다
도구의 흐름은 단순하다.
- 변경된 파일과 export한 심볼을 찾는다.
- 저장소 전체의 소비처와 변경 반경을 센다.
- 기본값·전역 스타일·override처럼 범위를 넓힐 수 있는 신호를 찾는다.
- 자동으로 결정할 수 없는 항목은 리뷰 질문으로 남긴다.
- 결과를 해당 PR에 기록한다.
처음 만든 형태에는 마지막 단계가 없었다. 대화창에 반경과 질문을 보여주고 끝났다. 그 자리에 있던 사람은 볼 수 있지만, 실제 리뷰를 맡은 사람이 다시 찾으려면 대화 기록을 거슬러 올라가야 했다.
이 도구를 팀에 넘길지 판단하는 과정에서 기준 하나에 걸렸다. 산출물이 다음 사람이 반드시 거치는 자리에 남는가. 불려본 적 없는 스킬들을 정리하며 얻은 기준인데, 대화창에서 끝나는 이 도구가 정확히 거기 걸렸다.
이번만 예외로 둘 수도 있었다. 대신 도구를 고쳤다. 결과를 채팅으로만 보고하지 않고 PR 코멘트로 남기는 단계를 붙였다.
# PR 본문을 덮어쓰지 않고 별도 코멘트로 남긴다.
gh pr comment <PR번호> --body-file /tmp/scope.md
그리고 도구의 규칙에도 한 줄을 추가했다.
반경을 채팅으로만 보고하고 끝내지 않는다. PR에 남기는 단계까지가 이 도구의 작업이다.
이 변경은 작지만 중요했다. 보고서를 만드는 데서 끝나지 않고, 다음 판단이 일어나는 곳까지 결과를 옮겨놓았기 때문이다. 거르려고 둔 기준이 오히려 도구를 고치게 만든 셈이다.
전달에는 팀이 이미 사용하던 플러그인 배포 경로를 그대로 활용했다. 마켓플레이스에 올려두면 팀이 같은 도구를 설치할 수 있어, 질문을 다음 리뷰까지 전달할 가장 가까운 수단이었다.
옮기는 과정에서 규칙도 고쳤다
옮길 때는 개인 환경에 묶인 절대 경로와 외부 스크립트 의존을 걷어냈다. 가져올 수 없는 참조는 조용히 지우지 않고, 묶음 밖에서 직접 진행해야 한다고 명시했다. 실행 환경이 달라져도 무엇까지 자동으로 처리되는지 알 수 있게 하기 위해서였다.
그리고 공유 묶음에 넣기 전 자체 점검을 돌리다가 기존 규칙 하나가 실패했다.
목록 파일은 추가만 되어야 한다. 삭제된 줄이 있으면 실패한다.
JSON을 통째로 다시 직렬화해 수백 줄이 바뀌는 사고를 막으려고 만든 규칙이었다. 그런데 기존 도구 묶음에 항목을 추가하려면 버전 번호도 올려야 했다.
"version": "0.1.0" → "0.2.0"
버전 한 줄이 지워지고 새 줄이 추가되자 점검이 실패했다. 규칙이 틀렸다기보다, 처음에는 없던 “기존 도구 묶음 갱신”이라는 사용 방식이 생긴 것이다.
호출하는 쪽에서 갱신 모드를 넘길 수도 있었지만, 삭제된 줄이 모두 version이면 통과하도록 판정을
정확하게 만드는 쪽을 택했다. 버전 외 다른 줄이 함께 삭제되면 여전히 실패하고, 문서 파일 삭제도
그대로 막힌다.
호출하는 쪽이 기억해야 할 인자를 늘리기보다, 검사 규칙이 실제 차이를 구분하게 한다.
도구를 옮기는 과정이 기존 안전장치가 고려하지 못한 사용 맥락까지 드러낸 셈이다.
아직 확인하지 못한 것은 그대로 적었다
함께 넣은 절차형 도구 하나는 실제 사례에서 순서를 뽑고 보조 스크립트도 검증했지만, 전체 흐름을 여러 작업에 걸쳐 실행해보지는 못했다. 결과를 자동 반영하지 않고 사람이 다시 확인하는 보조 절차였기 때문에 우선 포함하되, 실험 단계라는 표시를 분명하게 남겼다.
⚠️ 실험 단계입니다. 절차는 실제 사례 한 건에서 뽑았고 보조 스크립트는 그 건으로 검증했지만, 전체 흐름을 여러 건에 돌려본 적은 없습니다. 판정이 이상하면 그대로 따르지 말고 직접 확인해 주세요.
이 문구는 도구 설명과 본문 첫 줄, PR 본문에 함께 적었다. 목록에서 설명만 보는 사람, 도구를 열어 첫 부분만 보는 사람, 변경 자체를 검토하는 사람이 서로 다른 경로로 내용을 읽기 때문이다.
미검증 상태를 감추면 한 번의 잘못된 판정이 도구 묶음 전체의 신뢰를 떨어뜨린다. 반대로 먼저 밝히면 어긋난 사례를 피드백으로 받을 수 있다.
한 번의 수정 과정을 다음 작업으로 넘기기
이번에 만든 것은 대단한 자동화가 아니다. 한 번의 버그 수정에서 얻은 질문을 정리하고, 자동화할 부분과 사람이 판단할 부분을 나눈 작은 리뷰 도구다.
과정에서 남은 기준은 네 가지였다.
| 단계 | 남은 기준 |
|---|---|
| 버그를 다시 살펴볼 때 | 문제를 찾는 데 사용한 질문을 구체적으로 적는다 |
| 자동화할 때 | 코드 밖의 계약이 필요하면 신호만 찾고 판단은 남긴다 |
| 다른 사람에게 전할 때 | 결과를 다음 판단이 일어나는 작업 경로에 연결한다 |
| 검증이 부족할 때 | 감추지 않고 읽는 경로마다 밝힌다 |
도구는 저장소 구조가 바뀌면 손봐야 한다. 그런데 기준은 그보다 오래 남는다. 다음에 무엇을 자동화할지, 무엇을 공유할지, 검증이 모자란 것을 어떻게 내놓을지 정할 때 또 꺼내 쓰게 된다.
버그를 수정한 기록이 다음 리뷰의 질문이 되고, 그 질문이 실제 작업 흐름에 놓이면 같은 문제를 다시 만났을 때 처음부터 고민하지 않아도 된다.