Showing Posts From

코드

테스트 코드 작성: 해야 하는데 시간이 없어

테스트 코드 작성: 해야 하는데 시간이 없어

테스트 코드, 또 미뤘다 오늘도 PR 올렸다. 테스트 코드 없이. 리뷰어가 물어볼 거다. "테스트는요?" 그럼 나는 답한다. "다음 스프린트에 추가하겠습니다." 이게 벌써 세 번째다. 다음 스프린트는 안 온다. 우리 모두 알고 있다. 아침 스탠드업에서 PM이 말했다. "이번 주 배포 일정 타이트합니다." 타이트하다는 건 야근한다는 뜻이다. 테스트 코드 쓸 시간은 당연히 없다는 뜻이다. 모니터를 보며 펜을 돌린다. 막 짠 코드가 화면에 있다. 200줄짜리 서비스 로직. 분기 처리가 5개. 예외 케이스가 3개. 테스트 짜려면 최소 10개는 필요하다. 시계를 본다. 오후 4시. 퇴근까지 2시간. 코드 리뷰 반영하고, 문서 업데이트하고, 내일 회의 자료 준비해야 한다. 테스트는 무리다.악순환의 시작 테스트 없는 코드는 빠르다. 짜는 동안만. 이번 주에 3개 기능 만들었다. 테스트 코드 없이. 다음 주에 버그 리포트 5개 받았다. 엣지 케이스였다. 내가 놓친 분기들. 버그 수정하는 데 하루 반 걸렸다. 테스트 짰으면 2시간이면 찾았을 버그다. 근데 수정할 때도 테스트 안 짰다. 시간이 없어서. 후배가 물어봤다. "형, 이 함수 어떻게 동작하는 거예요?" 내가 3달 전에 짠 코드다. 주석도 없다. 테스트도 없다. 나도 기억 안 난다. 코드를 다시 읽었다. 10분 걸렸다. 테스트 코드가 있었으면 3분이면 이해했을 것이다. 테스트는 문서다. 살아있는 문서. 레거시 코드가 쌓인다. 테스트 없는 코드가 레거시가 되는 건 빠르다. 6개월이면 충분하다. 리팩토링 회의에서 팀장이 말했다. "이 부분 개선이 필요한데요." 나는 고개를 저었다. "건드리면 어디가 터질지 모릅니다." 테스트가 없어서. 결국 안 건드린다. 기술 부채가 쌓인다. 이자는 복리다.시간이라는 핑계 "시간 없어서 테스트 못 짰다"는 거짓말이다. 나한테 하는. 진짜는 이거다. 테스트 짜는 게 귀찮다. 당장 눈에 보이는 결과가 없다. 기획자는 테스트 코드 커버리지에 관심 없다. PM은 기능이 돌아가는지만 본다. 테스트는 미래를 위한 투자다. 근데 나는 오늘이 바쁘다. 내일도 바쁠 거다. 투자할 여유가 없다. 이게 7년째 반복이다. 신입 때는 달랐다. TDD 책도 샀다. JUnit 강의도 들었다. 첫 회사에서 테스트 커버리지 80% 채웠다. 그땐 시간이 있어서가 아니다. 배우고 싶어서였다. 지금은 다르다. 연차가 쌓이면서 핑계만 늘었다. "레거시라 테스트 짜기 힘들어요." "의존성이 너무 많아요." "모킹하기 복잡해요." 다 맞는 말이다. 근데 변명이다. 진짜 이유는 이거다. 테스트 없이도 어떻게든 돌아간다. 버그 나면 그때 고친다. 장애 나면 야근한다. 이게 익숙하다. 편한 길이다. 당장은.돌고 도는 이야기 목요일 저녁. 슬랙에 메시지가 떴다. "결제 API 오류 났어요." 심장이 뛴다. 내가 화요일에 수정한 부분이다. 테스트 없이 배포했다. 프로덕션 로그를 연다. NullPointerException. 예상 못 한 케이스였다. 테스트 짰으면 잡았을 거다. 핫픽스 시작. 코드 고치는 건 10분. 검증하는 데 1시간. 배포하고 모니터링하느라 2시간. 퇴근은 10시. 집에 가는 지하철에서 생각했다. "다음엔 테스트 꼭 짜야지." 이게 몇 번째 다짐인지 모르겠다. 금요일 아침. 새 기능 티켓이 떨어졌다. 월요일까지 완료. 타이트하다. 테스트 짤 시간은 또 없다. 악순환이다. 회사는 테스트를 강제하지 않는다. 커버리지 목표도 없다. PR에 테스트 없어도 머지된다. "바쁘니까 다음에"가 통한다. 처음엔 편했다. 이제는 무섭다. 내가 짠 코드가 시한폭탄처럼 느껴진다. 언제 터질지 모른다. 터지면 내가 고쳐야 한다. 주말에도 전화 온다. 변명들의 목록 "레거시라 테스트 짜기 힘들어요." 맞다. 의존성 주입 안 된 코드. 싱글톤 지옥. static 메서드 천지. 테스트하기 어렵게 설계됐다. 근데 새 코드는? 내가 어제 짠 코드도 테스트하기 어렵다. 내가 그렇게 짰다. 습관이다. "모킹하기 너무 복잡해요." 외부 API 6개 호출하는 함수. 데이터베이스 4개 테이블 조인. 레디스 캐시 체크. 모킹할 게 너무 많다. 근데 이건 테스트의 문제가 아니다. 설계의 문제다. 함수가 너무 많은 일을 한다. 책임이 분리 안 됐다. 테스트가 어려운 코드는 나쁜 코드다. 이건 학교에서 배웠다. 실무에선 잊었다. "시간 대비 효율이 안 나와요." 코드 짜는 데 1시간. 테스트 짜는 데 30분. 50% 오버헤드다. 비효율적으로 보인다. 근데 나중에 버그 고치는 시간은? 어제 핫픽스에 3시간 썼다. 테스트 있었으면 버그 자체가 없었다. 장기적으로 보면 테스트가 더 빠르다. 근데 나는 단기밖에 못 본다. 다음 주 배포만 보인다. "우리 팀은 빠른 개발이 중요해요." 스타트업 마인드. 일단 만들고 본다. 시장 검증이 먼저다. 테스트는 나중에. 근데 나중은 안 온다. 기능이 쌓인다. 유저가 늘어난다. 버그가 폭발한다. 그때는 더 못 짠다. 더 바쁘니까. 빠르게 가려면 제대로 가야 한다. 이것도 학교에서 배웠다. 실무에선 반대로 한다. 테스트 짜는 사람들 팀에 한 명 있다. 테스트 빡빡하게 짜는 후배. PR 올리면 테스트가 같이 온다. 유닛 테스트. 통합 테스트. 엣지 케이스까지. 코드보다 테스트가 더 길다. 처음엔 답답했다. "왜 이렇게 오래 걸려?" 3일이면 끝날 걸 5일 걸린다. 근데 그 코드는 안 터진다. 버그 리포트에 그 후배 이름이 없다. 리팩토링도 빠르다. 테스트가 보호하니까. 나는 빨리 짠다. 3일이면 끝낸다. 그리고 다음 주에 2일 동안 버그 고친다. 결국 5일이다. 야근 포함하면 더 길다. 누가 더 빠른 걸까. 오픈소스 코드를 볼 때가 있다. 유명한 라이브러리들. 테스트 커버리지 90% 넘는다. 그래서 믿고 쓴다. 내 코드는 어떨까. 커버리지 15%. 나도 내 코드 못 믿는다. 수정할 때마다 떨린다. 어디가 터질지 몰라서. 테스트는 자신감이다. 없으면 항상 불안하다. 시작하지 못하는 이유 테스트를 시작하기 어려운 건 맞다. 지금 프로젝트는 테스트가 없다. 시작하려면 환경부터 세팅해야 한다. JUnit 5? Mockito? AssertJ? 뭘 쓸지부터 정해야 한다. 기존 코드는 테스트하기 어렵게 짜여 있다. 리팩토링부터 해야 한다. 그러면 기능 개발은 언제 하나. 완벽하게 하려면 못 한다. 이게 함정이다. 테스트는 0 아니면 100이 아니다. 50도 괜찮다. 30도 없는 것보단 낫다. 어제 짠 핵심 로직 하나만 테스트 짜도 된다. 버그 나기 쉬운 부분만. 전체 커버리지 90% 목표 안 세워도 된다. 근데 나는 완벽주의자다. 시작하면 제대로 하고 싶다. 그래서 시작을 안 한다. 완벽한 테스트를 기다리다가 아무 테스트도 못 짠다. 이게 7년째다. 시간의 역설 테스트 짤 시간이 없어서 테스트를 안 짠다. 그래서 버그가 난다. 버그 고치느라 시간이 더 없어진다. 그래서 테스트를 더 못 짠다. 역설이다. 시간을 아끼려고 테스트를 건너뛴다. 결국 더 많은 시간을 쓴다. 이걸 알면서도 반복한다. 이번 달 야근 시간을 계산했다. 40시간. 대부분 버그 수정과 핫픽스였다. 테스트가 있었다면? 10시간이면 충분했을 것이다. 30시간을 아낄 수 있었다. 그 시간이면 테스트 100개는 짰다. 근데 다음 달도 똑같을 것이다. 테스트 짤 시간이 없어서. "바빠서 테스트 못 짠다"는 말은 틀렸다. "테스트 안 짜서 바쁜" 게 맞다. 원인과 결과가 뒤집혔다. 이걸 깨닫는 데 7년 걸렸다. 바꾸는 데는 얼마나 걸릴까. 작은 시작 오늘 결심했다. 하나만 짜보기로. 새 기능 티켓을 받았다. 쿠폰 발급 API. 간단해 보인다. 근데 분기가 많다. 중복 발급 체크. 기간 검증. 재고 확인. 유저 등급별 차등 지급. 예전 같으면 그냥 짰다. 포스트맨으로 몇 번 찔러보고 PR 올렸을 것이다. 오늘은 다르게 해봤다. 함수 하나 짜고, 테스트 하나 짰다. 정상 케이스. 통과했다. 다음 분기 추가하고, 테스트 추가했다. 중복 발급 시도. 예외 발생 확인. 통과했다. 이렇게 하나씩. 30분 더 걸렸다. 근데 확신이 생겼다. 이 코드는 안 터진다. 리팩토링도 해봤다. 함수 이름 바꾸고, 파라미터 순서 바꿨다. 테스트가 깨졌다. 고쳤다. 다시 통과했다. 테스트가 없었으면 못 했을 리팩토링이다. 어디가 망가질지 몰라서. PR 올렸다. 테스트 코드가 같이 올라갔다. 처음이다. 리뷰어가 댓글 달았다. "오 테스트 있네요. 좋습니다." 기분이 묘했다. 이게 당연한 건데. 변화는 느리다 일주일에 하나씩 짜기로 했다. 새 기능 하나. 리팩토링 하나. 버그 수정 하나. 뭐든 하나만. 완벽하지 않다. 커버리지는 여전히 낮다. 레거시는 그대로다. 근데 조금씩 늘고 있다. 한 달 뒤. 테스트 30개가 생겼다. 작은 숫자다. 근데 없는 것보다 훨씬 낫다. 버그가 줄었다. 체감된다. 이번 달 핫픽스가 2개였다. 저번 달은 5개였다. 리팩토링도 조금씩 한다. 테스트가 있는 부분만. 조심스럽지만 할 수 있다. 후배가 물어봤다. "형, 갑자기 왜 테스트 짜요?" 뭐라 답해야 할까. "이제야 정신 차렸어" 이렇게 말했다. 변화는 극적이지 않다. 어느 날 갑자기 좋아지지 않는다. 조금씩, 천천히. 근데 방향은 맞다. 처음으로 맞는 방향으로 가는 기분이다. 여전히 바쁘다 테스트 짜기 시작했지만 여전히 시간은 없다. 어제도 야근했다. 기획 변경으로 코드 다 갈아엎었다. 테스트도 같이 갈아엎었다. 시간 두 배 걸렸다. 짜증 났다. "테스트 없었으면 진작 끝났을 텐데." 이런 생각도 들었다. 근데 배포는 안심하고 했다. 터지진 않을 거다. 테스트가 통과했으니까. 다음 날 아침. 슬랙 알림 없었다. 버그 리포트 없었다. 조용한 아침이다. 이게 얼마 만인지. 시간은 여전히 부족하다. 근데 쓰는 방식이 달라졌다. 예전엔 빨리 짜고, 나중에 고치느라 시간 썼다. 지금은 천천히 짜고, 나중이 편하다. 같은 시간인데 결과가 다르다. 불안한 빠름보다 확실한 느림이 낫다. 후회와 다짐 7년을 돌아본다. 처음부터 테스트 짰으면 어땠을까. 지금쯤 시니어답게 코드 짰을 것이다. 레거시 만들지 않았을 것이다. 근데 후회해도 소용없다. 과거는 못 바꾼다. 바꿀 수 있는 건 오늘뿐이다. 오늘 하나 짰다. 내일도 하나 짤 거다. 이게 계획의 전부다. 완벽한 계획은 없다. 거창한 목표도 없다. 그냥 하나씩. 테스트는 시간이 없어서 못 짜는 게 아니다. 안 짜는 거다. 선택의 문제다. 나는 이제 다르게 선택한다. 느리지만 확실하게. 불안하지 않게.테스트는 사치가 아니라 기본이다. 이제야 안다.

코드 리뷰에서 '이건 안 됩니다'라고 말하기의 어려움

코드 리뷰에서 '이건 안 됩니다'라고 말하기의 어려움

코드 리뷰에서 '이건 안 됩니다'라고 말하기의 어려움 시작은 슬랙 알림 아침 10시. 슬랙 알림이 울렸다. "김 개발님, PR 올렸습니다~ 확인 부탁드려요!" 이모티콘까지 붙어있다. 귀엽다. 하지만 나는 안다. 저 PR을 열면 내 30분이 사라진다는 걸. 커피 한 모금 마시고 깃허브를 켰다.파일 하나에 500줄 첫 줄부터 한숨이 나왔다. public class UserService { // 500줄의 메서드들... }500줄이 한 파일에 있다. 메서드 하나가 100줄이다. if문이 5단 중첩이다. 작동은 한다. 테스트도 통과한다. 효율적이기까지 하다. 하지만 읽을 수가 없다. 나는 스크롤을 내리며 생각했다. "이거 어떻게 말하지?" 후배는 2년차다. 나름 열심히 한다. 야근도 마다 않는다. 근데 코드가 이렇다. 직책이 있으면 쉽다. "팀장 지시사항입니다" 하면 끝이다. 근데 나는 그냥 선임이다. 사실상 테크 리드인데 직책이 없다. 연봉도 별로 안 높다. "이건 안 됩니다" 라고 말할 권한이 애매하다. 댓글 창 앞에서 10분 커서가 댓글 입력창에서 깜빡인다. 뭐라고 쓸까. "이 코드는 가독성이 떨어집니다" - 너무 딱딱하다. "메서드를 좀 더 나눠주시면..." - 너무 약하다. "이렇게 하면 나중에 유지보수가..." - 잔소리 같다. 결국 이렇게 썼다. "수고하셨습니다. 몇 가지 제안 드립니다." 제안. 안전한 단어다. 명령이 아니다. 거절 가능하다.그리고 댓글을 달기 시작했다. "이 메서드가 100줄이 넘어서 한눈에 파악하기 어려울 것 같습니다. 책임별로 나눠보면 어떨까요?" "if 중첩이 깊어서 읽기 어렵습니다. Early return 패턴을 고려해보시면..." "변수명이 a, b, c로 되어있어서 의도를 파악하기 어렵습니다." 댓글 7개를 달았다. 20분이 걸렸다. 말투를 신경 썼다. "하세요" 대신 "하면 어떨까요". "틀렸습니다" 대신 "어려울 것 같습니다". 제출 버튼을 누르기 전에 다시 읽었다. 기분 나쁘게 들리지 않나. 너무 약하게 들리지 않나. 5분 더 고민했다. 그리고 제출을 눌렀다. 30분 뒤의 답장 "아 그렇군요! 그럼 이렇게 수정하면 될까요?" 답장이 빨랐다. 기분 나쁘지 않은 것 같다. 다행이다. 근데 수정본을 보니 별로 안 바뀌었다. 메서드 이름만 바꿨다. 구조는 그대로다. 여전히 100줄이다. "음... 제가 말씀드린 건 구조를 나누는 거였는데요." 이렇게 쓰려다 지웠다. 너무 직접적이다. "좋습니다! 다만 메서드 길이도 함께 조정하면 더 좋을 것 같아요." 또 제안이다. 명령이 아니다. "아 네! 그럼 어떻게 나누는 게 좋을까요?" 질문이 왔다. 이제 내가 예시를 보여줘야 한다.브랜치를 따서 직접 수정했다. 30분이 걸렸다. 500줄을 5개 클래스로 나눴다. 메서드는 20줄 이내로 줄였다. 변수명을 의미 있게 바꿨다. "이런 식으로 나누면 각 클래스의 책임이 명확해집니다." 커밋을 푸시하고 링크를 보냈다. "오 이해했습니다! 감사합니다!" 이모티콘 3개가 붙었다. 1시간이 지났다. 내 일은 못 했다. 직책 없는 테크 리드의 딜레마 팀장이 있긴 하다. 근데 팀장은 코드를 안 본다. 관리만 한다. 회의만 한다. 실제 기술 결정은 내가 한다. 아키텍처도 내가 짠다. 코드 리뷰도 내가 한다. 근데 직책은 없다. 명함에 "선임 연구원"이라고 적혀있다. 연구는 안 하는데. 월급은 6500이다. 동기들은 7천 넘게 받는다고 한다. "직책 주면 안 되냐"고 팀장한테 물었다. "위에서 아직 승인이 안 났어요. 조금만 기다리세요." 1년째 기다리는 중이다. 직책이 없으니까 말하기가 애매하다. "이건 안 됩니다"라고 딱 잘라 말할 수 없다. 권한이 없다. 그래서 항상 "제안"한다. "부탁"한다. "의견"을 낸다. 피곤하다. 점심시간의 고민 점심은 김치찌개집에 갔다. 사장님이 이름을 안다. "개발님 오셨어요~" 단골이다. 주 3회는 온다. 김치찌개를 먹으면서 생각했다. '내가 너무 약하게 말하나?' '아니면 적당한 건가?' '다른 회사 시니어들은 어떻게 하지?' 스택오버플로우에 비슷한 질문이 있었다. "How to give code review feedback without sounding harsh?" 답변들을 읽었다."Be specific and objective" "Focus on the code, not the person" "Suggest alternatives instead of just criticizing"다 알고 있다. 근데 한국 회사에서는 다르다. 위계가 있다. 눈치가 있다. 분위기가 있다. "이 코드는 SOLID 원칙을 위반합니다"라고 말하면 학술 논문이다. "형, 이거 좀 이상한 것 같은데요"라고 말해야 먹힌다. 근데 나는 형도 아니고 팀장도 아니다. 그냥 선임이다. 밥을 다 먹고 사무실로 돌아왔다. 슬랙에 알림이 7개다. 오후 3시, 두 번째 PR 또 알림이 왔다. "김 개발님, PR 수정했습니다!" 열어봤다. 여전히 별로다. 클래스를 나누긴 했는데 책임 분리가 안 됐다. 그냥 줄 수만 줄였다. 또 댓글을 달아야 한다. 커서가 깜빡인다. 뭐라고 쓸까. "이건 여전히 개선이 필요할 것 같습니다" - 너무 애매하다. "제가 보여드린 예시와 조금 다른 것 같아요" - 비교하는 것 같다. "다시 한 번 수정 부탁드립니다" - 짜증난 것 같다. 5분 고민했다. 그리고 이렇게 썼다. "방향은 좋습니다! 다만 클래스 간 의존성을 조금 더 정리하면 좋을 것 같아요. 각 클래스가 하나의 책임만 가지도록 해보시겠어요?" 또 제안이다. 칭찬 먼저 하고 제안한다. 샌드위치 피드백이다. 좋은 말 - 개선점 - 좋은 말. 근데 빵이 너무 얇다. 속이 뻔히 보인다. 회의 중에도 생각남 4시에 주간 회의가 있다. 기획자가 발표한다. "이번 기능은 간단합니다." 간단하다는 말이 나오면 복잡한 거다. 팀장이 묻는다. "개발 기간 얼마나 걸릴까요?" 나를 본다. "2주 정도 필요할 것 같습니다." "1주면 안 될까요?" "백엔드 구조를 새로 짜야 해서..." "기존 코드 활용하면 되지 않나요?" 기존 코드가 엉망이라서 못 쓴다. 리팩토링 필요하다. 근데 말할 수 없다. "기존 코드가 엉망입니다"라고 하면 누구 책임이냐고 물어본다. 내 책임이다. 내가 리뷰했으니까. "...최대한 단축해보겠습니다." 회의가 끝나고 자리로 돌아왔다. 슬랙에 또 알림이다. "김 개발님, 이해가 잘 안 가서요. 잠깐 설명 부탁드려요." 일어나서 후배 자리로 갔다. 설명하는 20분 "여기 이 부분이요." 후배가 화면을 가리킨다. "이걸 왜 나눠야 하는지 모르겠어요." 내가 작성한 예시 코드를 보고 있다. "지금은 UserService가 너무 많은 일을 하잖아." "네." "사용자 조회, 생성, 수정, 삭제, 권한 체크, 알림 발송까지." "네." "나중에 알림 로직만 바꾸고 싶으면?" "...UserService를 수정하면 되는데요?" "그럼 사용자 조회 기능도 영향받을 수 있어." "아..." "그래서 책임을 나누는 거야. 알림은 NotificationService로." "아 그렇구나!" 이해했다는 표정이다. 20분이 걸렸다. PR 댓글로는 5분이면 쓸 내용이다. 근데 직접 설명하면 20분이다. 자리로 돌아왔다. 시간을 봤다. 5시다. 오늘 내 코드는 한 줄도 못 썼다. 퇴근길 지하철에서 6시에 퇴근했다. 지하철에 앉아서 폰을 봤다. 유튜브에 추천 영상이 떴다. "시니어 개발자가 코드 리뷰하는 법" 봤다. 외국 개발자가 나온다. 영어로 말한다. "Be direct but kind." "Explain why, not just what." "It's about the code, not the coder." 다 맞는 말이다. 근데 저 사람은 직책이 있을 거다. Senior Engineer라고 명함에 적혀있을 거다. 나는 선임 연구원이다. 연구 안 하는. 댓글을 봤다. "우리 팀장은 그냥 '이거 왜 이렇게 짰어?' 하고 끝남 ㅋㅋ" "권한 없으면 말 안 먹힘. 그냥 포기." 공감이 됐다. 집에 와서 7시에 집에 도착했다. 아내가 야근이다. 라면을 끓였다. 신라면에 계란 1개. 먹으면서 슬랙을 봤다. 습관이다. "김 개발님 감사합니다! 이해했어요!" 후배가 메시지를 보냈다. 기분이 좋았다. 잠깐. 그리고 다음 메시지가 왔다. "그런데 이 부분은 원래대로 해도 될까요? 지금 방식이 더 익숙해서요." 한숨이 나왔다. 익숙하다는 건 핑계다. 바꾸기 귀찮다는 소리다. 댓글을 쓰려다 멈췄다. '또 설득해야 하나?' '그냥 놔둘까?' '나중에 문제 생기면 내가 고치면 되지.' 근데 그게 계속 쌓인다. 레거시가 된다. 결국 이렇게 답했다. "일단 현재 방식으로 머지하시고, 다음 스프린트 때 리팩토링 태스크로 잡읍시다." 타협이다. 읽음 표시가 떴다. 답은 없다. 아마 다음 스프린트 때도 우선순위 밀린다. 밤 10시, 침대에서 넷플릭스를 틀었다. 근데 집중이 안 된다. '내가 너무 약하게 말하나?' '직책이 있으면 다를까?' '다른 회사로 이직하면 나아질까?' 생각만 했다. 이직하려면 코테 준비해야 한다. 알고리즘 공부해야 한다. 피곤하다. 주말에 하자. 주말은 늦잠 자고 치킨 먹는 날이다. 폰을 내려놨다. 잠이 안 온다. 슬랙 알림이 또 울릴까봐 무음으로 해뒀다. 근데 자꾸 폰을 본다. 습관이다. 알림은 없다. 다행이다. 아내가 11시에 들어왔다. "오늘 어땠어?" "그냥 그랬어. 너는?" "디자인 수정 요청 5번 받았어." "힘들었네." "너도?" "응." 더 말하지 않았다. 둘 다 피곤하다. 다음날 아침 9시에 출근했다. 커피를 뽑았다. 아이스 아메리카노. 자리에 앉아서 슬랙을 켰다. 알림 3개다. 첫 번째: "김 개발님, 새 PR 올렸습니다~" 두 번째: "급한데 리뷰 부탁드려요!" 세 번째: "이번엔 잘한 것 같아요 ㅎㅎ" 깃허브를 켰다. 또 500줄이다. 커피를 한 모금 마셨다. 댓글 입력창을 열었다. 커서가 깜빡인다. "수고하셨습니다. 몇 가지 제안 드립니다." 오늘도 제안한다. 명령이 아니다. 직책이 생길 때까지. 아니면 이직할 때까지.직책 없는 테크 리드는 오늘도 제안한다. 조심스럽게.