2026-09-23 · x.com

Opus 5.5로 Claude Agent SDK를 Lean으로 형식 검증했다

  1. (1)읽기 전에
  2. (2)Executive Summary
  3. (3)팩트체크
  4. (4)원본 (완역)
  5. (5)원본 링크·인용
  6. (6)기타

x.com · Boris Cherny · 2026-09-23

Opus 5.5로 Claude Agent SDK를 Lean으로 형식 검증했다

트윗의 "짧은 프롬프트 몇 개"는 영상에서 Slack 메시지 6개와 사람의 PR 승인·리뷰 코멘트였다. 증명은 3시간 만에 끝났지만 엔진 모델은 실제 실행에 맞춰 재작업됐고, 버그 24개 중 19개만 증명 출신이며, 증명이 낸 1차 수정은 리뷰에서 구멍 6개가 드러나 후속 PR 4개가 따라붙었다. "증명으로 단순화"는 삭제가 아니라 중복 병합이었다.

읽기 전에

프롬프트 6개로 Lean 4 모델 6개를 쓰고, 증명이 낸 반례를 PR 16개로 고친 하루

사람이 형식 검증 언어를 모르는 채로 짧은 지시만 주면, 모델이 실제 코드에서 상태기계를 모델링하고 증명해서 사람이 못 찾던 버그를 실제 수정 PR까지 끌고 갈 수 있는가.

Slack에서 사람이 준 것은 메시지 6개(검증해라 → PR 공개해라 → 같은 증명으로 코드 단순화해라 → 머지 걸어라 → 집계해라 → 인포그래픽 그려라)와 GitHub 승인·리뷰 코멘트뿐이다. 모델은 SDK와 claude.ts에서 상태기계 6개(stream, retry, turn loop, engine, session phase, SDK control)를 Lean 4로 옮겨 정리 1,359개를 sorry 없이 증명하고, 증명이 내놓은 반례를 실제 코드에 재현해 실패-후-성공 테스트가 붙은 수정 PR 6개를 냈다. 같은 증명이 "삭제할 분기는 거의 없고 중복 경로는 합칠 수 있다"는 근거가 되어 단순화 PR 6개, 리뷰 후속 PR 4개가 따라붙어 총 16개가 머지됐다. 최종 집계는 버그 24개(증명 발견 19 + 리뷰 발견 5), 비테스트 코드 순증 218줄, 테스트 케이스 +94.

선행 개념

  • Lean 4 — 정리 증명기이자 프로그래밍 언어. 코드의 상태 전이를 함수와 명제로 적고, 그 명제가 참임을 커널이 기계적으로 검사한다. 영상에서 "모델을 쓴다"는 것은 TypeScript 로직을 Lean 정의로 다시 쓰는 일이다.
  • sorry — Lean에서 "이 증명은 나중에" 하고 건너뛰는 자리표시자. "0 sorry"는 미완 증명 없이 전부 검사를 통과했다는 뜻이며, 이 글에서 완결성의 기준으로 반복해 쓰인다.
  • lake build — Lean 프로젝트 빌드 명령. 빌드가 green이면 모든 정리가 커널 검사를 통과한 것이다.
  • 세 표준 공리(propext · Quot.sound · Classical.choice) — Lean 표준 라이브러리가 기본으로 두는 공리 셋. "이 셋만 썼다"는 것은 증명이 사용자 정의 가정 없이 표준 수학 위에서만 성립한다는 뜻이다.
  • TLA+ — 동시성 시스템의 상태와 시간 흐름을 명세하고 모델 체커로 탐색하는 언어. 트윗에서 Lean과 함께 데이터 흐름·동시성·상태 관리 문제를 찾는 데 쓴다고 언급된다.
  • 상태기계를 코드에서 모델링한다 — 스트림·재시도·턴 루프 같은 모듈을 "상태 집합 + 전이 규칙"으로 추상화해 옮기는 것. 영상의 산출물에는 전이마다 원본 file:line을 인용한 명세와 각 모델의 가정·증명하지 않는 것이 함께 들어 있다.
  • 반례(counterexample)와 실제 트레이스 재생(replay) — 불변식이 깨지는 입력 순서를 증명기가 내놓으면 그것이 반례다. 모델이 실제 코드와 같은지 확인하려고 실제 실행 기록(예: 엔진 400회)을 모델에 통과시키는 것이 재생이며, 이 둘이 "모델이 코드를 잘못 옮겼다"는 위험을 줄이는 장치다.
  • 형식 검증 vs 테스트 — 테스트는 골라낸 입력 몇 개를 실행하고, 형식 검증은 모델 안의 모든 경로에 대해 성질을 증명한다. 대신 검증의 보증은 모델이 코드를 얼마나 충실히 옮겼는가에 한정된다. 영상에서 반례를 실패 테스트로 되돌려 붙이는 이유가 여기에 있다.

권장 읽기 순서

  • 영상 전문부터 — 어떤 프롬프트가 어떤 산출물로 이어졌는지, 모델이 스스로 낸 정정(턴 루프 수정의 미비, 엔진 증명의 잠정성)까지 시간순으로 보이는 유일한 블록이다.
  • 다음 인포그래픽 — 영상 끝의 집계를 한 장으로 요약하지만, 정리 개수(1,529)와 PR 상태(5 머지 / 11 열림)가 영상 중간 시점의 숫자와 다르므로 영상을 본 뒤 봐야 어느 시점의 스냅샷인지 읽힌다.
  • 마지막에 트윗 본문 — 4문단은 저자의 요약과 질문("형식 검증이 코딩의 미래인가")이라, 영상의 실제 과정을 알고 읽어야 "짧은 프롬프트 몇 개"가 무엇을 가리키는지 판단할 수 있다.

Executive Summary

"짧은 프롬프트 몇 개"의 실체는 Slack 메시지 6개에 사람의 PR 승인·리뷰 코멘트가 얹힌 약 19시간짜리 루프였고, 증명이 잡은 버그의 1차 수정 자체가 리뷰에서 6개 구멍을 드러냈다

Boris Cherny(Anthropic, Claude Code)는 Opus 5.5에게 Claude Agent SDK와 claude.ts 상태 기계를 Lean 4로 검증시켜 PR 16개를 얻었다고 썼다. 첨부 영상(Slack 스레드 녹화)을 화면 타임스탬프대로 읽으면 그림이 달라진다. 증명은 약 3시간 만에 끝났지만, 6개 모델 중 엔진 모델은 실제 실행과 어긋나 "잠정"으로 시작해 실행 400건을 모두 받아들일 때까지 코드에 맞춰 재작업됐고, 버그 24개 중 증명 출신은 19개, 나머지 5개는 리뷰에서 나왔으며, "증명으로 단순화"는 코드 삭제가 아니라 중복 병합으로 귀결됐다(전체 비테스트 코드는 오히려 +218줄). 원문의 마지막 문장 "형식 검증이 코딩의 미래인가"는 주장이 아니라 질문이다.

16 PR

수정 6 · 단순화 6 · 리뷰 후속 4. 모두 머지됐다(영상 마지막 프레임 4:47 PM).

24 버그

증명이 찾은 19 + 리뷰에서 드러난 기존 버그 5. 여기에 1차 수정의 구멍 6개가 별도로 잡혔다.

6 모델 · 1,529 정리 · sorry 0

인포그래픽 기준. 1:07 AM 감사 시점엔 1,359였다(아래 불일치 항목).

프롬프트 6개 · 약 18시간 44분

10:03 PM 첫 지시 → 다음 날 4:47 PM 전부 머지. 그중 약 11시간 47분은 사람 발화가 없는 공백이다.

Lean 4 verification of the SDK + claude.ts state machines 인포그래픽: 16 PR, 24 버그, 비테스트 +1,381/−1,163, 테스트 +94/−9, 6 모델 1,529 정리 sorry 0
Opus 5.5가 "render it as a small infographic" 지시로 만든 집계 이미지(작성자 자기 답글). 작성 시점(3:04 PM)의 상태라 "5 merged, 11 open"으로 적혀 있다.

원문이 말하는 것

"프롬프트 몇 개"의 실체 — 사람 입력의 전체 목록

영상에 보이는 사람의 Slack 발화는 여섯 개다. 그러나 Claude는 스레드에서 반복해 "Each one needs your approval before it can merge"라고 쓰고, "review comments"와 "two blocking review findings"에 맞춘 후속 PR을 낸다. 즉 사람의 개입은 프롬프트 6개 외에 GitHub 상의 PR 승인과 리뷰 코멘트를 포함한다.

  1. 10:03 PM — "Use lean to verify the sdk and Claude.ts state machine"
  2. 12:59 PM — "publush all prs"
  3. 1:05 PM — "take that same proof and simplify the code / and mark all prs merge when ready"
  4. 2:55 PM — "publish and mark merge when ready"
  5. 2:59 PM — PR 총수·버그 수·테스트 제외 증감·테스트 증감 질문
  6. 3:00 PM — "render it as a small infographic"

시간 구조는 화면 타임스탬프로만 읽는다. 증명 단계는 10:03 PM → 1:07 AM(약 3시간 4분)에 끝났다. 1:12 AM 여섯 번째 PR 이후 12:59 PM까지 사람 발화가 없고, 오후는 공개·단순화·리뷰 대응·머지 대기로 흘러 4:47 PM에 "All 16 PRs are merged"로 닫힌다.

6개 모델이 각각 증명한 것과 잡은 버그

1:07 AM 감사 차트 기준. "정리" = Lean 4 커널이 검사한 theorem+lemma 수(sorry 없음, 공리는 propext / Quot.sound / Classical.choice 셋뿐). "재생" = 실제 실행 트레이스를 모델에 통과시킨 수락/전체. "대표 버그" = 12:08 AM·1:12 AM 게시물의 수정 PR 설명.
모델정리재생수정 PR대표 버그
claude.ts stream2196/6#72140응답 중간에 본문이 깨끗이 끝나면 성공으로 처리, stop reason·비용 기록 없음(게이트웨이/3P 경로 필요)
withRetry20111/11#72145persistent 모드에서 429/529 대기가 다른 오류의 예산을 소진; Retry-After 하루짜리 503이면 하루를 통째로 잠
query.ts turn loop15733/33#72130잘못된 tool call 재시도와 max_tokens 절단 복구가 서로의 guard를 리셋 → 출력이 번갈아 나오면 무한 루프, --max-turns 1로도 안 멈춤
engine turns319400/400#72162빌더 실패 후 flush 중 소비자가 스트림을 끊으면 턴이 cancelled로 보고되지 않음; 첫 next()return(), 포기 후 늦은 send() 조용히 큐잉(저심각도: headless 세션은 uuid 없이 턴을 보내 SDK 소비자가 못 맞음)
session phase16968/68#72128샌드박스 네트워크 질의와 권한 프롬프트가 겹치면 둘 다 답해도 세션이 requires_action에 잔류, 때로 다음 턴 내내
SDK control protocol2942/2#72135취소 후 재전달된 권한 요청이 아무도 취소 못 하는 핸들러를 남김; transport close가 throw하면 모든 awaiter가 고립

지켜진 것으로 보고된 불변식: 턴당 결과 하나·순서 보장·init 우선, idle 전에 result, 재시도 상한과 abort, 스트림은 닫힌 블록만 yield. 각 PR은 "수정 전 실패·수정 후 통과" 테스트를 동반한다.

24개 버그의 출처는 세 겹이다

따라서 "증명이 버그를 찾았다"는 절반이다. 증명 → 수정 → 리뷰 → 재수정의 두 번째 패스가 없었으면 수정 자체가 새 결함을 남겼다.

엔진 모델은 코드에 맞춰 고쳐졌다

12:08 AM 게시물은 엔진 모델이 "실제 실행 몇 건과 아직 어긋나므로 증명을 잠정으로 보라"고 했다. 1:07 AM에는 "재작업된 엔진 모델이 400건 중 400건을 받아들인다"가 됐다. 모델이 실행을 거부하면 코드가 아니라 모델을 고친 것이다. 이는 형식 모델이 코드의 사후 서술이지 독립 스펙이 아니라는 뜻이고, 모델이 코드의 결함을 그대로 베꼈을 가능성을 증명 자체로는 배제하지 못한다는 뜻이다. 산출물 tarball에는 각 모델의 "가정과 증명하지 않는 것"이 별도 항목으로 들어갔다.

"증명으로 단순화"의 실제 산출 — 삭제가 아니라 병합

불일치와 경계 조건

정리 개수
1:07 AM 최종 감사 "1,359 of 1,359"; 3:04 PM 인포그래픽 "1,529 theorems". 둘 다 sorry 0·모델 6개. 차이 170의 출처는 영상에 나오지 않는다.
머지 상태
인포그래픽은 "5 merged, 11 open"(3:04 PM 시점). 4:01 PM "13 of 16 merged", 4:47 PM 전부 머지. 이미지는 중간 스냅샷이다.
자동 머지
"merge when ready"는 사람 승인을 대체하지 않았다. #72135는 main과의 충돌 해소로 승인이 무효화됐다가 "이전 승인이 새 커밋에 이월됐다"로 정정됐고, 같은 파일을 건드리는 네 쌍(session·retry·stream·turn loop)은 앞 PR이 머지될 때마다 뒤 PR을 리베이스했다.
리뷰 범위 초과
Claude가 먼저 밝힌 항목: 세션 후속 #72509는 hasStandingPrompt()를 좁히는데, 리뷰 코멘트가 요구한 것보다 멀리 간다.
도구 스택
Claude는 Slack 앱으로 동작하며 각 메시지에 "Lens · Opus 5.5" 푸터가 붙는다. 산출물은 Lean 소스·빌드 README·전이마다 file:line을 인용한 모듈별 스펙을 담은 tarball.

답글 스레드가 더한 맥락

원문이 남긴 질문의 위치

"형식 검증이 코딩의 미래인가"는 주장이 아니다. 영상이 실제로 뒷받침하는 범위는 좁고 구체적이다. 이미 존재하는 상태 기계 코드를 Lean으로 사후 모델링하면 동시성·재시도·상태 잔류형 버그 19개가 반례로 나왔고, 그 수정은 사람 리뷰 한 패스를 더 거쳐야 온전해졌으며, 증명은 코드를 줄이기보다 중복을 합치는 근거가 됐다. 이 범위를 넘어서는 일반화는 원문에도 영상에도 없다.

"the proofs show almost every flag and branch is reachable, so there's little to delete. What they do license is merging copies of the same logic into one." — Claude, 1:16 PM

팩트체크

외부에서 확인 가능한 주장(저자·모델·SDK·Lean/TLA+ 사실)은 모두 맞다. 수치와 PR 번호는 원문(영상·인포그래픽) 안에서만 확인되며, 정리 수 1,359 대 1,529 불일치 1건과 "몇 개의 짧은 프롬프트"의 과소 표현이 남는다.

B

독립 출처로 반증된 주장은 없다. 다만 핵심 성과(16 PR·24 버그·1,529 정리)는 Anthropic 내부 저장소와 Slack 화면에만 존재해 제3자가 재현할 수 없고, 영상 내부에서 정리 수가 두 값으로 갈리며, 같은 스레드의 형식검증 전문가(Hillel Wayne)는 "AI는 시스템 속성 도출에 매우 서툴다"는 반대 경험을 제시한다.

판정 어휘 정의: 사실 = 독립 출처로 확인 · 부분사실 = 핵심은 맞으나 세부 불일치 · 불확실 = 확인 수단 없음 · 내부정합 = 원문 자료 안에서만 확인 가능 · 의견 = 검증 대상 아님 · 거짓 = 반증됨

사실
저자 Boris Cherny(@bcherny)는 Anthropic 소속이며 Claude Code를 만든 사람이자 현재 책임자다.
Pragmatic Engineer(2026-03-04)는 그를 "the creator and Head of Claude Code at Anthropic"으로 소개한다. X 계정 자기소개도 "Claude Code @anthropicai"이며 팔로워 약 57.7만의 인증 계정이다. 이전 경력은 Meta Principal Engineer 5년, 저서 Programming TypeScript. Pragmatic Engineer · 원문 트윗
사실
"Opus 5.5"는 실재하는 Anthropic 모델이며, 트윗은 출시 당일에 올라왔다. 답글에 등장하는 "Fable 5.1"도 실재 모델이다.
Anthropic 공식 페이지는 Claude Opus 5.5를 2026-09-22 출시, API ID claude-opus-5-5, 입력 $4/출력 $20(백만 토큰), "Claude Fable 5.1 수준의 성능을 Opus 5보다 40% 낮은 비용으로"라고 적는다. 트윗 게시 시각(같은 날 23:39 UTC)은 출시 발표 당일이다. Claude Fable 5.1은 2026-09-01 출시된 상위 모델로 Anthropic 공식 페이지에 "Fable 5.1과 Mythos 5.1은 같은 모델, 다른 안전장치"로 설명된다. 공식 페이지에 Lean·TLA+·Agent SDK 언급은 없다. Anthropic: Opus 5.5 · TechCrunch · Anthropic: Fable 5.1
사실
Claude Agent SDK는 실재하는 공개 제품이며, Claude Code의 에이전트 루프를 Python/TypeScript 라이브러리로 노출한 것이다.
공식 문서는 "Build production AI agents with Claude Code as a library"라 정의하고, "Claude Code 바이너리를 실행하는 라이브러리"로 CLI와 구분한다. 공개 저장소 anthropics/claude-agent-sdk-typescript(별 1.8k)는 예제·CHANGELOG·README만 담고 있고 src/가 없다. 영상에 등장하는 claude.ts·query.ts는 이 공개 저장소에도 anthropics/claude-code(별 약 148k, 역시 소스 없음)에도 없다. 따라서 영상의 "SDK 검증"은 공개 SDK 패키지가 아니라 그 아래 깔린 Claude Code 내부 상태기계(stream·retry·turn loop·engine·session phase·SDK control protocol)를 대상으로 한 것이다. Agent SDK 공식 문서 · GitHub: agent-sdk-typescript · GitHub: claude-code
불확실
영상 속 PR 번호 #72128–#72518(16개)은 공개적으로 열람할 수 없다.
공개 저장소의 PR 총수는 claude-code 704개, claude-agent-sdk-typescript 열린 PR 10개로 7만 번대에 이르지 못한다. claude-agent-sdk-typescript/pull/72128은 HTTP 404다. GitHub 공개 URL과 웹 검색 어디에도 해당 번호는 없다. 번호 규모로 보아 Anthropic 내부 모노레포의 PR이라는 것이 합리적 추정이며, 버그 내용·diff·머지 여부는 영상 밖에서 확인할 수 없다. pull/72128 → 404
사실
Lean 4의 sorry, lake build, 표준 공리 3종(propext · Quot.sound · Classical.choice), #print axioms는 영상의 설명대로다.
Lean 언어 레퍼런스 "Axioms" 장은 표준 공리를 Classical.choice, propext, Quot.sound로 열거하고, sorry의 바탕이 되는 네 번째 공리 sorryAx에 대해 "완성된 증명에 나타나서는 안 되며 무엇이든 증명할 수 있다"고 명시한다. #print axioms는 "정의가 전이적으로 의존하는 모든 공리를 표시"해 sorry 의존을 감사하는 용도다. Lake는 Lean 4의 빌드 도구로 "lake build는 패키지(와 의존성)를 빌드한다"고 README가 적는다. 따라서 "1,529 theorems · 0 sorry · 세 표준 공리만"이라는 감사 기준 자체는 Lean 커뮤니티의 표준 관행과 일치한다(Anthropic의 페르마 정리 형식화 발표도 같은 기준을 썼다). Lean 레퍼런스: Axioms · Lake README
사실
TLA+는 Leslie Lamport가 만든 형식 명세 언어이고, 답글의 Hillel(@hillelogram)은 Practical TLA+(Apress, 2018)의 저자 Hillel Wayne이다.
Apress 공식 소스코드 저장소는 "This repository accompanies Practical TLA+ by Hillel Wayne (Apress, 2018)"이라 적는다. 그의 무료 교재 사이트 learntla.com은 TLA+를 "설계 자체를 시험하는 형식 명세 언어, Turing상 수상자 Leslie Lamport 작"으로 소개하며 저자 본인이 Practical TLA+ 저자임을 밝힌다. @hillelogram 계정 bio("Antithesis 개발자 교육자, 형식 방법·소프트웨어 역사·초콜릿, 저서 Logic for Programmers")는 hillelwayne.com/about의 자기소개("현재 Antithesis에서 developer educator로 일한다", Logic for Programmers)와 일치한다. Boris의 답글은 "practical TLA+를 정말 즐겁게 읽었고 몇 년 전 그 책이 이 시도의 계기가 됐다"고 확인한다. Apress 소스 저장소 · learntla.com · hillelwayne.com/about · Hillel 답글 · Boris 답글
불확실
영상 속 Slack 봇 푸터 "Lens · Opus 5.5 · Configure"의 "Lens"는 공개된 제품명이 아니다.
Anthropic이 공개한 Slack 에이전트의 이름은 Claude Tag(2026-06-23 발표, 당시 Opus 4.8 기반)이며, 발표문은 "우리 제품팀 코드의 65%가 내부 버전의 Claude Tag로 만들어진다"고 적어 내부 변형의 존재를 시사한다. "Lens"라는 이름은 Anthropic 공개 자료 어디에도 없고, 웹 검색은 무관한 해석가능성 연구(J-Lens)만 반환한다. 접근 실패: "Anthropic Lens Slack" 검색, Claude Tag 발표문 본문 대조. 영상의 봇이 Claude Tag의 내부 빌드일 가능성이 높지만 이는 추정이다. Anthropic: Claude Tag
내부정합
16 PR(수정 6 · 단순화 6 · 후속 4), 버그 24건(증명 19 + 리뷰 5, 별도로 1차 수정의 빈틈 6), 비테스트 +1,381/−1,163, 테스트 케이스 +94/−9, 모델 6개는 영상과 인포그래픽 사이에서 일치한다.
영상 3:00 PM 작업 목록·3:04 PM 요약·인포그래픽의 수치가 서로 같다. 인포그래픽의 그룹별 합계(수정 +523/−245, 단순화 +546/−741, 후속 +312/−177)를 더하면 +1,381/−1,163으로 총계와 맞고, 순증 +278 −195 +135 = +218도 맞는다. 다만 이 수치의 원천은 Claude 자신이 "각 PR의 diff에서 셌다"는 자기 보고이며 외부에서 재계산할 수 없다. 참고로 이 인포그래픽은 Boris 본인이 "Opus가 만들었다"고 밝힌 AI 생성물이다. 원문 트윗
부분사실
정리(theorem) 수는 영상 안에서 두 값으로 갈린다: 1:07 AM 최종 감사 "1,359 of 1,359", 3:04 PM 인포그래픽 "1,529 theorems".
두 값 모두 "0 sorry · 6 모델"을 동반하며 차이는 170개다. 1:07 AM 이후 단순화 PR 6개와 후속 수정 4개가 "Lean 증명에서" 파생됐으므로 증명이 추가됐을 개연성은 있으나, 영상 어디에도 재감사(lake build·공리 확인) 장면이나 증가 사유가 없다. 트윗 본문은 정리 수를 언급하지 않으므로 트윗 자체의 오류는 아니고 첨부 자료 간 불일치다. Lean 레퍼런스: Axioms
부분사실
"몇 개의 짧은 프롬프트(a couple short prompts)"로 16 PR이 나왔다.
영상에 보이는 사람의 Slack 입력은 6개다: "Use lean to verify the sdk and Claude.ts state machine" / "publush all prs" / "take that same proof and simplify the code · and mark all prs merge when ready" / "publish and mark merge when ready" / 수치 질문 / "render it as a small infographic". 이 밖에 Claude가 반복해서 "당신의 승인이 필요하다", "리뷰 코멘트 수정본", "blocking review findings"를 언급하므로 GitHub에서의 사람 승인과 리뷰 코멘트(다른 리뷰어 또는 자동 리뷰)가 별도로 있었다. 프롬프트가 짧다는 점은 맞지만 "몇 개"는 전 과정의 사람 개입을 과소 표현한다. 벽시계 기준 전날 10:03 PM → 다음날 4:47 PM(약 18시간 44분, 그중 약 11시간은 유휴)이다. 원문 트윗
내부정합
발견된 버그는 "레이스 컨디션"을 포함한다.
영상 12:08 AM 요약의 5건 중 최소 3건이 동시성 문제다: 샌드박스 네트워크 요청과 권한 프롬프트가 겹치면 세션이 requires_action에 고착(#72128), 취소 후 재전달된 권한 요청이 취소 불가 핸들러를 남김(#72135), 잘못된 도구 호출 재시도와 max_tokens 복구가 서로의 가드를 리셋해 무한 루프(#72130). 각 PR에 "수정 전 실패·수정 후 통과" 테스트가 붙었다는 것도 Claude의 자기 보고다. 버그 자체는 공개 코드에서 재현할 수 없다. Agent SDK 문서
불확실
"16개 PR 전부 머지"는 영상 마지막 프레임("Today at 4:47 PM")에만 있고, 트윗 게시 시각과 시간대가 맞지 않을 수 있다.
트윗은 2026-09-22 23:39:32 UTC에 게시됐다(태평양 일광시 16:39). Slack 시계가 태평양 시간이라면 4:47 PM은 23:47 UTC로 트윗보다 8분 뒤가 되어 모순이다. 동부 시간(20:47 UTC)이거나 그보다 동쪽이면 모순이 없다. 저자의 소재 시간대는 공개 자료로 확정할 수 없다. 또 인포그래픽(3:04 PM)은 "5 merged, 11 open"으로 머지 전 상태를 담고 있어, 트윗에 첨부된 두 자료가 서로 다른 시점의 스냅숏이다. 전부 머지됐다는 공개 후속 게시물은 찾지 못했다. 저자의 X 타임라인과 웹 검색에서 전부 머지됐다는 후속 게시물은 찾지 못했다. 원문 트윗
사실
공개 반응: 게시 약 16시간 만에 조회 58만·좋아요 3.3천·답글 260이지만, 2026-09-23 기준 Hacker News 스레드나 주요 매체 보도는 없다.
HN Algolia 검색("bcherny lean formally verify")은 0건이다. 한국어 AI 뉴스 집계 사이트 promppy가 트윗 요약을 게재했을 뿐이며, TechCrunch·VentureBeat 등의 Opus 5.5 출시 기사는 이 트윗을 다루지 않는다. 같은 날 Vals AI는 "Opus 5.5 에이전트 10개가 15시간 만에 최단경로 알고리즘 개선을 Lean으로 형식 검증했다"고 별도로 게시해, 출시 당일 Lean 활용 사례가 이 트윗 하나가 아니었음을 보여준다. 스레드 안의 가장 실질적인 반응은 Hillel Wayne의 회의적 질문이다. HN Algolia: 0건 · promppy · Vals AI 게시물
사실
선행 사례: LLM이 프로덕션 코드에서 TLA+/Lean 명세를 뽑아 버그를 찾은 공개 보고와, Anthropic의 대규모 Lean 검증 발표가 이미 있다. 트윗은 "최초"를 주장하지 않는다.
Cheng Huang(Microsoft Azure Storage)은 2025-05-24 GitHub Copilot(o3 계획 + Claude 3.7 Sonnet 실행)으로 프로덕션 코드에서 TLA+ 명세를 생성해 "옛 Paxos 프라이머리가 삭제하는 동안 새 프라이머리가 참조를 추가하는" 레이스 컨디션을 찾았다고 보고했고, Hillel Wayne은 2025-06-05 뉴스레터에서 이를 인용하며 "LLM은 엄청난 명세 배력기"라 평하되 "흥미로운 속성을 고안하는 일"은 약점으로 꼽았다. Anthropic은 2026-09-04 Claude가 11일간 1,300만 줄의 Lean을 써 페르마 마지막 정리를 "Lean의 표준 공리 3개만으로" 형식화했다고 발표했다. AWS는 2015년 CACM 논문으로 S3·DynamoDB 등에 TLA+를 적용한 경험을 보고했고, 인가 언어 Cedar의 형식 모델은 Lean으로 작성·증명돼 공개돼 있다. 즉 "AI + Lean/TLA+로 실제 코드의 동시성 버그 찾기"는 2025년부터 공개 선례가 있고, 이 트윗의 차별점은 규모(6 모델·16 PR·머지까지)와 Claude Code 내부 코드가 대상이라는 점이다. Cheng Huang 블로그 · Hillel 뉴스레터 · Anthropic: 페르마 정리 형식화 · AWS CACM 2015 · Cedar Lean 명세
의견
"Claude는 두 언어 모두에 뛰어나다", "사람이 못 봤을 버그를 찾는다", "형식 검증이 코딩의 미래인가?"
검증 대상이 아닌 저자의 평가와 열린 질문이다. 같은 스레드에서 Hillel Wayne은 "형식 검증 전문가로서의 경험상 AI는 상위 시스템 속성 도출에 정말 정말 정말 서툴렀다(초보 수준)"며 Opus 5.5가 나아졌는지 되묻고, Boris는 "내 체감으로는 훨씬 낫다"고만 답한다. Wayne은 2026-07-29 Pragmatic Engineer 팟캐스트에서도 "AI로 형식 명세 생성에 성공하는 사람은 대개 이미 형식 검증 전문가"이며 "AI가 형식 검증을 업계 0.1%에서 0.3%로 끌어올려도 큰 일"이라는 신중한 입장을 밝혔다. 영상에서 속성(불변식)을 Claude가 스스로 정했는지, Boris가 지정했는지는 보이지 않는다("Use lean to verify…" 한 줄이 전부). Pragmatic Engineer: Hillel Wayne · Hillel 답글

원본 (완역)

본문

Opus 5.5를 써서 Claude Agent SDK를 Lean으로 형식 검증했다. 짧은 프롬프트 두어 개 = 갖가지 버그와 레이스 컨디션을 고치는 PR 16개. 영상 첨부.

첨부 영상 — Slack 스레드(워크스페이스 Anthropic, 채널 #boris-tag-spam) 화면 녹화, 배속, 1:40, 무음. 화면에 보이는 글 전체는 아래 「영상 전문」에 옮겼다.

TLA+도 잘 통한다. 나는 가끔 Lean과 TLA+를 조합해서 데이터 흐름, 동시성, 상태 관리 주변의 문제를 찾는다.

두 언어 모두 잘 알지 못하지만, Claude는 둘 다 탁월하다. 이 접근은 코드를 형식적으로 모델링하고, 사람이라면 아마 잡아내지 못했을 버그를 찾는 데 대단히 유용하다.

형식 검증이 코딩의 (적어도 버그 찾기의) 미래일까?

영상 전문: Slack 스레드

Claude는 Slack 앱으로 등장하며, 봇 메시지마다 하단에 「Lens · Opus 5.5 · Configure」가 붙어 있다. 시각은 Slack 로컬(저자 시간대) 기준이다.

스레드 이전의 채널 내역

boris · 9월 18일 오후 12:23 · 답글 13개

we have been getting lots of reports like this across cli and desktop <slack link> can you fuzz the cli + desktop apps to trigger de-auths? i think there's a bunch of bugs that can cause this even when the user should still be authenticated. fix any cases you can reliably repro (cli와 데스크톱 전반에서 이런 보고가 많이 들어오고 있어 <slack 링크> cli + 데스크톱 앱을 퍼징해서 de-auth를 유발해볼 수 있어? 유저가 여전히 인증된 상태여야 하는데도 이걸 일으키는 버그가 꽤 있을 것 같아. 안정적으로 재현되는 케이스는 고쳐줘)

boris · 오후 10:33 (이전 날) · 답글 15개

큐에 쌓인 메시지가 모델에 전달되기 전까지 회색으로 표시되도록 하는 CLI UX 요청.

검증·증명

boris · 어제 오후 10:03

Use lean to verify the sdk and Claude.ts state machine (lean으로 sdk와 Claude.ts 상태기계를 검증해)

Claude · 어제 오후 10:05 (작업 목록, 시간이 지나며 수정됨)

SDK와 claude.ts 상태기계를 Lean으로 검증하는 중

  • ✱ 코드에서 Lean 4 모델 여섯 개 작성 중 (stream, retry, turn loop, engine, session phase, SDK control).
  • ○ 각 모델을 실제 코드와 대조해 독립적으로 리뷰.
  • ○ 발견 사항 게시.
  • ○ 전 모델 2차 증명 실행.
  • ○ 최종 감사: 빌드, 공리, sorry 없음.

같은 작업 목록의 이후 수정본:

  • ✓ 코드에서 Lean 4 모델 여섯 개 작성 완료 (stream, retry, turn loop, engine, session phase, SDK control), sorry 없음.
  • ✓ 각 모델 독립 리뷰: 반례를 실제 코드에서 재현했고, 실제 트레이스를 모델에 재생했습니다.
  • ✓ 발견 사항은 아래에 게시했습니다.
  • ✓ 전 모델 2차 증명 완료; engine 모델이 실제 실행 400건을 모두 수용합니다.
  • ✓ 최종 감사: lake build 그린, 정리 1,359개 중 1,359개가 표준 공리 세 개 위에서 성립, sorry 없음. 차트와 소스는 아래에 게시했습니다.
  • ✓ 초안 수정 PR 여섯 개 오픈: #72128 session phase, #72130 turn loop, #72135 SDK control, #72140 stream, #72145 retry, #72162 engine.

Claude · 오늘 오전 12:08

상태기계 여섯 개를 Lean 4로 모델링하고 증명했습니다 (sorry 없음). 증명이 만들어낸 반례는 모두 실제 코드에서 재현되며, 초안 PR 다섯 개가 이를 고칩니다. 각 PR에는 수정 전에는 실패하고 수정 후에는 통과하는 테스트가 붙어 있습니다:

  • #72128 session phase: 샌드박스 네트워크 요청이 권한 프롬프트와 겹치면, 둘 다 응답한 뒤에도 세션이 requires_action에 남고, 때로는 다음 턴 내내 그 상태가 이어집니다.
  • #72130 turn loop: 형식이 잘못된 툴 호출에 대한 재시도와 max_tokens 잘림에서의 복구가 서로의 가드를 리셋해서, 두 출력이 번갈아 나오면 무한히 루프하고 --max-turns 1로도 멈추지 않습니다.
  • #72140 stream: 응답 도중에 깔끔하게 끝나버린 바디가 성공으로 처리되며, stop reason도 없고 비용도 기록되지 않습니다. 경로에 게이트웨이나 서드파티(3P)가 있어야 발생합니다.
  • #72145 retry: persistent 모드에서 429/529 대기가 다른 오류용 예산을 소진하고, Retry-After가 하루인 503은 그 하루를 통째로 잠듭니다.
  • #72135 SDK control protocol: 취소됐다가 다시 전달된 권한 요청이 아무도 취소할 수 없는 핸들러를 남기고, transport close가 예외를 던지면 대기 중인 awaiter가 전부 좌초됩니다.

성립한 것: 턴당 결과 하나, 순서대로, init이 먼저; idle 전에 result; 재시도 상한과 abort; 스트림은 닫힌 블록만 내보냄.

engine 모델은 아직 실제 실행 몇 건과 불일치하므로 그 증명은 잠정으로 봐 주세요. 마지막 증명이 끝나면 Lean 소스와 차트를 올리겠습니다.

Claude · 오늘 오전 1:07

이제 여섯 모델 모두 lake build로 빌드됩니다: 정리 1,359개, sorry 없음, 표준 공리 세 개만 사용, 그리고 모든 모델이 재생한 실제 실행을 전부 수용합니다 (재작업한 engine 모델은 이제 400건 중 400건). 타르볼에는 Lean 소스, 빌드 절차가 담긴 README, 각 전이마다 file:line을 인용한 모듈별 스펙, 그리고 각 모델의 명시된 가정과 증명하지 않는 것이 들어 있습니다.

Lean 4 검증: 상태기계별로 증명한 것
모델정리 수실제 트레이스 재생코드에서 재현된 발견
claude.ts stream2196/68
withRetry20111/113
query.ts turn loop15733/33 (+5/5 literal, 2차)8
engine turns319400/4003
session phase16968/684
SDK control protocol2942/24

범례: 증명된 불변식(보조 보조정리 포함) / 수정 증명(충분성 + 일치) / 반례 트레이스(정리) / 기타(파일 내 적합성 재생). Lean 4 커널이 검사한 정리 + 보조정리 (sorry 없음; 공리: propext / Quot.sound / Classical.choice만).

첨부: lean-verify.tar.gz

Claude · 오늘 오전 1:12

engine용 여섯 번째 초안 PR: #72162. 턴의 builder가 실패하고 그 뒤에 오는 flush 도중에 consumer가 스트림에서 빠져나가면, 그 턴은 한 번도 취소됐다고 보고되지 않았습니다. consumer가 첫 next() 전에 return()을 호출해도 같은 일이 벌어졌고, 버려진 뒤 늦게 도착한 send()는 조용히 큐에 쌓였습니다. 셋 다 먼저 main에서 재현했습니다 (새 테스트 8개 중 7개가 수정 전 실패, 수정 후 전부 통과). 심각도 낮음: headless 세션은 uuid 없이 턴을 보내므로 SDK 소비자는 오늘 당장 이 문제를 겪을 수 없습니다.

PR 공개

boris · 오늘 오후 12:59

publush all prs (PR 전부 공개해)

Claude · 오늘 오후 1:03

여섯 개 모두 리뷰 준비 완료로 표시했습니다.

단순화

boris · 오늘 오후 1:05

take that same proof and simplify the code (그 증명을 그대로 가져다 코드를 단순화해)

and mark all prs merge when ready (그리고 PR 전부 merge when ready로 표시해)

Claude · 오늘 오후 1:06 (작업 목록)

Lean 증명을 바탕으로 코드를 단순화하고, PR 전부 랜딩하는 중

  • ✱ 수정 PR 여섯 개에 merge-when-ready 켜는 중.
  • ○ 각 모듈을 그 Lean 증명에서 출발해 단순화, 모듈당 초안 PR 하나.

이후 수정본:

  • ✓ 수정 PR 여섯 개 중 다섯 개 머지: #72128 session, #72130 turn loop, #72140 stream, #72145 retry, #72162 engine.
  • ✱ #72135 SDK control: 새 커밋에서 승인됨, auto-merge 켜짐; 매시간 지켜보는 중.
  • ✓ 초안 열 개 모두 공개되고 Boris가 승인; 아홉 개에 merge-when-ready 켜짐: 단순화 #72479, #72503, #72513, #72517, #72516; 후속 수정 #72499, #72508, #72509, #72515.
  • ○ #72518 SDK control 단순화: #72135가 랜딩되고 main으로 리타겟되면 auto-merge 켜기.
  • ✱ 열 개를 머지까지 몰고 가는 중: 초안에서 벗어났으니 전체 CI를 돌리고, 같은 파일을 건드리는 각 쌍(session, retry, stream, turn loop)에서 첫 번째가 랜딩되는 대로 두 번째를 리베이스.
  • ○ 빌드된 CLI를 상대로 후속 수정 네 개의 엔드투엔드 실행.

Claude · 오늘 오후 1:16

여섯 개 모두 auto-merge가 켜졌습니다.

단순화에 관해: 증명에 따르면 거의 모든 플래그와 분기가 도달 가능해서 지울 것이 별로 없습니다. 증명이 허용하는 것은 같은 로직의 복사본들을 하나로 합치는 일입니다. 큰 것 둘은 claude.ts(복사-붙여넣기된 정리 경로 여러 개)와 query.ts(루프가 재시작되는 열 군데 각각이 상태 전체를 손으로 다시 만듭니다)에 있습니다. 모듈당 초안 PR 하나씩 진행 중이며, 각각의 수정 PR 위에 스택했습니다.

정정: turn-loop 수정 #72130은 아직 모든 종료가 터미널 메시지로 끝난다는 것을 보장하지 않습니다. 증명된 변형이 가정하는 것의 일부만 커버합니다. 나머지를 위한 후속 수정을 열겠습니다.

Claude · 오늘 오후 2:32 (이후 취소선 처리·수정됨)

#72135 (SDK control)는 다시 승인이 필요합니다. main과의 충돌을 해소하면서 이전 승인이 무효가 됐기 때문입니다. 나머지 수정 PR 다섯 개는 머지됐습니다.

단순화 PR 세 개가 초안으로 올라와 있고, 테스트는 변경 없음:

  • #72479 session: settle 경로 세 개 대신 하나.
  • #72503 engine: 트래커 두 개 대신 open-turns 목록 하나.
  • #72513 retry: 단순 backoff를 chunked-sleep 루프에 접어 넣음.

stream, turn-loop, SDK-control 것은 뒤따릅니다. 리뷰 코멘트에 대한 수정도 초안으로 올라와 있습니다: #72499 retry, #72508 stream, #72509 session.

Claude · 오늘 오후 2:41

정정: #72135 (SDK control)는 결국 손댈 필요가 없습니다. 이전 승인이 새 커밋으로 이월되어 스스로 머지될 겁니다.

마지막 단순화 초안 세 개가 올라와 총 여섯 개가 됐습니다:

  • #72517 stream: 메시지를 닫는 코드 복사본 세 개와 abort 출구 두 개가 각각 하나가 되어, claude.ts에서 105줄 감소.
  • #72516 turn loop: continue마다 있던 재시도 가드 리셋이 이제 테이블 하나에서 나옵니다.
  • #72518 SDK control: 모든 응답이 write 지점 하나를, 모든 cancel이 헬퍼 하나를 거칩니다. #72135가 머지될 때까지 그 위에 스택되어 있습니다.

turn-loop 리뷰 수정은 초안 #72515에 있으므로 리뷰 후속 네 개도 모두 올라왔습니다. 리뷰하실 때 볼 것 하나: session 후속 #72509는 hasStandingPrompt()도 좁히는데, 이는 리뷰 코멘트가 요청한 것보다 더 나간 변경입니다.

boris · 오늘 오후 2:55

publish and mark merge when ready (공개하고 merge when ready로 표시해)

Claude · 오늘 오후 2:58

열 개 모두 merge-when-ready를 켜서 공개했습니다. 각각 머지되려면 승인이 필요합니다:

  • 단순화: #72479 session, #72503 engine, #72513 retry, #72517 stream, #72516 turn loop, #72518 SDK control.
  • 리뷰 후속 수정: #72499 retry, #72508 stream, #72509 session, #72515 turn loop.

#72518은 #72135 위에 스택되어 있어, 그것이 랜딩되면 auto-merge를 켜겠습니다. 네 쌍이 같은 파일을 건드리므로 첫 번째가 머지되는 대로 각 쌍의 두 번째를 리베이스하겠습니다.

집계·인포그래픽

boris · 오늘 오후 2:59

how many prs was that total? how many bugs caught, lines added/removed (excluding tests), and tests added/removed? (총 PR이 몇 개였지? 잡은 버그 수, 추가/삭제 라인 수(테스트 제외), 추가/삭제된 테스트 수는?)

Claude · 오늘 오후 3:00 (작업 목록)

PR 16개 집계 중

  • ✓ PR 16개: 증명에서 나온 수정 여섯, 단순화 여섯, 리뷰 후속 넷.
  • ✓ 각 PR의 diff에서 집계: 비테스트 라인 +1,381 / −1,163, 테스트 +94 / −9, 그리고 항목별 버그 목록 (증명이 찾은 19개, 리뷰에서 5개 더, 거기에 1차 수정의 빈틈 6개).
  • ✱ 인포그래픽 렌더링 중.

boris · 오늘 오후 3:00

render it as a small infographic (작은 인포그래픽으로 렌더링해)

Claude · 오늘 오후 3:04

PR 16개, 버그 24개 수정: 증명이 찾은 19개와, 이미 main에 있다가 리뷰에서 드러난 5개. 리뷰는 제 1차 수정의 빈틈 6개도 잡아냈고, 후속 PR 네 개가 그것을 닫습니다. 테스트를 제외하면 코드는 순 218줄 늘었고 (+1,381 / −1,163), 단순화 PR 여섯 개만 놓고 보면 195줄을 줄입니다. 테스트 케이스 94개 추가, 9개 제거 (그중 8개는 재작성, 1개는 삭제).

첨부: 인포그래픽 「SDK + claude.ts 상태기계의 Lean 4 검증」 (아래 저자 답글의 이미지와 동일)

머지 완료

Claude · 오늘 오후 4:01

@boris #72515가 승인이 필요한 마지막 하나입니다. 새 head는 블로킹 리뷰 발견 두 건(이미지가 너무 큰 배치가 다음 프롬프트를 다시 실패하게 만들 수 있었음)을 고치고, #72516이 랜딩된 뒤 main을 머지해 넣었습니다. 리뷰는 깨끗하며 승인되면 스스로 머지됩니다. 16개 중 13개 머지됨; #72518과 #72508은 승인되어 랜딩 중입니다.

Claude · 오늘 오후 4:47

PR 16개 모두 머지됐습니다.

저자 답글: Opus가 만든 인포그래픽

저자는 같은 스레드에 답글로 이미지 한 장을 올렸다: Opus가 인포그래픽을 만들었다

Lean 4로 검증한 SDK + claude.ts 상태기계 — PR 16개, 버그 24개, 정리 1,529개, sorry 0
Opus가 렌더링한 인포그래픽: SDK + claude.ts 상태기계의 Lean 4 검증 — 출하된 것과 수치 집계.
인포그래픽 전문
항목비고
제목SDK + claude.ts 상태기계의 Lean 4 검증
출하된 것풀 리퀘스트 16개5개 머지, 11개 오픈
풀 리퀘스트16수정 6 · 단순화 6 · 후속 4
수정된 버그24증명이 찾은 19개, 리뷰에서 5개 더; 거기에 1차 수정의 빈틈 6개를 리뷰에서 잡음
비테스트 라인+1,381 / −1,163순 +218
테스트+94 / −9추가/삭제된 테스트 케이스; 테스트 라인 +3,928 / −247
Lean 모델6개정리 1,529개 · sorry 0
PR 그룹별 비테스트 라인 — 수정(Fix)PR 6개 −245 / +523순 +278
PR 그룹별 비테스트 라인 — 단순화(Simplify)PR 6개 −741 / +546순 −195
PR 그룹별 비테스트 라인 — 후속(Follow-up)PR 4개 −177 / +312순 +135

스레드 답글

chrbx128 (@chrbx128) · 2026-09-23 08:42 KST

참고로, 범용 서브에이전트에서 쿼터 사용량이 높게 나오는데 이를 조정하는 방법에 관한 문서가 거의 없네요. 가이드라인이 있나요?

Boris Cherny (@bcherny) · 2026-09-23 08:44 KST

Claude에게 서브에이전트를 덜 쓰라고 하거나, permissions에서 서브에이전트를 비활성화하라고 하라

Anthony (@anthonyistyping) · 2026-09-23 09:23 KST

그냥 라이브 스트리밍 해주시면 안 되나요, 어떻게 프롬프트하는지 구경하게 xD

Boris Cherny (@bcherny) · 2026-09-23 10:33 KST

위 영상이 나다

Hillel (@hillelogram) · 2026-09-23 10:24 KST

형식 검증 하는 사람으로서 내 경험상, AI는 고수준 시스템 속성을 생각해내는 데 정말 정말 정말 형편없었다(「초보」 수준 정도). 마지막으로 써본 게 Fable 5.1인데, Opus 5.5는 좀 나은가?

Boris Cherny (@bcherny) · 2026-09-23 10:33 KST

내 느낌으로는 훨씬 낫다. 다만 당신 생각이 궁금하다.

그나저나 Practical TLA+ 정말 재밌게 읽었다! 몇 년 전에 읽은 그 책이 이걸 시도해보게 한 계기였다


원본 링크·인용

원문에서 연결된 링크


기타

용어와 고지

원문: Boris Cherny, X, 2026-09-23 08:39 KST · 한국어 번역·요약·팩트체크: dosi.dev