레포를 읽는 도구라면, 자기 레포부터 검증해야 한다
repo-snapshot은 낯선 레포를 읽어 Tree, 언어, manifest, 프레임워크, 아키텍처 신호를 Markdown으로 정리하는 도구다.
처음 만들 때는 정적 분석 단계를 여러 개로 나누고, 파일을 고른 뒤 실제 내용을 다시 읽어 LLM 보강에 넘기는 흐름에 집중했다. 기능 깊이는 꽤 괜찮았다.
그런데 10~15년차 Backend/AI Engineer의 기준으로 다시 보니 질문이 달라졌다.
이 도구는 다른 레포의 품질을 말하기 전에, 자기 입력 경계와 실패 동작을 설명할 수 있는가?
좋은 기능만으로는 부족했다
스캐너는 scanner.py에 많은 책임을 가지고 있었다. 파일 수집, 소스 구조 분석, manifest 파싱, 프레임워크 탐지, 아키텍처 추정, 이슈 생성, RAG artifact 저장이 한 흐름 안에 있었다.
이 구조가 당장 동작하지 않는 것은 아니다. 하지만 언어와 manifest, 분석 규칙을 계속 추가해야 하는 도구에서는 변경 비용이 빠르게 커진다.
또 테스트가 충분한지보다 더 먼저 확인해야 할 계약이 있었다.
무시한 파일은 Tree·AST·RAG 어디에도 들어가지 않는다.
symlink를 따라가며 저장소 경계를 벗어나지 않는다.
잘못된 입력은 조용히 과도한 작업으로 이어지지 않는다.
일부 파일의 파싱 실패가 전체 스캔 실패가 되지 않는다.
취소 요청은 긴 파일 순회 중에도 전파된다.
같은 입력은 같은 순서와 결과를 만든다.이런 항목은 README의 약속이 아니라 코드와 테스트가 함께 보장해야 한다.
이번에 실제로 바꾼 것
먼저 max_tree_entries를 1~10,000으로 제한했다. 호출자가 음수나 비현실적으로 큰 값을 전달했을 때 내부 단계가 각자 다르게 행동하지 않도록 입력 경계에서 거절한다.
파일 수집 단계에서는 symlink 디렉터리와 파일을 건너뛴다. os.walk의 기본 동작에 기대는 것보다 스캐너의 경계 조건을 코드에 명시하는 편이 안전하다.
웹 정적 파일 제공도 문자열 prefix 비교에서 Path.is_relative_to 기반 검증으로 바꿨다. 경로 검증은 정상적인 파일 하나를 서빙하는 기능보다, 경계 밖 파일을 절대 반환하지 않는 불변조건이 먼저다.
입력 검증
→ 파일 경계 확정
→ 결정론적 분석
→ 실패를 근거로 기록
→ 보고서와 artifact 생성테스트는 기능 목록이 아니라 설계 가정을 보호해야 한다
이번에는 큰 테스트 스위트를 만들기보다 핵심 가정을 작은 회귀 테스트로 고정했다.
.gitignore가 Tree, AST 분석에 일관되게 적용되는지- symlink가 분석 대상에 포함되지 않는지
- tree 크기 상한이 fail-closed인지
- 취소 요청이
ScanCancelled로 전파되는지 - 잘못된 Python 파일이 전체 스캔을 중단시키지 않고 근거를 남기는지
- 동일 입력의 결과 순서가 안정적인지
그리고 GitHub Actions에 Python 3.11 설치, 패키지 설치, compileall, pytest를 등록했다.
5 passed숫자 자체가 품질을 증명하지는 않는다. 중요한 것은 다음 변경자가 어떤 계약을 깨뜨렸을 때 바로 알 수 있다는 점이다.
문서도 환경에서 분리했다
개발 문서와 에이전트 지침에 특정 장비, 내부 IP, 고정 서버 경로가 섞여 있었다. 공개 저장소에서 이런 내용은 프로젝트 설계와 개인 작업 환경을 구분하지 못하게 만든다.
그래서 실행 경로와 저장소 루트는 환경 변수로 주입하도록 바꾸고, MCP도 REPO_SNAPSHOT_ROOT를 사용하게 했다. 문서에는 특정 호스트 이름 대신 재현 가능한 실행 조건과 설정 경계를 남겼다.
환경이 바뀌어도 코드의 계약은 바뀌지 않아야 한다.
아직 끝난 것은 아니다
이번 변경으로 입력 경계와 CI의 기본선을 만들었지만, 가장 큰 maintainability 과제는 남아 있다.
scanner.py의 source analysis, dependency collection, architecture detection을 별도 모듈로 분리하고, 각 분석기가 공통 인터페이스를 통해 결과와 evidence를 반환하도록 바꾸는 일이다.
그 작업은 공개 API 호환성과 분석 결과의 재현성을 함께 지켜야 해서 별도 변경으로 남겼다. 파일을 기계적으로 쪼개는 것보다, 어떤 책임이 어떤 경계에 속하는지 먼저 명확히 해야 하기 때문이다.
좋은 분석 도구는 다른 프로젝트의 문제를 많이 찾아내는 도구가 아니다.
자기가 무엇을 보았고, 무엇을 건너뛰었고, 어디서 확신할 수 없는지를 계속 설명할 수 있는 도구다.
관련 변경은 repo-snapshot GitHub 저장소와 v0.1.0 릴리스에서 확인할 수 있다.