변경 전파 위험
모듈 경계, 순환 의존, fan-out, flat structure를 봅니다.
순환·과결합은 수정 비용이 커서 가장 높은 가중치입니다.Metrics v14.5.0
jam-lite는 빌드 없는 정적 분석으로 측정 가능한 구조적 품질 지표를 이 CLI 안에서 계산합니다. 각 finding은 세부 metric으로 기록되고, metric debt는 CPLX·ARCH·RES 같은 category score로 합성됩니다.
최종 jam-lite 점수는 7개 category score의 가중합입니다. 가중치가 높은 항목일수록 AI 산출물의 장기 유지보수 리스크를 더 크게 본다는 뜻입니다.
모듈 경계, 순환 의존, fan-out, flat structure를 봅니다.
순환·과결합은 수정 비용이 커서 가장 높은 가중치입니다.순환/인지 복잡도, 중첩 깊이, Halstead, MI를 묶습니다.
복잡한 함수는 테스트와 리뷰 비용을 동시에 높입니다.하드코딩 시크릿, SQL/NoSQL injection, 약한 crypto/TLS, XSS, 경로 조작, SSRF를 찾습니다.
SEC-07/08은 함수 내(+한 단계 inter-procedural) taint 분석으로 소스→싱크 흐름을 추적합니다.토큰 기반 중복 블록과 구조적 유사 함수를 측정합니다.
AI 산출물에서 증가하기 쉬운 copy-paste debt입니다.파일 크기, 함수 길이, 파라미터 수, 책임 집중 파일을 봅니다.
CPLX와 일부 신호가 겹치므로 낮은 가중치입니다.자원 해제 누락, 무한정 동시성, 가변 전역 상태를 찾습니다.
휴리스틱 성격이 강해 confidence와 함께 해석합니다.삼킨 에러, 죽은 코드, TODO debt, 주석 이상치, 파스 실패를 봅니다.
보조 신호지만 parse failure는 등급 cap을 적용할 수 있습니다.JAM은 세부 지표를 바로 평균내지 않습니다. 먼저 각 metric finding을 debt minutes로 바꾸고, category별로 technical debt ratio를 계산한 뒤 category score를 가중합합니다.
언어 frontend 또는 token/import graph가 원값을 산출합니다.
severity와 confidence를 적용해 수정 비용으로 환산합니다.
category별 debt를 CLOC 기반 개발 비용으로 정규화합니다.
TDR 10%를 기준으로 0~100점 스케일을 만듭니다.
category score에 가중치를 곱해 최종 점수로 합성합니다.
metric value = language frontend 또는 token/import graph가 산출한 원값
finding debt = severity_cost(metric, value) * confidence_factor
dev cost = project CLOC * 3.6 minutes
category TDR = capped_category_debt / dev cost
category score = max(0, 100 * (1 - category TDR / 0.10))
JAM Lite Score = Σ(category score * category weight)
세부 위반 1건입니다. metric_id, file:line, value, threshold, severity, confidence, debt minutes가 CSV/JSON/SARIF에 남습니다.
CPLX, ARCH, RES 같은 묶음 점수입니다. 한 카테고리 안의 세부 finding debt를 합산해 0~100점으로 정규화합니다.
함수의 실행 경로 수, 사람이 읽는 중첩 부담, 최대 블록 깊이, 어휘량, 유지보수성 지수를 함께 봅니다.
CPLX-01과 CPLX-02가 같은 함수에서 동시에 위반되면 큰 debt만 산입해 이중 감점을 줄입니다.
CCN = 1 + branch_count, HV = (N1+N2) * log2(n1+n2), MI = 171 - 5.2 ln(HV) - 0.23 CCN - 16.2 ln(LOC)
import/module graph로 SCC·fan-in/fan-out·instability·flat structure·허브(God Component)·변경 파급 비용을 보고, tree-sitter 타입 내부 구조로 응집도(LCOM4)·상속 깊이(DIT)까지 측정합니다. 순환 SCC가 크면 grade cap을, 심각 결합 violation이 개수로 집중되면 카테고리 상한을 적용해 대형 코드베이스에서 희석되지 않게 합니다.
SCC(G), Ca/Ce, I = Ce/(Ca+Ce), PC = transitive-closure density, LCOM4 = 연결요소 수, DIT = 상속 깊이
파일 실행 없이 acquire/release 짝, 루프 내부 unbounded concurrency, mutable global state를 찾습니다. 휴리스틱 성격이 강해 confidence를 노출하고, low confidence는 debt 50%만 산입합니다.
resource leak = acquire(x) without close/free/delete(x), unbounded = spawn in loop without limiter
각 category는 내부 metric debt 합계로 0~100점이 됩니다. 최종 jam-lite는
ARCH 0.22 + CPLX 0.20 + SEC 0.20 + DUP 0.15 + SIZE 0.10 + RES 0.08 + HYG 0.05 가중합입니다.
아래 목록은 finding에 기록되는 원값과 기본 임계값입니다. 데스크톱에서는 비교표로, 모바일에서는 metric별 카드로 읽히도록 구성했습니다.
| ID | 목적 | 산출값/산식 | 기본 임계값 또는 점수 영향 |
|---|---|---|---|
| SIZE-01 | 리뷰하기 어려운 대형 파일 탐지 | 파일별 CLOC, LOC | 500 / 1000 / 2000 CLOC |
| SIZE-02 | 긴 함수와 책임 과다 함수 탐지 | 함수 시작~끝 라인 span | 60 / 120 / 300 lines |
| SIZE-03 | 과도한 인터페이스 폭 탐지 | 함수 파라미터 개수 | 5 / 8 |
| SIZE-04 | God file/type와 책임 집중 탐지 | 선언 수, fan-in 백분위, 메서드/필드 수 | 상위 5%, 메서드 30+, 필드 25+ |
| CPLX-01 | 테스트 경로 수 증가 측정 | CCN = 1 + if/for/case/catch/&&/||/?: count | 10 / 15 / 30 |
| CPLX-02 | 사람이 읽는 난이도 측정 | 구조 증가분 + 중첩 레벨 가중치 | 15 / 25 |
| CPLX-03 | 깊은 들여쓰기와 사고 부담 탐지 | 함수 내 최대 block depth | 4 / 6 |
| CPLX-04 | 어휘량과 유지보수성 보조 입력 | HV = (N1+N2) * log2(n1+n2) | 직접 감점 없음, CPLX-05 입력 |
| CPLX-05 | 파일 단위 유지보수성 요약 | MI = 171 - 5.2 ln(HV) - 0.23 CCN - 16.2 ln(LOC) | 낮을수록 위험, 20 / 10 |
| ARCH-01 | 모듈 순환 의존 탐지 | import graph의 SCC, 최단 cycle path | 1건부터 violation, SCC 5+면 최대 B |
| ARCH-02 | 같은 모듈 안 파일 상호참조 탐지 | 파일별 정의/참조 심볼 graph SCC | info/medium, 설계 검토 신호 |
| ARCH-03 | 과결합과 안정 의존 원칙 위반 탐지 | Ca, Ce, I = Ce/(Ca+Ce) | Ce 15 / 25 |
| ARCH-04 | 평탄 구조와 죽은 내부 모듈 탐지 | 디렉터리 소스 파일 수, 내부 import graph orphan | 디렉터리당 50 source files |
| ARCH-05 | 허브형 의존(God Component) 탐지 | Ca·Ce가 둘 다 분포 outlier(평균+2σ) + 절대 하한 | min(Ca,Ce) 4 / 8 (노드 12+ 그래프) |
| ARCH-06 | 변경 파급 비용 탐지 | 전이적 의존(가시성 행렬) 밀도 = Σ|도달가능|/N² | 30% / 50% (노드 12+ 그래프) |
| ARCH-07 | 낮은 응집도(LCOM4) 탐지 | 타입 메서드의 공통 필드 접근·상호 호출 연결요소 수 | ≥2 그룹 경고 · Go+TS(tree-sitter) |
| ARCH-08 | 깊은 상속(DIT) 탐지 | 프로젝트 내부에서 해석되는 상속 체인 깊이 | ≥5 경고 · TS·Java·C#·C++(tree-sitter) |
| DUP-01 | copy-paste 블록과 수정 누락 위험 탐지 | 정규화 토큰 rolling hash, duplicate lines / DUP 대상 CLOC | 중복률 5% / 10% / 20% |
| DUP-02 | 일부 수정된 유사 함수 탐지 | 정규화 토큰 3-gram Jaccard similarity | 72% 이상, 60 tokens / 10 lines 이상 |
| SEC-01 | 하드코딩 시크릿 탐지 | 고엔트로피 문자열 + secret keyword, 알려진 token format | 1건부터 critical, test/example은 완화 |
| SEC-02 | SQL/command/HTML injection 위험 탐지 | 위험 sink 주변 문자열 결합/formatting 패턴 | 직접 결합은 violation, 추적 한계는 warning |
| SEC-03 | 약한 암호·난수·TLS 설정 탐지 | MD5/SHA1/DES, random misuse, TLS verify off | critical 패턴, test/example은 완화 |
| SEC-04 | 위험 역직렬화·동적 실행 탐지 | eval, pickle.loads, unsafe YAML, shell exec sink | 언어별 sink pattern finding |
| SEC-05 | 민감 정보 로깅 탐지 | logging call 인자 내 password/token/secret 식별자 | 직접 노출 패턴 finding |
| SEC-06 | 클라이언트 인젝션(DOM XSS) 탐지 | dangerouslySetInnerHTML, innerHTML=, document.write 등 비리터럴 | violation (CWE-79) · JS/TS |
| SEC-07 | 경로 조작(Path Traversal) 탐지 | 파일 sink + 사용자 입력, 함수 내 taint 추적 | 라인 기반 warning, 확정 흐름 violation (CWE-22) |
| SEC-08 | SSRF 탐지 | HTTP client(fetch/axios 등) + 입력, taint 추적 | 라인 기반 warning, 확정 흐름 violation (CWE-918) |
| RES-01 | 자원 해제 누락 탐지 | open/malloc/new/acquire 이후 close/free/delete 짝 검사 | 명백한 누락은 warning/violation |
| RES-02 | 무한정 동시성·큐 위험 탐지 | loop 안 goroutine/thread/promise spawn + limiter 부재 | info~warning, confidence 노출 |
| RES-03 | 전역 가변 상태와 상태 공유 위험 탐지 | 모듈/package level mutable global count | 경고 등급 휴리스틱 |
| HYG-01 | 삼킨 예외·무시된 에러 탐지 | empty catch/except, ignored error, 빈 error block | 건당 violation, docs/test 제외 |
| HYG-02 | 죽은 코드와 도달 불가 코드 탐지 | 비공개 심볼 참조 없음, return 뒤 구문 | 보수적 finding |
| HYG-03 | 방치된 기술부채 표시 탐지 | TODO/FIXME/HACK/XXX 주석 count, density | 건당 info, 밀도 warning |
| HYG-04 | 매직 리터럴 과다 탐지 | literal count / KLOC, 상수·테스트·자연어 제외 | 40/KLOC info, 120/KLOC warning |
| HYG-05 | 주석 과다/부족과 공개 API 문서 누락 탐지 | comment/CLOC ratio, Go exported doc missing ratio | 과다 1.5+, 부족 0.02-, public doc 50%+ |
| HYG-06 | 테스트 부재 신호 탐지 | test/source file ratio, 테스트 0 디렉터리 비율 | info signal, coverage는 test-cli 영역 |
| HYG-07 | 분석 신뢰도를 깨는 파스 실패 탐지 | Go parser error file:line:column | 1건부터 violation, 최대 C, --strict exit 3 |
finding별 수정 비용을 debt minutes로 환산하고, CLOC 기반 개발 비용 대비 technical debt ratio를 계산합니다.
기본 카테고리 점수는 100 * (1 - TDR / 0.10)이며, 최종 점수는 카테고리 가중합입니다.
여기에 더해, 밀도 정규화가 대형 코드베이스에서 가리기 쉬운 집중된 worst-case 결함은
4개 카테고리에 절대 상한을 둡니다.
보안은 단일 인스턴스가 규모 무관하게 해로우므로, critical이 있으면 SEC 카테고리 최대 25점, violation이면 최대 60점.
심각 결합/허브/파급 violation(ARCH-03/05/06)의 절대 개수로 상한 — 1~2건 89, 3건+ 79. god-module 여럿이 비율로 희석되는 것을 막음.
메서드 ≥100인 극단 god type 개수로 SIZE 상한(1개 89, 2개+ 79). 30~100 구간(정당한 fluent API)은 밀도만 받음.
CCN ≥100 god function/component 개수로 CPLX 상한(1개 89, 2개+ 79). McCabe 기준 ≥100은 어떤 단일 함수도 도달하지 않는 병적 수준.
A는 90 이상, B는 80 이상, C는 65 이상, D는 50 이상, F는 50 미만입니다. SEC critical, 큰 dependency cycle, parse failure는 등급 상한을 적용할 수 있고, 상한이 등급을 낮추면 총점도 해당 등급 밴드 상한으로 함께 클램프됩니다.
대형 코드베이스에서 누적형 finding 몇 건은 밀도로 희석되어도 무방하지만, 단일 결함이 곧 치명인 차원(보안·심각 결합·극단 god type/함수)은 위 절대 상한으로 별도 보정합니다.
Go는 표준 go/ast 기반으로 high confidence 경로가 많고, TypeScript/JavaScript/Python/Java/C#/Rust/C/C++는
빌드 없이 동작하는 경량 lexer와 파일 구조 분석을 사용합니다. 비-Go 경로의 일부 복잡도/아키텍처 지표는 medium confidence finding으로 남깁니다.
jam.yaml에서 metric별 warning/violation/critical threshold를 오버라이드할 수 있습니다. CLI 플래그가 설정 파일보다 우선합니다.
version: 1
score:
fail_under: 80
metrics:
CPLX-01:
warning: 12
violation: 20
critical: 35
SIZE-01:
warning: 800
violation: 1500