Task Master에서 SDD로
어떤 문서를 만들고 어떤 문서를 관리할 것인가에 대해서

AI 에이전트를 활용해서 개발을 할 때 어떻게 개발하면 좋을까. 처음에는 Task Master MCP를 도입해서 사용했다. 복잡한 기능은 작은 단위로 쪼개서 개발하고 다른 팀원이 해당 기능 개발을 바톤터치 해가기도 편리할거라고 생각했다. 정책이나 요구사항은 prd 한장으로 관리했다. 그리고 도메인별 상태 전이도, API 문서, 단어 사전정도만 살아있는 문서로 관리했다. 서비스 자체가 복잡하지 않고 당장 개발해서 서비스해야하니 단순하게 생각하자라고 가닥을 잡았다.
결과적으로 절반은 실패했다. 코드 복잡도가 너무 높다거나 버그가 많다거나 설계가 복잡해 유지보수가 어렵다거나… 그런 문제가 아니라, 최종 결과물을 봤을 때 개발자가 아닌 사람에게 정책에 대해서 설명하기는 참 쉽지 않은 프로젝트가 되었다. 기획자가 ‘그럼 이 서비스의 정책은 어떻게 봐야해요?’ 라고 물었을 때 음. 하게 되는 결과물이 되었다. 내가 이 프로젝트를 개발하면서 A 정책으로 결정했던 이유, 사용자가 무엇을 할 수 있는지에 대한 정의, 이 프로젝트를 관리 운영하는 사람들이 이해하고 있어야 하는 맥락들이 사라진 것이다. 그리고 그 와중에 서비스가 커지게 되면… 후폭풍을 감당하기 쉽지 않을거란 생각이 들었다.
간단하게 시작하자. prd 한장.
Task Master를 활용하는 방식은 단순했다. prd.md 한 장에 만들고 싶은 걸 적었다.
핵심 컨셉, 기술 스택, 패키지 구조까지. 그리고 이 문서를 파싱해 작업 목록을 도출했다.
tasks.json에는 태스크마다 제목, 설명, 상세 절차, 의존성, 상태, 서브태스크, 테스트 전략이 붙는다.
꽤 그럴듯했다. 간단한 서비스를 만들 때는 실제로 편했다. 작업의 복잡성 관리, 작업 분할, 작업 순서 관리, 작업 상태 관리 등 많은 것들이 해결되었다.
개발에 필요한 문서는 별도로 생성했다. API 문서, 데이터 사전, 상태 전이도 등 전체 서비스에서 일관된 정책을 가져가야하는 것들을 별도의 문서로 분리해 관리했다. 이것도 나쁘지 않았다. 문서가 많지 않으니 관리도 편할거라고 생각했다.
자유 분방하게 늘어나는 문서와 자유 분방하게 늘어나는 문서 관리 시간
문제는 프로젝트가 진행되면서 의사 결정 방향이 달라졌을 때 발생했다. 급하게 진행되는 프로젝트일 수록 의사결정은 크게 자주 뒤집혔고 그때마다 prd는 수정되어야 했으며 그때마다 작업 목록은 길을 잃었다. 작업이 마무리 되고 난 다음에 의사 결정이 변경되면 양반이었다. 작업 도중에 의사 결정이 변경되면? 그땐 TASK를 어떻게 번복해서 진행해야하는가. prd 이력은 어떻게 관리해야하는가. 번복된 의사결정은 어디에 기록하면 좋은가. prd는 생각보다 자주 변경되었고 그때마다 TASK가 번복되었으며 TASK에 따라 개발되다 멈춘 코드들은 운이 좋으면 정리되고 운이 나쁘면 도달되지 않는 코드가 되었다. 더 나쁜 것은 이런 변동 사항을 관리하기 위해 문서가 점점 늘었고 그만큼 문서를 일관성 있게 유지하는 것이 어려워졌으며 어떤 문서는 생성된 이후 단 한번도 읽히지 않기까지 했다. 작업자가 나 한명이었기에 망정이지 여러 작업자였으면 충돌이 어마어마했을 것이다.
수정할 문서, 수정하지 않을 문서, 관리할 문서, 관리되지 않는 문서의 분리
specs/ 디렉토리는 이렇게 생겼다. 역할별로 문서를 나눴다.
spec.md— 무엇을 만드는가. 요구사항과 인수 조건.plan.md— 어떻게 만드는가. 아키텍처와 흐름.data-model.md— 데이터는 어떻게 생겼는가. 스키마 계약.tasks.md— 그래서 지금 뭘 하는가. 작업 체크리스트.changes/— 최초 개발된 이후 바뀐 것들. 변경 하나에 폴더 하나.archive/— 작업이 완료된 것들.
핵심은 (1) 문서를 계층으로 나눈다 (2) 매번 현재 상태와 일치시켜 현행화할 문서와 수정하지 않고 과거 상태 그대로 유지할 문서를 분리한다
계획은 계획대로
plan.md에는 아키텍처와 처리 흐름만 있다. 문장마다 의사결정 번호 또는 해당 정책을 도입한 작업 번호를 명기했다.
“모든 발화는 tool 기반 에이전트 턴으로 처리한다(changes/0018)”, “루프를 감싸는 결정론 층이 앞뒤로 하나씩 있다(changes/0029)” 같은 식이다.
이러면 의사 결정을 역추적할 수 있다. 나중에 “이거 왜 이렇게 했지”하는 의문이 생겼을 때 그 번호를 따라가면 당시의 판단이 나온다. Task Master를 쓸 때는 내 머릿속에만 남아있던 의사결정 방향이 문서로 명시된 것이다.
데이터 모델은 한 곳에서만
데이터 모델은 data-model.md 하나가 소유한다. 테이블, 키와 제약, 그게 spec의 어느 항목에 대응하는지가 한 표에 있다.
따라서 어느 spec이든 일관된 데이터 스키마를 적용할 수 있다.
개정 이력도 마찬가지로 역추적이 가능하도록 의사결정 번호 또는 해당 정책을 도입한 작업 번호를 달아두었다.
예를 들어 entry → tasting_day, brew → cup으로 이름을 갈아엎은 개정이 있는데, “changes/0030에서 이렇게 바뀌었다”를 명기해두었다.
작업은 근거와 함께
tasks.md는 그냥 마크다운 체크리스트다. 대신 항목마다 두 가지가 붙는다. 근거와 테스트.
- T1-2 JsonFileNoteRepository (NoteRepository 구현, ADR-8)
- findAll/findBySlug/upsertEntry. 날짜 병합 로직: 같은 date 갱신, 다른 date append 후 정렬(ADR-4 POLICY)
- 테스트: 같은 날 upsert 2회 → 엔트리 1개(AC-14), 다른 날 → 2개 시간순(AC-13)
tasks.json의 details과 비슷한데, 개인적으로는 TASK MASTER를 쓸 때보다 훨씬 크게 확장해서 사용하고 있다.
Phase 단위로 비슷하거나 연관이 있는 작업을 묶어두었으며 각 항목이 어떤 의사 결정이나 요구사항에 근거하는지가 적혀 있다.
구현이 근거와 다르게 나오면 둘 중 하나에 문제가 생긴 것이고(예를 들면 구현하는 도중 예상하지 못한 설계 오류를 발견했다든지), 어느 쪽에서 틀어졌는지 쉽게 추적할 수 있다.
변경은 delta로
가장 크게 바뀐 습관이다. 특정 기능이 변경될 때 현재 작업 및 정책이 변경될 작업 및 정책과 뒤섞이지 않는다.
changes/0031-transcript-fold-notice/ 같은 폴더를 만들고 그 안에 delta.md(무엇이 어떻게 달라지는가)와 tasks.md(그래서 뭘 건드리는가)를 쓴다.
작업이 끝나면 archive/로 옮긴다.
이 방식의 이점은 변경이 아예 별개의 영역이라는 것이다. Task Master를 사용할 때 Task 가 변경되면 tag 등을 사용해 작업 목록 자체는 분화할 수 있었으나 변경된 정책과 prd 등, 작업 목록 이전에 관리되어야 하는 문서들을 어떻게 분화해서 관리할 것인가에 대한 고난이 있었다. 지금은 변경 하나가 폴더 하나고, 작업 중인 다른 스펙과 서로 뒤섞이지 않고 완전히 별개로 관리된다. 따라서 진행 중인 작업과 진행할 작업이 서로 뒤섞이지 않고 안전하게 관리된다.
더 나은 방법에 대한 고민
기능 개발은 다음과 같은 순으로 이루어진다
(1) 개발자는 클로드에게 요구사항과 세부 정책을 전달한다. (2) 클로드는 요구사항과 세부 정책을 검토하고 개발자에게 의사 결정 방향을 묻는다. (3) 기능이 크다면 이것은 3~4회정도 반복된다. (4) 모든 것이 결정되면 클로드가 문서 생성용 Skill을 사용해 문서를 작성한다. (5) 컨텍스트를 비우고 Task 진행용 Skill을 호출하여 작업을 진행한다. 작게는 하나의 task만, 크게는 하나의 md 파일 전체를 일괄적으로 진행할 수 있다. 후자의 경우엔 작은 기능 개발 위주로 시험해봤는데 추가 의사결정 할 사항이 없으면 문제 없이 완료되었다.
누군가는 루프에 사람이 적극적으로 참여하는 방향이 AI 에이전트의 자율성을 해치고 작업 효율성을 저해 한다고 생각할 수도 있을 것 같다. 상대적으로 생산성이 떨어지는 건 사실이다. 그러나 기능과 정책을 설명하는 발화가 짧아지면 짧아질수록 암묵적으로 체결되는 정책은 많아지고 최종적으론 기능끼리 정책이 충돌하거나 전혀 의도하지 않은 기능으로 개발될 가능성이 높아진다. 따라서 나는 개발 루프에 어느정도 사람이 참여하는 것은 피할 수 없다고 본다. 아직까지는.
약간 다른 이야기인데, Spec Kit이나 OpenSpec을 도입할까도 생각했다. 하지 않은 이유는 Skill을 사용해서 충분히 내게 필요한 만큼의 문서 작성과 관리가 가능했기 때문이다. 아직까지 외부 의존성을 높일 이유를 찾지 못해서라고 하겠다. 따라서 구조적인 부분만 참고하고 도입은 하지 않았다.
정리
AI 에이전트를 사용한 개발 방법은 너무나도 빠르게 너무나도 다양한 방법으로 진화하고 분화하고 있다. 이 방법도 누군가에겐 한계가 있고 오래된 것일 수도 있다. 그러나 TASK MASTER에서 SDD로 전환하면서 최종 목표였던 (1) 개발 작업의 바톤 터치가 편리하고 (2) 정책을 일관되게 적용시킬 수 있고 (3) 정책을 운영자에게 문서로 전달하기 용이하며 (4) 담당자가 자리를 비우더라도 해당 기능에 대한 정책적 히스토리를 이해할 수 있는 구조가 완성되었다. 따라서 서비스가 더 확장되어 더 빠른 속도가 필요하기 전까지는 현재 상태를 유지하고 개인적으로 따로 또 조금씩 사이드 프로젝트를 진행하면서 속도 향상을 위한 R&D를 진행해볼까 한다.