ALPACA-FW #10|공정 완료의 Quality Gate에 대하여. 품질 기준을 유지하기 위한 '일반적인' 개발 표준을 AI에 녹여내기
요약
본 글은 소프트웨어 개발 공정의 끝단에서 산출물의 품질을 평가하는 'Quality Gate(QG)' 메커니즘에 대해 논합니다. 단순히 파일 존재 여부를 넘어, 요구사항의 모호성이나 내용적 결함을 잡아내어 다음 단계 진행을 막는 것이 목표입니다. 이를 통해 AI가 생성한 결과물이라도 검증 가능한 상태를 유지할 수 있습니다.
핵심 포인트
- QG는 단순 체크리스트가 아닌, '다음으로 진행 불가' 상태를 설명 가능하게 멈추게 하는 시스템이다.
- 산출물의 유무(완비성)뿐 아니라 내용의 품질과 모호성을 검증하는 것이 핵심이다.
- 각 Gate마다 막고자 하는 실패 유형이 다르며, 요구사항 정의 단계에서부터 엄격한 기준을 적용해야 한다.
서론
이전까지는 ALPACA-template의 산출물, Traceability, Catalog, CLI 등을 순서대로 살펴보았습니다. 이번에는 그것들을 공정의 끝에서 어떻게 평가했는지, **Quality Gate(QG)**의 메커니즘을 되돌아봅니다.
Quality Gate라는 단어만 보면 '공정 말에 체크리스트를 확인하는 시스템'이라고 생각할 수 있습니다. 실제로 template 버전에도 많은 체크 항목이 있습니다. 하지만 제가 게이트에서 정말 하고 싶었던 것은 항목을 늘리는 것이 아니었습니다.
목표는 '아직 다음으로 진행해서는 안 되는 상태'를 분위기가 아닌 설명 가능한 형태로 멈추게 하는 것입니다.
AI를 사용하면 문서도 코드도 매우 빠르게 생성할 수 있습니다. 그렇기 때문에 '생성되었다', '검토했다', '검증되었다', '다음으로 진행 가능하다'는 같은 의미가 아닙니다. template 버전에서는 이 차이를 QG1~QG6이라는 공정 경계에 녹여냈습니다.
template 버전에서는 QG1~QG6을 배치했습니다
ALPACA-template의 워터폴(Waterfall) 방식에서는 요구사항부터 운영 준비까지를 다음 6개의 Gate로 구분하고 있습니다.
| Gate | 판정하는 주요 상태 |
|---|---|
| QG1 | 요구사항 정의가 완료되어, 요구사항이 검증 가능한 상태인가 |
| ... | |
| 흐름은 대체로 다음과 같습니다. |
요구사항 정의
↓ QG1
기본 설계
...
여기서 중요한 것은, QG6을 통과했다고 해서 바로 실제 운영 작업을 할 수 있다는 의미는 아니라는 것입니다. QG6은 어디까지나 '운영 준비가 되어 있는지'에 대한 판정이며, 실제 환경에 변경을 가하는 작업의 승인과는 분리되어 있습니다.
Gate를 '통과 스탬프'로 만들지 않기 위해, 무엇을 확인하는 Gate인지 명확하게 분리했습니다.
Gate에서 본 것은 산출물의 유무만은 아니었다
초기의 Quality Gate를 생각할 때 빠지기 쉬운 함정이 바로 '필요한 파일이 갖춰져 있는지'를 체크하는 시스템으로 만들어 버리는 것입니다.
예를 들어 QG1에서 요구사항 정의서, 비기능 요구사항, 시스템 컨텍스트, 용어집이 존재한다고 해도, 그것만으로는 요구사항 정의가 끝났다고 할 수 없습니다. 내용이 모호하거나, 요구사항끼리 모순되거나, 비기능 요구사항이 '고성능이어야 한다'와 같은 검증 불가능한 표현에 그친다면, 파일은 존재해도 품질이 부족합니다.
template 버전의 QG는 적어도 다음 3가지 관점을 보려고 했습니다.
| 관점 | 확인하고 싶었던 것 |
|---|---|
| 완비성 | 필요한 산출물/항목이 존재하는가 |
| ... | |
| 즉, Gate는 '파일이 있는지'만으로도 안 되고, '사람이 봐서 괜찮다고 했는지'만으로도 안 됩니다. 산출물, 내용, Traceability, Evidence, 승인을 결합하여 다음 공정으로 진행할 수 있는 상태인지를 판단하는 시스템으로 설계했습니다. |
QG마다 '막고 싶은 실패'가 다르다
각 Gate에는 그 단계에서 막고 싶은 실패가 있습니다.
QG1 — 모호한 요구사항을 그대로 설계로 넘기지 않기
QG1에서는 비즈니스 요구사항에 배경·목적·성공 기준이 있는지, 기능 요구사항이 입력·처리·출력을 특정할 수 있는지, 비기능 요구사항이 객관적으로 확인할 수 있는 형태로 되어 있는지 등을 봅니다.
예를 들어,
검색 기능을 제공한다
만으로는 검색 대상, 조건, 결과 건수, 권한, 성능 등이 알 수 없습니다. AI는 이 상태에서도 설계안을 만들 수 있지만, 그 빠름이 오히려 위험합니다. 모호한 요구사항을 전제로 하위 산출물이 대량 생성되면, 나중에 수정할 범위도 커지기 때문입니다.
QG1에서 막고 싶은 것은 '요구사항서가 없는 것'이 아니라, 아직 설계로 넘길 만큼 요구사항이 정해지지 않았는데 진행하는 것입니다.
QG2 — 요구사항과 설계가 단절된 채 진행하지 않기
QG2에서는 기능·비기능 요구사항이 기본 설계에 대응되어 있는지, 방식 선택에 이유가 있는지, 화면·IF·데이터 모델 사이에서 용어나 타입이 충돌하고 있지 않은지 등을 확인합니다.
여기서는 Traceability가 효과를 발휘합니다. 요구사항이 존재해도 그것을 실현하는 설계가 보이지 않으면 '미실현 요구사항'입니다. 반대로, 설계에만 존재하고 요구사항의 근거가 없는 기능도 주의가 필요합니다.
Gate를 두어 '설계서를 완성했다'가 아니라, 요구사항을 설계로 인계받고 있는지를 판정하고 싶었던 것입니다.
QG3 — 구현자에게 판단을 전적으로 맡기지 않기
QG3은 상세 설계와 테스트 계획의 Gate입니다. API의 정상 케이스·비정상 케이스, DB 물리 설계, 모듈 의존성, 단위 테스트 관점 등이 구현 시작 전에 필요한 수준까지 결정되어 있는지를 봅니다.
여기서 부족하면 구현자나 AI Coding Agent가 빈 공간을 임의로 채우게 됩니다. 구현 중에 적절한 판단을 하는 것 자체는 나쁘지 않지만, 그 판단이 요구사항이나 설계의 의미를 바꾼다면 단순한 구현 판단이 아닙니다.
QG3은 '코드를 작성할 수 있는 상태'와 '무엇을 구현해야 할지에 합의된 상태'를 분리하는 역할을 맡겼습니다.
QG4 — 코드가 있다는 것만으로 제조 완료로 간주하지 않기
QG4에서는 구현이 상세 설계와 일치하는지, 정적 분석(static analysis), 단위 테스트(unit test), 코드 리뷰(code review), 의존 라이브러리 확인 등을 살펴봅니다.
AI를 사용하면 특히 '코드가 생성되었고 테스트도 일부 통과했으니 완료'라고 판단하기 쉽습니다. 하지만 설계와 의미가 어긋나거나, 테스트 대상이 편향되어 있거나, 리뷰가 자체 점검으로 끝났을 가능성이 있습니다.
따라서 제조 완료는 코드량이나 생성 완료가 아니라, 재현 가능한 검증과 독립적인 확인을 거친 상태로 간주했습니다.
QG5 — '테스트했다'가 아닌, 요구사항을 검증했는지
QG5에서는 계획한 테스트가 완료되었는지뿐만 아니라, REQ-F/REQ-N이 시스템 테스트(system test)에서, REQ-B가 인수 테스트(acceptance test)에서 검증되었는지를 RTM으로 확인합니다.
테스트 케이스가 100건 모두 OK여도, 중요한 요구사항 자체가 테스트 케이스에 포함되지 않았다면 품질 보증이 되지 않습니다. 건수가 아니라, 무엇을 증명하고 싶었는지를 추적할 수 있어야 합니다.
미해결 불량(unresolved defect)에 대해서도 단순히 '잔여 3건'이라고 하는 것이 아니라, 중요도, 잔존 리스크(residual risk), 출시 판단과의 관계를 명시하는 형태로 바꿨습니다.
QG6 — 동작하는 시스템과 운영 가능한 시스템을 분리하기
QG6은 Operational Readiness Review, 즉 운영 준비 확인입니다.
모니터링(monitoring), 알림(alert), 백업/복구(backup/restore), 마이그레이션(migration), 롤백(rollback), Runbook, 운영 체제(operation structure), 구성 베이스라인(configuration baseline) 등을 확인합니다. QG5까지 기능이 올바르게 동작하더라도, 장애 시 복구할 수 없거나, 아무도 모니터링하지 않거나, 복구 절차가 시도되지 않았다면 본 서비스로서는 준비가 부족합니다.
여기서 '만들 수 있는 것'과 '운영 가능한 것'을 분리했습니다. 그리고 앞서 언급했듯이, 운영 준비가 완료된 것과 실제 운영(본격적인 조작)을 승인하는 것도 분리하고 있습니다.
Catalog와 문서를 분리한 이유
template 버전에서는 Gate의 정의를 한 곳에만 두지 않았습니다.
사람이 읽는 상세 기준은 docs/framework/quality-gates.md에 있습니다. 반면, framework/catalog.toml에는 Gate ID, 필요 산출물(deliverable), 품질 판정 역할을 수행할 주체, 진행 승인 역할을 수행할 주체 등 기계적으로 다루고 싶은 계약을 두었습니다.
예를 들어 QG1의 경우, 필요 산출물 목록과 함께,
- 품질 판정: qa-reviewer
- 진행 승인: Project Owner
이라는 책임 분리(separation of responsibility)를 Catalog 측에서도 표현했습니다.
또한, 공정 도중에는 project check --gate QGn와 gate preflight --gate QGn을 구분하여 사용합니다. 전자는 선택한 Gate까지 필요한 산출물과 구조를 누적 확인하고, 후자는 그 Gate 자체의 산출물/증거(evidence)/승인을 확인할 역할을 합니다.
이 설계로 목표했던 것은 사람을 위한 품질 관점과 기계가 확인할 수 있는 계약을 조금씩 분리하는 것이었습니다. 다만, 나중에 되돌아보니 이 분리는 아직 충분하지 않았습니다. 이 점은 후반부에 다루겠습니다.
품질 판정과 '진행해도 되는지'를 분리한 이유
Quality Gate에서 특히 중요하다고 생각했던 것은 품질을 평가하는 사람과 리스크를 감수하고 진행 여부를 결정하는 사람을 분리하는 것입니다.
template 버전에서는 qa-reviewer가 독립적인 입장에서 품질을 확인하며,
- 합격 권장(Pass recommended)
- 조건부 합격 권장(Conditional pass recommended)
- 불합격 권장(Fail recommended)
을 내놓습니다.
하지만, qa-reviewer가 '다음 공정으로 진행하라'고 승인하는 것은 아닙니다. 최종적인 공정 진행 판단은 Project Owner가 수행하며, QGR (Gate Review)에 기록합니다.
이 분리가 되지 않으면, 리뷰 담당자가 '품질적으로는 문제가 있지만, 일정상 어쩔 수 없으니 OK'라고 판단하거나, 반대로 책임자가 '사업상 진행해야 하니 품질도 OK로 처리하자'와 같은 혼선이 발생할 수 있습니다.
품질상의 사실과 사업/프로젝트로서의 의사결정은 관련되어 있지만 동일한 것은 아닙니다.
Gate의 판정 대상을 고정하기
또 하나 구현하면서 알게 된 중요한 점은, '무엇을 리뷰했는지'를 고정하는 것입니다.
리뷰 중 대상 결과물이나 코드가 변경되면, 시작할 때 보았던 것과 최종 판정 시의 것이 달라져 버립니다. 따라서 QGR에서는 대상 커밋, 결과물, 설정, 이관물 등을 gate.snapshot으로 기록하여 심사 대상을 고정합니다.
심사 중에 대상이 바뀌는 경우에는 이전 판정을 재사용하지 않고, 심사 회차를 올려서 재심사합니다.
이는 인간의 리뷰에서도 중요하지만, AI가 빠르게 수정을 반복하는 환경에서는 더욱 중요합니다. '아까 지적했던 문제는 고쳐졌다'고 해도, 그 대가로 다른 변경이 들어와 있을 가능성이 있습니다. 판정과 대상의 Identity를 연결할 필요가 있습니다.
조건부 합격을 '대충 괜찮다'로 만들지 않기
현실 프로젝트에서는 모든 중간 수준의 지적 사항을 현장에서 바로 고칠 수 있는 것은 아닙니다. 그래서 template 버전에서는 조건부 합격(Conditional Pass)을 준비했습니다.
하지만, '나중에 고치겠습니다'라는 말만으로 통과할 수 있게 만들면 Gate의 의미가 사라집니다. 따라서 조건부 합격 시에는 WVR로서 대상, 이유, 잔존 리스크, 책임자, 기한, 허용하는 다음 공정, 재확인 방법, 승인자를 명시하는 형태로 했습니다.
게다가 법령/계약/보안, 고중대도 결함, 필요한 인간 확인, 실제 운영 통제 대상 조작의 승인 등은 조건부 합격으로 면제할 수 없도록 하고 있습니다.
여기서의 생각 방식은 예외를 금지하는 것이 아니라, 예외를 구조화하여 보이게 하는 것입니다. 현실 개발에는 예외가 있습니다. 문제는 그 예외가 암묵적인 상태로 다음 공정으로 흘러가는 것입니다.
애자일(Agile)에서도 Gate를 없앤 것은 아니다
template 버전에서는 워터폴(Waterfall) 방식뿐만 아니라 반복형에도 동일한 품질 원칙을 적용했습니다.
다만, 스프린트마다 QG1부터 QG6까지 순서대로 통과하는 것은 아닙니다. 다음과 같이 해석할 수 있습니다.
| WF의 Gate | 애자일에서의 처리 |
|---|---|
| QG1 | 인셉션 게이트 |
| ... | |
| 즉, '공정이 다르니까 품질 기준을 없애는 것'이 아니라, 어떤 타이밍에 동일한 품질 조건을 확인할지 바꾸는 생각입니다. |
예를 들어, 기본 설계나 상세 설계에 해당하는 내용이 부족한 PBI(Product Backlog Item)는 DoR(Definition of Ready)을 충족하지 못해 착수하지 않습니다. 구현, 리뷰, 테스트, Traceability가 갖춰지지 않으면 DoD(Definition of Done)로 간주하지 않습니다. 릴리스 시에는 전체적으로 QG5, QG6을 확인합니다.
프로세스 모델이 바뀌어도 '상류가 결정되지 않은 작업을 시작하지 않는다', '검증하지 않은 것을 Done으로 만들지 않는다'라는 원칙은 유지했습니다.
AI 개발에서 Gate를 강화하고 싶었던 이유
ALPACA-template을 만들기 시작했을 때, AI에게 개발을 맡기면서 가장 무서웠던 것은 명백한 실패보다 그럴듯한 성공이었습니다.
문서는 깔끔하게 작성할 수 있습니다. 코드도 생성할 수 있고. 테스트도 '실행했습니다'라고 설명할 수 있습니다. 하지만 사람이 하나하나 확인해 보면, 요구사항이 빠져 있거나, 실제로는 테스트하지 않았거나, 다른 환경의 결과를 근거로 삼고 있는 경우가 있었습니다.
AI는 '무언가를 생성하는 능력'이 높을수록, 결과물의 외관만으로 진척도를 판단할 위험도 커집니다.
그래서 Gate에는 적어도 다음 구분점을 두어야 한다고 생각했습니다.
생성되었다
≠
필요한 결과물이 갖춰졌다
...
이 구분점은 AI 전용의 개념이 아닙니다. 인간 개발에서도 마찬가지입니다. 다만 AI로 인해 생성 속도가 빨라지면서, 모호한 완료 판정 문제가 더욱 두드러지게 된 것입니다.
만들어보니 좋았던 점
template 버전의 Quality Gate에는 몇 가지 남기고 싶은 생각들이 있었습니다.
첫째는 품질 문제를 '신경 쓰이는 지점'이 아니라, 다음으로 진행할 수 없는 구체적인 이유로 바꿀 수 있었다는 것입니다. 요구사항이 검증 불가능하면 QG1에서 멈추고, Traceability가 끊겨 있으면 해당 Gate에서 멈추고, 중대한 결함이 남아 있으면 QG5를 통과하지 못하는 식으로 판단하기 쉬워졌습니다.
둘째는 품질 권장(Quality Recommendation)과 진행 판단(Proceeding Judgment)을 분리한 것입니다. 누가 품질을 평가하고, 누가 리스크를 감수할지가 명확해졌습니다.
셋째는 Gate를 Evidence나 QGR과 연결했다는 것입니다. '확인했습니다'라는 대화가 아니라, 어떤 대상을, 무엇을 근거로, 누가 어떻게 판정했는지를 남기는 방향으로 나아갔습니다.
이 Evidence와 QGR에 대해서는 다음 기사에서 자세히 다루겠습니다.
만들어보니 알게 된 무게감
반면에 Quality Gate를 강화할수록 Framework가 무거워졌습니다.
quality-gates.md
여기에는 공통 기준과 각 Quality Gate(QG)별로 수많은 관점이 포함되며, Catalog에는 결과물 계약이 들어가고, CLI는 결과물, Traceability, Gate를 확인하며, 나아가 Evidence, QGR, CCR까지 관련됩니다. 품질을 지키려고 할수록 '무엇을 봐야 올바른지'가 여러 곳으로 퍼져나갔습니다.
또한, 기계적으로 판별할 수 있는 것과 인간/AI의 추론이 필요한 것이 같은 Gate 안에 혼재되어 있었습니다.
예를 들어,
- 필수 파일 존재 여부
- 필수 열(Column) 존재 여부
- ID가 Trace 가능한지
와 같은 것은 비교적 결정론적으로 확인할 수 있습니다.
반면에,
- 요구사항 간에 의미상의 모순이 없는지
- 기술 선정 이유가 타당한지
- 잔존 리스크를 수용할 수 있는지
와 같은 것은 단순 구조 검사만으로는 판별할 수 없습니다.
template 버전에서는 이들을 하나의 품질 체계로 통합하는 것을 우선했지만, 실제로 운영해 볼수록 기계 검증(Machine Verification), 추론 리뷰(Inference Review), 책임자 판단(Owner Judgment)을 더 명확히 분리할 필요성을 느꼈습니다.
이는 'Gate가 불필요했다'는 반성이 아닙니다. 오히려 그 반대라, Gate를 진지하게 기능시키려고 노력한 결과, Gate의 내용물을 더욱 분해해야 할 필요성을 발견한 것이 더 가깝습니다.
맺음말 (おわりに)
ALPACA-template의 Quality Gate는 공정 말에 체크리스트에 체크하는 메커니즘이 아니었습니다.
목표했던 것은,
무엇이 갖춰졌는지(What is complete).
무엇을 검증했는지(What was verified).
무엇이 아직 부족한지(What is missing).
누가 품질을 평가했는지(Who evaluated the quality).
누가 그 리스크를 책임지고 다음 단계로 진행하기로 결정했는지(Who accepted the risk and decided to proceed).
를 분리하여 남기는 것이었습니다.
AI로 생성 속도가 빨라질수록, '완료된 것처럼 보이는 상태'도 빠르게 만들 수 있습니다. 그렇기 때문에 완료의 정의를 생성 측면이 아니라, 검증과 판단의 측면에서 설계해야 합니다.
그리고 Gate를 실제로 운영하려면, 판정의 근거를 남겨야 합니다. 다음 번에는 template 버전에서 Evidence / QGR / Change Management를 어떻게 조합하여 '완료되었다'는 것을 증적(Evidence)과 판단으로 바꾸려고 했는지 되돌아보겠습니다.
토론 (Discussion)

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기