쇼핑몰에서 상품 하나를 내렸다고 해 보자. 관리 화면에서 「비공개」를 누르고, 상품 페이지 주소를 열어 404 가 뜨는 걸 확인했다. 끝났을까?
대개는 아니다. 그 상품의 이름과 사진은 아직 여러 군데에 남아 있다. 메신저에 링크를 붙이면 뜨는 미리보기 카드 그림, 검색 엔진에 제출한 사이트맵, 콘텐츠 전송망(CDN)의 캐시, 그리고 다음 배포 때 재활용될 빌드 캐시. 원본은 하나지만 사본은 여럿이고, 「내리기」 단추는 보통 원본 하나만 안다.
당신이 에이전트에게 「글 내리기 기능을 만들어 줘」라고 시켰을 때도 같다. 에이전트는 원본 페이지를 404 로 만들고, 그걸 확인하고, 일을 마쳤다고 보고한다. 틀린 말은 아니다. 다만 사본이 몇 개인지는 아무도 세지 않았다.
원리 — 내리기는 원본이 아니라 사본 목록에 거는 일이다
콘텐츠를 내리거나 지우는 기능을 만들기 전에, 먼저 그 콘텐츠가 복사되어 남는 자리를 전부 적는다. 그리고 내리기 단추가 그 목록을 하나하나 지우게 만들고, 확인도 목록 전체에 대고 한다.
사본은 두 가지 꼴로 살아남는다.
하나, 따로 구워 둔 파생물. 글 페이지와 그 글의 미리보기 그림은 주소가 다르다. 프레임워크에서 「이 페이지를 다시 만들어라」고 부르면 그 페이지 주소만 새로 굽고, 같은 글에서 파생된 그림 주소는 그대로 둔다. 실제로 이런 일이 있었다. 글을 내리면 본문은 404 가 됐는데, 그 글의 제목과 대표 그림이 박힌 미리보기 그림 주소는 계속 공개돼 있었다. 사람도 에이전트도 아니고, 커밋마다 도는 보안 검토가 짚어서야 알았다. 고친 방법은 단순했다 — 내리기 단추가 글 하나에 딸린 주소 셋(본문·미리보기 그림 두 종)을 콕 집어 다시 굽게 했다.
둘, 입력을 다 모르는 캐시. 빌드 도구의 캐시는 보통 코드를 보고 「지난번과 같다」를 판단한다. 그런데 페이지가 빌드 때 데이터베이스를 읽어서 만들어진다면, 빌드 결과는 코드와 데이터 둘 다에 달려 있다. 코드만 키로 쓰는 캐시는 데이터가 바뀐 걸 모른다. 시험 삼아 운영 빌드를 돌렸더니, 데이터베이스에는 글이 1편뿐인데 빌드 캐시가 46편이던 시절의 결과를 그대로 되살렸다. 관리 화면에서 내린 글이 다음 배포 때 도로 공개될 수 있었다는 뜻이다. 이쪽은 캐시를 끄는 것으로 막았다. 캐시 키에 데이터 상태를 넣는 길도 있지만, 무엇이 「같은 데이터」인지 정하는 일이 캐시로 얻는 시간보다 비쌌다.
두 경우 다 원본은 제대로 내려가 있었다. 문제는 원본을 확인한 것으로 끝났다는 것이다.

사본 목록 만들기 — 다섯 질문
내리기·지우기 기능을 만들기 전에, 그 콘텐츠에 대해 이것을 묻는다.
- 이 콘텐츠에서 만들어지는 다른 주소는? 미리보기 그림, 썸네일, RSS·사이트맵, 검색용 JSON, 인쇄용 페이지.
- 이 콘텐츠를 목록으로 보여 주는 곳은? 첫 화면, 카테고리 쪽, 「이전 글·다음 글」, 추천 칸.
- 누가 이걸 미리 구워 두나? 정적 생성, 증분 재생성, CDN, 브라우저 캐시 헤더.
- 그 캐시는 무엇을 보고 「같다」고 하나? 코드만 본다면, 데이터에 달린 결과는 캐시하면 안 된다.
- 바깥에 이미 나간 것은? 검색 엔진 색인, 메신저가 받아 간 미리보기. 이건 우리가 못 지운다 — 그래서 미리보기 그림 같은 건 내린 뒤 주소가 일반 그림으로 바뀌게 해 두면, 다음에 다시 가져갈 때 사라진다.
에이전트에게 줄 지침
이 원리를 에이전트의 작업 지침에 그대로 넣을 수 있다.
콘텐츠를 숨기거나 지우는 기능을 만들거나 고칠 때:
- 만들기 전에 그 콘텐츠의 사본 목록을 적는다
(파생 주소 · 목록 · 사이트맵 · 미리 구운 페이지 · 캐시).
- 내리기 동작은 그 목록 전체를 무효화한다. 원본만 지우고 끝내지 않는다.
- 확인은 운영과 같은 빌드에서 목록의 주소마다 한다.
"원본이 404 다"만으로 완료라고 보고하지 않는다.
- 빌드가 데이터베이스나 외부 데이터를 읽으면,
그 빌드 결과를 코드 기준 캐시에 맡기지 않는다.
- 되돌리기(다시 공개)도 같은 목록으로 확인한다.
마지막 줄이 생각보다 중요하다. 내리기만 고치면, 다시 공개했을 때 미리보기만 일반 그림으로 남는 반대쪽 구멍이 생긴다. 실제로 고친 뒤에는 운영 빌드에서 내리기 → 미리보기가 일반 카드·본문 404, 되돌리기 → 원래 그림·본문 200 을 둘 다 재서 확인했다.
확인 목록
- 내린 글의 본문 주소가 404 인가
- 그 글의 미리보기·썸네일 주소가 더 이상 글의 내용을 보여 주지 않는가
- 목록·사이트맵·RSS 에서 빠졌는가
- 캐시를 지운 깨끗한 빌드와 캐시를 쓴 빌드의 결과가 같은가
- 다시 공개하면 위가 모두 원래대로 돌아오는가
「지웠다」는 원본 하나의 상태가 아니라 사본 목록 전체의 상태다. 목록이 없으면, 지웠는지 아닌지 말할 근거도 없다.
이전 글에이전트의 권한은 미리 주지 말고, 막힌 기록으로 연다