시작은 단순했다

"느낌표 글 발행해줘."

블로그 글 하나를 Cloudflare Pages에 올리는 일이었다. /spark publish를 실행하면 Markdown을 HTML로 빌드하고, wrangler로 배포하고, git에 커밋하는 — 이미 만들어둔 파이프라인이 있었다.

첫 번째 글, 배포 완료. 두 번째 글, Remote Control 인사이트 — 이것도 완료. 세 번째, 테슬라 모델 Y 가이드 — 역시 완료.

3개를 배포하고 나서 문득 물었다. "이번 작업에서 개선해야 할 부분은?"

그리고 4개의 문제가 드러났다.

문제 1: 매번 JSON을 손으로 고치고 있었다

published.json은 발행된 글 목록을 관리하는 manifest 파일이다. 새 글을 배포할 때마다 이 파일에 항목을 추가해야 한다.

그런데 빌드 스크립트에 --files 플래그가 있었다. 이 플래그를 쓰면 manifest에 자동으로 추가된다. 스크립트가 이미 해주는 일을 매번 수동으로 하고 있었던 것이다.

교훈: 도구가 제공하는 기능을 먼저 파악하라. "내가 해야 한다"는 관성이 자동화를 무시하게 만든다.

문제 2: 배포는 했는데 커밋을 안 했다

세 번째 글(테슬라)을 배포한 후 published.json의 변경사항을 git에 커밋하지 않았다. 다음 세션에서 이 파일이 충돌하거나, 다른 글을 배포할 때 manifest가 꼬일 수 있는 상황이었다.

원인은 명확했다. publish 플로우 스펙에 "배포 후 git commit" 단계가 없었다. 빌드 → 배포 → 정리까지만 정의되어 있고, manifest 변경을 커밋하는 마지막 단계가 빠져 있었던 것이다.

교훈: 파이프라인의 마지막 단계는 "상태 저장"이어야 한다. 배포가 성공해도 그 사실이 기록되지 않으면 반쪽짜리다.

문제 3: 공개/비공개를 묻지 않았다

일주일 전에 공개/비공개 접근 제어 기능을 추가했다. public 글은 누구나 볼 수 있고, private 글은 Cloudflare Access 인증이 필요하다.

그런데 3개 글을 배포하면서 한 번도 "이 글을 공개할까요, 비공개로 할까요?"라고 물어보지 않았다. 전부 기본값인 public으로 나갔다.

스펙을 확인해보니, --files 플래그에 :private 접미사를 붙이거나 인터랙티브 모드에서 선택하도록 되어 있었다. 하지만 파일명을 직접 지정하는 경우(publish 글.md)에 대한 분기가 없었다.

교훈: 기능을 추가하면 모든 진입 경로에서 작동하는지 확인하라. "인터랙티브에서만 되는 기능"은 파워 유저가 쓸수록 빠지기 쉽다.

문제 4: CLAUDE.md가 뚱뚱했다

발행 시스템을 고치고 나서 CLAUDE.md를 들여다봤다. 183줄. spark.md에 이미 있는 Knowledge File Format을 그대로 복사해놓은 32줄, 카테고리 테이블 중복 9줄, 10일 전에 멈춘 Session Context.

그리고 존재하지 않는 경로를 참조하고 있었다. plugins/shortcut-master/scripts/learning.py — 이 디렉토리는 shortcut으로 이름이 바뀐 지 오래였다.

183줄 → 122줄. 33% 감량. 삭제한 61줄 중 실제로 필요한 정보는 0줄이었다.

교훈: 문서는 쓸 때보다 지울 때 더 많이 배운다. "혹시 필요할까 봐" 남겨둔 중복은 결국 오래된 거짓말이 된다.

정리

블로그 3개를 배포하려고 했을 뿐인데, 배포 시스템 자체를 4군데 고쳤다. 반복 작업을 하면 패턴이 보이고, 패턴이 보이면 개선점이 보인다.

발견 수정
manifest 수동 편집 빌드 스크립트 --files 플래그에 위임
git commit 누락 publish 플로우에 9단계(commit & push) 추가
접근 제어 미확인 파일명 직접 지정 시에도 공개/비공개 확인
CLAUDE.md 중복/오래된 정보 33% 감량 (183줄 → 122줄)

"도구를 쓰면서 도구를 고친다" — 이것이 1인 개발자의 가장 자연스러운 개선 루프다.