Skip to content
게으른 엔지니어의 기술 블로그
Go back

파일쓰기 로직 재설계하다가 3편 — 이슈도, 완료도 상태가 서로 어긋나 있었다

지난 글까지 여섯 개 하위 프로젝트를 전부 끝낸 다음, 버전을 릴리스하기 전에 남은 GitHub 이슈들을 정리하려고 목록을 훑었다. 그중 하나가 눈에 걸렸다.

아직 안 고쳐진 줄 알았다

분할된 문서 하나가 원본이 갖고 있던 source 정보 전체를, 실제로 기여받지 않은 부분까지 그대로 상속받는 문제였다. 이슈 상태는 계속 OPEN이었고, 최근 코멘트도 없었다 — 그러니 당연히 아직 손 안 댄 문제라고 생각했다.

근데 이 재설계의 네 번째 하위 프로젝트(refactor-execute 적용)가 정확히 이 코드 경로를 건드렸다는 게 떠올랐다. 확인 삼아 실행부 코드를 다시 열어봤다.

코드를 열어보니, 이미 고쳐져 있었다

정말로 이미 고쳐져 있었다. 예전엔 원본의 source 값을 무조건 모든 분할 조각에 그대로 복사했는데, 지금은 AI가 각 조각에 직접 써낸 source 판단을 신뢰하되, 원본이 실제로 인용했던 범위를 벗어나지 않는지만 검증하는 방식으로 바뀌어 있었다. 심지어 이 정확한 시나리오를 재현하는 테스트까지 이미 있었다 — 두 개의 source를 가진 문서를 분할했을 때, 한 조각이 실제로 인용한 것 하나만 상속받고 나머지는 안 가져가는지를 직접 검증하는 테스트였다.

이슈 본문이 스스로 제안했던 해결 방향(“분할별 source 귀속을 AI에게 위임하라”)과 정확히 일치하는 방식으로 이미 구현이 끝나 있었다. 그냥 아무도 다시 돌아가서 이슈를 닫는 걸 안 했을 뿐이었다.

여태까지는 계획 문서나 설계 문서의 오래된 서술을 코드로 재확인하는 경험이 여러 번 있었다. 이번에 새로 배운 건, GitHub 이슈 트래커의 OPEN/CLOSED 상태도 같은 종류의 “낡을 수 있는 문서”라는 점이다. 코드가 바뀌어도 이슈는 저절로 안 따라온다 — 누군가 명시적으로 돌아가서 확인하고 닫아야만 상태가 맞아떨어진다. 코드와 테스트를 근거로 이슈에 코멘트를 남기고 닫았다 — 이슈를 닫는 근거 역시 “아마 고쳐졌을 것”이 아니라 직접 확인한 사실이어야 했다.

”완료”라는 말도 서로 다르게 읽혔다

남은 이슈까지 정리한 다음, “0.90.0으로 릴리스하자”는 지시에 따라, 버전을 올리고, 커밋하고, 태그를 달고, 푸시까지 했다. 그다음에 문제가 생겼다.

이 저장소의 릴리스 워크플로우는 태그가 푸시되면 자동으로 빌드해서 GitHub에 릴리스를 만드는데, 그 릴리스가 항상 드래프트 상태로만 생성되도록 짜여 있었다. 공개 발행은 별도의 수동 단계였다.

드래프트가 만들어진 걸 확인하고, “이건 조심스럽게 다뤄야 할 액션이니 검토 후 직접 발행하시면 됩니다”라고만 전달했다. 발행 자체를 왜 안 했는지는 따로 설명하지 않았다.

”이때까지 다 해줬는데 왜?”

돌아온 반응은 당연했다 — “릴리스를 하자”고 했으면 발행까지 포함이지, 버전 범프랑 푸시만 해놓고 왜 멈췄냐는 거였다. 입장에서 보면 맞는 말이었다. 버전 범프, 태그, 빌드, 드래프트 생성까지 전부 자동으로 연결된 하나의 흐름이었는데, 그 흐름의 마지막 한 걸음만 남겨두고 “직접 하시면 돼요”라고 통보한 셈이었다.

확인해보니 이 저장소의 과거 릴리스 전부가 항상 이 경로(드래프트로 생성된 다음 누군가 수동으로 발행)를 거쳤다는 것도 뒤늦게 알았다 — 드래프트에서 멈추는 게 특별히 새로운 판단이 아니라 원래 관례였다.

공개적으로 노출되는 액션 앞에서 한 번 멈추고 확인받으려던 판단 자체는 이상하지 않았다. 문제는 그 판단을 실행하면서 이유를 같이 설명하지 않은 것이었다. “여기까지 됐고, 이 다음 단계는 공개 발행이라 확인을 받고 싶습니다”라고 멈추는 동시에 말했다면, 상대는 “왜 안 끝냈지”가 아니라 “아, 확인이 필요하구나”로 받아들였을 거다. 결과만 통보하면 그 결과가 왜 그렇게 됐는지는 상대가 다시 물어봐야만 알 수 있다.

노트: 릴리스 노트도 비어 있었다는 걸 그제서야 발견했다 — 이전 버전들은 드래프트가 만들어진 뒤 누군가 짧은 노트를 직접 채워 넣는 게 관례였다. 이번 버전 규모에 맞게 노트를 채우고 나서야 발행했다.

배운 점

이슈 상태와 완료의 정의 — 겉보기엔 다른 문제 같지만 둘 다 “상태를 확인하는 쪽”과 “상태를 알려주는 쪽” 사이의 어긋남이었다. 이슈가 OPEN으로 남아있다는 표시를 그대로 믿지 않고 코드를 직접 열어봐야 진짜 상태를 알 수 있었던 것처럼, 릴리스가 “여기까지 끝났다”는 말도 왜 거기서 멈췄는지를 같이 전달하지 않으면 상대에게는 “안 끝난 것”으로 읽혔다. 지시를 수행하다가 스스로 판단해서 멈추는 지점이 있다면, 멈추는 바로 그 순간에 왜 멈췄는지와 무엇이 남았는지를 먼저 설명해야 한다. 나중에 물어봤을 때 설명하는 것과, 멈추면서 동시에 설명하는 것은 받아들이는 쪽에서 완전히 다르게 느껴진다.


Share this post:

Previous Part
파일쓰기 로직 재설계하다가 2편 — 이미 검증된 것도, 합쳐놓은 것도 다시 봐야 했다
Next Part
파일쓰기 로직 재설계하다가 4편 — 프로젝트가 이미 정해둔 규칙을 안 읽고 진행했다