유저스토리는 불확실성을 거래하는 단위였다
켄트 벡의 XP에서 유저스토리는 고객이 인정하는 진전과 개발 비용을 거래하며 범위를 선택하는 계획 장치였다.
Jira에서 Story는 대개 티켓의 한 종류다. 제목 아래에 As a... 문장을 쓰고, 세부 요구사항과 acceptance criteria를 채운 뒤 개발자에게 넘긴다. 내용이 자세할수록 준비가 잘된 티켓처럼 보인다.
1990년대 후반 켄트 벡이 XP에서 사용한 유저스토리는 이런 문서가 아니었다. 스토리는 고객이 원하는 진전을 작은 단위로 나누고, 개발자가 그 비용을 추정하며, 양쪽이 지금 무엇을 만들지 선택하기 위한 도구였다. 요구사항의 그릇보다 불확실성을 거래하는 단위에 가까웠다.
구현할 만큼 자세하지 않아도 됐다
1999년에 켄트 벡의 초기 글을 중심으로 정리된 XP 개요는 유저스토리를 “추정하고 우선순위를 정할 수 있을 만큼의 유스케이스”로 설명한다. 구현에 필요한 모든 정보를 담는 대신, 다른 스토리와 비용과 순서를 비교할 수 있을 정도만 적었다.
카드가 모이면 고객은 제품 전체를 한눈에 놓고 볼 수 있었다. 프로그래머가 추정치를 붙이면 무엇을 먼저 얻고 무엇을 미룰지 결정했다. 스토리는 고객이 프로그래머의 피드백을 받아 직접 썼기 때문에 자연스럽게 사업의 언어를 유지했다.
초기 XP 위키에 남은 켄트 벡의 설명은 범위를 더 넓힌다. 스토리가 매번 직접적인 사업가치를 나타낼 필요는 없지만, 고객이 인정하는 진전은 나타내야 한다. 무엇을 진전으로 셀 것인지 아는 쪽이 고객이므로 스토리를 자르는 권한도 고객에게 있었다.
이 관점에서 스토리와 엔지니어링 태스크는 다르다. 스토리는 고객이 알아볼 수 있는 진전이고, 태스크는 그 진전을 만들기 위해 개발팀이 선택하는 기술 작업이다. 데이터베이스 변경, API 추가, 화면 수정은 한 스토리를 구현하는 과정에서 나올 수 있지만 그 자체로 고객의 진전이 되는 것은 아니다.
유명한 문장 형식은 나중에 붙었다
As a [역할], I want [기능], so that [가치] 형식은 켄트 벡이 만든 원형이 아니다. 2001년경 영국 Connextra 팀에서 등장했고 이후 널리 퍼졌다. Agile Alliance도 이 형식을 초보 팀을 위한 보조 바퀴로 설명한다. 누구를 위한 일이며 왜 필요한지 놓치지 않게 돕지만, 문장을 채우는 행위가 대화를 대신할 수는 없다.
스토리 카드가 짧았던 이유도 여기에 있다. 카드에는 합의 전체가 들어가지 않는다. 모두가 나중에 어떤 대화를 해야 하는지 기억할 만큼만 남는다. 세부사항을 미리 고정하지 않았기 때문에 고객은 작동하는 소프트웨어를 본 뒤 마음을 바꿀 수 있었고, 개발자는 구현 중 발견한 사실을 다시 협상에 가져올 수 있었다.
유저스토리는 잘 쓴 요구사항 문서가 아니라 선택 가능한 범위였다. 이 작은 차이를 받아들이면 XP의 계획 방식 전체가 따라 나온다.
범위를 선택 가능하게 만들자 사업과 개발의 권한도 분리할 수 있었다. 고객은 무엇이 중요하고 언제 필요한지 결정한다. 개발팀은 비용이 얼마나 들고 어떻게 구현할지 판단한다. 어느 한쪽이 다른 쪽의 결정을 대신하지 않는다.
Planning Game은 권력 분리 장치였다
켄트 벡은 2000년 인터뷰에서 XP의 뿌리 중 하나로 사업 판단과 기술 판단의 엄격한 분리를 꼽았다. 그는 XP를 높은 곳에서 보면 “짧은 주기와 구체적인 피드백”이라고 설명했다. 고객이 범위와 우선순위를 정하고, 개발자가 추정과 구현을 맡는 구조는 역할 구분 이상의 의미가 있었다. 서로가 모르는 것을 아는 척하지 못하게 했다. [켄트 벡 인터뷰]
스토리는 이 경계에서 오가는 협상 토큰이었다. 개발팀이 “이 스토리는 생각보다 크다”고 말하면 고객은 더 작은 진전으로 자르거나 순서를 늦출 수 있었다. 고객이 “이 날짜가 중요하다”고 말하면 개발팀은 품질을 몰래 낮추는 대신 그 안에 들어갈 범위를 보여줄 수 있었다.
켄트 벡은 프로젝트의 네 변수로 비용, 시간, 품질, 범위를 들고 그중 범위를 가장 유용한 제어 수단으로 봤다. 모든 요구사항을 고정한 채 날짜와 비용과 품질까지 명령하면 개발팀이 선택할 수 있는 것은 실패의 모양뿐이다. 스토리로 범위를 쪼개면 같은 시간과 팀으로도 가치가 높은 조합을 다시 고를 수 있다.
여기서 추정치는 약속이 아니라 가격 정보가 된다. 실제 처리량인 velocity 역시 사람을 평가하는 점수가 아니라 다음 반복 주기에 얼마만큼의 범위를 살 수 있는지 알려주는 데이터다. 마틴 파울러가 회고한 Planning XP의 단순함도 여기에 있었다. 프로젝트를 스토리로 나누고, 실제 처리량을 보고, 들어가는 만큼만 고른다.
대화만으로는 완료되지 않았다
카드가 짧다고 해서 XP가 모호함을 방치한 것은 아니다. 론 제프리스는 유저스토리의 작동 방식을 Card, Conversation, Confirmation으로 정리했다.
카드는 요구사항을 가리키는 토큰이다. Conversation은 추정할 때와 구현 직전에 고객과 개발자가 나누는 대화다. Confirmation은 그 대화가 맞았는지 확인하는 인수 테스트다. 고객은 반복 주기 초반에 무엇이 충족되면 완료로 인정할지 설명하고, 개발팀은 주기 마지막에 그 테스트가 통과하는 작동하는 소프트웨어를 보여준다.
인수 테스트가 있었기 때문에 카드를 가볍게 유지할 수 있었다. 문서의 분량으로 확실함을 흉내 내는 대신 실행 가능한 예시로 합의를 닫았다. 스토리의 세부사항은 티켓 한 칸이 아니라 카드, 대화, 테스트에 나뉘어 존재했다.
그리고 이 루프는 테스트 주도 개발, 리팩터링, 지속적 통합, 작은 릴리스와 연결됐다. 고객이 매주 우선순위를 바꾸려면 코드도 매주 안전하게 바뀔 수 있어야 한다. 테스트 없이 변경을 받아들이겠다는 말은 일정표에서만 유연하겠다는 뜻이 된다.
Jira가 아니라 거리가 스토리를 바꿨다
오늘날의 유저스토리가 길어진 책임을 Jira에만 돌리기는 어렵다. XP에는 팀 곁에서 결정을 내리는 고객이 있었다. 고객과 개발자가 멀어지고 대화가 회의 예약으로 바뀌자, 조직은 빠진 맥락을 티켓에 밀어 넣었다. Product Owner는 선택자가 아니라 요구사항 번역가가 되고, 개발자는 고객이 인정할 진전보다 자신에게 할당된 문장을 구현하게 됐다.
그 상태에서 Story Point를 붙이면 숫자는 남지만 Planning Game은 사라진다. 누가 범위를 선택하는지, 추정치로 어떤 trade-off를 했는지, 실제 결과를 보고 무엇을 바꿨는지가 없다. Velocity를 올리는 동안 고객이 원하지 않는 스토리를 더 빨리 완료할 수도 있다.
켄트 벡은 최근 XP를 프로젝트에 Undo 버튼을 주는 방식으로 다시 설명했다. 우선순위가 틀리면 다음 주 다시 계획하고, 설계가 틀리면 되돌리며, 동작이 깨지면 테스트가 곧바로 잡는다. 복잡성을 예측으로 정복하는 대신 비가역성을 줄여 학습 비용을 낮추는 방식이다.
코드가 싸질수록 진전의 정의가 비싸진다
AI가 코드를 빠르게 만들수록 이 원형은 더 직접적인 질문을 던진다. 구현 속도가 빨라졌다는 사실은 무엇을 구현해야 하는지 알려주지 않는다. 고객이 무엇을 진전으로 인정할지 정하지 못한 팀은 더 많은 코드를 더 빨리 만들 수 있을 뿐이다.
그래서 AI 시대의 유저스토리는 프롬프트를 길게 쓰는 형식으로 돌아가서는 안 된다. 고객이 알아볼 진전, 선택 가능한 범위, 구현 비용, 실행 가능한 확인을 한 묶음으로 유지해야 한다. Agent가 엔지니어링 태스크를 더 잘게 쪼개더라도 스토리의 경계까지 대신 정하게 두면 사업 판단과 기술 판단이 다시 한곳에 섞인다.
스토리 카드가 비어 있던 것은 작성자가 게을러서가 아니었다. 무엇을 만들지에 대한 합의를 문서가 대신하지 못하게 하려는 설계였다. 고객이 진전을 자르고, 개발자가 비용을 말하고, 인수 테스트가 합의를 닫고, 다음 주 다시 계획한다. 이 루프가 없다면 As a...를 백 번 써도 XP의 유저스토리는 돌아오지 않는다.