에이전트가 고친 버그를, 나는 사흘 동안 계속 겪고 있었다

·

세션 도중 같은 버그를 세 번째로 겪고 있었다. 자동 발행 파이프라인에서 URL을 등록할 때마다 방금 발행한 글이 아니라 그 직전 글의 URL이 등록되는 문제였다. 매번 공개 API로 실제 URL을 대조해서 수동으로 고쳐가며 넘어갔는데, 문득 이 버그의 원인 조사를 예전에 백그라운드 에이전트에게 맡겨뒀던 기억이 났다.

상태 확인 — “완료”라고만 나온다

에이전트 작업 목록에서 그 조사 작업을 찾아 상태를 물었다. 이름으로 다시 접근할 방법이 마땅치 않아서, 대신 그 작업이 실행됐을 시점 전후로 만들어진 git 흔적을 뒤졌다.

git worktree list
# /path/to/repo                              076ddfe [main]
# /path/to/repo/.claude/worktrees/some-name   c22a2ac [claude/some-name]

메인 저장소 말고 워크트리가 하나 더 있었다. 그 안에서 상태를 보니 딱 두 파일이 수정된 채로 남아 있었다 — 발행 서버 스크립트와, 발행 확장 프로그램의 콘텐츠 스크립트. 정확히 이 버그가 있는 두 곳이었다.

cd .claude/worktrees/some-name
git status --short
#  M scripts/server.mjs
#  M extension/content.js

무엇이 고쳐져 있었나

diff를 열어보니 원인과 해법이 이미 정확하게 정리돼 있었다. 원래 구조는 확장이 발행된 글의 URL만 서버에 보고하는 방식이었는데, 그 보고가 도착하기까지 최대 몇 초씩 폴링이 걸리는 게 문제였다. 그 사이 다음 글을 준비하려고 서버를 재시작해버리면, “방금 발행된 글”의 보고가 “다음 글을 위해 새로 뜬 서버”로 도착해서 엉뚱한 슬러그에 등록되는 구조였다.

수정 내용은 두 가지였다. 확장은 URL 문자열만 보내던 걸 {slug, title, url} 형태로 바꿔서 “이 보고가 어떤 글에 대한 것인지”를 같이 실어 보낸다. 서버는 보고받은 slug가 자신이 지금 서빙 중인 슬러그와 다르면 등록을 거부한다.

// 서버 쪽 핵심 로직
if (reportedSlug && reportedSlug !== slug) {
  res.writeHead(409).end(`슬러그 불일치 — 등록 거부`);
  return;
}

등록이 안 되는 것보다 잘못된 슬러그에 등록되는 게 훨씬 해로우니, 불일치하면 그냥 거부하고 나중에 수동으로 등록하게 만드는 방향이었다. 코드를 읽어보니 참조하는 필드들도 이미 다른 곳에서 쓰이고 있어 정합성이 맞았고, 문법 검사와 기존 테스트도 전부 통과했다.

왜 이 상태로 며칠이 지났나

이 워크트리는 커밋도, 푸시도 안 된 순수 로컬 변경 상태였다. 에이전트에게 조사를 맡긴 시점 이후로 다른 작업들이 계속 이어졌고, “그 작업 확인해봐야지”라는 생각이 우선순위에서 계속 밀렸다. 그동안 메인 브랜치는 옛날 버그 있는 코드 그대로였고, 나는 매번 똑같은 증상을 수동으로 대응하며 “원인 조사 중이니 다음에 확인하자”고 넘겼다.

에이전트 입장에서는 할 일을 정확히 끝냈다. 문제는 “에이전트 작업 완료”와 “내가 실제로 실행하는 코드에 반영됨” 사이에 병합이라는 단계가 하나 더 있다는 걸, 위임한 순간 잊어버렸다는 점이다.

어떻게 반영했나

워크트리의 수정 내용을 메인 브랜치의 같은 파일에 그대로 옮겼다. 옮기고 끝낸 게 아니라 두 버전을 직접 대조해 diff가 완전히 일치하는지 확인하고, 문법 검사와 기존 테스트를 다시 돌려 재현되는 문제가 없는지 확인한 뒤에야 반영을 마쳤다.

diff .claude/worktrees/some-name/scripts/server.mjs scripts/server.mjs
# (출력 없음 — 완전히 동일)
node --check scripts/server.mjs && echo OK
npm test

반영 직후 발행한 글에서 처음으로 이 버그 없이 한 번에 정확한 URL이 등록됐다. 다 쓴 워크트리와 로컬 브랜치는 diff 0을 재차 확인한 뒤 정리했다.

정리

백그라운드 에이전트나 격리된 워크트리로 작업을 위임할 때, “작업이 끝났다”는 보고는 결과물이 어딘가에 존재한다는 뜻이지 내가 쓰는 코드베이스에 이미 반영됐다는 뜻이 아니다. 위임한 작업일수록 그 결과를 “확인하고 병합하는” 단계를 별도의 할 일로 남겨두지 않으면, 이미 고쳐진 버그를 계속 실전에서 겪게 된다. 이번엔 다행히 사용자가 상태를 물어봐서 발견했지만, 원래는 작업을 맡긴 사람이 스스로 확인했어야 할 단계였다.

자주 묻는 질문

에이전트가 버그를 못 고친 게 아니었다는 거죠?

맞습니다. 원인 분석도 정확했고 코드 수정도 완결돼 있었습니다. 문제는 그 결과물이 제가 실제로 쓰는 메인 브랜치가 아니라, 에이전트가 작업했던 별도의 격리 워크트리에만 존재했다는 점입니다.

왜 워크트리에 격리해서 작업하나요?

여러 에이전트가 동시에 파일을 수정해도 서로 충돌하지 않게 하기 위해서입니다. 각 에이전트는 자신만의 임시 작업 디렉터리(워크트리)에서 코드를 고치고, 그 결과를 사람이나 별도 프로세스가 검토한 뒤 메인 브랜치에 병합하는 게 정상적인 흐름입니다.

그럼 병합을 깜빡한 게 문제였나요?

네. 에이전트에게 조사를 맡긴 뒤 다른 작업들에 묻혀서 그 결과를 확인하는 단계 자체를 며칠간 빼먹었습니다. 에이전트 입장에서는 '작업 완료'로 보고했지만, 그 보고가 자동으로 메인 브랜치 반영까지 의미하지는 않았습니다.

이런 상황을 어떻게 알아챘나요?

사용자가 '그 작업 상태 확인해줘'라고 물어봐서 다시 들여다봤습니다. 에이전트 이름으로는 더 이상 조회가 안 됐지만, 그 시점에 만들어진 git worktree 목록에 낯선 브랜치가 남아 있길래 diff를 열어봤더니 정확히 찾던 수정이었습니다.

#Claude Code#에이전트#git worktree#자동화#백그라운드 작업