실제 업무 경험을 바탕으로 썼다. 회사와 제품을 특정할 수 있는 이름, 주소, 티켓 번호와 코드는 모두 덜어내거나 바꿨다.
얼마 전에는 사람 사이의 책임과 코드 안의 지식 경계를 정리한 근황을 썼다. 이번에는 그중에서도 위임한 뒤 책임의 경계가 흐려질 때 생기는 문제를 조금 더 구체적으로 생각해봤다.
최근 서로 전혀 달라 보이는 두 가지 일을 겪었다. 하나는 휴가를 앞두고 사내 시스템에 업무 대리자를 지정하는 일이었고, 다른 하나는 빈 장바구니 화면의 버튼이 잘못된 페이지로 이동하는 버그를 고치는 일이었다.
하나는 사람과 조직의 문제이고 다른 하나는 프론트엔드 코드의 문제처럼 보였다. 하지만 둘을 지나고 나니 같은 질문이 남았다.
이 일의 결과는 대체 누가 끝까지 책임지는가?
담당자가 아예 없는 것보다 더 까다로운 상태가 있다. 담당자는 여럿인데, 결정할 사람과 마지막에 확인할 사람이 분명하지 않은 상태다. 책임이 사라진 것이 아니라 사람과 조건 사이를 둥둥 떠다닌다. 그렇게 떠 있는 책임은 조직에서는 갈등이 되고, 코드에서는 버그가 된다.
위임했다고 책임까지 전달된 것은 아니다
휴가를 가려면 사내 시스템에 업무 대리자를 지정해야 했다. 필요한 절차다. 사람이 자리를 비우는 동안에도 조직의 일은 계속되어야 하고, 급한 요청을 받을 창구도 필요하다.
그런데 대리자의 이름을 입력하는 것만으로 위임이 끝나는지는 의문이었다.
- 어떤 요청까지 대신 처리해야 하는가?
- 대리자가 직접 판단해도 되는 범위는 어디까지인가?
- 판단에 필요한 배경과 자료는 어디에 있는가?
- 보류해도 되는 일과 바로 대응해야 하는 일은 무엇인가?
- 원래 담당자가 돌아오면 어떤 상태로 다시 넘겨야 하는가?
- 문제가 생겼을 때 최종 결정을 회수할 사람은 누구인가?
이 질문들에 답이 없으면 시스템에는 대리자가 등록되지만, 실제 책임은 전달되지 않는다. 위임받은 사람은 부족한 맥락을 추측으로 채우게 된다. 원래 담당자는 자신이 넘겼다고 생각하고, 관리자는 대리자가 있으니 처리될 것이라고 생각한다. 결과가 어긋난 뒤에야 각자가 생각한 위임의 범위가 달랐다는 사실이 드러난다.
좋은 위임은 사람의 이름을 바꾸는 일이 아니다. 업무의 입력, 판단 기준, 권한의 범위, 종료 조건을 함께 옮기는 일이다.
화면 너비가 정책을 결정하고 있었다
비슷한 일이 코드에도 있었다.
빈 장바구니 화면에는 사용자가 상품을 다시 둘러볼 수 있는 버튼이 있었다. 그런데 이 버튼이 어느 페이지로 이동할지를 화면 너비가 결정하고 있었다. 구조를 단순화하면 이랬다.
const destination = isNarrowViewport
? mobileRankingPath
: desktopBestPath;
처음 보면 자연스럽다. 화면이 좁으면 모바일 경로를 사용하고, 넓으면 데스크톱 경로를 사용한다. 반응형 웹에는 이런 분기가 흔하다.
하지만 화면의 모양과 서비스 정책은 같은 것이 아니다. 브라우저 너비가 좁다고 해서 그 사용자가 반드시 모바일 앱의 정책을 따라야 하는 것은 아니다. 데스크톱 브라우저의 창을 줄일 수도 있고, 태블릿이나 작은 웹뷰일 수도 있다. 특정 픽셀을 경계로 버튼의 디자인이 바뀌는 것은 괜찮지만, 버튼이 향하는 서비스의 목적지까지 달라진다면 그 경계에는 분명한 근거와 주인이 필요하다.
이 코드에서는 그 주인이 보이지 않았다.
- 웹의 BEST 페이지 정책
- 모바일 웹의 이동 정책
- 앱 내부 화면의 이동 정책
- 오래된 페이지와 새 페이지의 전환 시점
각 정책은 존재했지만, 빈 장바구니 버튼이 어느 정책을 따라야 하는지는 화면 너비라는 간접 신호에 맡겨져 있었다. 책임이 코드의 조건문 사이에 떠 있던 셈이다. 한쪽 경로가 개편된 뒤에도 다른 분기는 그대로 남았고, 특정 화면 너비에서만 오래된 페이지로 이동하는 문제가 생겼다.
분기를 줄이는 것이 책임을 되찾는 일이었다
해결은 새로운 예외를 하나 더 붙이는 것이 아니었다. 웹에서는 화면 너비와 관계없이 같은 BEST 페이지로 이동하도록 목적지를 통일하고, 앱처럼 실제로 실행 환경이 다른 경우만 별도의 계약으로 남겼다.
const destination = isAppWebView
? appBestPath
: webBestPath;
핵심은 코드가 짧아졌다는 데 있지 않다. 어떤 환경이 어떤 정책을 소유하는지가 명시적으로 바뀌었다는 데 있다.
수정 후에는 넓은 데스크톱 화면과 작은 모바일 화면만 확인하지 않았다. 기존 분기가 바뀌던 경계의 바로 위와 아래도 함께 확인했다. 각 화면에서 빈 상태가 깨지지 않는지, 버튼이 잘 보이는지, 가로 스크롤이나 겹침이 없는지, 클릭 후 오래된 경로가 아니라 새 경로로 이동하는지를 살폈다.
그리고 결과를 배포 작업과 원래 작업 양쪽에 기록했다. 코드를 고친 사람이 알고 있는 것만으로는 작업이 끝난 것이 아니기 때문이다. 무엇을 확인했고 무엇은 확인하지 못했는지 다음 사람이 찾을 수 있어야 책임이 다시 떠다니지 않는다.
조직의 조건문도 계속 늘어난다
책임 경계가 불분명한 조직은 코드와 비슷하게 움직인다.
처음에는 “휴가 중에는 이 사람이 대신 본다”는 조건 하나뿐이다. 하지만 맥락이 전달되지 않으면 예외가 붙는다.
- 이 요청은 원래 담당자가 돌아올 때까지 기다린다.
- 저 요청은 대리자가 다른 팀에 다시 물어본다.
- 급해 보이면 관리자를 호출한다.
- 관리자가 바쁘면 일단 담당자를 하나 더 찾는다.
- 결과가 잘못되면 누가 결정했는지 다시 확인한다.
조건은 늘어나는데 판단의 주인은 더 흐려진다. 모두가 일부를 처리했지만 누구도 전체를 책임지지 않은 상태가 된다. 시스템에는 빈칸이 없는데 실제 업무에는 빈칸이 생긴다.
관리자는 이 상태를 “위임했다”라고 부르면 안 된다. 특히 권한이 더 적고 맥락도 부족한 사람에게 결정하기 어려운 일을 넘기면서, 누구에게 물어봐야 하는지까지 스스로 찾게 해서는 안 된다. 그것은 실행을 나눈 것이 아니라 관리자가 해소해야 할 불확실성을 아래로 이동시킨 것에 가깝다.
팀장은 사람만 지정해서는 안 된다
팀장이 업무를 위임할 때는 적어도 다음을 함께 전달해야 한다고 생각한다.
- 목적: 이 일을 왜 지금 처리해야 하는가.
- 범위: 대리자가 어디까지 결정할 수 있는가.
- 맥락: 판단에 필요한 문서와 이전 결정은 어디에 있는가.
- 중단 조건: 어떤 상황에서는 진행하지 말고 다시 확인해야 하는가.
- 검증 기준: 무엇을 확인하면 완료라고 볼 수 있는가.
- 회수 조건: 언제, 어떤 상태로 원래 책임자가 다시 가져가는가.
이 정보 없이 “누가 대신 봐주세요”라고 요청하고 빠지는 것은 충분한 위임이 아니다. 대리자를 지정했더라도 결과에 대한 관리 책임까지 사라지는 것은 아니다.
코드 리뷰에서 조건문 하나를 보면 “왜 이 조건이 정책을 결정하지?”라고 묻는다. 조직에서도 같은 질문이 필요하다. “왜 이 사람이 이 결정을 해야 하지?”, “결정할 권한과 맥락도 함께 받았나?”, “마지막 확인은 누가 하지?”를 물어야 한다.
다시 책임을 맡게 된다면
나도 이전에 사람과 일을 관리하는 역할을 맡아봤다. 모든 일을 완벽하게 처리한 것은 아니다. 다만 담당자를 지정했다는 이유만으로 내 일이 끝났다고 생각하지는 않으려 했다. 필요한 맥락을 전달하고, 상대가 결정하기 어려운 문제는 다시 가져오고, 결과에 대한 책임은 역할을 맡은 내가 져야 한다고 생각했다.
한동안은 그런 역할을 다시 맡고 싶지 않았다. 사람의 일까지 챙기는 데 드는 에너지를 이미 알고 있기 때문이다. 그런데 최근의 경험을 지나며 생각이 조금 달라졌다. 언젠가 다시 권한과 책임을 맡게 된다면, 예전보다 더 잘 챙길 수 있을 것 같다.
무엇을 지시할지보다 무엇을 내가 끝까지 확인해야 하는지 보려고 한다. 일을 나눠도 판단 기준까지 함께 나누고, 위임받은 사람이 내 모호함까지 대신 감당하게 만들지는 않으려고 한다. 문제가 생겼을 때 “누가 처리했나요?”부터 묻기보다, 내가 전달하지 않은 맥락과 회수하지 않은 책임부터 살펴볼 것이다.
책임에는 경계가 필요하다
좋은 위임은 책임을 버리는 기술이 아니다. 책임을 잃지 않은 채 실행을 나누는 기술이다.
코드에서도 조직에서도 경계가 흐리면 예외 조건과 전달 단계가 늘어난다. 처음에는 유연해 보이지만, 문제가 생기는 순간 누구도 전체를 설명하지 못한다. 반대로 목적지와 판단 기준, 검증 방법과 최종 책임자가 분명하면 분기는 줄고 대응은 빨라진다.
버그는 코드가 틀려서만 생기지 않는다. 어떤 조건에서 누가 결정해야 하는지 불분명할 때, 코드는 그 모호함을 조건문으로 복사한다.
사람의 이름만 넘기고 책임의 구조를 남겨두지 말 것. 코드의 분기만 고치고 정책의 주인을 잊지 말 것. 책임이 다시 둥둥 뜨지 않게 만드는 것까지가 위임이고, 수정이고, 관리다.