프로젝트 소개

Ditto는 컴파일, 테스트, 린트와 더불어 '이 코드베이스가 이미 알고 있는 것을 다시 구현하고 있는가?'라는 질문을 던지는 'Semantic CI'를 표방합니다. 이는 토큰 및 AST 기반 중복 탐지기가 일반적으로 보고하지 않는, 동작은 같지만 작성 방식이 다른 Type-4 클론을 타겟으로 합니다. 문서화된 파이프라인의 작동 방식은 다음과 같습니다. 백엔드에서 저장소 타르볼을 다운로드하고 ts-morph로 탐색하여 내보내지 않은 함수를 포함한 모든 함수를 추출한 다음, 저렴한 모델을 사용하여 이름 정보를 배제한 방식으로 각 함수를 하나씩 핑거프린팅합니다. 원본 코드나 이름이 아닌 이 핑거프린트들은 메모리 내에서 코사인 유사도에 따라 임베딩되고 클러스터링됩니다. 결과로 나온 후보 클러스터만이 판정을 위해 더 큰 모델로 전달되며, 이 모델은 적대적 입력값도 제안합니다. 기능적으로 순수한 함수들은 타임아웃이 설정된 worker_threads 샌드박스에서 나란히 실행되며, 여기서 확인된 발산(divergence)이 실행 증거로 제시됩니다. 불순한 함수들도 클러스터링 및 판정 과정을 거치지만, 실행된 것이 아니라 예측된 것으로 표시됩니다. 결과는 MongoDB에 기록되고 읽기 전용 엔드포인트와 Next.js 프론트엔드를 통해 제공되며, 제공 경로에서는 모델을 호출하지 않습니다. README에 따르면 5개의 저장소(함수 수 2,870, 2,654, 336, 31, 6개)에 대해 실행한 결과, 중복 클러스터, 행동적 충돌 및 실행으로 증명된 18가지 사례가 나열되었습니다. 여기에는 cline의 truncateText 구현체 제품군 중 예약 공간 계산으로 인해 특정 제한 이상에서 유지 텍스트가 한 글자로 축소되는 사례가 포함됩니다. 또한 해당 파일들에 대해 jscpd는 중복 클론을 0개로 보고했다고 명시합니다. 잘 관리되는 두 개의 작은 라이브러리가 깨끗한 것으로 평가되었으며, 저자들은 이를 과잉 보고가 없다는 증거로 제시합니다. 명시된 제한 사항은 다음과 같습니다. AST 레이어가 ts-morph이므로 JavaScript/TypeScript만 지원하며, 실행을 위해서는 순수성이 필요합니다. 대규모 저장소는 함수가 무작위로 누락될 경우 전체 클러스터가 사라질 수 있으므로 단순 절단이 아닌 명시적인 범위 지정이 필요합니다. 또한 도구는 두 개의 충돌하는 구현 중 어느 것을 유지할지 추천하지 않으며, 이는 인간의 결정 영역으로 정의합니다. README의 비용 및 시간 수치(예: 2,870개 함수 분석에 ₹232, 계획 중인 Guard 체크당 약 ₹1)는 프로젝트 자체 측정치이며 독립적인 벤치마크가 아닙니다. 호스팅된 데모는 유지 관리자의 API 크레딧 제한으로 인해 온디맨드 분석을 600개 함수로 제한하며, 자신의 키를 사용하여 로컬에서 실행하면 이 제한이 제거됩니다. 설정 노트에는 MongoDB나 API 키 없이 저장소를 인덱싱하는 방법, MongoDB, OpenAI 및 선택적 GitHub/모델 설정이 포함된 .env 파일, 1200초 요청 타임아웃이 설정된 Cloud Run 배포, Atlas 네트워크 액세스, 그리고 빌드 시 NEXT_PUBLIC_* 값이 인라인되는 Vercel 프론트엔드 설정이 포함되어 있습니다. 로드맵에는 GitHub Action PR 체크인 Ditto Guard, 코딩 에이전트가 중복 작성 전 인덱스를 쿼리할 수 있는 MCP 도구, tree-sitter를 통한 추가 언어 지원, 증분 재인덱싱이 포함되어 있습니다. 기여자는 라벨이 지정된 'good first issues'를 통해 안내됩니다.