의존성 보안 패치를 하나 끝냈다. 28개 앱이 든 모노레포에서 HTTP 클라이언트 라이브러리를 올리는 작업이었다. 리뷰어 세 명 승인을 받았고, QA 환경 334개 지면을 훑었고, 기록도 다 남겼다.
끝내고 나서 두 가지 의문이 남았다.
나는 그냥 타이핑만 한 걸까. 코드는 에이전트가 썼고, 검증 스크립트도 에이전트가 짰고, 문서도 에이전트가 정리했다.
그리고 내가 만든 스킬들은 대체 언제 도는 걸까. 개인 스킬을 꾸준히 만들어 왔는데, 정작 작업 중에 그게 발동했는지 아닌지 알 수가 없었다.
둘 다 요즘 흔히 보이는 의문이다. 그래서 그날 세션 기록을 그냥 세어 봤다. 결과가 생각보다 불편했고, 세 가지를 세고 나니 하나의 기준이 남았다.
사실 1 — 스킬 58개, 해당 12개, 발동 0
먼저 세어 봤다.
설치된 개인 스킬 58개 (중복 제거)
이번 작업에 직접 해당 12개
코드 검증 · 브라우저 검증 · PR 리뷰 대응 ·
자동리뷰 재현 · 배포 후 E2E · 프레임워크별 리뷰
이번 세션에 발동한 것 0개
작업 중 실제로 불린 스킬은 다섯 개였는데, 전부 주변부였다. 브랜치를 공유 환경에 반영하는 절차, 이슈 트래커 티켓 규약, 블로그 발행 파이프라인, 로컬 브랜치 정리. 정작 어려운 일에는 하나도 안 붙었다. 코드를 만들고 검증하는 일 말이다.
없어서 안 붙은 게 아니다. 있는데 안 불렸다.
특히 아팠던 게 하나 있다. 사내 자동 리뷰가 이 PR에 세 번 지적을 남겼는데, 그 자동 리뷰와 같은 프롬프트를 로컬에서 미리 돌려보는 스킬을 내가 이미 만들어 뒀다. PR을 올리기 전에 한 번 돌렸으면 그 왕복이 줄었을지도 모른다. 안 돌렸다.
그리고 배포 후 E2E 절차를 담은 스킬 하나는 disable-model-invocation: true로 잠겨 있었다. 슬래시로 직접 부르지 않으면 에이전트가 열어볼 수조차 없다. 내가 그날 그 명령어를 기억하지 못했으니, 그 스킬은 존재하지 않는 것과 같았다.
사실 2 — 자동 검사가 전부 통과한 뒤에, 사람이 세 건을 찾았다
이게 더 불편했다.
내가 돌린 자동 검사는 이랬다.
타입 체크 41/41 통과
전체 앱 빌드 28/28 통과
런타임 계약 점검 13/13 통과
QA 지면 스윕 334/334 이상 없음
전부 초록이었다. 그 상태에서 PR을 올렸고, 사람 리뷰어들이 코드를 읽고 결함 세 건을 찾았다. 설정 객체를 얕게 병합해서 하위 설정이 통째로 덮이는 문제, 라이브러리 내부 판정 함수와 우리 판정 함수가 갈라지는 문제, 헤더 이름 대소문자에 따라 가드가 통째로 우회되는 문제.
셋 다 실제 결함이었다. 그리고 셋 다 내 검사를 전부 통과했다.
세 번째 것이 특히 지독했다. 리뷰 지적을 받고 내가 물었다.
아니 그럼 왜 QA 배포해서 검증할 때는 안 나왔을까?
파 보니 답이 명확했다. 소문자 헤더 이름을 넘기는 호출부가 코드베이스에 0곳이었다. 그러니 지면을 334개가 아니라 3,340개를 훑어도 재현되지 않는다. 그 결함은 내 검증 방식으로는 영원히 관측 불가능했다.
여기서 배운 게 하나 있다. 검사를 늘리기 전에 물어야 하는 질문은 「무엇을 더 검사할까」가 아니라 「이 검사는 실패할 수 있는가」다. 실패할 수 없는 검사는 검사가 아니라 의식이다. 초록불이 늘어날수록 안심되지만, 안심의 근거는 늘지 않는다.
사실 3 — 에이전트가 혼자 판단할 때 낸 오류 다섯 건
같은 세션에서 에이전트가 낸 실수를 늘어놓아 봤다.
측정 자체가 무효였던 것. 14개 호스트의 번들을 비교하는데 curl -L을 써서 리다이렉트를 따라갔다. 전부 로그인 화면으로 튕겼고, 결국 같은 파일을 열네 번 잰 꼴이 됐다. 그대로 「전부 통과」라고 보고할 뻔했다.
대상을 잘못 지정한 것. 한쪽 서비스의 경로 목록을 다른 쪽 스윕에 손으로 옮겨 적어서 404를 세 번 냈다.
성급한 경보. 한 앱이 아직 옛 버전을 내려준다며 「멈춰야 합니다」라고 보고했다. 배포 도구가 아직 롤아웃 중이었을 뿐이다.
셸 문법 오류를 두 번. zsh는 변수를 단어 분리하지 않는데 bash처럼 썼다. 한 번은 호스트 목록이 한 줄로 뭉쳤고, 한 번은 커밋 수가 6,045개 같은 헛값으로 나왔다.
그리고 마지막 하나. 작업을 다 끝내고 로컬 브랜치를 정리하는데, 에이전트가 브랜치 여섯 개를 가리키며 「지워도 잃을 게 없습니다」라고 했다. 내가 「그리 해줘」라고 답했다.
스킬 하나를 뒤늦게 불렀더니
그 순간 내가 브랜치 정리 스킬을 슬래시로 불렀다. 습관이었지 의심해서가 아니었다.
스킬 기준으로 다시 판정하니 결과가 달랐다. 여섯 개 중 하나가 원격 어디에도 없는 커밋 33개를 들고 있었다. 이번 작업과 무관한, 다른 티켓의 작업이었다. 로컬이 유일한 사본이었다.
그 스킬에 적혀 있던 건 대단한 게 아니다.
삭제 = 나이 초과 AND ( 머지 완료 OR 미푸시 커밋 0 )
- 나이만 보고 삭제하지 말 것
- upstream이 사라진 브랜치를 「안전」으로 분류하지 말 것
- git branch -D 를 쓰지 말 것 — -d 가 거부하면 판정이 틀렸다는 신호다
판정식 하나와 규칙 세 줄이다. 그리고 저 세 줄은 예전에 누군가 작업을 날려 먹고 배운 것이다.
에이전트의 판단은 틀렸고, 내 판단도 그 순간엔 틀렸다(「그리 해줘」라고 했으니까). 틀리지 않은 건 예전에 글로 굳혀 둔 판단뿐이었다.
그래서 개발자는 그날 뭘 했나
첫 번째 의문으로 돌아간다. 나는 타이핑만 했나.
기록을 다시 읽어 보니 그날 결과를 가른 지점들은 이런 것들이었다.
문제를 처음 발견한 게 나였다. 배포 산출물이 런타임에 필요한 파일을 빠뜨리고 있었다. 자동 검사는 그걸 전부 통과시켰고, 내가 찾았다. 에이전트는 그 뒤에 라이브러리 소스를 읽으며 내 가설을 검증했다. 이 작업 후반부 전체가 거기서 시작됐다.
에이전트의 오경보를 껐다. 「멈춰야 합니다」에 「아직 롤아웃 중이야」라고 답했다. 배포 도구의 동작을 모르면 그 자리에서 롤백을 논의하고 팀 시간을 태웠을 것이다.
검증 범위를 정했다. 표본이 아니라 28개 전부 배포해 보자고 한 건 나였다. 에이전트가 제안한 게 아니다. 이 결정이 334지면 검증을 의미 있게 만들었다.
검증의 한계를 드러낸 질문을 했다. 위의 「왜 QA에서는 안 나왔을까」. 이 질문이 없었으면 그 결함이 구조적으로 관측 불가라는 걸 몰랐을 것이고, 지금 티켓에 「이 검증이 못 잡는 것」이라는 절도 없었을 것이다.
범위를 두 번 잘랐다. 무관한 린트 경고 하나는 「이전 문제니 고치지 말고 소명하자」, 부수적인 업로드 경로 하나는 「거기까지는 안 하자」. 에이전트 혼자였으면 둘 다 손대서 diff를 불리고 리뷰를 더 받았을 것이다.
여기에 로그인·2차 인증, 배포 트리거, 인프라 대시보드 확인, 리뷰어 소집, 조직의 권한 구조 판단이 붙는다. 에이전트가 물리적으로 못 하는 것과, 조직을 몰라서 못 하는 것이 절반이다.
그래서 답은 「타이핑만 했다」가 아니다. 그날 나는 판단을 실시간으로 공급하고 있었다.
두 의문은 사실 같은 질문이었다
이 지점이 두 번째 의문과 이어진다.
스킬이 그날 덜 필요해 보인 이유는 명확하다. 내가 옆에 있었기 때문이다. 오경보를 즉시 껐고, 범위를 그때그때 잘랐고, 배포 판단을 직접 내렸다. 판단이 살아서 작동 중이면, 굳혀 둔 판단은 당연히 덜 쓰인다.
스킬은 개발자와 별개의 무언가가 아니다. 개발자의 판단을 글로 굳혀 놓은 것이다.
그러니 「스킬이 필요한가」와 「개발자가 필요한가」는 같은 질문이다. 그리고 그날 그 질문의 답이 나온 순간은 딱 한 번이었다 — 내가 안 보고 있던 순간, 정확히는 내 판단이 잠깐 꺼졌던 순간. 거기서 굳혀 둔 판단이 살아 있는 판단을 구했다.
한 걸음 더 나간 기대 — 「티켓만 있으면 되지 않나」
이 믿음이 한 단계 더 나가면 이런 기대가 된다. 요즘 자주 보인다.
이슈 트래커에 티켓만 잘 만들어 두면, 에이전트가 알아서 결함이랑 개선을 처리하지 않을까. 개발자 없이 티켓만 쌓으면 되는 거 아닌가.
공평하게 말하면, 되는 종류가 있다. 범위가 닫혀 있고, 완료 기준이 검증 가능하고, 중간에 사실이 바뀌지 않는 작업이라면 티켓 하나로 끝까지 갈 수 있다. 그런 작업이 실제로 꽤 많다.
그런데 그날 작업을 이 기준으로 다시 보면 상황이 다르다.
티켓에 없던 것이 작업의 절반이었다. 원래 티켓 제목은 「의존성 취약점 대응」 한 줄이었다. 배포 산출물이 런타임에 필요한 파일을 빠뜨리는 문제는 어느 티켓에도 적혀 있지 않았다. 작업 중에 튀어나왔고, 사람이 찾았다. 티켓을 아무리 상세히 적어도 이건 적을 수 없다. 시작할 땐 존재를 몰랐으니까.
문서는 네 시간 만에 낡았다. 배포 티켓에 「이 항목은 재현하지 못했다」고 적어 둔 잔존 리스크가 있었다. 그날 오후 검증에서 그중 일부가 확인됐다. 오전 10시에 쓴 문장이 오후 2시에 부분적으로 거짓이 됐다. 문서는 스냅숏이고 작업은 흐름이다. 누군가 그 간극을 알아차리고 고쳐야 한다. 티켓은 자기가 낡았다고 알려 주지 않는다.
요구사항이 대화 중에 두 번 바뀌었다. 배포 티켓의 체크리스트를 채우자고 시작했다가, 그게 배포 후 항목이라는 걸 알아차려 방향을 틀었고, 다시 「배포하고 나면 나한테 권한이 없다」는 이유로 본문 자체를 바꾸는 쪽으로 갔다. 마지막 근거 — 조직의 권한 구조 — 는 어느 문서에도 적혀 있지 않았다.
완료 상태가 계속 이동했다. 리뷰가 사흘에 걸쳐 여러 파도로 왔다. 「이제 끝났다」고 판단한 시점이 그때마다 뒤집혔다.
그리고 이 지점에서 늘 나오는 반사 반응이 있다.
그럼 그것도 스킬로 만들어서 붙이면 되지 않나.
이 글의 앞부분이 그 반사에 대한 답이다. 나는 이미 58개를 갖고 있었고, 그날 해당하는 12개가 하나도 안 불렸다. 안 불리는 게 문제인데 59번째를 만드는 건, 라우팅 문제를 커버리지 문제로 오진하는 것이다. 스킬을 하나 더 만들면 뭔가 한 것 같은 기분이 드는데, 그 기분은 결과와 무관하다.
그래서 「티켓만 있으면 되나」의 답은 이렇게 정리된다. 자율로 돌릴 수 있는 건 사실이 고정된 작업이다. 사실이 도중에 바뀌는 작업 — 새로운 실패 양식이 튀어나오고, 문서가 낡고, 요구가 이동하고, 완료 판정이 뒤집히는 작업 — 에서는 바뀐 걸 알아차리는 역할이 반드시 필요하다.
그 역할이 「조종」이다. 그리고 조종은 티켓을 더 상세히 쓰는 걸로 대체되지 않는다. 상세함은 시작 시점에 아는 것만 담을 수 있기 때문이다.
그래서 어떻게 균형을 잡을까
이 경험에서 실제로 쓸 만한 것만 추린다.
스킬에는 「좋은 습관」이 아니라 「대가를 치른 판단」만 적는다. 그날 실제로 값을 한 규칙들은 전부 그 형태였다. -D 금지, 특정 티켓 타입 금지, 강제 푸시 금지, 타임존 규칙. 반대로 일반론을 적어 둔 부분은 있으나 없으나 결과가 같았다. 비용이 비대칭인 자리 — 되돌릴 수 없는 행동, 저장소를 읽어선 알 수 없는 조직 관례 — 에만 스킬을 쓴다.
발동 여부를 관측할 수 있게 만든다. 안 불리는 스킬은 없는 것과 같다. 나는 58개를 갖고도 그날 해당 12개를 하나도 못 불렀다. 스킬을 더 만들기 전에, 이미 있는 것이 왜 안 불리는지부터 본다. 잠가 둔 것(disable-model-invocation)이 있다면 그건 의도적으로 없앤 것임을 인정하고 시작한다.
검사를 늘리기 전에 「이 검사는 실패할 수 있는가」를 묻는다. 초록불 네 줄보다, 실패할 수 있는 검사 한 줄이 낫다. 특히 자동 검사가 전부 통과한 상태에서 사람이 결함을 찾았다면, 그건 검사 개수의 문제가 아니라 검사 종류의 문제다.
에이전트가 「안전합니다」라고 할 때 근거의 종류를 묻는다. 그날 「지워도 잃을 게 없습니다」의 근거는 고장난 스크립트였다. 결론이 아니라 어떻게 확인했는지를 물었으면 30초 만에 드러났을 것이다.
감독의 밀도를 되돌림 가능성에 맞춘다. 코드를 쓰는 동안엔 느슨해도 된다. 틀리면 고치면 되니까. 삭제·배포·머지·외부 공유처럼 되돌리기 어려운 자리에서만 밀도를 올린다. 그날 내가 실수한 자리도 정확히 거기였다.
자율로 돌릴지는 「사실이 고정되어 있는가」로 가른다. 범위가 닫혀 있고 완료 기준이 검증 가능하면 티켓 하나로 끝까지 보내도 된다. 반대로 새 실패 양식이 나올 여지가 있거나, 문서가 도중에 낡거나, 완료 판정이 뒤집힐 수 있는 작업이면 바뀐 걸 알아차릴 사람을 붙인다. 판단 기준은 작업의 난이도가 아니라 사실의 안정성이다.
남는 것
작업은 잘 끝났다. 리뷰어 세 명 승인, CI 통과, 334지면 이상 없음. 그 결과만 보면 「에이전트한테 시켰더니 되더라」로 요약할 수 있다.
그런데 그 요약에서 빠지는 게 있다. 문제를 처음 발견한 것, 오경보를 끈 것, 검증 범위를 정한 것, 검증의 한계를 물은 것, 그리고 무엇을 하지 않을지 정한 것. 이건 타이핑이 아니다.
동시에 이런 것도 있다. 내가 실수한 그 한 순간, 나를 구한 건 내 실력이 아니라 예전의 내가 적어 둔 세 줄이었다.
그러니 스킬을 만드는 일은 「AI를 잘 쓰기 위한 설정 작업」이 아니라, 판단이 꺼지는 순간을 대비해 자기 판단을 백업해 두는 일에 가깝다. 그렇게 보면 무엇을 적어야 하는지도 분명해진다. 잘 아는 것 말고, 비싸게 배운 것을 적으면 된다.