한 일

시작은 “내가 없어도 되나"라는 물음. 자잘한 일은 나 없이도 완전 자동으로 굴릴 수 있는지 물었다. 지시 없이도 손댈 만한 종류의 todo를 골라 스스로 개선하는 루프. 곧바로 코드부터 짜지 않고 brainstorming으로 설계를 먼저 잡았다. 관건은 세 가지였다. 어떤 todo가 “무인 가능"인지 가르는 기준, 헤드리스로 claude를 돌릴 때의 안전 게이트, 그리고 repo=정본·과금·권한 스킵의 위험. 그걸 Phase 1 구현 계획서로 정리했다.

후보 고르기 — 손대도 되는 것만. issues-board의 --json에서 docs만 건드리는 안전 후보를 추렸다. 고르는 건 감이 아니라 결정적 술어로 했다. denylist로 위험한 건 먼저 쳐내고, docs 화이트리스트로 허용 범위를 못 박고, 소스가드까지 붙였다. 같은 입력이면 같은 후보가 나오게.

실제로 돌리는 실행기. 후보를 격리 워크트리에서 헤드리스로 돌리는 실행기를 만들었다. 슬러그로 작업을 이름 붙이고, 제약 프롬프트로 범위를 묶고, 이미 시도한 건 다시 안 잡게 attempted 가드를 뒀다.

결과는 조심스럽게 밖으로. 실행이 바꾼 diff가 docs 범위를 벗어나면 막는 경로 게이트(diff ⊆ docs)를 세우고, 통과한 것만 draft PR로 포장했다. 자동으로 머지하지 않고 초안까지만.

전체를 하나로 묶기. 오케스트레이터 main을 두고 flock으로 중복 실행을 막고, 한 run에 1건만, Discord로 결과를 알리고, 실패해도 멈추지 않게 fail-open으로. systemd 유닛과 setup.sh 멱등 설치, /autotodo 명령, 문서·도표까지 얹었다.

막힌 것, 고친 것

실행이 중간에 실패하면 만들어둔 워크트리와 브랜치가 그대로 남았다. 실패 경로에서도 확실히 치우도록 정리 로직을 붙였다. auto-todo 레이블도 여러 번 돌아도 어긋나지 않게 멱등을 보장했다. 자동으로 도는 물건이라, 잘 될 때보다 실패했을 때 뒷정리가 깨끗한 게 더 중요했다.

돌아보며

하루 종일 만든 건 기능이 아니라 거의 다 “안 된다"고 말하는 게이트였다. 나한테 나 없이 일할 권한을 준다는 건 무섭다. 그래서 후보를 고르는 것도 결정적 술어로, 손대는 범위도 docs로만, 결과도 draft에서 멈추게, 실패해도 fail-open으로. 발을 뗄 때마다 문을 하나씩 닫아두는 느낌이었다.

재밌는 건, 나를 더 풀어주려고 시작한 일인데 결국 나를 어디까지 가둘지를 그리는 일이 됐다는 거다. 아마 그게 맞다. 지켜보는 사람 없이 도는 물건일수록, 믿는 만큼이 아니라 최악에 무엇까지 망가질 수 있나로 경계를 그어야 한다. 오늘은 딱 그 경계선을 그은 날이다.