코드는 쉬운 부분이다. 요구사항을 제대로 잡는 것이 어려운 부분이다.
Code as Source of Truth → Spec as Source of Truth
소프트웨어 공학의 역사에서 '진실의 원천(Source of Truth)'은 항상 코드였다. 문서가 아무리 잘 작성되어 있어도, 실제 시스템이 어떻게 동작하는지를 알려면 결국 코드를 봐야 했다. 요구사항 문서는 프로젝트 초기에 작성된 후 방치되었고, 설계 문서는 코드와 점점 괴리되어 갔다. '코드가 곧 문서다'라는 말이 개발 현장에서 반쯤 농담으로 통용되었던 이유다.
이 패러다임은 수십 년간 유효했다. 코드를 작성하는 것은 인간 개발자의 전유물이었고, 코드는 개발자의 의도가 가장 정확하게 구현된 형태였다. 그러나 2025년, AI가 코드를 생성하는 시대에 이르러 이 공식이 근본적으로 흔들리기 시작했다. AI가 코드를 작성한다면, 코드는 더 이상 인간의 의도를 '직접적으로' 반영하는 것이 아니다. 코드는 AI가 인간의 의도를 '해석'하여 생성한 결과물이다. 이 해석 과정에서 의도의 왜곡, 누락, 환각이 발생할 수 있다.
이 문제를 해결하기 위해 등장한 것이 명세 주도 개발(Specification-Driven Development, SDD)이다. SDD에서는 '코드가 아닌 명세(Specification)가 진실의 원천'이다. 명세는 인간의 의도가 가장 직접적으로 표현된 문서이며, 코드는 그 명세를 특정 프로그래밍 언어와 프레임워크로 '번역'한 결과물에 불과하다.
이 전환의 핵심은 '의도(Intent)'의 보존에 있다. 전통적 개발에서 의도는 개발자의 머릿속에서 코드로 직접 번역되었다. 하지만 AI 시대에는 의도 → 명세 → AI 해석 → 코드라는 더 긴 경로를 거친다. 이 과정에서 의도가 왜곡될 위험이 커졌고, 따라서 의도를 가장 정확하게 포착하는 '명세'의 중요성이 비약적으로 높아진 것이다.
왜 AI 시대에 명세가 중요한가
AI 코딩 도구의 발전은 역설적으로 '명세'의 가치를 재발견하게 만들었다. 그 이유를 세 가지 관점에서 분석해보자.
첫째, AI는 모호함에 취약하다. 인간 개발자는 모호한 요구사항을 받아도 경험과 도메인 지식으로 빈틈을 메울 수 있다. '로그인 기능 만들어줘'라고 해도, 시니어 개발자는 보안, 세션 관리, 에러 처리 등을 자동으로 고려한다. 하지만 AI는 명시되지 않은 것은 고려하지 않거나, 임의로 '환각(Hallucination)'하여 채운다. 명세는 이 모호함을 제거하는 장치다.
둘째, AI는 맥락 없이 국소 최적화한다. AI에게 개별 기능을 요청하면, 각 기능은 나름대로 잘 동작할 수 있다. 그러나 이 기능들이 전체 시스템에서 어떻게 조화를 이루어야 하는지, 서로 어떤 의존성이 있는지는 AI가 스스로 파악하기 어렵다. 명세는 전체 시스템의 청사진을 제공함으로써, AI가 국소 최적화의 함정에 빠지지 않도록 안내한다. 이것은 제3장에서 다룬 '시스템 사고(Systems Thinking)'를 문서로 구현하는 것이다.
셋째, 코드는 구속적 산출물(Binding Artifact)이다. 일단 코드를 작성하면, 그것과 분리되기가 매우 어렵다. 대규모 리라이트나 실험에는 큰 팀의 많은 노력이 필요하다. 반면, 명세는 비구속적(Non-binding)이다. 같은 명세에서 여러 가지 구현 방식을 실험할 수 있고, 기술 스택을 바꾸어 재생성할 수도 있다. AI 시대에 이 유연성은 결정적인 장점이다.
명세 = 실행 가능한 의도
전통적 소프트웨어 공학에서 명세(Specification)는 '문서'였다. 워드 파일이나 위키 페이지에 작성된 텍스트로, 개발자가 읽고 해석하여 코드로 구현하는 참고 자료였다. 이 명세는 '실행'될 수 없었다. 읽히고, 해석되고, 때로는 무시되는 정적인 문서였다.
SDD에서의 명세는 본질적으로 다르다. 명세는 '실행 가능한 의도(Executable Intent)'다. AI가 명세를 읽고 직접 코드를 생성할 수 있기 때문이다. 이는 마치 건축에서 3D BIM(Building Information Modeling) 모델이 단순한 도면을 넘어, 자재 발주와 시공 시뮬레이션까지 가능한 '실행 가능한 설계'가 된 것과 유사하다.
명세가 '실행 가능'하려면, 다음 네 가지 속성을 갖추어야 한다.
이 네 가지 속성은 이상적인 목표이며, 현실에서 모든 명세가 처음부터 완벽할 수는 없다. 중요한 것은 명세를 반복적으로 정교화(Iterative Refinement)하는 과정이다. 바이브 코딩의 '빠른 반복' 정신과 일맥상통한다. 처음에는 대략적인 명세로 시작하고, AI의 출력물을 보면서 명세를 정교화하고, 다시 생성하는 사이클을 반복하는 것이다.
필자의 서울시 야경명소 프로젝트가 좋은 예다. 이 프로젝트에서 필자는 '개발 계획서 작성 → 상세 개발 Task 작성 → Task별 프롬프트 작성 → 프롬프트 기반 프로젝트 수행'이라는 4단계 워크플로우를 따랐다. 이것은 명세를 점진적으로 정교화하는 과정 그 자체였다. 개발 계획서라는 상위 명세에서 시작하여, 점점 구체적인 Task 수준의 명세로 분해해나간 것이다.