여러 단계를 순서대로 밟아야 하는 작업을 시키면, 단순 체크리스트로는 "이 파일은 아직 손대면 안 된다"는 순서 제약이 잘 지켜지지 않는 경우가 있습니다. 앞 단계가 끝나기 전에 뒤 단계 파일부터 건드려버리면, 아직 확정되지 않은 인터페이스를 참조한 채로 코드가 만들어져서 나중에 다시 손봐야 했습니다. Claude Code의 Task 도구(TaskCreate/TaskUpdate/TaskList)로 작업 사이의 선후 관계를 명시하고 진행 상황을 관리한 과정을 정리합니다.

어떤 작업이었나

공유 모듈에서 쓰는 네트워크 클라이언트 인터페이스를 바꾸는 작업이었습니다. 순서가 명확했습니다: (1) 인터페이스 시그니처를 먼저 바꾸고, (2) 그 인터페이스를 구현하는 클래스를 고치고, (3) 인터페이스를 호출하는 쪽 코드를 고치고, (4) 마지막에 관련 테스트를 갱신하는 순서였습니다. 이전에 단순 텍스트 체크리스트로 같은 작업을 시켰을 때는, Claude Code가 3번 작업을 하다가 1번이 아직 끝나지 않은 걸 놓치고 옛 시그니처 기준으로 호출부를 고쳐서 다시 되돌린 적이 있었습니다.

AI를 어떻게 활용했나

먼저 네 개 작업을 TaskCreate로 등록했습니다.

{"subject": "네트워크 클라이언트 인터페이스 시그니처 변경", "description": "fetch(url) -> fetch(url, headers) 로 파라미터 추가"}
{"subject": "구현체 수정", "description": "인터페이스 변경에 맞춰 구현 클래스의 fetch 함수 수정"}
{"subject": "호출부 수정", "description": "fetch를 호출하는 모든 위치를 새 시그니처로 변경"}
{"subject": "테스트 갱신", "description": "변경된 시그니처에 맞춰 관련 테스트 수정"}

이렇게 만들면 네 작업 모두 pending 상태로 생성되는데, 이 상태만으로는 순서가 강제되지 않습니다. 그래서 TaskUpdate로 의존 관계를 걸었습니다.

{"taskId": "2", "addBlockedBy": ["1"]}
{"taskId": "3", "addBlockedBy": ["2"]}
{"taskId": "4", "addBlockedBy": ["3"]}

이후 작업을 진행할 때는 TaskList로 지금 시작해도 되는 작업이 뭔지 먼저 확인했습니다. blockedBy가 남아 있는 작업은 목록에서 시작 가능한 작업으로 잡히지 않아서, 1번을 completed로 바꾸기 전까지는 2번을 건드리지 않고 넘어갈 수 있었습니다.

TaskList 결과:
1. 인터페이스 시그니처 변경 - in_progress
2. 구현체 수정 - pending (blockedBy: 1)
3. 호출부 수정 - pending (blockedBy: 2)
4. 테스트 갱신 - pending (blockedBy: 3)

1번을 끝낸 시점에는 TaskUpdate로 status: completed를 넣었는데, 이때 인터페이스는 바꿨지만 구현체가 아직 컴파일 에러 상태였습니다. completed는 "빌드까지 정상인 상태"를 기준으로 삼기로 했기 때문에, 실제로는 in_progress를 유지한 채로 구현체 수정까지 같이 끝내고 나서야 completed로 바꿨습니다.

결과와 얻은 팁

  • blockedBy를 걸어두면 Claude Code가 스스로 순서를 지켜야 한다는 걸 매 프롬프트마다 다시 설명하지 않아도 됐습니다. 텍스트 체크리스트는 순서를 지문으로만 표현해서 종종 무시됐는데, 의존 관계는 구조로 표현되어 있어서 앞 작업이 끝나지 않은 목록 항목을 건너뛰는 일이 없었습니다.
  • completed 처리 기준을 "빌드/테스트까지 정상인 상태"로 엄격하게 잡는 게 중요했습니다. 인터페이스만 바꾸고 completed로 표시했다면, 다음 작업을 시작할 때 이미 끝난 일로 착각하고 구현체의 컴파일 에러를 놓칠 뻔했습니다.
  • 정말 순서가 있는 작업에만 addBlockedBy를 걸어야 했습니다. 서로 독립적으로 끝낼 수 있는 작업까지 의존 관계로 묶으면 병렬로 처리할 수 있었던 부분까지 직렬로 늘어져서 오히려 느려졌습니다.
  • 여러 서브에이전트에 작업을 나눠 맡길 때는 owner 필드로 어떤 작업을 누가 맡았는지 구분할 수 있어서, 같은 작업을 두 에이전트가 동시에 건드리는 상황을 피할 수 있었습니다.