Reference

04. 아키텍처

Go 기반 내부 구조, 파이프라인, 파서 전략, 패키지 설계

Source: docs/04-architecture.md

04. 아키텍처

1. 최상위 파이프라인

jam-lite:

 ┌──────────┐   ┌──────────────┐   ┌──────────────┐   ┌───────────┐   ┌──────────┐
 │ Discover │ → │ Lang Frontend│ → │   Analyze    │ → │   Score   │ → │  Report  │
 │ 파일 수집 │   │ Go AST/lexer │   │ 메트릭 실행   │   │ 점수 합성  │   │ md/csv   │
 └──────────┘   └──────────────┘   └──────────────┘   └───────────┘   └──────────┘
      │                │                  │
   .gitignore      internal/lang       analyzer 인터페이스
   jam.yaml        경량 렉서            파일/프로젝트 단위
   생성파일 감지    Go parser

jam-full:

 jam-lite ─┬─ test-cli run      → test/report.json
           └─ security-cli scan → security/security-report.json
              ↓
           jam-full-report.md + jam-full.json

assurance (점수와 독립):

 jam-run + detail CSV + security report + policy/review → security verdict
 security verdict + SBOM/scan/ticket evidence + control plan → control evidence index

단계별 책임

  1. Discover: 루트부터 파일 순회. 루트와 하위 디렉터리의 .gitignore, jam.yaml 제외 규칙, 기본 패키지/빌드/가상환경 디렉터리(node_modules/, .next/, .venv/, venv/, env/, target/, dist/, build/, coverage/ 등), 자동 생성 파일 휴리스틱(Code generated by, *.min.js, lockfile)을 적용한다. 언어 감지(확장자 + 셔뱅). 결정적 순서로 정렬.
  2. Lang Frontend: Go는 표준 라이브러리 go/parser/go/ast를 사용한다. TS/JS, Python, Rust, Java, C#, C/C++은 internal/lang 경량 렉서 프론트엔드가 함수/복잡도/import 정보를 추출한다.
  3. Analyze: model.Analyzer 구현체를 카테고리 순서로 실행한다. 파일 단위 지표(SIZE/CPLX/SEC/RES/HYG)와 프로젝트 단위 지표(ARCH/DUP)를 같은 인터페이스로 다룬다.
  4. Score: 03-scoring-model.md의 jam-lite SQALE 모델 적용.
  5. Report: jam-report.md, jam-detail.csv, jam-run.json, 옵션 JSON/SARIF 생성(06-output-spec.md).
  6. Full compose: --set full이면 internal/fulltest-clisecurity-cli를 호출하고, jam-full-report.md/jam-full.json을 생성한다.
  7. Assurance: internal/assurance가 scanner finding을 review candidate로 유지한 채 Git 대상·실행 시각·coverage·정책·귀속 가능한 리뷰를 검증한다. 별도 control plan은 원본 증거의 SHA-256과 commit/source hash 상관관계를 기록하며 품질 점수에는 영향을 주지 않는다.

2. 파서 전략 — 핵심 결정

결정: Go AST + 내부 경량 렉서 + 필요 지표의 tree-sitter WASM

옵션장점단점판정
smacker/go-tree-sitter (CGo)성숙, 빠름CGo → 3-OS 크로스 컴파일 시 각 OS용 C 툴체인 필요, 정적 단일 바이너리 어려움
tree-sitter 문법을 wasm32-wasi로 빌드 + wazero 런타임순수 Go 실행, CGo 없이 타입 내부 구조/함수 내 taint 추출wasm 바이너리 크기, 문법 업데이트 관리✓ 현재 부분 경로
Go AST + 내부 경량 렉서 프론트엔드빌드 불가 프로젝트도 스캔, 단일 바이너리 유지비-Go 경로의 타입 해석 한계, confidence medium 중심✓ 현재 기본 경로
외부 Language Server 구동정밀외부 프로세스/설치 의존 → "단일 실행파일" 제약 위반✗ (선택적 확장으로만)

공통 프론트엔드 추상화

언어마다 구문이 다르므로 메트릭 코드가 언어별 lexer를 직접 알지 않도록 internal/lang.Frontend를 둔다.

type Frontend interface {
    Languages() []string
    Functions(content []byte) []Function
    Imports(content []byte) []Import
}

프론트엔드는 init()에서 등록되며, 엔진은 internal/engine에서 언어 패키지를 blank import한다.

3. 패키지 구조

jam/
├── cmd/jam/              # main. CLI 파싱(flag 또는 cobra), 종료 코드
├── internal/
│   ├── discover/         # 파일 수집, gitignore, 생성 파일 감지, 언어 감지
│   ├── lang/             # 경량 언어 프론트엔드(jsts/python/rust/java/csharp/cpp)
│   ├── model/            # Finding, Metric, Location, Severity 등 공용 타입
│   ├── analyze/
│   │   ├── size/         # SIZE-01..04
│   │   ├── cplx/         # CPLX-01..05
│   │   ├── arch/         # import 그래프, Tarjan SCC, fan-in/out
│   │   ├── dup/          # 토큰 정규화, Rabin-Karp 클론 인덱스
│   │   ├── sec/          # 시크릿 엔트로피, 패턴 룰 엔진
│   │   ├── res/          # 자원 쌍 추적
│   │   └── hyg/          # 에러 무시, 데드 코드, SATD
│   ├── score/            # SQALE debt 계산, 가중 합성, 등급
│   ├── report/           # markdown/csv/json/sarif
│   ├── runmeta/          # jam-run.json v2 provenance/integrity 계약
│   ├── assurance/        # security verdict와 control-evidence 계약/게이트
│   ├── full/             # jam-full external CLI orchestration
│   ├── e2ecorpus/        # 16개 fixed-SHA regression manifest 계약
│   ├── labeledbench/     # 독립 정답지 parser와 confusion matrix 평가
│   └── config/           # jam.yaml 로드, 기본값, 임계값 오버라이드
├── tools/
│   ├── e2e-corpus/       # clone/strict scan/exact score·산출물 회귀 gate
│   └── labeled-benchmark/# OWASP label 기반 precision/recall/FPR/F1 gate
└── testdata/
    ├── fixtures/         # 안티패턴 주입 픽스처 (언어별)
    ├── e2e-corpus.yaml   # project-score regression partition
    ├── labeled-benchmarks.yaml # independent validation partition
    └── golden/           # golden file 테스트 (report/csv 스냅샷)

핵심 인터페이스

type Analyzer interface {
    Category() string
    Analyze(p *model.Project) ([]model.Finding, error)
}

type Finding struct {
    MetricID   string
    Severity   model.Severity     // info / warning / violation / critical
    Confidence model.Confidence   // high / medium / low
    File       string             // 루트 기준 상대 경로, '/' 구분자 통일
    Line, Col  int                // 1-based
    EndLine    int
    Message    string             // 사람용 설명
    Value      float64            // 측정값 (CCN=23 등)
    Threshold  float64
    Related    []Location         // 클론 상대편, 사이클 경로 등
}

4. 동시성 모델

5. 크로스 플랫폼 고려사항

항목처리
경로내부 표현은 항상 / 구분 상대 경로. OS 경계에서만 filepath 변환
줄바꿈CRLF/LF 모두 라인 카운트 일관 처리. 라인 인덱스는 바이트 오프셋 테이블로 산출
인코딩UTF-8 가정 + BOM 스킵. 비UTF-8 파일은 스킵하고 jam-run.json에 기록; production 파일이면 --strict에서 exit 3
빌드CGO_ENABLED=0 go build 로 3 OS × (amd64, arm64) 매트릭스. goreleaser 사용 예정

6. 성능 목표와 전략

7. 확장 포인트 (v1 이후)