Software Quality & Release 의사결정

출시 여부를 결정할 때 테스트 결과 외에 무엇을 확인해야 할까

핵심 답변

테스트 결과는 출시 판단의 중요한 증거지만 전체 판정은 아니며, 출시는 검증된 사실·남은 불확실성·사용자 영향·복구 가능성을 근거로 잔여 위험을 수용할지 결정하는 일이다.

출시 판단을 위해 여러 증거 흐름이 하나의 결정 게이트로 모이는 추상 시각화

테스트 결과만으로 출시를 확정해서는 안 된다. 테스트는 특정 버전과 환경, 데이터, 시나리오에서 관찰한 사실을 보여준다. 그 범위가 실제 변경을 충분히 덮었는지, 운영 환경에서도 같은 결과가 나올지, 실패가 사용자와 데이터에 어떤 영향을 주는지까지 대신 판단하지는 않는다. Google SRE도 테스트 환경과 운영 환경이 완전히 같지 않고 모든 시나리오를 시험할 수 없기 때문에 일부 결함은 실제 트래픽에서 드러날 수 있다고 설명한다. (Google SRE)

출시 회의가 결정해야 하는 것은 “테스트가 통과했는가”의 다음 단계다. 무엇이 확인됐고 무엇이 아직 불확실한지, 문제가 발생하면 누구에게 어떤 피해가 생기는지, 그 문제를 알아차리고 노출을 멈추거나 복구할 수 있는지 확인해야 한다. 그 근거를 놓고 조직이 남은 위험을 받아들일지 결정하는 것이 출시 판단이다.

결론은 GO, CONDITIONAL, NO-GO로 나눌 수 있다. 이때 여러 항목에 점수를 매겨 합산하면 안 된다. 사용자 데이터 손실 가능성, 확인되지 않은 핵심 경로, 복구 방법 부재처럼 다른 결과로 상쇄할 수 없는 조건이 있기 때문이다. 출시 준비도는 평균 점수가 아니라 차단 조건과 증거 공백을 먼저 봐야 한다.

테스트 결과가 증거가 되려면 맥락이 함께 있어야 한다

“전체 테스트가 통과했다”는 문장만으로는 판단하기 어렵다. 최소한 다음 맥락이 붙어야 한다.

어떤 버전인지, 무엇을 검증했는지, 어떤 환경과 데이터로 실행했는지, 실행하지 못하거나 제외한 항목은 무엇인지, 결과가 언제 생성됐는지를 알아야 한다.

예를 들어 테스트가 모두 통과했더라도 그 이후 설정이 바뀌었다면 결과의 유효성이 달라진다. 핵심 사용자 경로가 테스트 범위에서 빠졌거나, 외부 결제·인증·메시징 시스템이 정상일 때만 검증했다면 “통과”가 말해주는 범위도 좁다. 실패한 테스트가 없다는 것과 실패할 수 있는 조건을 충분히 확인했다는 것은 같은 말이 아니다.

Release Evidence Matrix

출시 판단에는 테스트 보고서 외에도 요구 충족, 보안과 데이터, 운영 환경, 사용자 영향, 복구 가능성, 책임자에 관한 Evidence가 필요하다.

기능 테스트 결과만으로 보안 준비를 대신할 수도 없다. NIST SSDF는 보안 활동을 SDLC에 통합할 고수준 실천 영역으로 제시하며 OWASP ASVS는 기술적 보안 통제를 검증할 수 있는 요구사항 기준을 제공한다. (NIST, OWASP)

아래 Matrix는 품질 점수를 계산하는 표가 아니다. 판단에 필요한 증거가 있는지, 어떤 공백이 출시를 막는지, 어떤 위험만 조건부로 받아들일 수 있는지 확인하는 표다.

증거 영역 확인할 질문 필요한 Evidence 차단 조건 조건부 허용 조건 Owner
요구 충족과 변경 범위 이번 릴리스가 해결하기로 한 요구와 실제 변경이 일치하는가? 승인된 릴리스 범위, 변경 요약, 수용 기준, 제외 항목 핵심 요구나 변경 범위를 팀이 합의하지 못함 비핵심 항목을 명시적으로 제외하고 후속 Owner·기한을 기록함 Product Owner
테스트 결과와 한계 중요한 경로를 적절한 환경과 데이터로 검증했는가? 대상 버전, 실행 환경, 테스트 결과, 미실행·차단·제외 항목, Evidence 생성 시점 핵심 경로가 미실행·차단됐거나 결과가 현재 버전과 연결되지 않음 영향이 제한적인 검증 공백이며 노출 범위·관찰 방법·후속 검증이 정해짐 QA Lead / Engineering Lead
미해결 결함과 잔여 위험 남은 결함이 실제로 발생하면 누구에게 어떤 피해가 생기는가? 미해결 결함 목록, 영향 분석, 재현 조건, 우회 방법, 불확실성 데이터·금전·권한·법적 의무 또는 복구하기 어려운 피해가 통제되지 않음 영향 범위가 제한되고 대응 방법, Owner, 만료 시점이 기록됨 Product / Engineering
보안·개인정보·데이터 새 권한, 민감정보 처리, 데이터 변경에서 확인하지 못한 위험이 있는가? 보안 검토, 적용한 요구사항과 버전, 데이터 흐름 확인, 미해결 보안 이슈 무단 접근, 정보 노출, 데이터 손상 가능성이 해결되지 않았거나 승인 권한자가 위험을 검토하지 않음 비핵심 공백이고 노출 범위가 제한되며 보완 조치와 재검토 시점이 정해짐 Security / Privacy Owner
운영 환경과 외부 의존성 운영 설정, 용량, 자격증명, 외부 서비스가 실제 조건에서 준비됐는가? 운영 구성 확인, 의존성 상태, 제한 조건, 지원 연락망, 운영 담당자 핵심 의존성이나 운영 설정이 불명확하고 장애 시 대응 주체도 없음 특정 사용자·시간·기능으로 노출을 제한하고 담당자가 즉시 대응할 수 있음 Operations / Service Owner
사용자 영향 관측 출시 후 중요한 사용자 실패를 팀이 알아차릴 수 있는가? 관찰할 사용자 영향, 확인 화면 또는 신호, 관찰 기간, 중단 트리거 사용자에게 큰 피해가 발생해도 팀이 이를 발견할 방법이 없음 제한된 범위에서 사람이 직접 확인할 수 있고 확대 전 재판정하기로 함 Service Owner / Reliability Owner
복구 가능성 문제가 발생하면 노출을 멈추고 알려진 상태로 돌아가거나 안전하게 수정할 수 있는가? 검증된 중단·복구 경로, 실행 권한, 책임자, 복구 완료 확인 방법 되돌릴 수 없는 고영향 변경이거나 복구 경로를 검증하지 못함 영향 범위가 제한되고 검증된 대체 대응 또는 전진 복구 경로가 있음 Release / Operations Owner
책임과 승인 기록 누가 출시를 결정하고 남은 위험을 누가 받아들이며 문제가 생기면 누가 행동하는가? Release Decision Record, 잔여 위험 Owner, 승인 권한자, 재검토 시점 결정권자나 대응 Owner가 없고 위험 수용 주체가 불명확함 조건과 Owner, 승인자, 만료 시점을 모두 기록한 경우에만 조건부 출시 가능 Release Authority

Matrix의 모든 칸을 길게 채울 필요는 없다. 다만 차단 조건에 해당하는 공백을 다른 항목의 좋은 결과로 상쇄해서는 안 된다.

GO / CONDITIONAL / NO-GO는 어떻게 나눌까

GO

현재 릴리스 범위에 필요한 Evidence가 확보됐고 받아들일 수 없는 잔여 위험이 발견되지 않은 상태다.

GO가 “결함이 없다”거나 “장애가 발생하지 않는다”는 뜻은 아니다. 정상적인 운영 위험은 남을 수 있다. 다만 중요한 불확실성이 파악됐고 조직이 정한 수용 범위 안에 있으며 문제가 생겼을 때 관찰하고 대응할 수 있다는 근거가 있어야 한다.

CONDITIONAL

출시를 막는 절대적 차단 조건은 없지만 확인하지 못한 조건이나 남은 위험이 있는 상태다. 다음 항목이 모두 정해져야 한다.

  • 누구 또는 어떤 기능에만 노출할지
  • 무엇을 관찰할지
  • 어떤 상황에서 노출을 멈출지
  • 문제가 발생하면 어떻게 대응할지
  • 누가 그 결정을 실행할지
  • 언제 다시 GO 또는 NO-GO를 판정할지

“일단 출시하고 지켜본다”는 CONDITIONAL이 아니다. 범위와 중단 조건, 책임자, 만료 시점이 없는 조건부 출시는 사실상 기록되지 않은 GO다.

NO-GO

다음 중 하나라도 해당하면 출시를 보류하는 편이 타당하다.

  • 핵심 변경 범위나 요구사항이 불명확하다.
  • 중요한 사용자 경로를 검증하지 못했다.
  • 데이터·금전·권한·개인정보에 회복하기 어려운 피해가 생길 수 있다.
  • 남은 불확실성의 영향 범위를 제한할 수 없다.
  • 사용자 피해를 발견할 방법이 없다.
  • 문제가 생겨도 노출을 중단하거나 복구할 근거가 없다.
  • 위험을 받아들일 권한자와 대응 Owner가 없다.

복구 가능성은 출시 후 운영 편의를 위한 부록이 아니다. Google SRE는 점진적 적용, 진행 중단, 되돌리기 능력을 안전한 변경의 핵심 속성으로 설명하며 복구가 불가능한 배포는 사용자 피해를 더 오래 지속시킬 수 있다고 지적한다. (Google SRE Canarying, Configuration Design)

Decision Tree

구조 다이어그램

text
1. 상쇄할 수 없는 차단 조건이 있는가?
   └─ 예 → NO-GO

2. 남은 불확실성의 사용자·데이터·사업 영향을 설명할 수 있는가?
   └─ 아니오 → NO-GO

3. 노출 범위를 제한하고 문제를 관찰하며 중단·복구할 수 있는가?
   └─ 아니오 → NO-GO

4. 조건, Owner, 중단 트리거, 재판정 시점이 기록됐는가?
   └─ 예 → CONDITIONAL

5. 현재 범위에 필요한 Evidence가 충분하고
   받아들일 수 없는 잔여 위험이 없는가?
   └─ 예 → GO

잔여 위험은 결함 목록과 다르게 기록해야 한다

NIST는 잔여 위험을 통제나 대응을 적용한 뒤에도 남는 위험으로 정의한다. 허용 가능한 위험은 조직이 정한 위험 수용 범위 안에 있는 잔여 위험이다. 원래는 보안 위험 관리 문맥의 정의지만 출시 판단에서도 유용한 구분이다. (NIST Residual Risk)

결함 목록에는 “무엇이 잘못됐는가”가 적힌다. 잔여 위험 기록에는 “어떤 조건에서 누구에게 어떤 일이 생길 수 있으며 왜 지금 수용하려는가”가 적혀야 한다.

“중간 위험”, “Severity 3”, “추후 수정”처럼 압축된 라벨만 남기면 다음 사람이 판단을 재현할 수 없다. 다음 문장 구조를 사용하면 위험의 조건과 책임을 함께 남길 수 있다.

[원인 또는 미확인 조건] 때문에 [영향 대상]에서 [실패 사건]이 발생해 [사용자·데이터·사업 영향]이 생길 수 있다. 현재 확인된 근거와 불확실성은 [Evidence]다. 출시 시 [노출 제한 또는 완화 조치]를 적용하고 [관찰 신호]에서 [중단 트리거]가 확인되면 [대응 또는 복구]한다. Owner는 [역할], 위험 수용 권한자는 [역할], 재검토 시점은 [날짜 또는 사건]이다.

Residual Risk Register 필드

필드 기록할 내용
Risk ID 변경되지 않는 식별자
위험 시나리오 원인, 실패 사건, 결과를 한 문장으로 기록
영향 대상 사용자 유형, 데이터, 업무, 외부 의존성
확인된 Evidence 테스트, 검토, 운영 확인 등 이미 아는 사실
남은 불확실성 아직 확인하지 못한 조건
영향과 가역성 피해의 크기뿐 아니라 되돌릴 수 있는지
출시 조건 사용자·기능·시간·지역 등 노출 제한
관찰 및 중단 트리거 무엇을 보고 언제 멈출지
대응 또는 복구 트리거 발생 시 실행할 조치와 완료 확인
Owner 관찰하고 행동할 담당 역할
Acceptance Authority 잔여 위험을 수용할 권한자
Expiry / Review 조건부 승인이 끝나거나 다시 판단할 시점

Severity와 발생 가능성을 기록해도 되지만 그것만으로 출시 여부를 자동 계산해서는 안 된다. 같은 라벨을 가진 위험이라도 데이터 복구 가능성, 사용자 범위, 탐지 가능성, 책임자 유무에 따라 결론이 달라질 수 있다.

Release Decision Record에는 무엇을 남겨야 할까

Release Decision Record는 승인 서명을 모으는 문서가 아니다. 어떤 Evidence를 보고 어떤 불확실성을 받아들였는지, 판단을 나중에 다시 검토할 수 있게 만드는 기록이다.

필드 기록할 내용
Release ID 제품·서비스명, 버전 또는 변경 식별자
Decision GO / CONDITIONAL / NO-GO
Decision Time 판단 시점과 적용 예정 시점
Release Scope 포함 기능, 제외 기능, 대상 사용자
Affected Assets 사용자, 데이터, 권한, 외부 시스템
Evidence References Matrix 각 영역의 근거 문서와 생성 시점
Known Unknowns 확인하지 못한 조건과 현재 가정
Hard Blocker Check 차단 조건의 존재 여부와 판단 근거
Residual Risks Risk ID와 조건부 수용 내용
Release Conditions 노출 제한, 관찰 기간, 확대 조건
Stop Trigger 중단 또는 재판정을 시작할 사건
Recovery Evidence 검증한 중단·복구 경로의 참조
Owners 관찰, 대응, 복구를 맡는 역할
Acceptance Authority 최종 판단과 위험 수용 권한자
Expiry / Reassessment 조건부 결정의 만료·재검토 시점
Rationale 왜 다른 판정이 아닌 이 결론을 선택했는지

결정 기록은 길수록 좋은 것이 아니다. Evidence를 찾을 수 있고 판단의 전제와 책임이 드러나며 조건부 결정이 언제 끝나는지만 명확하면 된다.

가상 시나리오: 주문 상태 알림 기능 출시

B2B 주문 관리 서비스에 외부 메시징 사업자를 이용한 주문 상태 알림 기능을 추가한다고 가정해 보자.

기능 테스트와 회귀 테스트는 통과했다. 승인된 연락처만 사용하며 새로운 민감정보를 별도로 저장하지 않는다는 보안·데이터 검토도 끝났다. 알림 전송이 실패해도 주문 상태 자체는 정상적으로 저장된다.

다만 실제 피크 시간대에 외부 메시징 사업자의 호출 제한이 어떻게 작동할지는 충분히 확인하지 못했다. 문제가 생기면 일부 사용자가 알림을 늦게 받거나 받지 못할 수 있다. 주문 데이터 손실로 이어지지는 않지만 업무 지연은 발생할 수 있다.

팀은 제한된 고객 그룹에만 기능을 먼저 노출할 수 있고 메시지 처리 지연·전송 실패·주문 상태와 알림 상태의 불일치를 확인할 수 있다. 문제가 확인되면 기능 노출을 중단할 수 있다는 Evidence도 검증됐다. 운영 Owner와 재판정 시점은 첫 정상 피크 구간이 끝난 뒤로 지정했다.

이 경우 판정은 다음과 같다.

yaml 예시

text
decision: CONDITIONAL

rationale:
  - 핵심 주문 데이터의 정확성과 저장 경로는 검증됐다.
  - 외부 메시징 사업자의 실제 피크 제한 동작은 아직 불확실하다.
  - 남은 위험은 알림 지연·누락으로 제한되며 주문 처리 자체에는 영향을 주지 않는다.
  - 노출 범위 제한, 관찰, 중단, 담당자 지정이 가능하다.

release_conditions:
  - 선택된 고객 그룹에만 노출한다.
  - 메시지 처리 지연과 전송 실패를 운영 담당자가 확인한다.
  - 주문 상태와 알림 상태가 불일치하는 경우 확대를 중단한다.
  - 첫 정상 피크 구간이 끝난 뒤 Evidence를 다시 검토한다.

owner:
  - Service Owner
  - Operations Owner

reassessment:
  - 첫 정상 피크 구간 검토 완료 시점

GO가 아닌 이유는 실제 운영 조건에서 확인하지 못한 중요한 의존성이 남아 있기 때문이다.

NO-GO가 아닌 이유는 핵심 주문 데이터가 손상되지 않고 영향 범위를 제한할 수 있으며 문제를 관찰하고 노출을 중단할 수 있기 때문이다.

이 차이를 설명하지 못한다면 CONDITIONAL 판정을 내려서는 안 된다.

출시 판단에서 자주 생기는 오류

테스트 개수나 통과율을 품질 전체로 본다

테스트가 많아도 변경과 관계없는 항목만 반복했다면 출시 Evidence는 약하다. 테스트 개수보다 이번 변경에서 중요한 사용자·데이터·의존성을 확인했는지가 먼저다.

결함 Severity만 보고 사용자 영향을 보지 않는다

동일한 Severity 라벨이라도 극소수 화면의 표현 오류와 금전·데이터 불일치는 같은 방식으로 다룰 수 없다. 발생 조건, 영향 범위, 가역성을 함께 기록해야 한다.

복구 문서가 있다는 이유로 복구 가능하다고 본다

문서가 존재하는 것과 현재 버전·설정·데이터에서 실제로 실행할 수 있는 것은 다르다. Release Gate가 확인할 것은 문서의 존재가 아니라 검증된 Evidence다.

조건부 출시를 무기한 상태로 둔다

Owner와 만료 시점이 없는 조건부 결정은 위험을 다음 회의로 미루는 방식이 된다. 조건이 충족되면 GO로 전환하고 충족되지 않으면 NO-GO 또는 추가 제한을 다시 판단해야 한다.

종합 점수로 차단 조건을 가린다

보안 Evidence가 없거나 복구할 수 없는 데이터 변경이 있는데도 다른 항목의 높은 점수로 전체 결과를 통과시켜서는 안 된다. Release Gate는 평균보다 비상쇄 조건을 먼저 본다.

출시 여부는 “결함이 없는가”가 아니라 “무엇을 알고 감수하는가”의 문제다

좋은 테스트 결과는 출시 판단에서 매우 중요한 Evidence다. 그러나 테스트 결과가 출시 판정 그 자체가 되지는 않는다.

출시할 수 있는 상태란 모든 위험이 사라진 상태가 아니다. 현재 범위에 필요한 사실이 충분히 검증됐고 남아 있는 불확실성과 사용자 영향을 설명할 수 있으며 문제가 발생했을 때 관찰하고 중단하거나 복구할 수 있고 그 위험을 받아들일 책임자가 분명한 상태다.

따라서 출시 회의의 마지막 질문은 “테스트가 몇 개 통과했는가”가 아니다.

무엇을 확인했고 무엇을 아직 모르며 그 상태로 출시했을 때 생길 수 있는 결과를 누가 받아들이는가.

그 질문에 근거와 기록으로 답할 수 있을 때 비로소 GO, CONDITIONAL, NO-GO를 구분할 수 있다.