아이디어와 인사이트

AI 퍼스트 개발, 코딩 가드레일, 그리고 폐기 가능한 아키텍처를 탐구합니다.

버전 1은 결코 문제가 아니다: AI coding과 장기 유지보수

AI coding 도구는 버전 1을 생성하는 데 탁월합니다. 진짜 엔지니어링 과제는 버전 4에서 시작됩니다. 팀이 나머지를 깨뜨리지 않고 무언가를 바꿔야 할 때입니다.

모든 AI coding 데모는 같은 흐름을 따릅니다. 누군가 모델에 프롬프트합니다. 동작하는 앱이 나타납니다. 청중은 감탄합니다. 감탄할 만합니다. 속도는 실제입니다. 능력도 실제입니다. 버전 1은 AI가 루프에 있을 때 진짜로 더 빠르게 배포됩니다. 문제는 버전 1이 결코 어려운…

AI 생성 코드와 대체 가능성 원칙

AI 생성 코드의 진짜 품질 기준은 첫날에 동작하느냐가 아닙니다. 30일째에 나머지를 전부 rewrite하지 않고도 그 코드를 교체할 수 있느냐입니다.

AI 생성 코드 품질에 대한 대부분의 논의는 생성 시점의 정확성에 초점을 맞춥니다. 출력이 컴파일되는가? 테스트를 통과하는가? 명세에 맞는가? 이것들은 기본 조건일 뿐입니다. 진짜 비용에 대해서는 아무것도 알려주지 않습니다. 진짜 지표는 대체 가능성입니다. 요구사항이 변할 때 이…

AI codebase를 위한 결정론적 가드레일

사람의 리뷰는 일관적이지 않습니다. AI 리뷰는 더 나쁩니다. AI 생성 codebase에 대해 확장 가능한 유일한 방어는 결정론적 enforcement입니다. 무시되는 제안이 아니라 빌드를 실패시키는 규칙입니다.

AI 생성 코드에 대한 표준 조언은 "주의 깊게 리뷰하라"입니다. 이 조언은 정확하지만 규모에서는 쓸모없습니다. AI 출력을 리뷰하는 개발자는 주의력이 높고, 해당 도메인에 익숙하고, 시간 압박이 없을 때 문제를 잡아냅니다. 그 외의 모든 조건에서 — 그리고 대부분의 조건이 그렇습니다…

단위 테스트는 통과했지만, 프로덕션 코드는 여전히 망가져 있다.

코드 커버리지 지표는 허위 안전감을 조성한다. 단위 테스트가 실제로 잠을 설치게 하는 버그를 놓치는 이유, 그리고 대신 무엇을 테스트해야 하는지 알아보자.

코드 커버리지가 90%인데도 새벽 2시에 호출을 받았다. 단위 테스트는 통과했다. CI는 초록불이었다. 그런데 버그는 어김없이 프로덕션에 올라갔다. 커버리지가 거짓말을 한 건 아니지만, 진실을 말해준 것도 아니다. 커버리지는 어떤 라인이 실행됐는지 쟀을 뿐, 어떤 동작이 실제로…

Rust 런타임 contracts는 릴리스 빌드에서 오버헤드 없이 사용할 수 있지만, 컴파일러가 대신 해주지는 않는다

Rust는 디버그 assertions를 자동으로 제거하지만, 진정한 design-by-contract는 debug_assert! 이상의 것이 필요하다. 릴리스 바이너리에서 완전히 사라지는 zero-cost runtime contracts를 만드는 방법을 소개한다.

Rust는 개발 환경에서 runtime contracts를 강제할 수 있고, 릴리스 빌드에서는 완전히 지워버릴 수 있다. 전제 조건은 이 언어가 contract를 first-class 개념으로 다루지 않는다는 것이다. 필요한 구성 요소는 주어지지만, 직접 연결해야 한다. 는 가장 먼저…

0개, 1개, 아니면 12개: 프로덕션 함수에 실제로 필요한 assertion의 개수

개발자들은 assertion을 색종이처럼 뿌리거나 아예 사용하지 않는다. 유용한 invariant와 프로덕션 crash를 유발하는 요인을 구분하는 결정 프레임워크를 소개한다.

대부분의 프로덕션 codebase는 두 진영 중 하나에 속한다. A 진영은 를 장식용 조미료처럼 다루어 함수가 편집증적인 변호사가 쓴 법률 계약서처럼 읽힐 때까지 한 줄 걸러 뿌린다. B 진영은 assertion을 개발 중에만 쓰는 보조 바퀴로 여겨 빌드 시점에 모두 제거하고,…

검증 계층이 비즈니스 로직보다 더 커지는 경우

수동 검증은 codebase를 부풀리고 여전히 엣지 케이스를 놓친다. 선언적 스키마로 runtime contracts를 간섭 없이 강제하는 방법을 알아본다.

API가 요청을 받을 때마다 검증한다. 함수가 외부 시스템으로부터 인자를 받을 때마다 확인한다. 이를 수동으로 하면, 단일 엔드포인트에 비즈니스 로직보다 더 많은 검증 코드가 쌓일 수 있다. 이것이 runtime contracts의 숨겨진 비용이다. 타입 시스템이 거짓말을 하기 때문에…

TypeScript strictNullChecks는 컴파일 타임 가드일 뿐, 런타임 방패가 아니다

strict mode는 내가 작성한 null만 잡아낼 뿐, API나 DOM 쿼리, JSON.parse를 통해 런타임에 유입되는 null은 잡지 못한다. 타입 시스템의 한계가 끝나는 지점과 진짜 방어가 시작되는 지점을 살펴 본다.

에서 를 켰다. 모든 빨간 물결표시를 고쳤다. 과 는 이제 해결된 문제라는 자신감을 안고 프로덕션에 배포했다. 그런데 백엔드 응답 구조가 바뀌고, DOM 쿼리가 아무것도 반환하지 않았고, TypeScript가 안전하다고 말한 바로 그 코드에서 이 을 던지며 죽었다. 무슨 일이 일어난…

AI 시대, 코드 리뷰는 명세 검토가 된다

AI가 명세에서 구현, 테스트, contract까지 만들어낼 수 있게 되면, 인간이 가장 크게 기여할 수 있는 일은 더 앞단으로 이동합니다. 가장 엄격하게 검토해야 할 대상은 구현이 아니라 명세 그 자체입니다.

AI를 붙여 몇 주만 개발해 봤어도, 아마 이 감각을 이미 알고 있을 겁니다. PR을 엽니다. 코드는 충분히 깔끔합니다. 이름도 무난합니다. 테스트도 있습니다. 겉으로 보기엔 분명히 망가진 곳이 없습니다. 그런데도 어딘가가 걸립니다. 경계가 조금 흐릿한 걸지도 모릅니다.…

AI Safety Stack: types, contracts, property tests, mutation gates

AI-generated code를 production에서 버티게 하려면 code review만으로는 부족합니다. type constraints부터 mutation testing, runtime containment까지 layered safety stack이 필요합니다.

AI-generated code의 가장 위험한 점은 항상 틀리다는 데 있지 않습니다. 가장 위험한 점은 너무 자주, merge해도 될 만큼 그럴듯해 보인다는 데 있습니다. 바로 그 점이 리스크입니다. 명백히 깨진 code는 잡힙니다. 하지만 그럴듯해 보이고, 몇 개의…