type-recursive-issue-try-callback/ 신설(spikes 35개) — type function/ 메타테이블/제네릭/이중 꺾쇠 명시 인스턴스화까지 전방위로 재시도했으나 quad의 state:Compute(fn) 단일 호출 모양을 유지한 채로는 여전히 안 됨, 근본 원인은 재귀 특유가 아니라 "제네릭 콜백 인자엔 컨텍스트 타입 전파가 안 됨"이라는 더 일반적 Luau 한계임을 확인. typing-limits.md §1/§7에 반영, 원칙 자체는 안 바뀜. 이어진 /code-review 2회전이 이 작업과 luau-test/16 복구 세션 전반에서 정합성 문제 다수 발견 — 스파이크 결과 표 stale(16번 실패로 잔존), 폴더 개수 off-by-one 여러 건, type-recursion-issue/REPORT.md의 실제 오류(self가 제네릭이면 자유 함수로 빼도 여전히 실패한다는 사실이 "통과"로 잘못 서술됨), 옛 솔버 캐비엇 누락, 체크리스트 항목 간 모순, 이 세션 자체의 히스토리 누락 등 — 전부 수정. doc-check.py ERROR 0 유지. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HvEKn9f67kkx2nGLG8PsP
7.2 KiB
2026-08-15 두 번째 세션 — 콜백 파라미터 무주석 추론 전방위 재시도, /code-review 2회전 정합성 수정
배경
직전 세션(2026-08-15-01)이 typeof(named fn) 간접참조로 0-Y(반환
타입 leak)를 우회했지만, "콜백 파라미터는 여전히 명시 주석 필요"라는
캐비엇은 그대로 남겨뒀음. 사용자가 이 캐비엇에 대해 "제 손으로도
안 된다는 결론이 나오긴 했지만, 확실하다고 보기는 어려워 보인다"며
type function/메타테이블/제네릭 등 전방위 재시도를 요청 —
"확장 시도가 지금 설계에 영향 안 미치더라도 좋다"는 전제로 순수
탐색적 리서치 성격임을 명시.
1차 조사 — type-recursive-issue-try-callback/ 신설 (에이전트 위임, spikes 00~19)
general-purpose 에이전트에 위임(luau 스파이크 다수 작성/실행이라 메인 컨텍스트 보호 목적). 결과:
- 근본 원인 재정정: 재귀 자기참조 특유의 문제가 아니라 "제네릭이
관여하는 함수 호출 인자로 넘긴 함수 리터럴엔 Luau가 컨텍스트 타입을
전파하지 않는다"는 더 일반적 한계(재귀 없는
Map<T,U>(arr,fn)도 똑같이 샘, 00번). - near-miss 두 개 발견, 둘 다 채택 안 함: (a)
T를 명시 중간 변수로 먼저 고정하면 재귀형에서도 콜백 파라미터가 정확히 추론됨 (09번), (b) 재사용 가능한 monomorphize 헬퍼 함수를 거치면 T별로 손으로 다시 쓸 필요 없이 같은 효과(18번, 이번 조사의 가장 흥미로운 발견). 둘 다state:Compute(fn)단일 호출을 2단계 체인으로 바꿔야만 작동해typing-limits.md§0 대전제(API를 타입 사정으로 비틀지 않음) 위반으로 기각. type function으로 재귀 반환 자체를 지연 평가하는 시도는 여전히stack overflow막다른 길(직전 리서치와 같은 결론 재확인).
base/typing-limits.md §1에 각주로 반영, .claude/README.md audit
색인에 신설 행 추가.
/code-review high 1회전 — 문서 정합성 9건 + 미검증 각도 1건
메인 세션이 직접 검증 후 수정. 대부분 카운트/인용 stale(README
audit 개수 7→6, luau-test/STATUS.md 헤딩 7→6, ROADMAP.md M0
체크리스트 미갱신, luau-test-first-run 표의 스파이크 16 결과가
"❌ 실패"로 안 고쳐진 것 등 — 전부 프로젝트 자체 규율인 "배너뿐 아니라
본문도 고칠 것"이 재발한 사례).
핵심 발견 1건: 1차 조사 20개 formulation이 전부 암묵 호출만
시도했고, 코퍼스에 이미 실사용 중인 이중 꺾쇠 명시적 제네릭
인스턴스화(Foo<<T,U>>(...), base/attribute-plan.md의
AttributeKey<<T>>, type-recursion-issue/spikes/38/39/41에 이미
있음)를 단 하나도 시도하지 않았음. 메인 세션이 직접 빠르게 재현해보니
quad 실제 self-핸들 계약에서 부분 성공(다운스트림 타입은 정확) +
이전과 다른 spurious 진단(read-only/read-write 불일치)이 섞여 나옴 —
새 각도라 판단해 후속 조사로 위임.
후속 조사 — <<T,U>> 명시적 인스턴스화 (에이전트 위임, spikes 20~33+21b)
- spurious 진단 원인 규명:
08-metatable-BUG(직전 세션의 solver 버그)와 다른 문제 — duck-typed 콜백 파라미터가 "읽기만 관측돼 read-only로 잡히는데 기대 타입은 기본 read-write"인 단순 가변성 불일치. 쪼개기(②)+Get필드에 명시readmodifier로 완전 해소됨. - leaf 호출에선 실제로 sound하게 성립(체이닝 depth 3까지 완전 클린, 음성 대조군도 정확히 잡힘).
- partial instantiation은 이름이 아니라 선언 순서로 바인딩 —
U만 주려 해도T부터 채워짐, 재귀형에서 Internal error로 깨짐(21/21b). - 최종 채택 안 함: 매 호출마다 이미 self로부터 결정되는
T까지 중복 명시 + 콜백을 쓰기도 전에 반환 타입U를 미리 선언해야 하는 부담이 지금 관례("파라미터에 타입 하나만 주석")보다 크고,:Apply중첩 자기호출은 여전히 안 풀림 —typing-limits.md§0 대전제상 순손해. - 함정 하나 추가 발견: 쪼개기+
read만 하고 명시 인스턴스화를 뺀 암묵 호출은 겉보기엔 깨끗해 보이지만 음성 대조군을 전혀 못 잡는 순수 duck-typing이었음(27 vs 28 대조).
REPORT.md §11 신설(TL;DR 갱신 포함), typing-limits.md §1엔 각주
포인터만(원칙 자체는 안 바뀜).
/code-review(재사용 high) 2회전 — 정합성 9건
첫 회전이 새로 만든 문서/수정 자체에서 또 발견된 stale — 대부분 "수정하며 새 stale을 만드는" 패턴의 재발:
typing-limits.md§1③의 "바뀌지 않는 것" 목록에 옛 솔버 거부 캐비엇이 빠져있던 것(①만 그 캐비엇이 있고 ③엔 없었음) — 추가.- §7 체크리스트 항목 1(무조건 ③ 쓰라는 투)과 항목 2(파라미터 추론엔 ②도 같이 필요하다는 헤지)가 서로 부딪히던 것 — 항목 1에 "③은 반환 타입 안전성만 고쳐줌, 파라미터 추론엔 부족" 경고 추가.
- 이 세션 자체의 작업이 세션 히스토리에 아직 안 남아있던 것 — 이 파일이 그 반영.
CLAUDE.md의.claude/audit/소개 bullet이 3개 폴더만 나열한 채 최신 3개(fallback-xpcall/typeof/try-callback)가 안 반영돼 있던 것 — luau-test bullet과 같은 패턴으로 "나열 안 하고 README.md로 미룸"으로 전환.type-recursion-issue/REPORT.md(0-Y 원래 리서치, 13차 세션 산출물)의 "06/07/10 자유 함수로 빼면 재귀 유무 무관하게 통과" 서술이 실제로는 틀렸음 —06은self: Box<A>처럼 self 자신이 제네릭이라 실제로는 duck-typing 오염 + TypeError가 남(직접luau-analyze --annotate로 재현 확인).07/10은 self가 모노몰픽이라 통과 — 진짜 분기점은 "자유 함수인가"가 아니라 "self가 비제네릭인가"였음, 06을 13(self 완전 자유 제네릭도 안 풀림)과 같은 편으로 재분류.- 스파이크 개수 off-by-one 2건(README의 try-callback 34→35, 직전
세션 로그의 typeof 폴더 14→15 — 둘 다 서브레터 파일(
21b,00b/00c)을 안 세서 생긴 것). - 직전 세션 로그가 "raw 값 콜백 + 50단 체이닝이 깨끗이 통과"를 마치 확정 사실처럼 서술한 것 — 그 formulation은 파일로 저장 안 돼 지금 재현 불가라는 정정 각주 추가(REPORT.md §5-1이 이미 밟은 것과 같은 조치).
남은 것
.claude/README.md(audit 현재 6개 카운트가 커밋 시점 기준으로는
아직 5개였던 것 — 커밋 안 한 현재 작업 트리 기준으로는 이미 6개로
정확해서 별도 조치 없음, 커밋되면 자동 해소), 3건은 code-review가
검증 단계에서 이미 refuted 처리(허위 양성).
관련 문서
.claude/audit/type-recursive-issue-try-callback/(REPORT.md + spikes
35개), base/typing-limits.md §1/§7, .claude/README.md,
CLAUDE.md, .claude/audit/type-recursion-issue/REPORT.md,
.claude/session/2026-08-15-01-typeof-recursive-generic-workaround.md.