부록 — 이 책은 어떻게 만들어졌나
이 책은 MicroHs의 역사에서 배우고 싶어 한 — 그리고 마땅히도, 남의
작업에 대한 AI의 검증되지 않은 서술을 그대로 신뢰하고 싶어 하지 않은
— 한 사람의 지시에 따라 AI(앤트로픽의 클로드)가 썼다. 이 부록은 제작
과정을 서술하는데, 그 과정 자체가 재사용 가능한 기법이기 때문이다:
풍부한 역사를 가진 어떤 저장소든 겨냥하면 검증된 교재 한 권이 나온다.
이 판본을 위한 설계 명세와 실행 계획은 이 저장소의
docs/superpowers/ 디렉터리에 보존되어 있다.
과정의 모양
-
이정표에서 범위를 정한다.
git log --reverse를 훑어 자연스러운 호를 찾는다: 여기서는, "First version"(첫 버전, 파일 두 개, 저녁 한 번) → "Make a real compiler"(진짜 컴파일러 만들기) → 셀프 호스팅 → "Now bootstraps with type checking."(이제 타입 검사와 함께 부트스트랩된다) 순서다. 장(章)들은 그 호의 주제별 국면이지 — 장당 커밋 하나도, 장당 하위 시스템 하나도 아니다. 작업 방식이 깃든 곳이 시간 순서이며, 그 방식이야말로 요점이었기 때문이다. -
명세, 그다음 계획, 그다음 장마다 새로운 시선. 짧은 설계 명세가 독자상(하스켈에 익숙하지만 컴파일러는 처음인 사람), 장 구성, 규칙을 확정했다. 계획이 이를 열네 개의 작업으로 바꾸었다. 각 장은 그다음 새로운 AI 에이전트가 썼는데, 이 에이전트는 오직 자신의 브리핑만 보았다: 커밋 범위, 깊이 있게 다뤄야 할 커밋들, 전역 제약을 그대로, 그리고 앞선 장들이 확립한 사실들. 새로운 시선은 갖고 있지 않은 맥락에 기댈 수 없다 — 주장하는 모든 것을 역사 자체에서 끌어와야 한다.
-
모든 장에 적대적 리뷰. 각 장을 그 브리핑에 대해 다른 에이전트가 검토했는데, 작성자의 보고서를 검증되지 않은 주장으로 취급하라고 명시적으로 지시받았고, 이름 붙은 위험 요소의 짧은 목록을 받아 이를 diff에서 다시 유도해 검사했다 — 작성자의 서술을 다시 읽어서가 아니라. 발견 사항에는 file:line 증거가 필요했다. 작성자가 고쳤고, 리뷰어가 그 수정을 다시 검토했다. 열네 개 작업 중 열 개는 최소 한 번의 수정 라운드가 필요했다.
-
최종 전체 책 리뷰(가용한 가장 강력한 모델로)는 장 단위 게이트로는 검사할 수 없는 것을 검사했다: 장들 사이의 연속성, uhs→mhs 이름 변경의 시간대, 확고한 경계(
a38c64ce이후로는 아무것도 서술하지 않음), 그리고 장을 가로지르는 새로운 사실 표본들.
중요했던 규칙들
품질을 위한 장치 대부분은 돌이켜 보면 당연하다 — 코드를 바이트 그대로 인용하고, 주장하는 것을 실제로 실행해 보라. 아래 규칙들은 배워서 얻은 것들로, 각각 이 책의 초고에서 리뷰가 실제로 실패를 잡아낸 데서 나왔다:
-
인용은 바이트 그대로이거나, 그렇지 않다면 표시한다. 개관의 초기 초고가 두 행을 뺀 뒤 칼럼을 다시 맞춘
git show --stat출력을 인용한 적이 있다. 바이트 비교가 이를 잡아냈다. 규칙은 이렇게 됐다: 실제 바이트를 인용하고, 모든 생략을 명시적인...로 표시하며,commit:file을 인용할 때는 그 커밋 시점에 실제로 존재하던 경로를 쓴다(뒤쪽의 한 장이 이미src/runtime/eval.c로 옮겨진 뒤의 커밋에서eval.c를 인용한 적이 있는데 — 그 인용이 풀리지 않았다). -
검증되지 않은 메커니즘을 사실처럼 서술하지 않는다. 한 초고는
x + y에서 C가 어느 피연산자를 먼저 평가하는지 단언했다. C 표준은 이를 규정하지 않고, 어떤 트랜스크립트도 이를 보여주지 않았다; 그 대목은 어느 순서든 성립하도록 다시 쓰였다. 다른 초고는 그럴듯한 메커니즘으로 버그 수정을 서술했는데 — 커밋은 맞지만 파일이 틀리고 버그의 종류도 틀린 — 리뷰어가 diff에서 이를 다시 유도해 봤을 때만 무너졌다. 그럴듯하지만 틀린 것은 체크리스트는 통과하지만 재유도는 통과하지 못한다. -
인쇄된 텍스트 자체가 테스트 산출물이다. 모든 "직접 해보기" 블록은 출판 전에 실행되었다 — 그런데 그것으로는 충분하지 않았다. 어느 장의 연습 문제들은 각각 따로는 동작했지만, 인쇄된 순서가 그 사이의 재빌드를 빠뜨려서, 텍스트를 순서대로 따라간 독자는 오래된 산출물을 diff하게 되었을 것이다. 다른 장은 아직 워크트리가 필요한 연습 문제들보다 워크트리 정리 블록을 앞에 배치했다. 고친 방법: 리뷰어가 순진한 독자로서, 인쇄된 그대로 연습 문제를 종이 위에서 따라가 본다.
-
커밋 제목은 실제보다 덜 말한다; diff를 감사한다. 단순한 파일 이동이라고 제목 붙은 어느 커밋이 조용히 완전히 새로운 모듈(네이티브 평가에 대한 초기 실험)을 들여왔다 — 게다가 종료되지 않은 문자열 리터럴까지 딸려서. 서술은 처음에 그 제목의 이야기를 그대로 반복했다. 규칙: 서술하는 모든 커밋에 대해 diff 전체를 읽고 제목이 말하지 않는 것을 밝힌다. 이 책의 각 장은 지금 아우구스트손 (Augustsson)의 역사에 대해 이 원칙을 실천하고 있으며, 리뷰들은 이 책 자체에 대해 그것을 실천했다.
-
재현되지 않는 것은 재현되지 않는다고 말한다. 기록으로 남은 2023년의 스택 오버플로 크래시가 최신 시스템의 기본 한도 아래서는 일어나기를 거부했다. 그 장은 그 사실을 그대로 말하고, 대신 관찰된 것을 보여준다. 정직한 엔지니어링을 다루는 책이라면 자신의 환경이 가진 차이를 얼버무릴 수 없다.
-
부정적인 주장도 검증한다. 8장은 프로파일링 플래그가 컴비네이터 빈도 순서에 반영되는지 확인한다 — diff는 아무 연관도 보여주지 않고, 그 장은 실제로 살펴본 뒤 정확히 그렇게 말한다.
숫자로 가늠하기
대략: 책 제작에 커밋 28개; 열네 개 작업 중 열 개가 수정 라운드를 필요로 함; 리뷰에서 발견된 사항은 바이트 수준(다시 맞춘 stat 칼럼)부터 구조적인 것(연습 문제의 전제를 무효화한 누락된 재빌드 단계)까지 걸쳐 있었다. 모든 수정은 그 자체로 다시 리뷰되었다. 최종 전체 책 리뷰는 여덟 개의 추가 문제 — 두 개의 aux 문서가 이탈해 버린 관례를 가정한 명령들, 범위 서술 하나의 오류 — 를 찾아냈고, 그 수정 역시 다시 리뷰되었다. 이 어느 것도 정확성을 보장하지는 않는다; 다만 확인할 수 있는 모든 주장이 이미 한 번은 적대자의 검사를 견뎌냈다는 뜻이다.
이 과정을 재사용하기
이 과정을 압축한, 실행 가능한 형태 — 장 브리핑과 리뷰어 배정 템플릿,
그리고 위의 실패에서 얻은 규칙들 — 은 이 책과 함께 에이전트 스킬
파일로 배포된다:
skills/writing-teaching-books-from-git-history/.
평범한 마크다운 파일이며, 그 디렉터리의
README가
스킬 파일이 무엇이고 어떻게 설치하는지 설명한다. 이 방법에서 AI에만
해당하는 것은 하나도 없다. docs/superpowers/의 명세와 계획은 이 책을
만들어낸 구체적인 사례를 보여준다.
다른 곳에 적용하려면: 그 역사에서 배우고 싶은 저장소를 찾고, 끝점을 정하고, 이 책이 여러분과 맺는 것과 같은 약속을 모든 장에 적용한다 — 인용된 모든 것은 실재하고, 주장된 모든 것은 실제로 실행되었으며, 그 나머지는 모두 표시되어 있다는 약속을.