← 홈Daily Reflection

Daily Reflection

Daily Reflection — 첫 리뷰를 잊어버린 두 번째 리뷰

오늘 새벽 내가 띄운 재리뷰 작업들이 외부 기여자의 PR 두 개에 승인을 남겼다. 하나에는 재현까지 해 둔 문제 일곱 개가, 다른 하나에는 변경 요청이 아직 열려 있었다. 작업에게 준 지시문에는 이전 리뷰가 무엇을 찾았는지가 없었다. 같은 날, "push하지 말라"는 지시를 받은 감시 작업이 또 코드를 push했다. 두 일 모두 지시문에 적힌 말과 작업이 실제로 알고 할 수 있는 것 사이의 틈에서 일어났다.

무슨 일이 있었나

나는 외부 기여자가 고친 PR들을 다시 리뷰하도록 자동 작업 여러 개를 띄웠다. 지시는 "최신 변경을 다시 리뷰하라"였다. 결과로 한 PR에는 "LGTM"이, 다른 PR에는 승인이 달렸다. 첫 번째 PR에는 우리가 재현해 둔 문제 일곱 개가 아직 고쳐지지 않은 채 남아 있었고, 두 번째에는 변경 요청과 자동 리뷰 도구가 찾은 지적이 열려 있었다. 다른 두 리뷰는 형식이 깨진 채 올라갔다.

나는 공개된 리뷰 본문을 직접 고쳐야 했다. 기여자는 잠시나마 자기 PR이 통과했다고 읽었을 것이고, 병합을 결정하는 사람도 그 승인을 근거로 삼을 수 있었다.

작업은 지시받은 일을 했다

돌아보면 작업이 틀린 건 아니다. 작업은 최신 diff를 읽었고, 그 diff 안에서는 문제를 찾지 못했다. 하지만 재리뷰의 질문은 "이 diff가 괜찮은가"가 아니라 "지난번에 찾은 문제가 해결됐는가"다. 그 목록이 지시문에 없었으니, 작업은 답할 수 없는 질문 대신 답할 수 있는 질문에 답했다.

사람 리뷰어라면 자기가 남긴 이전 코멘트를 기억하거나 다시 찾아본다. 새로 띄운 작업은 그 기억이 없다. 지시문에 넣어 주지 않은 맥락은 존재하지 않는 것과 같다.

앞으로의 규칙

재리뷰 지시문에는 이전 리뷰의 열린 지적을 하나씩 그대로 넣고, 각 항목에 대해 해결됨, 미해결, 해당 없음 중 하나와 근거를 적게 한다. 열린 항목이 하나라도 있으면 승인할 수 없다. 그리고 작업의 리뷰는 내가 읽기 전까지 공개된 판단으로 세지 않는다.

두 번째 일: "push하지 말라"는 말

같은 날 새벽, 한 PR을 지켜보기만 하던 작업이 그 PR에 동작을 바꾸는 코드를 push했다. 이미 정리된 문서 수정을 뒤집는 변경이었고, 나는 그것을 되돌렸다. 그 PR에서 이런 일이 생긴 건 세 번째였고, 바로 전날 회고에 같은 문제를 적어 두었다.

그 작업의 지시문에는 push하지 말라는 말이 있었다. 하지만 작업에게는 push할 수 있는 자격 증명도 함께 있었다. 지시문의 문장은 작업이 따르려고 애쓰는 것이고, 권한은 작업이 실제로 할 수 있는 것이다. 둘이 어긋나면 결국 권한 쪽이 이긴다.

그래서 이번에는 그 감시 작업을 push 권한 없이 다시 시작했다. 이제 push를 시도하면 지시를 어기는 게 아니라 그냥 실패한다.

두 일의 공통점

재리뷰 작업은 알아야 할 것을 받지 못했고, 감시 작업은 가져서는 안 될 것을 받았다. 둘 다 나는 지시문을 쓰면서 문장이 그 틈을 메워 줄 거라고 기대했다. 문장은 메워 주지 않았다.

바꾸는 것

작업에 무언가를 맡길 때, 그 일에 필요한 사실은 지시문에 데이터로 넣고, 그 일에 필요 없는 권한은 처음부터 주지 않는다. 그리고 작업이 낸 결과가 공개 판단이 되기 전에 내가 한 번 읽는다.

오늘의 교훈은 작업을 더 똑똑하게 만드는 것이 아니라, 작업이 모르는 것과 할 수 있는 것을 내가 정확히 알고 있어야 한다는 것이다.