개념
폐루프 SDLC — 사람이 손을 떼도 한 바퀴가 도는 구조
전통적인 개발 수명주기(SDLC)는 단계마다 사람이 산출물을 넘겼다. 기획자가 명세서를 쓰면 개발자가 읽고 코드를 쓰고, QA가 다시 읽고 테스트를 설계했다. 단계 사이마다 사람의 해석 이 끼어 있었다. 2025년 이후 말하는 "AI 네이티브" 흐름은 이 사이를 AI 에이전트가 잇는다.
[기획] 요구 정리 에이전트 : 이슈·회의록 → 사용자 스토리·수용 기준 초안
[설계] 설계 에이전트 : 스토리 → 기술 계획·작업 목록
[구현] 코딩 에이전트 : 작업 → 코드·단위 테스트·PR
[검증] 테스트 에이전트 : PR → E2E 시나리오 생성·실행·판정
[배포] 파이프라인 : 게이트 통과 시 카나리 → 점진 확대
[관측] 모니터링 : 에러율·지연·비즈니스 지표
[치유] 셀프힐링 에이전트 : 테스트 실패 → 테스트 수정 / 운영 이상 → 롤백·패치 PR
[재배포] 수정본이 다시 [검증] 으로 들어간다마지막 줄이 처음으로 돌아가기 때문에 폐루프(closed loop) 라고 부른다. 아무도 버튼을 누르지 않아도 "실패 → 수정 → 재배포"가 반복된다. 이것이 빠른 이유이고 위험한 이유다. 루프 안의 실수도 같은 속도로 운영까지 흘러간다.
이 레슨의 질문은 하나다. 루프가 스스로 돈다면 QA는 어디에 서 있어야 하는가. 답은, QA는 루프를 돌리는 사람이 아니라 루프가 멈춰야 할 지점 을 정하고 그 지점의 판정 근거를 남기는 사람이라는 것이다.
AI가 하는 일과 사람이 판정할 일을 가르는 기준
기준은 두 가지다. 그 판정이 틀렸을 때 누가 책임질 수 있는가, 그리고 틀렸는지를 기계가 확인할 수 있는가.
| 단계 | AI가 맡아도 되는 일 | 사람이 판정할 일 |
|---|---|---|
| 기획 | 회의록 요약, 스토리 초안, 수용 기준 후보 | 만들지 말지, 정책 해석, 우선순위 |
| 설계 | 작업 분해, 영향 범위 후보, 테스트 조건 초안 | 보안·성능 기준값, 외부 연동 방식 |
| 구현 | 코드·단위 테스트, 리팩터링 | 아키텍처 변경, 비밀정보·권한 관련 변경 |
| 검증 | 케이스 펼치기, 실행, 결정적 판정 | 해석 판정 보정, 기준 변경, 실패의 결함 여부 |
| 배포 | 지표 수집, 카나리 비교, 자동 롤백 | Go/No-Go 최종 결정, 예외 승인 |
| 치유 | 로케이터·대기 수정 제안, 롤백 실행 | 기대 결과 변경, 운영 패치 승인 |
오른쪽 열의 공통점은 전부 기준을 바꾸는 일 이거나 되돌리기 어려운 일 이라는 것이다. AI는 정해진 기준 안에서 빠르게 움직이는 데 강하고, 기준 자체를 옮기는 결정에는 약하다. 기준을 옮기는 순간 그 판정을 검증해 줄 상위 기준이 없기 때문이다.
만드는 쪽과 판정하는 쪽은 분리한다
폐루프에서 가장 흔한 구조적 결함은 같은 에이전트가 만들고 판정하는 것 이다. 코딩 에이전트가 구현과 테스트를 함께 쓰면 테스트는 구현을 베낀 기대 결과를 갖는다. 구현이 틀려도 통과한다. 모듈 18c의 "항상 통과하는 가짜 테스트"가 자동으로 생산되는 셈이다.
1. 입력 분리 : 테스트 에이전트는 구현 코드가 아니라 test basis(요구사항·수용 기준·화면설계)를 입력으로 받는다
2. 기준 분리 : 기대 결과는 QA가 관리하는 기준 저장소에서 온다. 코딩 에이전트는 여기에 쓰기 권한이 없다
3. 판정 분리 : 판정은 결정적 어서션 또는 보정된 별도 판정자가 내린다. 생성 모델이 자기 결과를 채점하지 않는다두 번째 줄이 가장 중요하다. 프롬프트에 "기대값을 바꾸지 마라"라고 쓰는 것만으로는 부족하다. 에이전트는 "테스트를 통과시켜라"라는 목표 압박 아래서 그 지시를 비켜 가는 경로를 찾는다. 저장소 권한, 브랜치 보호, 코드 소유자 규칙 같은 시스템 장치 가 진짜 경계다.
셀프힐링의 두 얼굴 — 테스트 치유와 운영 치유
"셀프힐링"은 성질이 다른 두 가지를 섞어 부른다.
| 구분 | 고치는 대상 | 예 | 덮을 수 있는 결함 |
|---|---|---|---|
| 테스트 치유 | 테스트 코드 | 셀렉터 교체, 대기 조정, 데이터 교체 | 화면 회귀, 사라진 기능, 잘못 바뀐 문구 |
| 운영 치유 | 운영 시스템 | 자동 롤백, 원인 추정 후 패치 PR 배포 | 근본 원인, 데이터 오염, 재발 |
Playwright 1.56부터 제공되는 Test Agents의 healer는 실패한 단계를 다시 실행하고, 현재 UI에서 동등한 요소나 흐름을 찾아 로케이터·대기· 데이터 수정 패치를 제안한 뒤, 통과하거나 가드레일이 멈출 때까지 재실행한다. 공식 문서는 기능 자체가 망가졌다고 판단하면 통과시키는 대신 건너뛴 테스트 로 표시한다고 설명한다. 좋은 치유 도구는 "고칠 수 있는 실패"와 "고치면 안 되는 실패"를 구분하려 한다.
그러나 그 구분도 AI의 판단이다. 버튼 문구가 "결제하기"에서 "구독 시작"으로 바뀌었다고 하자. 치유 도구는 가장 비슷한 버튼을 찾아 테스트를 고친다. 그 변경이 배포되면 안 되는 실험 코드였다면, 테스트는 회귀를 잡는 대신 승인 한 것이 된다. 치유는 테스트가 앱을 따라가게 만들고, 테스트의 존재 이유는 앱이 기준을 따라가는지 보는 것이다. 방향이 정반대다.
운영 치유는 더 무겁다. 자동 롤백은 비교적 안전하지만 AI가 원인을 추정해 패치를 배포하는 흐름은 증상을 없애는 패치 를 만들기 쉽다. 예외를 삼키는 처리, 타임아웃만 늘리기, 검증 로직 우회가 대표적이다. 지표는 정상으로 돌아오고 결함은 남는다.
치유 정책 — 허용·검토·금지 세 칸
셀프힐링은 켜고 끄는 스위치가 아니라 정책 으로 운영한다.
| 칸 | 치유 행동 예 | 처리 |
|---|---|---|
| 허용 | 같은 요소의 속성 변경에 따른 로케이터 교체, 대기 조건 조정 | 자동 반영, 치유 로그, 주간 리뷰 |
| 검토 | 다른 요소로 교체, 테스트 데이터 변경, 단계 추가·삭제 | PR로만 반영, QA 승인 필수 |
| 금지 | 어서션 기대값 변경·삭제, 검증 단계 건너뛰기 | 치유 차단, 결함 후보로 등록 |
여기에 치유 예산 을 붙인다. 한 테스트가 일정 기간에 정해진 횟수 이상 치유되면 격리하고 원인을 사람이 본다. 치유된 결과는 Passed가 아니라 Healed 같은 별도 상태로 보고한다(모듈 18a 레슨 15). 치유 건수가 급증한 날은 화면이 크게 바뀐 날이고, 그런 날은 회귀가 숨기 좋은 날이다.
# healing-policy.yaml
test_healing:
auto_apply: [locator_attribute_change, wait_condition_adjust]
require_review: [locator_target_change, test_data_change, step_add_or_remove]
forbidden: [assertion_value_change, assertion_removal, step_skip]
budget:
per_test_per_14d: 2 # 초과 시 격리
per_run_ratio_alert: 0.05 # 한 실행의 치유 비율 5% 초과 시 게이트 보류
report_status: healed
prod_healing:
auto_apply: [rollback_to_last_good]
require_review: [config_change, patch_pr]
forbidden: [disable_validation, swallow_exception, raise_timeout_only]재배포 게이트와 롤백 — 루프가 멈춰야 하는 곳
QA가 지키는 가장 중요한 지점은 재배포 게이트 다. 처음 배포와 재배포는 같은 게이트를 통과해야 한다. "치유된 수정본이니 빨리 내보내자"는 예외가 쌓이면 게이트는 의미를 잃는다.
[A. 변경 성격] 어느 치유 칸에서 나왔는가 / 검토 칸이면 승인자·시각이 있는가
기준 저장소(기대 결과)가 이번 루프에서 바뀌었는가 → 바뀌었으면 자동 재배포 금지
[B. 검증 결과] 결정적 판정 전부 통과 / Healed 비율 임계치 이하 / 판정자 보정 기록 유효(m38 레슨 3)
[C. 운영 신호] 카나리 대 대조군의 핵심 SLI 차이가 허용 범위 안 / 직전 롤백 원인 지표 재악화 없음카나리 비교는 Google SRE 워크북의 "Canarying Releases" 장이 좋은 기준이다. 변경을 받은 일부(카나리)와 나머지(대조군)를 비교하고, 지표는 사용자 영향을 직접 나타내며 변경에 귀속되는 소수만 고르라고 권한다. 같은 장은 카나리 분석 서비스가 운영을 바꾸는 쪽과 분석하는 쪽을 엄격히 분리 해 순수한 관찰자로만 동작한다고 설명한다. 배포를 실행한 에이전트가 자기 배포의 성공을 판정하게 두지 않는다.
자동 재배포의 전제는 자동 롤백이 확실히 동작한다 는 것이다.
| 변경 종류 | 롤백 가능성 | 루프 처리 |
|---|---|---|
| 애플리케이션 코드, 기능 플래그 | 이전 이미지 교체·플래그 끄기 | 자동 루프 허용 |
| 설정 값 | 복원 가능, 캐시·세션 영향 확인 필요 | 검토 후 허용 |
| DB 스키마, 데이터 보정 배치 | 이미 바뀐 데이터는 되돌리기 어려움 | 자동 루프 금지 |
| 외부 시스템 호출 방식 | 상대 시스템 상태는 되돌릴 수 없음 | 자동 루프 금지 (레슨 6) |
QA는 이 표를 서비스별로 만들고, 파이프라인이 변경 경로나 PR 라벨로 "자동 루프 금지" 변경을 감지해 사람 승인으로 넘기게 요구한다. 롤백 자체도 테스트 대상이다. 정기적으로 실제 롤백을 실행해 데이터·세션·캐시를 확인하는 롤백 리허설 을 QA 활동에 넣는다.
감사 기록 — 나중에 "왜"를 되짚을 수 있게
루프가 빠를수록 사고 후 "이 변경은 누가 왜 허락했나"를 묻기 어렵다. 모든 판정에 감사 기록 이 붙어야 한다.
{
"loop_id": "LOOP-2026-10-05-0142",
"trigger": "e2e_failure",
"failed_test": "checkout/pay-with-card.spec.ts",
"healing": { "category": "require_review", "action": "locator_target_change",
"before": "button '결제하기'", "after": "button '구독 시작'",
"agent": "healer", "model": "모델 ID와 버전", "rationale": "같은 위치의 버튼 문구 변경으로 판단" },
"approval": { "by": "qa-reviewer-03", "decision": "rejected", "reason": "근거 티켓 없음, 결함 후보 등록" },
"linked_defect": "BUG-8812",
"gate_result": "blocked"
}빠지기 쉬운 항목이 모델과 버전 이다. 같은 요청도 모델이 바뀌면 다른 판단을 낸다. 그날 어떤 모델이 판단했는지 모르면 재현할 수 없다. 거절된 치유도 반드시 남긴다. 거절 기록이 쌓이면 정책의 칸을 조정하는 근거가 된다.
책임 경계 — 자동화되어도 책임은 사람에게 남는다
| 결정 | 실행 | 최종 책임 | 자문 |
|---|---|---|---|
| 수용 기준 확정 | 요구 정리 에이전트 | 기획 담당 | QA·개발 |
| 테스트 기준 변경 | QA | QA 리드 | 기획 |
| 치유 반영(검토 칸) | 치유 에이전트 | QA 담당 | 개발 |
| 재배포 Go/No-Go | 파이프라인 | 릴리스 책임자 | QA 리드 |
| 운영 패치 반영 | 코딩 에이전트 | 개발 리드 | QA·보안 |
"최종 책임" 열에 에이전트가 한 번도 없다. 에이전트는 실행할 수 있지만 책임질 수 없다. DORA의 2025년 AI 보조 개발 보고서는 AI가 조직의 기존 상태를 증폭하는 증폭기 처럼 작동해, 잘 정비된 팀은 더 강하게 하고 절차가 흩어진 조직의 약점은 더 드러낸다고 요약했다.
실무에서 왜 필요한가
폐루프는 대개 속도를 명분으로 도입되고, 그 이득은 진짜다. 그러나 몇 달 뒤 다른 숫자가 보인다. 테스트 통과율은 99%인데 운영 결함은 줄지 않는다. 파 보면 치유된 테스트가 회귀를 승인하고 있었고, 패치 PR 일부는 증상만 없앴다.
QA가 이 레슨의 게이트·정책·기록을 갖고 있으면 대화가 달라진다. "AI가 알아서 고쳤다"는 말에 "그 치유는 어느 칸이었고, 누가 승인했으며, 기대값이 바뀌었는가"로 답할 수 있다. 이것은 AI 도입을 막는 말이 아니라 지속 가능하게 만드는 말이다. 사고 한 번에 자동화가 통째로 꺼지는 조직과, 어느 칸이 문제였는지 찾아 정책만 고치는 조직의 차이가 여기서 생긴다.