소프트웨어 역사에서 특정 변화는 익숙한 통제 신호를 제거하기 때문에 자유로움처럼 느껴지지만, 실제로는 엄격함을 진실에 더 가까운 곳으로 재배치하여 진척을 가장하기 어렵게 만듭니다. 저자의 경력에서 이러한 패턴은 최소 세 번 반복되었습니다.
규율 재배치의 반복된 패턴
-
동적 언어의 정적 타입 시스템 대체: Ruby와 Python 같은 동적 언어가 확산될 때, 컴파일 시간 보장이나 엄격한 타입 제약이 없어 ‘무규율하다’는 비판을 받았습니다. 그러나 실제로는 엄격함이 정적 약속에서 런타임 진실로, 타입 선언에서 실행 가능한 동작으로 이동했습니다. 성공적인 팀들은 실행 가능한 명세(테스트)에 집중하여 사실상의 타입 시스템처럼 기능하도록 했습니다. 규율은 사라진 것이 아니라 테스트, 계약, 그리고 시스템이 실제로 어떻게 실행되는지를 반영하는 피드백 루프로 옮겨갔습니다.
-
익스트림 프로그래밍(XP)의 단계별 개발 대체: XP는 계획, 설계 문서, 단계별 게이트를 제거했습니다. 이는 조직에 안정감을 주던 인공물이었으나, XP는 그 자리에 테스트 우선 개발, 지속적 통합, 지속적인 동료 검토, 실제 고객 피드백 등 훨씬 덜 관대한 메커니즘을 설치했습니다. 겉으로는 혼란스러워 보였지만, 코드가 직접 상황을 알려주는 운영상의 진실이 그 자리를 대체했습니다.
-
지속적 배포의 릴리스 관리 대체: 릴리스 주기, 안정화 단계, 영웅적인 통합 노력이 사라지면서 또 다른 규율 상실처럼 보였습니다. 그러나 지속적 배포는 분기별 릴리스보다 훨씬 엄격한 엔지니어링을 요구합니다. 가역성, 관찰 가능성, 자동화된 검증, 빠른 롤백 경로가 필수적입니다. 지속적 배포는 속도에 관한 것이 아니라 ‘절대 놀라지 않는 것’에 관한 것이며, 시스템이 항상 무엇을 하는지 정확히 알아야만 가능하므로 규율 또한 지속적으로 요구됩니다.
생성형 소프트웨어가 이 패턴에 부합하는 이유
생성형 AI는 궁극적인 제약인 ‘수작업 코드’를 제거하는 것처럼 보입니다. 이는 사람들이 불안해하는 부분이며, 그럴 만도 합니다. 하지만 위험은 확률적 생성 자체가 아니라 ‘조용한 실패’에 있습니다. 코드를 생성할 때, 모든 문자를 타이핑하며 얻는 부수적인 지식과 이해를 강요하는 마찰을 잃게 됩니다. 그 결과, 작동하는 이유를 전혀 모른 채 작동하는 시스템을 만들 수 있습니다.
그러나 해결책은 생성을 거부하는 것이 아니라 ‘규율을 재배치’하는 것입니다. 생성형 시스템은 불변성이 암묵적이 아닌 명시적일 때, 인터페이스가 부수적인 경계가 아닌 실제 계약일 때, 평가가 무자비하고 실패가 시끄럽고 즉각적일 때만 작동합니다. 엔지니어의 역할은 코드를 타이핑하는 것에서 의도를 명시하고 결과를 검증하는 것으로 전환됩니다.
하나의 가능성은 개발자가 테스트를 작성하고 LLM이 구현을 생성하는 것입니다. 테스트가 통과하지 못하면 코드는 배포되지 않습니다. 이는 구현의 저자만 다를 뿐, 1999년에 배운 테스트 우선 개발과 동일한 규율입니다. 엄격함은 코드를 누가 작성하는지에서 코드가 무엇을 만족해야 하는지로 재배치됩니다. 생성은 유연하고 확률적일 수 있지만, 평가는 엄격해야 합니다. 시스템은 의도에서 벗어날 때 눈에 띄게 실패해야 합니다.