AI 자동화 실패 로그를 보고서로 바꾸고 자동수정을 늦춘 이유
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로 고정해야 한다.
이어 읽기
시리즈는 순서대로, 편집 추천은 맥락대로, 비슷한 주제는 태그 기준으로 정리합니다.
시리즈 전체
6개 Repository AI Native 자동화 실습4/4편- 1.AI와 파트너가 아니라 위임자로 일하기 위해 중장기계획을 만들었다
- 2.Codex Slack 알림을 먼저 붙인 이유: AI 자동화의 완료 신호
- 3.Codex task brief로 프롬프트 작업 인수인계서 만들기
- 4.AI 자동화 실패 로그를 보고서로 바꾸고 자동수정을 늦춘 이유
함께 읽으면 좋은 글
편집 추천비슷한 주제의 글
태그가 겹치는 글입니다. 시리즈와 편집 추천에 이미 나온 글은 제외합니다.
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이 생성되는 흐름을 입문자 관점에서 정리한다.