리스크 기반 릴리즈 게이트
blocker, evidence bundle, hotfix 예외, production-safe probe를 어떤 기준으로 운영할지 설명합니다.
핵심 요약
- 릴리즈 게이트는 테스트를 돌리는 일이 아니라 어떤 실패가 배포를 멈추는지를 정해 두는 규칙입니다.
- PR(smoke)·main·release(critical+blocker 없음)·canary(prod-safe probe) gate를 계층으로 둡니다.
- 로그인·결제·권한·데이터 무결성·canary prod-safe 실패는 blocker, 승인된 known flaky 등은 비blocker입니다.
- gate가 설득력을 가지려면 분류·근거 artifact·environment fingerprint·commit SHA를 담은 evidence bundle이 있어야 합니다.
- hotfix는 게이트 우회가 아니라 범위 축소로 다루고, agent가 green을 만들어도 evidence와 human gate로 판단합니다.
릴리즈 게이트는 테스트를 돌리는 일이 아니라 어떤 실패가 배포를 멈추는지를 정해 두는 규칙입니다. 게이트 기준을 문서로 못 박아 두지 않으면 red build는 매번 해석 싸움으로 번집니다.
gate 계층
| gate | 목적 | 통과 기준 | 실패 시 |
|---|---|---|---|
| PR gate | 변경 보호 | smoke green | merge block |
| main gate | trunk 안정성 | smoke green + known blocker 없음 | main red 유지 |
| release gate | 배포 승인 | critical green + blocker 없음 | release hold |
| canary gate | 실제 환경 확인 | production-safe probe green | rollout stop |
blocker 정의
아래는 기본적으로 release blocker 후보로 봅니다.
- 로그인, 가입, 결제, 구독, 권한 검증 실패
- 데이터 저장, 수정, 삭제의 무결성 실패
- 법적, 보안, 권한 경계가 깨지는 경우
- production-safe probe가 canary에서 실패하는 경우
반대로 아래는 기본 blocker가 아닙니다.
- nightly full suite에서만 발견된 비핵심 회귀
- 승인된 known flaky 실패
- 운영 영향이 없는 low-priority admin flow 실패
evidence bundle이 있어야 gate가 설득력을 가진다
릴리즈를 멈추려면 "테스트가 실패했다"는 한마디로는 부족하고, 아래가 함께 있어야 합니다.
- 어떤 gate와 tier에서 실패했는가
- 실패 분류는 무엇인가
- screenshot, trace, log, event 중 어떤 근거가 있는가
- 환경 fingerprint와 commit SHA는 무엇인가
- 예외 승인 또는 rollback 판단에 필요한 최소 설명이 있는가
hotfix 예외 정책
hotfix는 게이트를 건너뛰지 않고 게이트 범위를 좁혀서 다룹니다.
| 상황 | 허용 범위 | 필요 승인 |
|---|---|---|
| UI 텍스트 hotfix | smoke + 관련 critical subset | 제품 오너 + release manager |
| 결제 / 권한 hotfix | 전체 critical 유지 | release manager + QA platform |
| infra-only hotfix | production-safe probe 유지 | SRE + release manager |
production-safe browser probe 예시
브라우저 gate는 Playwright 같은 runner로 짤 수 있지만, 관건은 도구가 아니라 실제 rollout을 멈출 근거를 남기느냐입니다.
import { test, expect } from '@playwright/test'
test.describe('prod-safe smoke', { tag: ['@smoke', '@prod-safe'] }, () => {
test('읽기 전용 계정으로 로그인 후 핵심 대시보드를 확인한다', async ({ page }) => {
await page.goto('/login')
await page.getByLabel('Email').fill(process.env.E2E_CANARY_USER!)
await page.getByLabel('Password').fill(process.env.E2E_CANARY_PASSWORD!)
await page.getByRole('button', { name: '로그인' }).click()
await expect(page).toHaveURL(/dashboard/)
await expect(page.getByTestId('revenue-summary')).toBeVisible()
})
})- 계정은 읽기 전용으로 두고 비가역 mutation은 금지합니다.
- production-safe suite는 trace와 screenshot을 반드시 남깁니다.
- 같은 probe를 PR gate와 canary gate에서 재사용하더라도 의미가 달라짐을 문서로 고정합니다.
agentic 환경에서의 추가 원칙
- agent는 실패 관련 subset을 재실행할 수 있지만 gate 의미를 바꾸면 안 됩니다.
- high-risk 변경에서는 agent repair loop 이후에도 human gate가 남아 있어야 합니다.
- "agent가 green 만들었으니 배포"가 아니라 "증거 묶음이 blocker를 해소했는가"를 봐야 합니다.
리뷰 질문
- blocker 정의가 제품 리스크와 직접 연결되는가?
- evidence bundle 없이 gate만 red/green으로 소비되고 있지 않은가?
- hotfix 예외가 사실상 우회 통로가 되지 않도록 승인 기준이 문서화됐는가?