Reference

07. CLI와 설정

명령행 인터페이스, 설정 파일 jam.yaml, 제외 규칙

Source: docs/07-cli-and-config.md

07. CLI와 설정

현재 구현 상태 (v0.46.0 / metrics v14.5.0): scan(--set lite|full/--out/--fail-under/--json/--sarif/--strict/--quiet/--include-generated/--exclude/--only/--config), lite, full, diff, assurance verdict, assurance evidence, version, metrics, explain 구현됨. Go/TS/JS/Python/Java/C#/Rust와 C/C++ 제한 지원이 동작한다. v13은 production/test/documentation/configuration/generated 역할과 카테고리×언어 eligible CLOC를 점수 계약으로 기록한다. jam.yamlversion/exclude/suppress/score.fail_under/metrics.<ID>.warning|violation|critical/arch.layers·arch.rules(ARCH-09)/full.weights(lint/spec 포함) 지원(자체 YAML 서브셋 파서 — 외부 의존성 0 유지). 인라인 억제 주석(jam:ignore <ID> -- 사유) 동작. --componentlint/spec(둘 다 opt-in) 추가. 미구현: jam init, jam languages, --lang/--csv-bom/--jobs/--verbose, 인라인 억제 건수의 HYG 집계.

1. 명령 구조

jam scan [path]        # 기본은 jam-lite. path 기본값 = 현재 디렉터리
jam lite [path]        # jam scan --set lite alias
jam full [path]        # jam scan --set full alias
jam diff old.csv new.csv
jam assurance verdict --policy security-policy.json [--review security-review.json]
jam assurance evidence --plan control-plan.json
jam metrics            # 내장 메트릭 레지스트리 출력
jam explain <metric>   # 메트릭 설명·근거·임계값 출력 (예: jam explain CPLX-02)
jam version

v1 이후 후보: jam languages, jam init, jam serve(로컬 HTML 뷰어).

assurance의 입력·상태·감사 경계는 17-security-assurance.md를 따른다.

2. jam scan 플래그

플래그기본설명
--out DIR.출력 디렉터리 (jam-report.md, jam-detail.csv, jam-run.json, 옵션 JSON/SARIF; full은 추가 산출물 생성)
--config FILEjam.yaml 자동 탐색설정 파일 경로
--set lite|fulllite측정 세트. full은 jam-lite 뒤에 test-cli/security-cli를 호출
--fail-under N(없음)현재 세트의 종합 점수 N 미만이면 exit 1
--exclude GLOB추가 제외 패턴 (반복 가능)
--include-generatedfalse자동 생성 파일도 분석·감사 출력에 포함. role은 generated라 production 점수에는 미산입
--jsonfalsejam-result.json 추가 생성
--sariffalsejam.sarif(SARIF 2.1.0) 추가 생성
--strictfalseproduction source 스킵·파스 실패, analyzer 오류·config 경고·억제 정책 문제가 있으면 산출물 작성 후 exit 3. test/docs/config 전용 스킵·파스는 감사만 기록
--quietfalse한 줄 요약만 출력
--only CAT[,CAT]전체특정 카테고리만 (예: --only SEC,ARCH)
--component all|test|security|lint|specallfull 모드에서 실행할 외부 컴포넌트. all=test,security(하위호환). lint/spec은 opt-in(예: all,lint 또는 spec). 콤마 구분
--skip-testfalsefull 모드에서 test-cli 생략
--skip-securityfalsefull 모드에서 security-cli 생략
--skip-lintfalsefull 모드에서 lint 컴포넌트 생략
--test-cli PATH자동 탐색full 모드에서 사용할 test-cli 실행 파일
--test-baseline FILEtest-cli report@2 baseline 비교
--test-history FILEtest-cli 추세/flaky 분석용 이전 report@2. 반복 가능
--test-diff-base REFtest-cli changed-line coverage용 Git ref
--test-fail-on-regressionfalse--test-baseline 비교가 회귀하면 test gate 실패
--test-fail-on-flakyfalse최소 2개 --test-history와 현재 런에서 flaky가 확인되면 실패
--test-fail-diff-coverage PCTchanged-line coverage가 PCT 미만이면 실패. --test-diff-base 필수
--security-cli PATH자동 탐색full 모드에서 사용할 security-cli 실행 파일
--security-profile NAMEcifull 모드에서 security-cli에 넘길 profile
--security-baseline FILEsecurity-cli fingerprint baseline 비교
--security-fail-on-newfalsebaseline에 없던 security finding이 있으면 실패
--security-historyfalsesecurity-cli/Gitleaks 전체 Git 이력 검사. 기본은 시간 상한이 예측 가능한 working tree 검사
--lint-cli tool=path[,...]PATH--component lint에서 린터 실행 파일 재정의(예: ruff=/usr/bin/ruff)
--spec-cli PATH자동 탐색--component spec에서 사용할 외부 spec-cli 실행 파일 재정의
--spec-requirements PATHspec-cli 기본요구사항 문서 경로를 spec-cli에 전달
--spec-trace-baseline FILEspec trace diagnostic suppression baseline
--spec-trace-fail-on LEVELspec-cli 기본 error`noneinfowarningerror` 중 trace gate 임계
--full-timeout DUR30mfull 모드 외부 컴포넌트별 타임아웃

콘솔에는 01-vision-and-scope.md 시나리오 A의 요약 박스만 출력. 상세는 파일로.

스캔 범위는 먼저 루트와 하위 디렉터리의 .gitignore를 적용한 뒤, 내장 기본 제외 디렉터리와 jam.yaml/--exclude 규칙을 적용한다. 기본 제외 디렉터리는 node_modules, bower_components, .pnpm-store, .yarn, .next, .nuxt, .svelte-kit, .venv, venv, env, .tox, .nox, __pycache__, __pypackages__, target, vendor, dist, build, coverage, out, .cache 등이다. 패키지 lockfile(package-lock.json, pnpm-lock.yaml, poetry.lock, go.sum 등)은 생성 파일로 기록하고 기본 분석에서는 제외한다.

분석 대상으로 발견된 파일은 다시 점수 역할로 분류된다. production만 점수의 CLOC·debt 모집단이며 test/testdata/fixture/mock, 문서, 설정, 생성 파일 finding은 CSV/SARIF에 보존하되 score_exclusion 사유와 debt_counted=0을 기록한다. 지원표 밖 언어도 unsupported_language로 같은 방식으로 보존한다. 따라서 테스트나 README를 추가해 production 점수를 희석할 수 없다. --only 밖 카테고리 finding은 unselected_category이며, 제한 점수는 동일 --only 범위끼리만 비교한다.

미구현 플래그 후보: --lang ko|en, --csv-bom, --jobs N, --verbose.

2.5 jam diff 플래그

jam diff OLD.csv NEW.csv는 두 jam-detail.csvfinding_id 기준으로 비교해 added/fixed/unchanged finding과 counted debt 증감을 출력한다. 기본으로 각 CSV 옆의 jam-run.json을 검증하여 도구·Metrics Spec·정책·스캔 범위가 같고 두 측정이 완전할 때만 비교한다.

플래그기본설명
--fail-on-addedfalse새 finding이 --min-severity 이상이면 exit 1
--min-severity LEVELwarninginfo/warning/violation/critical
--limit N20added/fixed 섹션별 최대 출력 건수
--quietfalse한 줄 요약만 출력
--allow-incompatiblefalse구버전 baseline 등 매니페스트 검증을 신중하게 우회

CI 예:

jam scan . --out out/new
jam diff --fail-on-added --min-severity warning out/baseline/jam-detail.csv out/new/jam-detail.csv

2.6 jam full

jam full PATHjam scan PATH --set full과 같다. full 모드는 다음 순서로 실행한다.

  1. jam-lite 스캔: jam-report.md, jam-detail.csv, jam-run.json, 옵션 JSON/SARIF 생성.
  2. test-cli run PATH --format json --output-dir <out>/test 실행. baseline/history/diff 플래그가 있으면 그대로 전달.
  3. security-cli scan PATH --profile <profile> --format json --output-dir <out>/security 실행. schema 1의 scanner coverage가 complete인지 검증.
  4. --component spec이면 spec-cli를 실행하고 report/trace/summary 원자 계약을 검증.
  5. jam-full-report.md, jam-full.json 생성.

부분 full 실행:

jam full . --component security   # jam-lite + security-cli만 합성
jam full . --skip-test            # jam-lite + security-cli만 합성
jam full . --component test       # jam-lite + test-cli만 합성
jam full . --component test --test-baseline baseline/report.json --test-fail-on-regression
jam full . --component test --test-history run-1.json --test-history run-2.json --test-fail-on-flaky
jam full . --component test --test-diff-base origin/main --test-fail-diff-coverage 80
jam full . --component security --security-baseline baseline/security.json --security-fail-on-new
jam full . --component spec --spec-trace-fail-on warning

부분 full에서는 선택된 컴포넌트의 기본 가중치만 합산한 뒤 1.0으로 재정규화한다. 예를 들어 --component security는 jam-lite 0.50, security 0.25를 0.667/0.333으로 재정규화한다.

외부 도구 탐색 순서:

  1. --test-cli/--security-cli/--spec-cli
  2. PATH
  3. 개발 환경 fallback: ~/git/test-cli, ~/git/security-cli, ~/git/cli/security-cli, ~/git/spec-cli

3. jam.yaml 설정 파일

원칙: 설정 없이도 잘 동작(convention over configuration). 현재 설정은 제외/억제 규칙, fail-under 게이트, 레지스트리 기반 jam-lite 메트릭 임계값 오버라이드, jam-full 컴포넌트/하위 지표 조정용이다.

version: 1

# 수백 개 저장소에 동일한 --config 파일을 배포할 때의 정책 식별자.
# 실제 전체 설정 SHA-256도 jam-run.json에 함께 기록되므로
# ID/version을 바꾸지 않고 내용만 변경해도 비교 불일치가 검출된다.
policy:
  id: engineering/portfolio
  version: "3"

# 분석 범위
exclude:
  - "vendor/**"
  - "**/*_test.go"        # 분석·감사 출력에서도 테스트를 완전히 제외하려는 경우

score:
  fail_under: 70           # CLI --fail-under와 동일, CLI가 우선

# 메트릭별 임계값 오버라이드. warning/violation/critical 중 필요한 것만 지정.
# 레지스트리에 숫자 임계값이 있는 메트릭(SIZE-01, CPLX-01, ARCH-03 등)에 적용.
metrics:
  CPLX-01:
    warning: 12
    violation: 20
    critical: 35
  SIZE-01:
    warning: 800
    violation: 1500

# 프로젝트 프로파일 (opt-in): "application"일 때만 SIZE-05(사변적 일반화) 측정.
# 라이브러리 공개 API 오탐 방지를 위해 기본은 미측정.
profile: application

# 변경 이력 지표 (CPLX-06, CHURN-01..04, opt-in — git 저장소 + 아래 설정 필요.
# 이력은 환경 의존적이라 모두 info 등급·점수 미산입)
churn:
  enabled: true

# 아키텍처 레이어 규칙 (ARCH-09, opt-in — 선언 없으면 미측정)
arch:
  layers:
    domain:
      - "internal/domain/**"
    infra:
      - "internal/infra/**"
      - "internal/db/**"
  rules:
    - deny: domain -> infra
      reason: "도메인 계층은 인프라 세부구현을 몰라야 함(DIP)"

# jam-full 컴포넌트/하위 지표 override
full:
  weights:
    jam-lite: 0.45
    test: 0.30
    security: 0.25
    lint: 0.15
    spec: 0.15
  metrics:
    TEST-DENSITY:
      weight: 0.18
      cap: 80
    TEST-SOURCE-COV:
      weight: 0.12
      cap: 90
    SEC-TOOLCHAIN:
      weight: 0.20
    SEC-CVSS:
      floor: 20

# 개별 finding 억제 (false positive 관리)
suppress:
  - finding: SEC-01-f01c44aa        # finding_id로 지정 (안정적 해시)
    reason: "테스트용 더미 키"       # reason 필수 — 억제도 감사 가능해야 함
    owner: security-team
    ticket: SEC-42
    expires: 2026-12-31
  - metric: RES-02
    path: "src/legacy/**"
    reason: "v2에서 재작성 예정"

설정 해석 규칙

인라인 억제 주석

소스 주석으로도 억제 가능 (린터 관례 준수):

db.Query(q) // jam:ignore SEC-02 -- 내부 고정 쿼리

-- 사유 부분이 없으면 경고와 suppression issue를 남기고 --strict에서 exit 3으로 처리한다.

4. 콘솔 UX

5. 종료 코드

code의미
0측정 성공, 품질 게이트 통과
1품질 게이트 실패 또는 assurance fail/gap·열린 예외
2명령/설정/스캔/리포트 작성 실패
3scan --strict 또는 assurance에서 불완전 측정/증거
4full 모드 외부 컴포넌트 측정 불가

production 코드가 없어 jam-lite가 N/A인 실행은 --fail-under를 통과할 수 없으며 exit 1을 반환한다. 숫자 0/F로 해석하지 않고 not_assessed 상태를 산출물에 유지한다.