감리 대응을 위한 아키텍처 증적 자동 수집 시스템 설계

· 약 10분 읽기 · 조회 0 #감리#아키텍처#공공 SI#CI/CD#증적 관리#자동화

공공 SI의 감리는 "설계한 대로 만들었는가"를 문서와 결과물로 확인한다. 그런데 증적을 감리 직전에 사람이 모으면 날짜가 맞지 않거나, 화면 캡처가 지금 코드와 다르거나, 누가 언제 만든 파일인지 설명하지 못하는 일이 생긴다. 이 글은 빌드·검사·배포 과정에서 증적이 저절로 쌓이고, 요구사항 ID와 연결된 상태로 감리 자료가 나오도록 하는 수집 시스템의 설계안을 정리한 것이다.

작은 로봇 팔들이 사진·로그·설계도를 이름표 붙은 폴더에 정리하고, 나무 책상에서 감리인이 정돈된 바인더를 검토하는 기록 보관실

한눈에 보기

단계 하는 일 결과물
원천 형상관리, CI, 정적 분석, 인프라 설정, 운영 지표에서 결과 파일을 낸다 테스트 리포트, 분석 결과, 설정 파일, 지표 스냅샷
수집 CI 이벤트와 야간 스케줄로 결과 파일을 가져온다 날짜별 증적 묶음
보관 파일마다 해시를 계산하고 고칠 수 없는 저장소에 넣는다 매니페스트(목록 + 해시 + 출처)
매핑 증적을 요구사항 ID와 감리 관점에 연결한다 요구사항–증적 추적표
보고 감리 일정에 맞춰 관점별 자료를 뽑는다 감리 대응 리포트

형상·빌드, 코드 검사, 인프라 설정, 운영 지표에서 나온 결과를 수집기가 모아 해시와 함께 증적 보관소에 넣고, 요구사항 추적표와 매핑해 감리 대응 리포트를 만드는 흐름

핵심은 증적을 "만드는" 일과 "모으는" 일을 분리하는 것이다. 증적은 개발 과정이 이미 만들고 있다. 시스템은 그것을 잃지 않고 출처와 함께 보관할 뿐이다.

사람이 모은 증적이 약한 이유

감리 대응을 문서 담당자 한두 명이 맡으면 다음 문제가 반복된다.

  • 시점이 어긋난다. 감리 일주일 전에 찍은 화면 캡처는 그 단계 종료 시점의 시스템이 아니다. 감리인이 날짜를 물으면 답하기 어렵다.
  • 출처가 사라진다. "정적 분석 결과.xlsx"가 어느 커밋, 어느 빌드에서 나왔는지 기록이 없으면 결과를 다시 만들 수 없다.
  • 선택이 섞인다. 사람이 고르면 결과가 좋은 날의 자료만 남는다. 의도가 없어도 검증 자료로서의 신뢰가 떨어진다.
  • 일이 몰린다. 단계 종료마다 개발자가 하던 일을 멈추고 자료를 찾는다. 그 시간만큼 결함 조치가 늦어진다.

자동 수집은 이 네 가지를 구조로 막는다. 수집 시각은 시스템이 기록하고, 출처는 커밋과 빌드 번호로 남고, 모든 실행 결과가 빠짐없이 쌓인다.

감리 관점별로 무엇을 모으나

증적 목록은 감리에서 묻는 관점에서 거꾸로 정한다. 관점마다 이미 결과 파일을 내는 도구가 있다.

감리 관점 자동으로 모을 원천 증적 형태
요구사항 추적 이슈 관리 도구, 커밋 메시지의 요구사항 ID 요구사항별 커밋·이슈 목록
설계 반영 ArchUnit 테스트, 의존성 분석 레이어·모듈 규칙 검사 결과
표준 준수 SonarQube, 코딩 규칙 검사 규칙 위반 건수와 추이
시험 결과 JUnit 리포트, 통합·성능 시험 결과 실행 일시가 찍힌 리포트 원본
보안 점검 취약점 진단 도구, CycloneDX SBOM 구성요소 목록, 진단 결과
배포·운영 Terraform·Ansible 설정, Prometheus 지표 설정 파일 사본, 지표 스냅샷

여기서 주의할 점은 원천을 새로 만들지 않는 것이다. 이미 CI가 내는 파일을 모으는 데서 시작해야 개발팀의 일이 늘지 않는다. 결과 파일이 없는 관점(예: 화면 설계 반영)만 따로 수작업 등록 경로를 둔다.

수집기: 언제 모으나

수집 시점은 세 가지로 나눈다.

CI 이벤트

  • 메인 브랜치 빌드가 끝날 때마다 테스트 리포트, ArchUnit 결과, SonarQube 분석 결과, SBOM을 가져온다.
  • Jenkins나 GitLab CI의 마지막 단계에 수집 작업 하나를 붙이면 된다. 빌드 번호와 커밋 해시가 같이 남는다.

야간 스케줄

  • 인프라 설정 저장소의 현재 상태와 Prometheus 지표 요약(응답 시간 퍼센타일, 오류율)을 하루 한 번 스냅샷으로 남긴다.
  • 지표는 원본 시계열이 아니라 그날의 요약값과 조회 쿼리를 함께 저장한다. 나중에 같은 쿼리로 다시 확인할 수 있어야 한다.

단계 종료 스냅샷

  • 설계·구현·시험 단계가 끝나는 날, 그 시점의 증적 전체를 하나의 묶음으로 봉인한다. 감리는 대개 단계 단위로 보기 때문에 이 묶음이 기본 제출 단위가 된다.

수집 작업이 실패하면 빌드를 실패시키지 않고 알림만 보낸다. 증적 수집 때문에 배포가 막히면 팀이 수집기를 끄게 된다.

증적 보관소: 해시와 고칠 수 없는 저장

증적의 가치는 "그때 그 상태 그대로"라는 데 있다. 그래서 보관소 설계가 이 시스템의 중심이다.

규칙

  • 모든 파일의 SHA-256 해시를 수집 시점에 계산해 매니페스트에 적는다.
  • 저장소는 덮어쓰기와 삭제를 막는다. 객체 잠금(보존 기간 동안 수정·삭제 금지)을 지원하는 스토리지를 쓰거나, 최소한 쓰기 권한을 수집 계정 하나로 제한한다.
  • 정정이 필요하면 원본을 고치지 않고 새 항목을 추가하고 이전 항목을 가리키게 한다.
  • 매니페스트 자체의 해시를 단계 종료 스냅샷에 남긴다. 목록이 바뀌면 해시가 달라지므로 변조를 확인할 수 있다.

매니페스트는 사람이 읽을 수 있는 형식이 좋다. 아래는 이 글에서 정한 예시 형식이다.

# evidence/2026-10-30/manifest.yaml (예시 형식)
stage: 구현
collected_at: 2026-10-30T02:00:00+09:00
collector: evidence-bot
items:
  - id: EV-20261030-007
    viewpoint: 설계 반영
    requirements: [REQ-ARC-001, REQ-ARC-004]
    source:
      repo: app-backend
      commit: 3f9c2a1
      pipeline: build#418
    file: archunit/TEST-LayerRuleTest.xml
    sha256: 9b1e…(생략)
    result: pass
  - id: EV-20261030-008
    viewpoint: 보안 점검
    requirements: [REQ-SEC-012]
    source:
      repo: app-backend
      commit: 3f9c2a1
      pipeline: build#418
    file: sbom/bom.json
    sha256: 47ac…(생략)
    result: info

항목마다 감리 관점, 요구사항 ID, 출처(저장소·커밋·빌드), 해시가 있으면 감리인이 "이 결과는 어디서 나왔나"를 물었을 때 같은 커밋으로 다시 실행해 보여 줄 수 있다.

설계 반영을 코드로 증명하기

감리에서 가장 설명하기 어려운 관점이 설계 반영이다. 설계서의 레이어 구조가 실제 코드에서 지켜지는지를 문서로 보이기는 어렵다. ArchUnit은 이 규칙을 테스트로 만든다. 테스트가 매 빌드마다 돌면, 그 결과 파일이 곧 "설계대로 구현했다"는 증적이 된다.

@AnalyzeClasses(packages = "kr.example.app")
class LayerRuleTest {

    // 아키텍처 정의서의 레이어 규칙을 그대로 옮긴다 (REQ-ARC-001)
    @ArchTest
    static final ArchRule layers = layeredArchitecture().consideringAllDependencies()
            .layer("Controller").definedBy("..controller..")
            .layer("Service").definedBy("..service..")
            .layer("Repository").definedBy("..repository..")
            .whereLayer("Controller").mayNotBeAccessedByAnyLayer()
            .whereLayer("Service").mayOnlyBeAccessedByLayers("Controller")
            .whereLayer("Repository").mayOnlyBeAccessedByLayers("Service");
}

테스트 주석에 요구사항 ID를 적어 두면 매핑 단계에서 결과 파일과 요구사항을 자동으로 잇기 쉽다. 규칙을 위반한 빌드의 결과도 버리지 않는다. 위반이 언제 생기고 언제 조치됐는지가 오히려 좋은 증적이다.

요구사항 ID와 연결하고 리포트로 뽑기

증적이 아무리 많아도 요구사항과 연결되지 않으면 감리 때 다시 사람이 찾는다. 매핑은 세 경로로 만든다.

  • 커밋 메시지: REQ-SEC-012 비밀번호 정책 적용처럼 요구사항 ID를 접두어로 쓰게 하고, 수집기가 커밋 목록에서 ID를 뽑는다.
  • 테스트 이름과 주석: 시험 결과는 테스트 클래스나 주석의 요구사항 ID로 잇는다.
  • 매핑 표: 자동으로 연결되지 않는 증적(정적 분석 전체 결과, SBOM)은 요구사항 추적표에 관점 단위로 한 번 등록해 두고 이후 수집분에 그대로 적용한다.

리포트는 감리 관점별로 나눈다. 관점마다 "요구사항 ID / 증적 ID / 수집 일시 / 결과 / 해시" 다섯 칸이면 충분하다. 증적이 하나도 없는 요구사항은 리포트 맨 위에 따로 모은다. 감리 전에 팀이 먼저 봐야 할 목록이다.

도입 순서와 구성요소별 역할

한 번에 다 만들 필요는 없다. 결과 파일이 이미 있는 것부터 붙인다.

  1. CI 마지막 단계에 테스트 리포트와 정적 분석 결과를 날짜별 폴더로 복사하고 해시를 적는다.
  2. 저장소의 쓰기 권한을 수집 계정으로 제한하고 삭제를 막는다.
  3. 커밋 메시지 요구사항 ID 규칙을 개발 표준에 넣고, 수집기가 ID를 뽑게 한다.
  4. ArchUnit으로 아키텍처 정의서의 핵심 규칙 두세 개를 테스트로 만든다.
  5. SBOM과 인프라 설정 스냅샷을 추가한다.
  6. 단계 종료 스냅샷과 관점별 리포트 생성을 붙인다.

1~2단계만으로도 "언제, 어디서 나온 결과인가"에 답할 수 있게 된다. 나머지 구성요소는 빠졌을 때 생기는 일을 보고 우선순위를 정한다.

구성요소 주로 쓰는 사람 없으면 생기는 일
수집기 PMO, 품질 담당 단계 종료마다 개발자가 결과 파일을 찾느라 작업이 멈춤
해시와 매니페스트 감리인, 품질 담당 파일이 그 시점 원본인지 증명하지 못함
삭제 금지 저장소 품질 담당 결과가 나쁜 날의 자료가 사라져 신뢰를 잃음
요구사항 ID 매핑 AA, 시험 담당 감리 직전에 추적표를 손으로 다시 만듦
ArchUnit 규칙 AA 설계 반영을 설명할 자료가 문서뿐임
관점별 리포트 PM, 감리 대응 담당 증적이 없는 요구사항을 감리 지적으로 처음 알게 됨

자주 하는 실수

  • 증적을 위해 새 산출물을 만든다. 개발팀이 따로 작성해야 하는 증적은 결국 밀린다. 이미 나오는 결과 파일을 모으는 데서 시작한다.
  • 좋은 결과만 남긴다. 실패한 빌드와 위반 기록을 지우면 조치 이력을 보여 줄 수 없다. 전부 남기고 리포트에서 최신 상태를 보여 준다.
  • 화면 캡처를 핵심 증적으로 쓴다. 캡처는 출처와 시점을 증명하지 못한다. 원본 리포트 파일과 해시가 우선이다.
  • 수집 실패로 빌드를 막는다. 배포가 막히면 수집기가 꺼진다. 실패는 알림으로 처리한다.
  • 요구사항 ID 규칙을 나중에 정한다. 구현 중반에 규칙을 넣으면 그 전 커밋은 연결되지 않는다. 착수 시점에 개발 표준에 넣는다.

점검표

  • 감리 관점마다 자동으로 결과 파일을 내는 원천이 정해져 있다
  • 메인 브랜치 빌드가 끝나면 증적이 수집되고 빌드 번호와 커밋 해시가 함께 남는다
  • 모든 증적 파일에 수집 시점의 SHA-256 해시가 있다
  • 증적 저장소는 수집 계정만 쓸 수 있고 삭제가 막혀 있다
  • 실패한 빌드와 규칙 위반 결과도 보관된다
  • 커밋 메시지 요구사항 ID 규칙이 개발 표준에 있다
  • 아키텍처 정의서의 핵심 레이어 규칙이 ArchUnit 테스트로 매 빌드마다 돈다
  • 단계 종료일에 증적 묶음과 매니페스트 해시가 봉인된다
  • 증적이 없는 요구사항 목록을 리포트에서 바로 볼 수 있다
  • 같은 커밋으로 결과를 다시 만들어 보여 줄 수 있다

감리 대응의 목표는 자료를 잘 꾸미는 것이 아니라, 개발 과정이 남긴 결과를 출처와 시점 그대로 보여 주는 것이다. 증적이 빌드와 함께 저절로 쌓이면 감리는 준비하는 행사가 아니라 이미 있는 기록을 여는 일이 된다.

댓글 0개

아직 댓글이 없습니다. 첫 댓글을 남겨보세요.

댓글 쓰기

← 목록으로 돌아가기