| name | tech-blog-manager |
| description | Curates the ThakiCloud tech blog content inventory: per-category policy, 250-posts/language publish cap, add-one/drop-one rule, and published-flag toggling. Use when managing blog categories, enforcing or inspecting the post cap, toggling published state, routing a twitter-selected topic to the blog. Korean+English triggers: 기술 블로그 관리, 블로그 카테고리 정리, 글 250개 상한, 배포 글 빼기, 블로그 발행 상태, blog cap, unpublish post, blog curation. Do NOT use for building/pushing the site (use tech-blog-deploy), translating posts to en/ar (use blog-i18n-sync), nightly quality scoring/rewriting (use tech-blog-evolve), or humanizing prose (use humanizer). |
tech-blog-manager
ThakiCloud 기술 블로그(서브모듈 thakicloud.github.io/, Jekyll Minimal-Mistakes)의 콘텐츠 관리.
포맷 결정론은 [[sonnet-format-determinism]]을 따른다 — 모델은 글 본문만, 카운트·priority·
published 토글·집계는 결정론 코드가 소유한다. 모든 배포 글은 [[humanizer]] 통과가 게이트이고,
한국어 글은 humanizer 직후 [[korean-tone-reviewer]]로 합니다체 격식을 통일한다(humanizer는 AI 흔적만
제거하고 격식/경어는 보장하지 않으므로 별도 register 게이트 필수 — 2026-06-22 컬처 5편 배포 시 humanizer
후 별도 합니다체 변환이 또 필요했던 사고).
메커니즘 (사용자 결정)
- 250 cap = 언어별(ko/en/ar 각 250).
published: false로 공개 배포에서 제외(파일은 repo에
남아 jekyll serve --unpublished로 로컬 확인 가능 — 삭제 아님).
- 1넣고1빼기 = blog_plan.py가 곧 엔진: 항상 언어별 상위 우선순위만 published 유지. 새 글 추가
후 재실행하면 최저 우선순위가 자동으로 published:false. 별도 로직 불필요(idempotent).
결정론 스크립트 (scripts/, stdlib only, py3.12)
| 스크립트 | 역할 |
|---|
blog_inventory.py [--json] | _posts/<lang>/<cat>/ 스캔 → 카테고리별 카운트/manifest |
blog_plan.py [--json] | 카테고리 정책 + 250 backstop으로 post별 target_published 계산 |
blog_apply.py [--write] | 플랜을 front-matter published:에 최소-diff로 기록(기본 dry-run) |
blog_common.py | POLICY 표·VALID_CATEGORIES·front-matter 파서·set_published (공용) |
blog_category_check.py | ⛔ 카테고리 게이트: 모든 글의 디렉토리+front-matter categories:가 VALID_CATEGORIES 부분집합인지 검증(위반 exit 1). 배포 전 필수 |
실행은 절대경로 또는 repo 루트에서: python3 .claude/skills/tech-blog-manager/scripts/blog_plan.py.
BLOG_ROOT env로 블로그 경로 오버라이드(기본 <repo>/thakicloud.github.io).
⛔ 카테고리 = 폐쇄집합 11개 (blog_common.VALID_CATEGORIES — 코드가 강제)
블로그가 노출하는 카테고리는 딱 11개뿐이다. 이 집합 밖의 카테고리로 글을 만들면
_pages/<lang>/categories/에 페이지가 없어 카테고리 인덱스에서 도달 불가(전체 글 보기로만
보임) = 사고(2026-07-03: iaas/paas/saas/technique/만화/devops 등 stray 카테고리 83편 + 자유형
2차 카테고리 107건이 orphan). 신규/재작성 글의 categories: 첫 항목 = 디렉토리명 = 아래 11개
중 하나여야 하고, 2차 항목도 전부 이 집합이어야 한다. 자유형 라벨(AI, Kubernetes,
DevOps, ai-application 등)은 categories:가 아니라 tags: 에 넣는다.
| 카테고리(slug) | 나비 라벨 | tier | cap(목표 max) | 비고 |
|---|
| culture | 🎨 Culture | 100 | 전량(protected) | 삭제 금지, humanizer 재작성 |
| careers | 🤝 Careers | 100 | 전량(protected) | 삭제 금지 |
| owm | 📀 OWM | 90 | 10 | 신모델로 교체(refresh). 비메인 모델 → news |
| research | 📒 Research | 70 | 30 | 최신 30 |
| datasets | ☁️ Datasets | 60 | 11 | 최신 11 |
| llmops | 🤖 LLMOps | 55 | 35 | 핵심만 |
| agentops | 🏗️ AgentOps | 50 | 20 | 핵심만 |
| comics | 💬 Comics | 45 | 전량 | 홍보 만화(news-comic-strip 산출), 소수 keep-all |
| dev | 🚀 DevOps | 40 | 19 | K8s/vLLM/Ollama 스택 |
| tutorials | 💻 Tutorials | 10 | 20 | 핸즈온 |
| news | 🌐 News | 10 | 10 | 최신 company-fit only |
카테고리 추가 시: VALID_CATEGORIES·POLICY·_pages/<lang>/categories/<slug>.md·
_data/navigation.yml 4곳 모두 갱신. 넷 중 하나라도 빠지면 orphan/불일치. stray 디렉토리로
글을 만들지 말 것.
cap 합 ~168 < 250 → 신규 콘텐츠 헤드룸. cap은 "최신 N개(날짜순)"로 기계 적용.
큐레이션 오버라이드 (references/curation_overrides.json)
기계 cap 위에 사람 판단을 얹는다(결정론 유지):
refresh_categories: 해당 카테고리 기존 전량 unpublish(전면 교체용, 예: owm).
force_unpublish / force_publish: 특정 글 경로 강제.
워크플로
- 현황:
blog_inventory.py → 카테고리별 카운트 확인
- 플랜:
blog_plan.py → 언어별 published 수·변경 규모 확인 (dry)
- 적용:
blog_apply.py --write → published: 플래그 기록
- 신규/재작성: 카테고리 레시피(
references/category-recipes.md)를 콘텐츠 계약으로 따른다 —
카테고리마다 필수 산출물(이미지·아키텍처 도표·코드·소스/GitHub/HF 링크·GDrive 링크·ThakiCloud
관점 섹션)과 사용 스킬이 정해져 있다. 글만 올리지 않는다. 비주얼은 blog-author-pipeline.md
[3-D]를 따른다 — (0) NLM 슬라이드 갤러리가 기본 1차 비주얼([[nlm-deck-blog-visuals]],
NotebookLM 렌더 슬라이드를 그대로 사용, gpt-image-2 hero는 유지·폴백). 스타일은 포스트마다
랜덤 로테이션(사용자 지시 2026-06-30 — 매 글 같은 스타일로 굳지 않게 코드 소유 RNG가 큐레이션
풀에서 1개; 발표/소개 덱만 jobs 고정). humanizer 통과 → 한국어는
[[korean-tone-reviewer]]로 합니다체 격식 통일 → en/ar 번역
([[blog-i18n-sync]]) → _posts/<lang>/<cat>/에 배치 → 2~3 재실행(자동 드롭)
- 검증/배포: [[tech-blog-deploy]]로 로컬 serve / push
운영 목적(모든 글): 검색 유입 → 회사 홍보·채용·투자자 어필. research/owm/llmops/agentops는
ThakiCloud 관점/자랑 섹션 필수(category-recipes.md).
검증 (apply 전 필수)
blog_apply.py --write 전에 항상 dry-run으로 변경 규모를 확인한다 — front-matter 대량
재포맷(692-diff 폭발)·의도치 않은 unpublish를 사전 차단한다.
blog_plan.py --json → target_published 변경 건수 확인
- 변경 수가 예상 범위면 VERDICT: PASS →
blog_apply.py --write
- 변경 수가 비정상(예: 전 카테고리 unpublish)이면 VERDICT: FAIL →
curation_overrides.json 점검 후 재실행
twitter 연동
twitter-timeline-to-slack이 블로그 적합 주제 선정 시: 카테고리 배정 → humanizer 초안 →
해당 _posts/<lang>/<cat>/에 배치 → blog_apply.py --write(자동 1넣고1빼기). 상세 references 참조.
gotchas
set_published는 published 글에서 published: 줄을 제거(Jekyll 기본=published) → diff 최소.
unpublish 글에만 published: false 추가. YAML 전체 재포맷 금지(692개 diff 폭발 방지).
- 날짜는 파일명
YYYY-MM-DD-에서 파싱(front-matter date보다 신뢰). 파싱 실패 시 0000-00-00.
- owm/tutorials/news 과거 제거는 기본 unpublish(로컬 보존). 하드 삭제가 필요하면 명시 지시 후 git rm.