Claude Code로 블로그 정리하기
오랜만에 블로그 저장소를 열어보니 GitHub Dependabot이 취약점 36건(critical 1건 포함)을 알려주고 있었다. Claude Code의 도움을 받아 저장소 정리와 취약점 해소 작업을 진행한 내용을 기록한다.
작업 내용 요약
CLAUDE.md생성 및README.md를 블로그 정보에 맞게 수정- 미사용 gulp 관련 파일 삭제 (npm 취약점 제거)
- Ruby gem 의존성 업데이트 (Dependabot 취약점 36건 → 0건)
- 미래 날짜 글이 사이트에서 안 보이는 문제 확인
- 기존 글(AI TOOLS)을 현재 시점 내용으로 갱신, 새 글(PaperBanana) 작성
_drafts에 방치되어 있던 임시 글 11건을 보완해서 발행하고 드래프트 정리- 발행 글 전체 검토 후 낡은 글 36건 우선순위별 업데이트 (7/15)
- 시간대 미설정으로 URL 날짜가 하루 밀리는 문제 수정 (7/15)
- 본문 테이블 스타일 정비 — 미니멀 가로선 + 지브라 + 가로 스크롤 (7/24)
- 코드블록 구문 강조 정비 — 다크 배경에 라이트 팔레트가 겹쳐 있던 문제 수정 (8/18)
- GitHub 부분 장애로 Pages 빌드 실패 시 대응 기록, json 젬 취약점 패치 (8/18)
- 코드블록·표가 페이지 폭을 밀어내는 반응형 문제 연쇄 수정 (8/24·8/29)
- 자동 발행 글의 타이틀 이미지 누락·한글 폰트 깨짐 대응 (8/29)
- 발행 글마다 “검수 로그”를 Disqus 댓글로 자동 등록 (8/30)
- 스케줄러 견고화 — 놓친 실행 자동 따라잡기, 중복 마커 제외, 강제 종료 복구 사례 (9/6)
- Gist 임베드 줄무늬 가독성 수정, SSH Bastion 다이어그램 재작성 (9/7)
- SEO 정비 — 빈 og:image 제거, 트위터 카드 확대, GSC 월간 리포트 자동화 (9/7)
- 검색 순위 하락 원인 분석 후 트래픽 상위 3개 글 콘텐츠 리프레시 (9/7)
- 접이식 “원문 근거(evidence)” 블록 도입 — 핵심 주장에 원문 인용 첨부, 검수 파이프라인 규칙화 (9/9)
- GSC 사이트맵 2년 정체 발견 — 주간 재제출 자동화, robots 차단 오탐 전수 검증 (9/9)
- 자잘한 함정 둘 —
nul예약 파일명 빌드 실패, Disqus 댓글이 옛 URL 스레드로 간 문제 (9/9) - 검수 스케줄 21시 이동 — Hermes 초안 체인과의 타이밍 충돌 해소, 작성 규칙 문서로 에이전트 간 협업 (9/10)
- 관련글 목록에 최신 글 자동 역링크 — 레이아웃 개선 + 40개 글 태그 백필 (9/10)
- 공유 버튼 리디자인 (X·페이스북·링크 복사) — 레거시 CSS 특이성 함정 또 한 번 (9/10)
CLAUDE.md와 README 정리
Claude Code의 /init 명령으로 저장소 구조를 분석해 CLAUDE.md를 생성했다. 빌드/실행 명령, 글 작성 규칙(front matter 템플릿, <!--more--> 구분자 등)이 정리되어 있어 이후 세션에서 바로 활용할 수 있다.
README.md는 테마(Flexible-Jekyll) 원본 내용 그대로였는데, 블로그 소개와 로컬 실행 방법, 글 작성 절차로 교체했다.
gulp 관련 파일 정리
이 블로그는 Jekyll만으로 빌드되는데, 테마에 포함되어 있던 gulp 3 기반의 gulpfile.js와 package.json이 남아 있었다. 오래된 npm 의존성이 Dependabot 경고의 원인 중 하나였으므로 두 파일을 삭제하고 _config.yml의 exclude 목록도 정리했다.
git rm gulpfile.js package.json
Ruby gem 취약점 해소
남은 경고는 전부 Gemfile.lock의 Ruby gem이었다. gh CLI로 확인해보면 다음과 같다.
gh api repos/OWNER/REPO/dependabot/alerts --paginate \
-q '.[] | select(.state=="open") | [.security_advisory.severity, .dependency.package.name] | join(" | ")'
nokogiri, rexml, faraday, activesupport, webrick, addressable, google-protobuf, concurrent-ruby 등이 취약 버전으로 잠겨 있었다.
bundle update 실행 시 Gemfile에 글로벌 source가 없어 아래와 같은 오류가 발생했다.
Could not find gem 'jekyll-sitemap' in locally installed gems.
Gemfile 상단에 source와 jekyll gem을 명시하고 다시 실행하니 정상적으로 갱신되었다.
source "https://rubygems.org"
gem "jekyll"
bundle update
bundle exec jekyll build # 빌드 정상 확인 후 push
push 후 Dependabot 알림을 다시 확인하니 열린 알림이 0건으로 정리되었다.
미래 날짜 글은 사이트에 안 보인다
이 글을 처음 올렸을 때 사이트에 보이지 않아 당황했는데, 원인은 front matter의 date를 현재보다 늦은 시각으로 적었기 때문이었다. GitHub Pages는 기본 설정(future: false)에서 미래 날짜 글을 빌드에서 조용히 제외한다. 에러도 없이 그냥 안 보이므로, 새 글의 date는 반드시 현재 시각 이전으로 적어야 한다. 이 내용은 CLAUDE.md에도 주의사항으로 추가해뒀다.
글 정리
- 기존 AI TOOLS 글을 현재 시점에 맞게 갱신했다. 글에서 소개했던 AI Toolkit이 Foundry Toolkit for VS Code로 이름이 바뀌고 Bulk Run이 Evaluation으로 통합된 내용을 반영했다.
- 문장으로 아키텍처 다이어그램을 만들어주는 서비스를 소개하는 PaperBanana 글을 새로 작성했다.
드래프트 정리
_drafts 디렉토리에 2019~2023년 사이에 쓰다 만 임시 글 19건이 방치되어 있었다. 내용이 있는 11건(Slack webhook, ffmpeg SRT, 터널링 도구, 네이버 서치어드바이저 등)은 2026년 기준으로 사실관계를 다시 확인하고 보완해서 발행했고, 제목만 있고 내용이 없던 8건은 템플릿만 남기고 삭제했다. 버전이 오래됐거나(OpenSIPS 2.4 → 4.0), 이름이 바뀌었거나(MATIC → POL), 서비스 상태가 달라진 것들이 많아 오래된 드래프트는 발행 전에 반드시 현재 상태를 다시 확인해야 한다는 것을 실감했다.
발행 글 전수 검토 및 업데이트 (7/15 추가)
드래프트 정리에 이어 발행된 글 80여 건 전체를 검토해서 업데이트가 필요한 글 36건을 우선순위별로 나눠 수정했다.
- 높음 11건: 폐기된 도구/절차 —
letsencrypt-auto→ snap 기반 certbot 재작성(3건), WSL 최신 설치법(wsl --install), SMB1 보안 경고, 종료된 서비스(TeamSQL, Pocket 등) 안내, Owncast/Janus 현재 버전 반영 - 중간 14건: EOL 환경·바뀐 UI — winget 시대 반영, Tailscale 무료 플랜(현재 Personal, 6명/디바이스 무제한), Oracle 프리티어 축소(2026-06부터 A1 2 OCPU/12GB), UA → GA4, Python 3.12의
ssl.wrap_socket제거 대응 등 - 낮음 11건: 오타·죽은 링크 수정, 유지보수 중단 도구(Vundle 등) 안내. 콘텐츠 가치가 없는 Jekyll 기본 샘플 글은 삭제
모든 글은 원본 날짜와 URL을 유지한 채 본문 상단에 [업데이트] 안내 블록을 넣고 last_modified_at만 갱신하는 방식으로 처리했다. letsencrypt-auto 폐기(3건), Vundle 중단(2건)처럼 같은 원인이 여러 글에 걸쳐 있는 경우가 많았다.
시간대 미설정으로 URL 날짜가 하루 밀리는 문제 (7/15 추가)
업데이트 반영을 확인하다가 또 하나의 함정을 발견했다. _config.yml에 timezone 설정이 없으면 GitHub Pages는 UTC로 빌드하기 때문에, 게시 시각이 오전 9시(KST) 이전인 글은 사이트 URL의 날짜가 하루 앞으로 밀린다. 예를 들어 date: 2023-11-14 01:00 +0900인 글의 실제 URL은 /2023/11/13/...이 된다. 로컬 빌드(KST)와 결과가 달라 내부 링크가 조용히 깨지는 원인이 됐다.
# _config.yml
timezone: Asia/Seoul
Windows 로컬 빌드에서는 timezone 설정 시 tzinfo-data gem이 없으면 빌드가 실패하므로 Gemfile에 함께 추가해야 한다.
gem 'tzinfo-data', platforms: [:mingw, :x64_mingw, :mswin]
timezone 설정으로 오전 9시 이전 게시 글 10건의 URL이 바뀌었기 때문에, 검색엔진이 새 주소를 빨리 색인하도록 Google Search Console과 네이버 서치어드바이저에 사이트맵을 다시 제출했다. 제출 전에 sitemap.xml이 유효한 XML인지(104개 URL), robots.txt에 사이트맵 경로가 선언되어 있는지 확인했고, Search Console에서는 “성공”으로 처리 완료를 확인했다. 참고로 예전 방식의 사이트맵 ping URL은 폐지되어 재제출은 콘솔에서 직접 해야 한다.
본문 테이블 스타일 정비 (7/24 추가)
최근 글에 비교표가 부쩍 많아졌는데, 이 테마에는 테이블 CSS가 아예 없어서 브라우저 기본 스타일(경계선 없는 밀집 표)로 표시되고 있었다. _sass/_base.scss에 본문 스코프(.wrap-content table)로 기술 블로그 스타일을 추가했다: 세로선 없는 가로선 미니멀 구성, 헤더 배경과 지브라 스트라이프, 행 호버 하이라이트, 넓은 표의 표 내부 가로 스크롤.
한 가지 삽질 기록 — 처음에 배경색을 테마 변수 기반 lighten($grey-color-light, 12%)로 지정했는데, 원본 색이 이미 밝아서 밝기 한계를 넘겨 전부 #fff(흰색)로 컴파일되어 버렸다. 로컬에서는 눈치채지 못했고 배포 후 라이브 CSS를 grep으로 검사하다 발견했다. Sass 색상 함수는 컴파일 결과를 확인하기 전까지 믿지 말 것. 명시적 색상(#f4f6f8, #f9fafb)으로 교체해 해결했다.
.wrap-content table {
display: block;
overflow-x: auto; // 넓은 표는 표 안에서만 가로 스크롤
border-collapse: collapse;
th { background-color: #f4f6f8; border-bottom: 2px solid $grey-color; }
th, td { padding: 10px 14px; border-bottom: 1px solid $grey-color-light; }
tbody tr:nth-child(even) { background-color: #f9fafb; }
tbody tr:hover { background-color: #eaf2fd; }
}
코드블록 구문 강조 정비 (8/18 추가)
테이블에 이어 이번엔 코드블록이었다. 코드블록 배경은 다크(#1d1f21)인데 Rouge 구문 강조 색상은 라이트 배경용 팔레트(키워드 #069, 연산자 #555, 문자열 어두운 빨강)가 걸려 있어서, 어두운 배경 위에서 키워드가 거의 보이지 않았다. 강조 클래스가 없는 일반 토큰은 색 지정이 아예 없어 본문의 어두운 글자색을 상속받아 배경에 묻혔다.
수정 내용:
- 315줄짜리 라이트 팔레트를 GitHub Dark 계열 팔레트 30줄로 교체 (키워드 연한 빨강, 문자열 하늘색, 함수 보라, 주석 회색 이탤릭)
.highlight에 기본 텍스트색#e6edf3지정 — 강조 안 된 토큰도 항상 밝게word-break: break-all제거 — 변수명·URL이 글자 중간에서 꺾이던 것을 가로 스크롤(overflow-x: auto)로 변경
테이블 때와 같은 함정이 반복됐다는 것도 기록해둔다: 이 테마는 SCSS 산출물이 아니라 레거시 assets/css/main.css를 로드하므로, _sass/만 고치면 사이트에 반영되지 않는다. 스타일 수정 후에는 라이브 CSS를 직접 받아 반영 여부를 확인해야 한다.
GitHub 부분 장애와 Pages 빌드 실패 (8/18 추가)
위 CSS 커밋의 Pages 빌드가 실패했는데, 로그를 보니 Jekyll에 들어가기도 전에 GitHub Actions가 빌드 액션 다운로드 단계에서 429/503으로 죽어 있었다 — githubstatus.com이 “Partial System Outage”인 상태였다. 이런 경우 저장소를 고칠 게 아니라 gh run rerun으로 재시도하면 되고, 실패한 빌드가 있어도 직전 성공 빌드가 계속 서비스되므로 사이트가 내려가지는 않는다. 장애 해소 후 재실행으로 정상 배포됐고, 라이브 CSS에 새 팔레트가 반영된 것까지 확인했다.
같은 날 Dependabot 알림 1건(json 젬 2.21.1의 ResumableParser 해제 버퍼 참조, low)도 bundle update json --conservative로 2.21.2 패치해 정리했다 — 7월의 36건 정리 이후 새로 생긴 것이라, 락파일 취약점은 한 번 정리하고 끝이 아니라 알림이 올 때마다 소소하게 갱신하는 운영 항목이라는 걸 보여준다.
폭 넘침 문제 연쇄 수정 — flex와 표 (8/29 추가)
코드블록 팔레트를 정비하고 나니 폭 문제가 연달아 드러났다. 둘 다 “overflow-x: auto를 줬는데 왜 페이지가 넓어지지?”라는 같은 증상, 다른 원인이었다.
- 데스크톱(8/24): 본문 컨테이너(
.article-page)가 flex 아이템이라 기본값이min-width: auto다. 자식(긴 코드 줄)이 줄바꿈 없이 길면 스크롤이 생기는 게 아니라 아이템 자체가 늘어나 페이지를 민다.min-width: 0+max-width: 100%로 컨테이너 폭을 잠가야 overflow-x가 비로소 동작한다. flex 레이아웃의 고전 함정. - 모바일(8/29): 4~5컬럼 표가 화면 폭을 밀어냈다. “≤768px에서 표 내부 가로 스크롤” 규칙을 예전에 만들어뒀는데, 하필 사이트가 로드하지 않는 SCSS 쪽에만 넣어놨던 것 — 테이블·코드블록에 이어 세 번째로 밟은 같은 함정이다. 로드되는 레거시 CSS의 미디어쿼리에
table { display: block; overflow-x: auto; }를 넣어 해결했다.
교훈은 하나로 수렴한다: 스타일을 고쳤으면 라이브 CSS를 직접 받아서 확인하고, 배포 후 데스크톱·모바일 양쪽에서 실제 페이지를 열어봐야 한다.
자동 발행 글의 타이틀 이미지 함정 (8/29 추가)
Hermes 초안 자동 검수 파이프라인이 발행한 글에서 두 가지 이미지 문제가 나왔다.
- 이미지 미커밋: 초안이 참조하는 새 이미지가
assets/img/에 생성돼 있었지만 발행 커밋에 포함되지 않아 사이트에서 썸네일이 깨졌다. 글 파일만 add하는 습관이 원인. - 한글 폰트 깨짐(tofu): 이미지를 열어보니 다이어그램 속 한글이 전부 □로 렌더링돼 있었다. 이미지 생성 환경에 한글 폰트가 없으면 생기는 문제로, Malgun Gothic으로 재생성해 교체했다.
파이프라인 프롬프트에 두 규칙을 추가했다: 글이 참조하는 미추적 이미지도 함께 커밋할 것, 이미지를 직접 열어 한글 렌더링을 확인하고 깨졌으면 범용 이미지로 대체할 것(재생성은 사람 몫). 자동 발행에서는 “파일이 존재한다”와 “제대로 보인다” 사이의 간극을 규칙으로 메워야 한다.
검수 로그를 댓글로 — 발행 파이프라인의 투명화 (8/30 추가)
자동 발행되는 글이 늘면서 “이 글에서 뭘 검증하고 뭘 고쳤는지”를 독자에게도 보여주고 싶어졌다. Disqus API(posts/create)로 발행 직후 검수 요약을 봇 댓글로 등록하는 단계를 파이프라인에 붙였다 — 원문 대조 결과, 정정 사항, 제거한 참조, 윤문 적용 여부를 5줄 내외로 남긴다.
구현 포인트: Disqus API 앱을 만들어 API key + Access Token을 로컬에만 두고, 파이썬 표준 라이브러리로 스레드 조회(ident → link 폴백) 후 스레드가 없으면(아무도 안 연 새 글) 직접 생성해서 댓글을 단다. 댓글 등록 실패가 발행을 막지 않도록 “실패해도 발행은 유효”를 프롬프트에 명시했다. AI가 쓰고 AI가 검수하는 블로그에서 검수 과정 자체를 공개하는 것이 독자 신뢰에 대한 최소한의 예의라고 생각한다.
스케줄러 견고화 세 가지 (9/6 추가)
한 주 운영하며 잡은 자잘한 구멍들:
- 놓친 실행 자동 따라잡기: 일요일 18시에 PC가 절전이면 주간 발행이 통째로 빠졌다. 작업 스케줄러의
StartWhenAvailable을 켜서 부팅/복귀 즉시 놓친 실행을 따라잡게 했다. - 강제 종료 복구 사례: 실제로 주간 발행이 실행 도중 프로세스 강제 종료(0xC000013A)로 끊긴 날이 있었는데, 재실행된 에이전트가 커밋 직전까지 완성돼 있던 미커밋 글을 발견하고 — 재작성 대신 재검증 후 그대로 발행했다. 부분 실패 상태를 이어받는 안전장치가 실전에서 확인된 사례.
- 중복 마커 제외: Hermes가 중복 검증용으로
_drafts/에 남기는*duplicate-skipped*.md마커 때문에 매일 빈 검수가 돌았다 — 스케줄러의 초안 감지와 프롬프트 양쪽에서 마커를 제외해 “마커만 있는 날은 claude 호출 없이 스킵”으로 정리했다.
Gist 줄무늬와 다이어그램 재작성 (9/7 추가)
- Gist 임베드 줄무늬: 7/24에 만든 본문 테이블 카드 스타일(지브라·헤더 배경)이 GitHub Gist 임베드 내부의
table에까지 번져, 코드가 [Image] 줄무늬처럼 보이는 문제가 있었다. 레거시 CSS 끝에.gist table리셋을 추가하고 Gist 전용 스타일시트의 배경을 코드블록과 같은#1d1f21계열로 통일해 해결. 전역 테이블 스타일은 임베드 위젯까지 오염시킬 수 있다는 교훈. - SSH Bastion 다이어그램: 오래된 글의 구성도 이미지를 현재 내용(클라이언트 → 게이트웨이 8022 → Bastion → 내부 호스트 2대, ProxyJump 표기)에 맞게 다시 그렸다. 💻 이모지가 tofu로 렌더링되는 환경이라 노트북 아이콘은 도형으로 직접 그렸다 — 한글 폰트에 이어 이모지도 이미지 생성의 함정 목록에 추가.
SEO 정비와 GSC 월간 리포트 자동화 (9/7 추가)
메타 태그를 점검해 두 가지를 고쳤다: 썸네일 없는 글에서 og:image가 빈 값으로 출력되던 것을 조건부 출력으로 제거했고, 트위터 카드를 summary → summary_large_image로 올렸다.
이어서 Google Search Console을 서비스 계정(읽기 전용)으로 연결하고, 매월 1일 검색 실적 리포트를 자동 생성하는 스케줄러를 추가했다 — 28일 실적(클릭·노출·CTR·평균 순위)을 직전 동기간과 비교하고 상위 쿼리/페이지·기기·사이트맵 상태까지 마크다운으로 남긴다. 수동으로 콘솔을 열어보는 대신 매달 정기 데이터가 쌓이게 됐다.
순위 하락 분석과 상위 글 리프레시 (9/7 추가)
GSC 데이터를 받아보니 최근 28일 클릭이 직전 대비 −60, 평균 순위가 11.5 → 15.1로 밀려 있었다. 원인을 파보니 새 글이 노출을 희석한 게 아니라(신규 페이지는 노출의 1% 수준), 오래된 실용 글들의 순위가 8월 중순 구글 스팸 업데이트 시점에 일제히 하락한 것이었다 — 대표적으로 PowerShell 글이 15위 → 48위, “powershell” 쿼리 노출이 반토막.
대응은 날짜만 바꾸는 눈속임이 아니라 실질 콘텐츠 리프레시: 트래픽 상위 3개 글을 현재 기준으로 전면 갱신했다.
- PowerShell 글: 5.1 → 7.x 기준 전면 갱신 — 버전 표, 프로필 경로(
Documents\PowerShell\), PS7에서 제거된 wget/curl 별칭,Get-Uptime, winget - Tailscale 글: 요금 페이지 실시간 재확인 후 무료 플랜에 포함된 Tailscale SSH·MagicDNS 보강
- ffmpeg 캠 스트리밍 글: ffmpeg 8.x·winget 설치 반영, 외부망용 SRT 스트리밍/MediaMTX 섹션 신설
효과는 GSC 반영 지연을 감안해 다음 달 자동 리포트에서 확인할 예정이다. 순위 하락에 대한 정석 대응은 결국 “그 글이 지금도 정확한가”를 다시 만드는 것뿐이다.
“원문 근거” 접이식 인용 도입 (9/9 추가)
AI가 초안을 쓰고 AI가 검수하는 블로그에서 “이 수치, 진짜 원문에 있는 거 맞아?”라는 의심은 정당하다. 검수 로그 댓글(8/30)에 이어 이번엔 본문 안에서 바로 확인하는 장치를 붙였다: 핵심 수치·주장 바로 아래 “▸ 원문 근거” 알약 버튼을 두고, 클릭하면 원문에서 그대로 복사한 문장이 말풍선풍 인용 박스로 펼쳐진다. HTML <details>라 JS가 필요 없고 모바일에서도 그대로 동작하며, 접혀 있어도 검색엔진은 인용문을 색인한다.
규칙에서 가장 중요한 한 줄은 이것이다 — 인용문은 fetch한 원문에서 복사만 허용, 기억 재구성·의역 금지. 근거 블록 자체가 환각되면 신뢰 장치가 역효과이기 때문이다. GPT-6 Astra 글(5곳)부터 AgentPerf·OCI 블록볼륨 글까지 적용했고, 일간·주간 검수 파이프라인 프롬프트에도 규칙으로 넣어 이후 발행 글에는 자동으로 붙는다.
GSC 사이트맵 2년 정체와 재제출 자동화 (9/9 추가)
“robots.txt가 Googlebot을 차단한다”는 경고를 추적하다가 더 큰 문제를 찾았다. 사이트맵 170개 URL 전체를 URL 검사 API로 전수 조사한 결과 robots 차단은 0건(오탐)이었지만, 106개 URL(62%)이 “구글이 모르는 URL”이었다. 원인은 사이트맵 자체가 아니라(200·XML 유효) 구글이 사이트맵을 2024-10-13 이후 한 번도 다시 읽지 않은 것 — 재제출해도 pending으로만 남아 있었다.
대응으로 ① 서비스 계정 권한을 전체로 올려 API로 sitemap.xml을 재제출하고, ② 구글이 더 자주 읽는 경향이 있는 Atom 피드(feed.xml)를 보조 사이트맵으로 추가 제출했으며, ③ 매주 수요일 재제출 + lastDownloaded 14일 이상 정체 시 경고를 남기는 스케줄러(gsc-sitemap-resubmit)를 붙였다. 색인 회복 여부는 월간 GSC 리포트에서 추적한다. 교훈: “차단 경고”를 들으면 robots.txt만 볼 게 아니라, 구글이 실제로 판정한 상태(URL 검사 API)와 사이트맵을 언제 마지막으로 읽었는지까지 봐야 한다.
자잘한 함정 둘 (9/9 추가)
nul예약 파일명: 저장소 루트에 어쩌다nul이라는 파일이 생겼는데(Windows 예약 장치명), Jekyll이_site/nul을 지우지 못해 빌드가 통째로 죽었다. Git Bash의rm으로 양쪽을 제거해 복구. 스케줄러의 헤드리스 빌드까지 막을 수 있던 문제라, 원인 불명의 빌드 실패 때는 예약 파일명부터 의심해볼 것.- Disqus 댓글이 옛 스레드로: 검수 댓글을 달 때 페이지 경로를 파일명 날짜로 조립했는데, 이 블로그엔 파일명 날짜와 front matter date가 다른 글이 있다(URL은 date 기준). 댓글이 존재하지 않는 옛 URL 스레드에 달려 실제 페이지에는 안 보였다. 올바른 스레드에 재게시하고, 파이프라인 규칙을 “경로는 빌드 결과/sitemap에서 확인”으로 고쳤다.
검수 스케줄 이동과 에이전트 간 작성 규칙 (9/10 추가)
초안을 쓰는 Hermes의 크론 체인이 수집 18시 → 생성 19시 → 분석 20시로 바뀌면서, 19시에 돌던 Claude 검수가 그날 초안이 나오기도 전에 실행되는 타이밍 충돌이 생겼다. 검수를 21시로 옮겨 “초안이 다 모인 뒤 검수”로 순서를 바로잡았다.
같은 날, 검수 체크리스트를 작성자 관점으로 뒤집은 WRITING-RULES.md를 Hermes 작업 폴더에 두고 Hermes의 영속 메모리에 “초안 쓰기 전에 이 파일부터 읽어라”라는 포인터를 심었다. 검수에서 반복되는 지적(미래 날짜, 수치 창작, 링크 날조, 이미지 폰트)을 발행 후 고치는 대신 작성 시점에 예방하려는 시도다. 효과는 바로 나타났다 — 다음 초안(OmniDocBench 검토 글)이 처음으로 원문 인용(evidence 블록)을 스스로 달아 왔고, 인용문도 전부 진짜였다. 반면 “이미 발행한 주제 재초안” 문제는 이틀 연속 재발해서, 중복 검사 범위를 _drafts 마커만이 아니라 _posts까지 넓히라는 규칙을 추가로 심어둔 상태다. 에이전트끼리의 협업 규칙은 한 번에 완성되지 않고, 이렇게 반려 사례를 먹이며 자란다.
관련글 목록, 옛 글에 최신 글 역링크 (9/10 추가)
새 글이 옛 글을 링크해도 옛 글은 새 글의 존재를 모른다 — 이 비대칭을 없앴다. 알고 보니 테마의 “관련글 목록”은 원래 “이 글의 related 값을 태그로 가진 모든 글”을 나열하는 구조여서, 새 글이 자기 related 값을 태그에도 넣기만 하면 옛 글에 자동으로 역링크가 생기는 것이었다. 문제는 최근 글 40개가 이 조건을 안 지키고 있었다는 것.
레이아웃을 최신순·자기 제외·최대 7개로 다듬고(원래 있던 닫는 태그 버그도 수정), 40개 글 태그를 일괄 백필하고, 파이프라인 규칙에 “related 값을 tags에도 포함”을 추가했다. 이제 7월 글을 열면 관련글 목록 맨 위에 이번 주 글이 보인다. 내부 링크가 양방향으로 엮이니 색인 문제를 겪는 요즘 SEO 관점에서도 남는 장사다.
공유 버튼 리디자인 — 그리고 세 번째 특이성 함정 (9/10 추가)
글 하단의 밋밋한 텍스트 링크(“Twitter”, “Facebook”)를 브랜드 컬러 알약 버튼으로 바꿨다. X 로고(트위터 리브랜딩 반영)와 페이스북 아이콘을 SVG로 넣고, 실용성이 가장 높은 “링크 복사” 버튼을 추가했다 — 클릭하면 클립보드 복사 후 1.5초간 “복사됨!”으로 바뀐다. 트윗 공유 URL의 한글 제목이 깨지던 버그(url_encode 누락)도 함께 수정.
교훈 코너: 배포하고 보니 버튼이 hover 전까지 안 보였다. 테마의 기존 규칙 .page-footer .page-share a(연회색 배경)가 새 규칙보다 특이성이 높아 배경을 덮었고, 글자색(흰색)만 새 규칙이 이겨서 흰 배경에 흰 글자가 된 것. 테이블·코드블록·gist에 이어 이 레거시 CSS에서만 벌써 몇 번째 밟는 함정이다. 이 파일에 뭔가 추가할 때는 기존 셀렉터보다 특이성을 높여서 쓰는 게 기본값이어야 한다.
마무리
테마를 fork해서 쓰는 블로그는 사용하지 않는 빌드 도구 흔적이 남아 취약점 경고의 원인이 되기 쉽다. 실제로 쓰는 의존성만 남기고, Gemfile.lock은 주기적으로 bundle update로 갱신해주는 것이 좋겠다. 드래프트도 쌓아두면 결국 내용이 낡아버리니 그때그때 발행하거나 정리하는 편이 낫다. 그리고 미래 날짜 글 미노출, 시간대에 따른 URL 밀림처럼 GitHub Pages의 조용한 함정들은 한 번 겪을 때마다 CLAUDE.md에 기록해두면 같은 실수를 반복하지 않는다.