Multi-repo AI Native 자동화 실습 04. 실패 로그 보고서화
1편에서는 AI와 파트너가 아니라 위임자로 일하기 위해 중장기계획을 만들었다고 썼습니다.
2편에서는 그 위임을 가능하게 하는 첫 운영 신호로 Codex 완료 Slack 알림을 붙였습니다.
3편에서는 프롬프트 작성법이 결국 Codex task brief라는 작업 인수인계 양식으로 바뀌었다는 이야기를 했습니다.
그다음 글을 바로 쓰지는 않았습니다. 일부러 미뤘습니다. 4편은 실제 실행 증거가 없으면 쓰기 어려운 글이었기 때문입니다. 중장기계획이 정말 매일 움직이는지, task brief가 실제 작업에서 범위를 좁히는지, 자동화가 어디까지 가고 어디서 멈추는지 확인한 뒤에야 쓸 수 있었습니다.
2026년 5월 6일과 5월 7일에 그 증거가 생겼습니다.
FinSight PRD를 쓰고, task brief를 shared harness 후보로 검증하고, 회귀 테스트 실패 분석 봇의 PRD와 report template을 만들고, mock failure log를 markdown report로 바꾸는 local generator까지 만들었습니다. 그 과정에서 깨달은 핵심은 간단했습니다.
위임자로 일하려면 자동수정이나 Slack 알림보다 먼저, 실패를 사람이 검토할 수 있는 보고서로 바꿔야 했습니다.
실행 증거가 없으면 4편은 예고편이 됩니다
AI 자동화 이야기는 쉽게 앞서 나갑니다.
테스트가 실패하면 AI가 원인을 분석합니다. 고칠 수 있으면 패치를 만듭니다. PR을 엽니다. Slack으로 알려 줍니다. dashboard에 성공률을 쌓습니다.
흐름만 보면 그럴듯합니다.
하지만 실제로 그 순서로 만들면 위험합니다. 실패 로그에는 secret이 섞일 수 있고, production log나 고객 payload가 들어갈 수 있습니다. 실패 원인이 한 줄이 아니라 여러 category에 걸칠 수도 있습니다. 단순 lint failure인지, publish contract mismatch인지, local environment 문제인지 분류하지 않은 상태에서 Slack이나 GitHub comment로 보내면 보고 체계가 아니라 소음이 됩니다.
그래서 4편은 예고편으로 쓰면 안 됐습니다.
먼저 실제 작업을 해 봐야 했습니다. 무엇을 만들었는지보다 무엇을 일부러 만들지 않았는지가 더 중요한 작업이었기 때문입니다.
PRD 세 개를 쓰면서 task brief의 쓰임이 바뀌었다
이번 실행에서 task brief는 "일을 잘 시키는 프롬프트"가 아니었습니다.
오히려 반대였습니다. 일을 너무 빨리 키우지 않게 막는 장치였습니다.
FinSight PR Reviewer Agent PRD를 쓸 때 첫 번째 경계가 생겼습니다. Project 2 PR Reviewer agent는 자동 승인 봇이 아니었습니다. 자동 거절 봇도 아니었습니다. PR 이벤트를 reviewer-facing risk report로 바꾸는 agent였습니다. rules convention, risk category, severity, required checks, reviewer question은 만들 수 있지만, merge/reject 결정은 사람에게 남겨야 했습니다.
FinSight MVP PRD에서는 두 번째 경계가 생겼습니다. Project 1 MVP는 제품 skeleton을 설명하지만, 제품 코드는 이 repository에 두지 않습니다. 고객 데이터, 결제 데이터, runtime secret도 넣지 않습니다. ai-survival-log는 PRD와 학습 기록과 blog-ready 해설을 보관하고, 실제 제품 코드는 future product repo에서 다룹니다.
Regression Failure Analysis Bot PRD에서는 세 번째 경계가 생겼습니다. 회귀 테스트 실패 분석 봇은 자동수정 봇으로 시작하지 않습니다. 먼저 failure category와 report envelope을 만듭니다. 실패를 고치기 전에 실패를 설명할 수 있어야 합니다.
세 PRD의 공통점은 "무엇을 할지"보다 "아직 하지 않을 것"을 먼저 고정했다는 점이었습니다.
이게 task brief의 실제 가치였습니다.
실패 로그는 먼저 report가 되어야 했습니다
실패 로그는 기계에게는 유용하지만 사람에게는 시끄럽습니다.
한 화면에 stack trace, secondary error, dependency warning, test runner noise가 같이 나옵니다. 첫 번째 실패 신호가 어디인지 찾기 어렵습니다. 실패 command가 무엇인지도 흐려집니다. 의심 파일과 consumer contract가 섞입니다.
AI에게 바로 넘기기에도 위험합니다.
raw log 안에는 credential, webhook URL, env 값, customer payload, production path, 회사 source trace가 섞일 수 있습니다. 그런 내용을 그대로 LLM, Slack, GitHub comment, Jira, dashboard로 보내면 자동화가 아니라 유출 경로가 됩니다.
그래서 lab 3의 첫 구현은 실패 로그를 저장하거나 고치는 일이 아니었습니다.
실패를 다음 report로 바꾸는 일이었습니다.
failed command
failure category
first failing signal
suspected scope
reproduction command
likely next action
unsafe data check
raw log retained: no
처음 category는 일곱 개로 잡았습니다.
assertion-mismatchimport-runtime-errordom-query-failurecontract-mismatchlint-format-failureenvironment-dependency-failureunknown-needs-triage
이 정도만 있어도 raw log는 바로 다른 성격의 문서가 됩니다. 더 이상 "뭔가 실패했다"가 아니라 "어떤 종류의 실패이고, 어느 surface를 의심해야 하며, 어떤 command로 재현해야 하는지"를 말하는 report가 됩니다.
local generator는 자동수정 봇이 아니라 보고 체계의 첫 구현이었습니다
그다음 만든 것은 scripts/regression-failure-report.mjs였습니다.
이름만 보면 작은 스크립트입니다. mock failure log를 읽고 category를 분류한 뒤 markdown report를 출력합니다. category별 fixture도 만들었습니다. assertion mismatch, import/runtime error, DOM query failure, contract mismatch, lint/format failure, environment dependency failure, unknown triage fixture를 하나씩 준비했습니다.
하지만 이 스크립트의 의미는 기능보다 순서에 있었습니다.
이 스크립트는 raw log archive를 만들지 않습니다. GitHub comment를 쓰지 않습니다. Slack alert를 보내지 않습니다. auto-fix branch를 만들지 않습니다. protected path인 raw/, wiki/, output/, assets/에 generated report를 쓰지 않습니다. unsafe pattern이 보이면 파일을 쓰기 전에 막습니다.
즉 첫 구현은 자동화의 속도를 높이는 코드가 아니라, 자동화가 어디서 멈춰야 하는지 확인하는 코드였습니다.
이 과정에서 작은 버그도 하나 나왔습니다. site mock fixture를 적용해 보니 .mdx 경로를 .md로 잘라 잡고 있었습니다. failure report에서 의심 파일을 잘못 표시하면 reviewer가 엉뚱한 파일을 봅니다. 그래서 확장자 매칭을 고치고 테스트를 추가했습니다.
이 작은 수정은 이번 실습의 방향을 잘 보여줍니다.
자동화를 키우기 전에 report의 신뢰도를 먼저 고쳐야 합니다.
shared harness에는 실행 도구가 아니라 template부터 옮겼습니다
local generator가 생기면 바로 shared command로 올리고 싶어집니다.
하지만 그렇게 하지 않았습니다.
shared-agent-harness에는 실행 도구가 아니라 domain-neutral template만 먼저 옮겼습니다.
codex-task-brief.mdcontext-budget-git-safety.mdtask-completion-report.mdfailure-report.mdtask-brief-review-rubric.md
이 선택도 일부러 느린 선택이었습니다.
shared repo는 개인 블로그 원고를 담는 곳도 아니고, 회사 운영 증거를 담는 곳도 아닙니다. shared repo가 가져야 하는 것은 role, lane, template, review policy입니다. 실제 실패 로그, test evidence, source trace, production payload는 owning repository에 남아야 합니다.
그래서 shared harness의 첫 승격은 executable skill이 아니라 template-only transfer였습니다.
좋은 패턴을 발견했다고 곧바로 command나 hook으로 만들면 안 됩니다. 반복 사용은 template 후보가 될 수 있지만, 실행 표면이 되려면 별도의 review gate가 필요합니다.
site에는 실제 실패가 아니라 mock application부터 적용했습니다
다음 적용 대상은 ai-survival-log-site였습니다.
여기서도 실제 CI log를 가져오지 않았습니다. production log도 보지 않았습니다. content post나 runtime code도 바꾸지 않았습니다.
대신 site가 실제로 겪을 수 있는 실패 표면을 mock fixture로 나눴습니다.
| command | report category |
|---|---|
npm run lint | lint-format-failure |
npm test | dom-query-failure 또는 assertion-mismatch |
npm run build | contract-mismatch 또는 runtime error |
npm run state | contract-mismatch |
그리고 각 fixture마다 sample failure report를 붙였습니다.
이 작업의 의미는 site에 새 기능을 넣는 것이 아니었습니다. site runtime을 건드리지 않고도 failure report shape가 downstream consumer repository에 맞는지 확인하는 것이었습니다.
이제 Project 4 CI/CD pipeline agent를 생각할 때, 추상적인 "빌드 실패 분석"이 아니라 실제 site command map을 기준으로 말할 수 있습니다.
FinSight Project 4도 report-first로 다시 정렬했습니다
마지막으로 FinSight Project 4 CI/CD Pipeline Agent PRD Outline을 작성했습니다.
FinSight 로드맵의 Project 4는 원래 더 큰 그림이었습니다. lint/type/build failure를 분석하고, 자동 수정 PR을 만들고, Slack 알림을 보내고, dashboard에 이력과 비율을 쌓는 CI/CD pipeline agent입니다.
이 그림은 여전히 맞습니다.
다만 순서를 바꿨습니다.
- template과 fixture
- local report command
- CI artifact preview
- Slack summary dry-run
- GitHub PR comment dry-run
- auto-fix proposal dry-run
- approval-gated apply
- dashboard/history
이 순서가 중요합니다.
Slack은 네 번째입니다. GitHub comment는 다섯 번째입니다. auto-fix는 여섯 번째입니다. dashboard도 마지막 쪽입니다.
먼저 해야 할 일은 실패를 안전하게 요약하고, 사람이 검토할 수 있는 artifact로 만드는 것입니다. 그 다음에 알림과 comment와 fix proposal이 따라옵니다.
자동화의 핵심은 빨리 가는 것이 아니라 승격 순서를 지키는 데 있습니다
이번 작업을 하기 전에는 "AI 자동화"라는 말을 들으면 자꾸 실행을 떠올렸습니다.
테스트가 실패하면 고칩니다. PR을 만듭니다. 댓글을 답니다. 알림을 보냅니다. dashboard에 쌓습니다.
하지만 실제로 위임자의 입장에서 자동화를 설계해 보니, 더 중요한 것은 승격 순서였습니다.
먼저 report가 있어야 합니다. 그 report가 안전해야 합니다. category가 deterministic해야 합니다. raw log를 보존하지 않는 기본값이 있어야 합니다. shared로 올릴 것은 template인지 executable인지 구분해야 합니다. downstream repo에는 실제 증거가 아니라 mock fixture부터 적용해야 합니다. external write는 dry-run과 approval gate를 통과해야 합니다.
빠른 자동화는 매력적입니다.
하지만 오래 쓸 자동화는 처음부터 실행을 서두르지 않습니다.
이번 4편에서 제가 정리하고 싶었던 장면은 바로 이것입니다. 위임자는 AI에게 더 많은 일을 맡기기 위해서, 먼저 AI가 아직 하면 안 되는 일을 문서와 테스트와 report로 고정해야 합니다.
이어 읽기
시리즈는 순서대로, 편집 추천은 맥락대로, 비슷한 주제는 태그 기준으로 정리합니다.
시리즈 전체
Multi-repo AI Native 자동화 실습4/5편- 1.Multi-repo AI Native 자동화 실습 01. 중장기계획으로 위임 구조 만들기
- 2.Multi-repo AI Native 자동화 실습 02. Codex 완료 Slack 알림
- 3.Multi-repo AI Native 자동화 실습 03. Codex task brief
- 4.Multi-repo AI Native 자동화 실습 04. 실패 로그 보고서화
- 5.Multi-repo AI Native 자동화 실습 05. owner가 판단하기 쉬운 queue 만들기
함께 읽으면 좋은 글
편집 추천비슷한 주제의 글
태그가 겹치는 글입니다. 시리즈와 편집 추천에 이미 나온 글은 제외합니다.
AI라는 다른 종 앞에서, 나는 나를 더 보여주기로 했다
AI를 다른 종처럼 느낀 두려움과 안도를 출발점으로, 흩어진 취향과 반복 자동화 작업을 AI에게 나를 더 잘 알 수 있는 지도로 건네며 나와 AI가 함께 특징화되는 과정을 쓴 개인 에세이.
개발자 자동화 실습 03. 개인 Jira와 회사 Jira를 한 도구로 다루되 섞지 않는 법
개인 Jira PER와 회사 Jira KAN을 같은 자동화 도구로 다루면서도 섞지 않기 위해 personal-jira, company-jira, needs-classification profile과 shared-agent-harness skill 위치를 어떻게 나눴는지 정리합니다.
LLM 공부 01. LLM은 검색기가 아니라 다음 토큰 생성기다
LLM을 내부 검색기나 외부 도서관으로 오해하지 않도록, 문장이 token으로 바뀌고 embedding, Transformer block, LM head, prefill/decode, KV cache를 거쳐 다음 token이 생성되는 흐름을 입문자 관점에서 정리합니다.