2026년 7월, Lean 주변에서는 다소 기묘한 사건들이 이어졌다. AI 지원으로 만들어졌다는 콜라츠 추측(Collatz conjecture)의 '반증'이 공개되었는데, 심지어 그 증명은 sorry가 없는 Lean 형식화된 형태로 나타났다. 하지만 나중에 거슬러 올라가 보니, 그것은 수학적 신규 발견이라기보다는 증명 검사기 측의 허점을 이용한 결과였다. 증명의 내용 자체를 보고 안심하는 것만으로는 충분하지 않다. 마지막으로 그것을 심판하는 커널이 제대로 거부할 수 있는지가 핵심이다.
Lean 개발자가 2026-08-01에 공개한 사후 보고서에서는 이 문제의 중심에 커널의 soundness bug #14576가 있었다고 설명했다. 발각 계기는 7월 25일에 공개된 콜라츠 반증 리포지토리였다. 7월 28일에는 그것을 작은 False의 증명까지 축소한 보고서가 issue로 올라왔고, 약 1시간 후에 수정이 이루어졌다. 즉, 외부에서 보기에는 'AI가 난제를 풀었을지도 모른다'고 보였던 것이 실제로는 증명 기반의 허점을 건드렸을 뿐이었다.
이런 종류의 사고에서 까다로운 점은, 전 단계의 검사를 모두 빠져나갈 필요는 없다는 것이다. Lean의 프론트엔드는 보통 입력된 항(term)을 타입 체크한다. 하지만 이번 결함은 더 안쪽, 즉 커널이 직접 받는 경로에 있었다. 사후 보고서에 따르면, 중첩된 귀납형(nested inductive type) 처리를 하면서 특정 매개변수가 '유령'처럼 사라져 버리고, 생성된 보조 타입의 타입 체크를 피할 수 있는 상황이 발생했다. 그곳에 부적절한 인수를 슬쩍 넣으면 커널이 False의 증명을 받아들이게 된다.
여기서 중요한 것은, 이것은 이론의 붕괴가 아니라 구현 버그라는 점이다. Lean의 메타 이론 자체에 구멍이 생긴 이야기가 아니다. 게다가 도달 경로는 메타 프로그래밍을 통해서만 가능하다. 프론트엔드는 거부하지만, 커널 단독으로 직접 주입하면 통과해 버린다. 증명 지원계에서는 이 '외부는 신뢰하지 않고, 내부에서 반드시 재검사한다'라는 분리가 생명선이 된다.
더 흥미로운 것은, 독립 구현의 외부 검사기 nanoda 역시 이번 사건에서 다른 결함을 안고 있었다는 점이다. 원래 콜라츠 계열 리포지토리는 week-old의 nanoda로도 통과했지만, nanoda는 그 부분을 다른 이유로 놓치고 있었다. Lean 본체의 버그와 nanoda의 버그는 무관하며, 우연히 같은 증명이 두 개의 구멍을 지나갔던 것이다. 독립적인 검사기를 사용한다고 해서 안심할 수만은 없다는 것이 명확해진 순간이었다.
이 사건 이후, Lean 측은 '외부 커널로 재검사하는' 메커니즘을 본격화했다. 2026-10-15 개발자 블로그에서는 Lean v4.35.0에 lake check가 추가되어 개발 성과를 sandbox 내에서 재검사할 수 있게 되었다고 안내되었다. 게다가 --paranoid 옵션을 붙이면 공식 커널뿐만 아니라 nanoda, lean4lean, con-leche, con-ron 네 개의 외부 커널에서도 검사가 가능하다. 심지어 공식 커널의 변종도 하드화된 메모리 할당자(memory allocator)가 적용되어 실행된다. 이는 메모리 손상이 조용히 오답이 되는 것이 아니라 checked abort로 바뀌도록 하기 위함이다.
이 구도가 보여주는 것은, 단일한 감시자만으로는 부족하다는 현실이다. 하나의 커널이 옳은지 의심하는 것이 아니라, 다른 설계의 감시자를 여러 개 배치하고 같은 증명을 각각 통과시키는 것이다. 만약 하나가 놓치더라도, 다른 하나가 막는다. 사후 보고서에서도 con-leche와 con-ron을 모두 통과시킴으로써, Lean의 compiler나 runtime 쪽에 숨어있는 결함까지 포함하여 상당히 강력한 방어가 된다고 설명했다. 이유는 간단하다. 같은 구현 실수가 Lean 측과 Rust 측 양쪽에 동시에 있을 가능성은 낮기 때문이다.
여기서 등장하는 것이 con-leche이다. 이것은 Lean으로 작성된 외부 검사기로, 게다가 'False의 증명을 받아들이지 않는다'는 것이 Lean 내에서 증명되어 있다. README에는 검사기 구현에 약간 과도한 작업, 즉 soundness를 깨뜨리지 않는 범위의 타입 비교를 허용함으로써 증명이 통과하기 쉽게 만들었다고 적혀 있다. 설계적으로는 Lean의 Expr에 의존하지 않는 독자적인 항 표현을 사용하며, 기존 미검증 C++ 루틴에 의존하지 않는다. 게다가 nested나 mutual을 포함하는 귀납형을 일관된 방침으로 다룬다.
proof idea 문서를 읽어보면, 이 증명은 상당히 논리적이다. 검사기가 수용한 환경에는 집합론적 모델(set-theoretic model)이 반드시 존재한다는 방식으로 consistency를 보여준다. False는 공집합이고, Eq
는 집합의 등호로 해석되기 때문에, False
증명을 포함하는 환경은 모델을 가질 수 없다. 요컨대, 수리적 증명(truth)과 수용(acceptance)을 연결하는 다리를 타입 이론 내부가 아니라 모델론에서 놓고 있는 것이다.
게다가 con-leche는 '느려서 안전하다'는 의미가 아니다. 개발자 블로그에 따르면, full Mathlib export를 공식 커널의 0.69배 명령수로 실행하며, 8 스레드에서 약 100초 만에 전체를 검사할 수 있다고 한다. 방어적인 태도를 취하면 느려진다는 통념을 그대로 받아들이지 않는 것이다. 여기서 더 나아가 Rust 버전인 con-ron이 만들어져, Lean으로 증명된 결과를 Rust로 옮겨 다른 실행계에서 재확인한다. 이 정도에 이르면 더 이상 '커널을 신뢰하는' 문제가 아니다. 커널을 여러 방법으로 의심해 보는 설계가 되어 있는 것이다.
흥미로운 점은 Lean 개발자들이 이 단계에서도 만족하지 않는다는 것이다. lake check를 더욱 사용하기 쉽게 만들고, 원하는 외부 커널을 연결할 수 있게 하고, 나아가 미래에는 컴파일러의 일부까지 검증하고 싶다고 적혀 있다. 이유는 명확하다. Mathlib는 2.5M LoC(Lines of Code)이고, Anthropic의 FLT는 13M LoC를 넘으며, Tau Ceti는 3M LoC를 넘고, 게다가 1B LoC급의 수학 라이브러리 구상까지 나와 있다. 현재 외부 커널 연결 방식으로는 이 규모를 감당할 수 없다. 이중화만으로는 부족하며, 바이너리 형식의 내보내기(export)나 증분 검사(incremental check)까지 필요하다.
따라서 이번 본질은 'AI가 난제를 해결한 것처럼 보였다'는 것이 아니다. 그 뒤에서 증명 지원계가 자신의 발판을 어디까지 스스로 단단하게 만들 수 있는지 시험받았다는 데 있다. Lean은 지금 공식 커널만 지키는 것을 넘어, 자신만의 감시자(watchdog)를 스스로 증명하고, 심지어 다른 구현체로 뒷받침하는 단계에 진입했다. 그렇다면 이 검증된 커널들 중에서 con-leche와 con-ron은 각각 무엇을 어디까지 보장하며, 어디에 아직 구멍이 남아있는 것일까. 그 부분이 다음 초점이 될 것이다.
👉 계속(핵심은 여기서부터)은 PaPoo에서 읽을 수 있습니다: https://papoo.work/doc/121e566cb2a3c858