| name | reverse-doc |
| description | Document current code behavior as an As-Is baseline before refactor, spec drift checks, or cleanup. |
Reverse Documentation: 코드 → As-Is 문서 생성
Overview
코드를 읽고, 그 코드가 실제로 하는 것을 문서화한다. 설계 의도나 주석이 아니라, 코드의 실제 실행 흐름 기준.
When to Use
- 바이브코딩이나 에이전트가 작성한 코드의 실제 동작을 파악할 때
- 리팩토링 전 현재 상태를 기록할 때
- 스펙 drift를 발견하기 위한 비교 기준을 만들 때
- "이 코드가 뭘 하는지 문서화해", "역문서화", "현재 코드 상태 정리" 요청 시
When NOT to use:
- Tobe 스펙을 작성할 때 (이 스킬은 코드만 본다)
- 코드를 실행해서 확인해야 할 때 (정적 분석만 한다)
- 전체 코드베이스를 한 번에 문서화할 때 (모듈 단위로 실행)
핵심 원칙
- 코드가 진실이다. 주석이 코드와 다르면 코드를 따른다. 주석은
[주석불일치] 태그로 표시만 한다.
- 해석하지 않는다. "이건 아마 ~하려는 것 같다"가 아니라 "이 코드는 ~한다"로 기술. "X is broken", "silently fails", "accidentally works" 같은 판단은 하지 않는다. 대신 "X는 Y를 한다. 타입 선언은 Z이다." 처럼 사실만 기술.
- 누락보다 과잉이 낫다. 확실하지 않은 side effect도 기록하고
[확인필요] 태그를 붙인다.
- 모듈 경계를 지킨다. 이 모듈의 코드만 문서화한다. 호출자(caller)를 검색하거나 외부 모듈의 내부 구현을 참조하지 않는다.
- 구조 탐색은 위임하고 범위는 유지한다. 모듈 내부의 심볼 맵핑이나 exact body 추출이 필요하면
probe-deep-search를 사용하되, 호출자 추적이나 외부 모듈 내부 읽기로 범위를 넓히지 않는다.
분석 대상 항목
모듈 하나에 대해 다음을 파악한다:
1. 입력 (Inputs)
- 함수 파라미터: 이름, 타입(annotation 있으면), 기본값
- 외부에서 읽는 것: 전역변수, 환경변수, 파일, DB
- 암시적 의존: import된 모듈의 상태에 의존하는 경우
2. 출력 (Outputs)
- return 값: 타입과 구조
- Side effects: 파일 쓰기, 전역변수 변경, 외부 API 호출, 로깅
- 예외: 어떤 조건에서 어떤 예외를 raise하는지
3. 내부 흐름 (Internal Flow)
- 주요 분기 로직 (if/else, early return)
- 루프 구조와 종료 조건
- 다른 모듈/함수 호출 순서
4. 외부 의존성 (Dependencies)
- import하는 외부 패키지
- 호출하는 다른 내부 모듈/함수 (호출 그래프)
- 공유 자료구조 (다른 모듈과 같은 객체를 참조하는 경우)
5. 이상 징후 (Anomalies)
- dead code (도달 불가능한 분기)
- 사용되지 않는 파라미터
- 주석과 코드의 불일치
- 하드코딩된 매직 넘버
- 같은 로직의 중복 구현
태그 규약
반드시 다음 태그를 사용한다. 산문으로 풀어쓰지 않는다:
| 태그 | 용도 | 예시 |
|---|
[주석불일치] | 주석과 코드 동작이 다를 때 | [주석불일치] L45: 주석은 "SGG6 level 1"이라 하지만 코드는 (4, 2) 즉 SGG4 level 2 |
[Dead Code] | 도달 불가능한 분기 | [Dead Code] L120-125: else 분기가 실행 불가 |
[매직넘버] | 하드코딩된 상수 | [매직넘버] L30: threshold 0.85의 출처 불명 |
[중복] | 유사 로직 반복 | [중복] L50, L120: 동일한 정규화 로직 |
[확인필요] | 코드만으로 판단 불가 | [확인필요] NaN→0 변환이 의도된 동작인지 |
[타입추론] | annotation 없이 사용 패턴에서 추론 | [타입추론] param1은 str로 사용됨 |
[미사용] | import 또는 파라미터가 사용되지 않음 | [미사용] L5: import os — 모듈 내 사용처 없음 |
출력 형식
파일: {module_name}_ASIS.md
# {모듈명} - As-Is (코드 기준)
> 생성일: {날짜}
> 대상 파일: {파일경로}
> 코드 기준: 코드의 실제 동작만 기술. 설계 의도 아님.
## 모듈 개요
(이 모듈이 실제로 하는 것 1-2문장)
## Public Interface
### `function_name(param1: type, param2: type) -> return_type`
- **실제 동작**: (이 함수가 하는 것)
- **입력**:
- `param1`: (실제 사용 방식)
- `param2`: (실제 사용 방식)
- **출력**: (실제 return 구조)
- **Side Effects**: (있으면 기술)
- **호출하는 함수**: [`other_func_1`, `other_func_2`]
- **예외**: (raise 조건)
(모든 public 함수/클래스에 대해 반복)
## 내부 함수 (Private)
(주요 내부 함수만. 사소한 유틸은 이름만 나열)
## 의존성 그래프
이 모듈 → 호출하는 모듈1 → ...
이 모듈 → 호출하는 모듈2
외부: numpy, ortools, ...
## 데이터 흐름
(주요 자료구조가 어떻게 변환되는지. 입력 → 중간상태 → 출력)
## 이상 징후
- [주석불일치] {위치}: 주석은 ~라고 하지만 코드는 ~함
- [Dead Code] {위치}: 도달 불가능
- [매직넘버] {위치}: 하드코딩된 값 {값}
- [중복] {위치1}, {위치2}: 유사 로직 중복
## [확인필요] 항목
(코드만으로 판단 불가한 것. 사람에게 확인 요청)
워크플로우
- 대상 모듈의 모든 파일을 읽는다.
- Public interface부터 파악 (외부에서 어떻게 호출되는지).
- 각 public 함수의 내부 흐름을 추적.
- 의존성 그래프 작성 (이 모듈이 import하는 것만. 호출자는 추적하지 않는다).
- 이상 징후를 태그 규약에 따라 수집.
- 위 출력 형식에 맞춰 문서 생성.
모듈 크기 가이드
- 파일 1개, 함수 10개 이하: 전부 상세 문서화
- 파일 1개, 함수 10개 초과: public만 상세, private는 주요 것만
- 파일 여러 개 (디렉토리): 파일별로 나눠서 각각 문서화. 디렉토리 수준 개요 문서 별도 작성.
Common Mistakes
| 실수 | 올바른 방법 |
|---|
| "이 로직은 broken이다" (판단) | "이 코드는 X를 한다. 타입 선언은 Y이다." (사실) |
| 호출자(caller)를 검색해서 문서에 포함 | 이 모듈의 import와 호출만 기술. 누가 이 모듈을 호출하는지는 범위 밖 |
| 이상 징후를 산문으로 설명 | 태그 규약 표의 태그를 사용. [주석불일치] L45: ... 형식 |
| 테이블/불릿 형식을 자유롭게 선택 | 출력 형식 템플릿을 그대로 따른다 |
| 설계 의도를 추측 ("아마 ~하려는 것") | 코드가 하는 것만 기술. 의도 추측이 필요하면 [확인필요] 태그 |
| 전체 코드베이스를 한 번에 문서화 | 모듈 단위로 실행. 디렉토리는 파일별 + 개요 |
주의사항
- 실행하지 않는다. 정적 분석만 한다.
- Tobe 스펙을 참조하지 않는다. 코드만 본다. 스펙 비교는 별도 스킬.
- 테스트 코드가 있으면 활용한다. 테스트가 실제 사용 패턴을 보여주므로, 입출력 파악에 참고.
- 타입 annotation이 없으면 실제 사용 패턴에서 추론하되
[타입추론] 태그를 붙인다.