# KERCHU RSS · 사이트맵 관리 지침

개정: 2026-10-18. 이 문서가 현재 운영 규칙이다. 이전 지침은 계정 홈 kerchu-feed-system/의 백업에 보존한다.

## 1. 반드시 유지할 원칙
- 현재 운영 public_html을 기준으로 작업한다. 오래된 GitHub 백업으로 덮어쓰지 않는다.
- RSS와 사이트맵은 브라우저·구독기·검색엔진 모두에 XML만 반환한다. HTML 보기, XSL, xml-stylesheet, Accept별 화면 분기를 추가하지 않는다.
- 프론트엔드 디자인, 전체 페이지 푸터 날짜, 기존 콘텐츠를 일괄 변경하지 않는다.
- RSS 3개: /rss.xml 통합, /rss-music.xml 음반, /rss-novels.xml 소설.
- 홈페이지 작업 기록: /updates/history.json 및 /updates/rss.xml. 창작물 RSS에 섞지 않는다.
- /sitemap.xml은 인덱스이며 sitemap-music.xml, sitemap-novels.xml, sitemap-pages.xml을 연결한다.
- 개수는 고정하지 않는다. 15음반·4소설·19항목·21URL은 이번 배포 당시 수량일 뿐이다.

## 2. 새 음반 또는 싱글을 추가할 때
1. 현재 운영본과 변경할 파일을 먼저 백업한다. 아래 상태 데이터도 백업한다.
2. music/ 안의 기존 양의 정수 파일명을 확인하고 사용하지 않은 다음 번호를 정한다. 예: music/16.html. 기존 번호를 재사용하거나 재번호하지 않는다.
3. 실제 작품 내용으로 HTML을 작성한다. title, description, JSON-LD datePublished, 수록곡·가사·공식 감상 링크를 확인한다.
4. canonical은 실제 파일에 맞춰 https://kerchu.com/music/16.html처럼 정확히 설정한다. 다른 도메인·별칭·프래그먼트를 쓰지 않는다.
5. 실제 발매일을 확인할 수 없으면 임의로 오늘 날짜나 파일 수정일을 발매일로 만들지 않는다. datePublished가 없으면 신규 RSS pubDate는 생략된다.
6. 메인 페이지 작품 목록에 새 정규 URL을 연결한다. 기존 음반·소설은 유지한다.
7. HTML을 운영 서버에 올린다. 새 파일은 다음 RSS·사이트맵 요청 때 자동 발견된다. cron은 사용하지 않는다.
8. 아래 rebuild 및 공개 검사를 실행한다. 통합 RSS와 음반 RSS에 새 항목이 각각 한 개, 음악 사이트맵에 새 정규 URL 한 개가 추가돼야 한다.

## 3. 기존 음반에 노래·가사를 추가하거나 수정할 때
- 새 음반이 아니라면 해당 music/번호.html의 수록곡·가사·곡 수와 관련 정보를 수정한다. 별도 음반 번호나 중복 HTML을 만들지 않는다.
- 별도 정규 HTML이 없는 곡의 #앵커, 외부 감상 URL, 이미지 URL을 사이트맵 항목으로 추가하지 않는다.
- 사이트맵 URL 개수는 그대로이며 실제 본문이 바뀐 해당 음반의 lastmod만 갱신된다.
- RSS는 음반 단위다. 기존 항목의 GUID와 최초 pubDate를 보존한다. 제목·설명을 수정하면 기존 RSS 항목에 반영된다. 곡 한 개를 추가했다고 기존 음반을 새 RSS 항목으로 복제하지 않는다.
- 따라서 기존 음반에 곡만 추가하는 경우 새 RSS 알림 항목은 발행되지 않는다. 곡별 발행·알림이 필요하면 별도 콘텐츠 유형과 고정 ID 설계를 추가해야 한다. 현재 곡별 자동 RSS는 구현되어 있지 않다.

## 4. 소설을 추가하거나 새 회차를 반영할 때
- 새 작품: novels/5.html처럼 다음 사용 가능한 번호로 작성하고 canonical·제목·설명·실제 발행 정보를 설정한다. 메인 작품 목록에 연결한다. 통합·소설 RSS 및 소설 사이트맵에 자동 반영된다.
- 기존 작품의 회차 목록·소개 수정: 해당 novels/번호.html을 수정한다. 작품 GUID·최초 pubDate는 유지하고 해당 작품의 lastmod만 갱신한다.
- 외부 네이버웹소설 회차 주소를 kerchu.com 사이트맵에 넣지 않는다. 현재 RSS는 작품 단위이며 회차별 신규 알림은 구현되어 있지 않다.

## 5. GUID·날짜·정렬 규칙
- 신규 음반 ID: urn:kerchu:album:번호. 신규 소설 ID: urn:kerchu:novel:번호.
- 기존 URL형 GUID와 isPermaLink 속성도 그대로 보존한다. URL 변경을 이유로 GUID를 새로 만들지 않는다.
- 경로 변경은 별도 마이그레이션 작업이다. seed/state의 기존 항목을 새 URL 키로 이관하면서 GUID·pubDate를 유지하고, 이전 URL은 새 URL로 301 처리한다. 신규 파일 추가처럼 처리하지 않는다.
- 기존 pubDate를 작업일로 바꾸지 않는다. RSS 수정 알림을 만들려고 날짜를 임의로 올리지 않는다.
- 정렬은 pubDate 최신순, 발행일이 같으면 숫자 번호 내림차순이다. 1,10,11,2 같은 문자열 정렬을 쓰지 않는다.
- lastmod는 본문·제목·설명의 내용 지문이 바뀐 페이지에만 반영한다. 공통 푸터·메뉴·스타일 변경은 제외한다. 모든 lastmod를 오늘로 일괄 갱신하지 않는다.

## 6. 실행 명령과 완료 기준
운영 서버 cPanel 터미널에서 실행한다.

    python3 ~/public_html/updates/rebuild.py
    python3 ~/kerchu-feed-system/verify_public.py
    python3 ~/kerchu-feed-system/test_reader.py

- rebuild.py와 content_audit.py는 같은 점검 진입점이다. XML 스냅샷과 updates/inventory.json을 갱신한다. HTML은 수정하지 않는다.
- 공개 XML은 요청 시 최신 HTML에서 생성된다. rebuild는 보관용 스냅샷과 점검 현황까지 확정하기 위한 절차다.
- matched=true, issues=[]를 확인하고 warnings도 검토한다. 메인에 새 작품 링크가 빠져 있으면 보완한다.
- 8개 XML 주소가 모두 200·XML 형식이어야 한다. Accept:text/html 요청에도 HTML을 반환하면 실패다.
- 사이트맵의 모든 정규 페이지가 200이며 canonical과 같아야 한다. 리디렉션·외부 URL·중복·JSON·관리 파일은 제외한다.
- 각 분류의 실제 파일·RSS·사이트맵 URL 집합이 일치해야 한다. 신규 항목의 고정 GUID와 날짜, 기존 GUID·pubDate 보존을 확인한다.
- 수정 전후 내용이 같으면 XML 항목 날짜와 lastmod도 같아야 한다.
- 공개 검사 수량은 현재 원본에서 계산한다. 앞으로 파일이 늘었다고 검사기의 15·4·19·21을 수작업으로 고치지 않는다.
- test_feeds.py와 과거 배포 검증 로그는 2026-10-18 배포 당시 회귀 자료다. 일상 운영 검사는 위 세 명령을 사용한다.
- Search Console 제출·색인 확인은 별도 인증 작업이며 로컬 XML 검증 완료와 구분한다.

## 7. 상태 파일과 복구
- 비공개 생성기: ~/kerchu-feed-system/feeds.php
- 영속 식별자·날짜: ~/kerchu-feed-system/data/seed.json 및 state.json. 삭제·재초기화 금지. lock 파일도 임의로 변경하지 않는다.
- 공개 연결 파일: public_html/feed-system.php 및 .htaccess의 KERCHU FEEDS 구간. 다른 리디렉션·호스팅 PHP 설정은 유지한다.
- 마지막 정상 XML 스냅샷은 public_html의 8개 XML 파일이다. 생성 실패 시 스냅샷을 반환하므로 HTTP 200만으로 성공을 판단하지 말고 rebuild 오류·로그·최신 항목도 확인한다.
- 전체 운영본 백업: ~/kerchu-backups/public_html-20261018-1943.tar.gz. 무결성 검사 통과.
- 변경 전 개별 파일·생성기·상태 데이터를 새 시각의 비공개 백업 디렉터리에 보관한다. 복구 시 필요한 변경분만 복원하고 새로 추가된 운영 콘텐츠를 오래된 전체 백업으로 덮어쓰지 않는다.
- 작업 후 history.json에 실제 작업·검증 결과만 새로 추가한다. 기존 이력을 삭제·소급 조작하지 않는다. /updates/ HTML의 과거 정적 표시는 자동 생성 원본이 아니다.
