Develop

프롬프트로 막은 줄 알았는데 새고 있었다 — 자동 발행 파이프라인에 게이트를 붙인 이야기

홈 디렉터리 경로가 자동 생성 글에 실려, 프롬프트의 상대 경로 조건과 코드의 형태 검사를 함께 보강했다

한 줄로

어제 정리 노트를 근거로 블로그 글을 자동 발행하는 크론잡을 만들었는데, dry-run 결과 글 본문에 내 홈 디렉터리 경로가 그대로 실려 나왔다. 원인은 프롬프트에 넣은 “파일 경로를 그대로 보존한다”는 지시였다. 프롬프트만 고치지 않고 형태 패턴을 검사하는 게이트를 코드에도 붙였다 — 프롬프트만으로는 샌다는 것을 실측으로 확인했기 때문이다.

무엇이 샜나

dry-run(실제 발행 없이 결과만 뽑아보는 실행)에서 나온 본문에 홈 디렉터리 경로와 worktree 경로가 그대로 들어 있었다. 아래는 실제 경로를 제외한 요약이다.

작업 레포의 홈 디렉터리 경로와 worktree 경로가 본문에 그대로 나왔다.

내 노트북 안에서만 의미가 있는 경로다. 공개 블로그에 나갈 이유가 없다.

원인은 내가 쓴 지시문이었다

프롬프트에는 “정리 노트에 있는 파일 경로·커밋 해시·명령어·에러 메시지는 그대로 보존한다”가 있었다. 이 지시 자체는 필요하다. web/upload.py 같은 레포 상대 경로는 글의 근거라서 보존하는 게 맞다.

문제는 모델이 “파일 경로”를 넓게 해석했다는 것이다. 레포 상대 경로와 홈 디렉터리 경로를 구분해 주지 않았으니, 노트에 적힌 개인 작업 폴더 경로도 보존 대상으로 끌려왔다. 지시가 틀린 게 아니라 경계가 없었다.

두 겹으로 막았다

조치 내용
프롬프트 레포 상대 경로만 쓰고 ~/...·/Users/...·worktree 경로는 금지
게이트 형태 패턴 추가. ~/.bashrc 같은 흔한 홈 경로는 통과, 개인 작업 폴더만 차단

프롬프트만 고쳐도 재생성 결과에서는 홈 경로가 사라졌다. 그런데도 게이트를 붙인 이유는, 프롬프트 지시가 지켜지지 않는 걸 이미 한 번 봤기 때문이다. LLM 출력은 매번 같지 않다. 다음 날 노트가 조금 다르면 다시 샐 수 있고, 자동 발행이라 그때는 아무도 안 보고 있다.

게이트 설계에서 신경 쓴 것 — 오탐이 더 비싸다

차단 규칙을 넓게 잡으면 안전할 것 같지만, 이 파이프라인에서는 반대다. 오탐이 나면 그날 발행이 통째로 멈춘다. 그래서 게이트는 개인 작업 폴더 형태만 잡고, ~/.bashrc처럼 어느 글에나 나올 수 있는 흔한 홈 경로는 통과시키도록 했다.

같은 이유로 별도의 blocklist.txt(회사명·사내 레포명 목록)에서도 짧은 일반 단어는 제외했다. web, api, core 같은 단어를 넣으면 정상적인 기술 글이 매일 막힌다.

목록 방식과 패턴 방식을 나눈 기준

홈 경로는 형태가 정해져 있다(~/나 /Users/로 시작). 그래서 정규식 같은 패턴으로 잡을 수 있다.

반면 회사명·사내 레포명은 형태가 없다. 그냥 단어다. 이건 목록으로 적는 것 외에 방법이 없다고 판단해 blocklist.txt를 따로 뒀고, 목록 자체가 민감하므로 gitignore 대상으로 두고 레포에는 blocklist.txt.example만 올렸다. 고객사는 아직 없어 해당 줄은 비워뒀다.

검증

네 가지를 실제로 돌려서 확인했다.

  • 이미 새어 나온 글을 게이트에 다시 넣기 → 2건 검출
  • 프롬프트 수정 후 재생성 → 홈 경로 없음
  • 오탐 확인용으로 web/upload.py, ~/.bashrc → 둘 다 통과
  • 테스트 41개 → 47개

커밋은 master f65c304, 병합 커밋은 815a863(PR #36 squash).

아직 안 끝난 구간

남은 건 맥미니 등록이다. 원격 기기라 다른 노트북에서는 실행할 수 없다.

등록은 작업 레포에서 최신 코드를 받은 뒤, plist를 LaunchAgents에 연결하고 launchd에 로드하는 순서다. 등록 상태는 launchctl list로 확인한다.

한 대에만 등록해야 한다. 두 대에 걸면 같은 날 글이 두 번 나간다.

그리고 dry-run이 닿지 않는 유일한 구간이 푸시 경로다 — launchd 환경에서의 키체인 접근과 claude 인증. 여기는 실제로 한 번 돌려보기 전까지 검증됐다고 말할 수 없다.