15. 실제 프로젝트 JAM Full 평가 리포트
평가일: 2026-06-14 · 도구:
jam v0.24.0개발 빌드 · 지표 세트:jam-full
이 문서는 사용자가 지정한 실제 프로젝트 3개를 수정하지 않고 /tmp/jam-real-sourcecov에 산출물을 생성해 측정한 결과다.
대상:
~/git/sepilotd~/git/gitops-console~/git/jpad-web
실행:
go build -o /tmp/jam-current ./cmd/jam
go build -o /tmp/test-cli-current ~/git/test-cli/cmd/test-cli
/tmp/security-cli-current tools install
PATH="$PWD/.security-cli/tools/trivy:$PWD/.security-cli/tools/grype:$PWD/.security-cli/tools/osv-scanner:$PWD/.security-cli/tools/gitleaks:$PWD/.security-cli/tools/syft:$PATH"
/tmp/jam-current full "$project" \
--out "/tmp/jam-real-sourcecov/$(basename "$project")" \
--test-cli /tmp/test-cli-current \
--security-cli /tmp/security-cli-current \
--full-timeout 600s
security-cli는 Trivy/Gitleaks/OSV-Scanner/Syft/Grype가 필요하다. 이번 실행은 대상 프로젝트를 수정하지 않고 jam repo의 .security-cli/tools에 설치한 scanner PATH만 주입했다.
1. 결과 요약
| 프로젝트 | exit | Full | Lite | Test | Test status | Security | Security status | 핵심 판단 |
|---|---|---|---|---|---|---|---|---|
sepilotd | 1 | 56 D | 87 | 50 | failed | 0 | failed | 100% coverage가 .md/.yml/.json 파일만 덮는 과대평가를 TEST-SOURCE-COV cap으로 보정. 보안은 critical/high/SCA/secret 다수. |
gitops-console | 1 | 58 D | 91 | 50 | failed | 0 | failed | 테스트 1건 실패, coverage tail 45점. 보안은 critical IaC, high SCA/secret 다수. |
jpad-web | 1 | 61 D | 84 | 40 | failed | 34 | failed | coverage-only report가 no_test_evidence로 분류됨. 보안은 IaC 중심 policy failure. |
2. 개선 전 이상 측정
이번 실제 측정에서 확인한 이상 신호:
| 프로젝트 | 이상 신호 | 판단 | 반영 |
|---|---|---|---|
sepilotd | 3 tests, 100% line coverage, coverage files 48 md + 1 yml + 1 json | smoke test가 문서/설정 coverage를 소스 coverage처럼 보이게 함 | TEST-SOURCE-COV 추가, 큰 coverable surface에서 source line 비율 20% 미만이면 test score 최대 50 및 quality failure |
sepilotd | 3 tests over 7,075 coverable lines | 큰 코드 표면에 smoke test 3개가 과대평가됨 | TEST-DENSITY 추가, coverable lines 1K 이상에서 density 20점 미만이면 test score 최대 70 및 quality failure |
jpad-web | 0 tests, 92.6% line coverage, test component OK | coverage-only evidence를 테스트 성공처럼 해석 | 실행 테스트 0개면 no_test_evidence, 최대 40점 |
| 모든 대상 | 명시 /tmp/security-cli-current 실행 시 scanner tool home 미발견 | JAM 문제가 아니라 외부 CLI tool home 전달 부족 | ~/git/security-cli fallback에서 SECURITY_CLI_HOME 자동 설정 |
sepilotd, gitops-console | report에 CVSS가 있어도 SEC-CVSS=not_assessed | CVSS provider nested map 파싱 누락 | recursive CVSS score extraction 추가 |
3. 하위 지표 관찰
3.1 Test
| 프로젝트 | TEST-PASS | LINE | BRANCH | EVIDENCE | TAIL | DENSITY | SOURCE | SKIP | DURATION | 판단 |
|---|---|---|---|---|---|---|---|---|---|---|
sepilotd | 100 | 100 | n/a | 100 | 100 | 8 failed | 0 failed | 100 | 100 | 100% line coverage지만 coverable line 7,075줄 전부가 문서/설정 파일이다. |
gitops-console | 99 failed | 74 | 74 | 100 | 45 | 100 | 100 | 100 | 100 | 테스트 수와 branch coverage는 충분하지만 실패 1건과 coverage tail이 실제 품질 리스크. |
jpad-web | 0 failed | 93 | n/a | 50 failed | 79 | 0 failed | 100 | n/a | n/a | 실행 테스트가 없으므로 coverage-only evidence를 production readiness로 인정하면 안 됨. |
coverage 파일 구성:
| 프로젝트 | source coverage files | non-source coverage files | 판단 |
|---|---|---|---|
sepilotd | 0 files / 0 lines | 50 files / 7,075 lines (md, yml, json) | source coverage mix 0%, test score 최대 50 |
gitops-console | 65 .ts files / 13,921 lines | 0 | source coverage mix 100% |
jpad-web | 55 .ts files / 6,527 lines | 0 | source coverage mix 100% |
3.2 Security
| 프로젝트 | Findings | Policy fail | Severity | Category | CVSS | CWE | 판단 |
|---|---|---|---|---|---|---|---|
sepilotd | 93 | 37 | critical 3, high 34 | iac 15, sca 72, secret 6 | max 9.8 | 24 tags, 6 high-risk | 실제 게이트 실패로 보는 것이 타당. secret과 critical SCA는 오탐이어도 수동 triage 필요. |
gitops-console | 103 | 42 | critical 1, high 41 | iac 35, sca 62, secret 6 | max 10.0 | 59 tags, 15 high-risk | policy failure와 CVSS/CWE가 일치해 강한 실패 신호. |
jpad-web | 19 | 1 | high 1, medium 9, low 9 | iac 19 | n/a | n/a | IaC rule 중심. ConfigMap with secrets는 실제 환경 변수/secret 분리 여부 확인 필요. |
4. 오탐/과소탐 판단
오탐 후보:
sepilotd,gitops-console의 secret finding 일부는 fixture, 문서, 예시 값일 수 있다. 하지만security-cli가 policy failure로 분류했고 JAM은 원본 evidence를 보존하므로, JAM 쪽에서 조용히 낮추지 않는 것이 맞다.jpad-web의 IaCRestrict container images to trusted registries류 warning은 조직 정책에 따라 완화될 수 있다. 기본 policy에서는 warning이고, policy failure는 high 1건이다.test-cli가sepilotd의.md/.yml/.jsoncoverage file에language=typescript를 붙인 것은 upstream evidence 품질 문제다. JAM은 path 확장자를 language보다 우선해 source/non-source를 판별하도록 보정했다.
과소탐/부족 후보:
sepilotdtest는 source coverage cap으로 50점/failed까지 내려갔다. "테스트가 얕다"는 신호를 더 강하게 보려는 조직은full.metrics.TEST-DENSITY.cap,full.metrics.TEST-SOURCE-COV.cap, 또는weight를 설정으로 더 엄격히 조정할 수 있다.- branch coverage가 없는 프로젝트는
TEST-BRANCH-COV=not_assessed로 재정규화된다. 해당 언어/도구가 branch coverage를 낼 수 있는데 빠진 경우를 별도 policy failure로 강제하는 옵션은 아직 없다. jpad-websecurity는 CVSS/CWE가 없는 IaC finding 중심이라SEC-CVSS/SEC-CWE는not_assessed다. 이는 JAM 누락이 아니라 source tool evidence 한계다.
5. 반영된 보강
- jam-full test 하위 지표를 5개에서 9개로 확장:
TEST-DENSITY,TEST-SOURCE-COV,TEST-SKIP-RISK,TEST-DURATION-TAIL추가. - jam-full security 하위 지표를 6개에서 8개로 확장:
SEC-CVSS,SEC-CWE추가. - 실행 테스트 0개는 coverage가 있어도 quality failure.
- 큰 coverable surface에서 낮은 test density는 score cap 및 quality failure.
- 큰 coverable surface에서 source coverage mix가 낮으면 문서/설정 coverage 과대평가로 보고 score cap 및 quality failure.
- security secret, unfixed high/critical SCA, stale DB는 hard cap에 반영.
jam.yaml의full.weights와full.metrics.<ID>.weight/floor/capoverride 지원.jam-full.jsonJSON Schema와 golden fixture 추가.
6. 남은 후속 후보
- diff-aware changed-file coverage: PR에서 변경 파일이 테스트/커버리지에 포함됐는지 확인.
- branch coverage required 옵션: branch coverage 미제공을
not_assessed가 아니라 policy failure로 강제. - security finding suppression density: suppression이 늘어나는 추세를 security hygiene으로 별도 기록.
- test report source provenance: coverage-only report가 어떤 tool output에서 왔는지
test-clischema에 원천 provenance를 추가하면 triage가 쉬워진다.