만화 드라마 (소설 / 웹소설 / 만화 각색) · 5단계 파이프라인 (novel-video-pipeline)
개요
텍스트 스토리(웹소설, 만화, 오리지널 각본, 동화 그림책 등)를 안정적으로 스토리보드 프롬프트 팩 + 시각 참조 이미지 + CC0 더빙 및 배경 음악으로 변환하여 AI 영상 생성 모델에 입력할 수 있도록 하며, 전체 과정에서 실제 타사 저작권 이미지를 복제하지 않음을 보장합니다. 기본적으로 만화 드라마 (가로 16:9 / 시리즈 연재) 생산 라인을 대상으로 하며, 필요에 따라 아동용 만화 드라마, 단편 숏폼 비디오 등 하위 유형으로 전환할 수 있습니다. 생산 라인의 기본基调는 현재 인기 만화 드라마의 '강력한 후크 + 감정 끌어당김 + 반전 + 시원함 + 에피소드 간 서스펜스' 리듬을 따르지만, 방법론 수준의 골격만 차용하고 캐릭터 / 줄거리 / 화풍은 모두 오리지널입니다.
파이프라인은 네 개의 순차 작업 스테이션으로 구성되며, 각 스테이션은 약속된 JSON / 리소스 디렉토리를 출력하고 다음 스테이션은 이전 스테이션의 결과물을 소비합니다. 핵심 생산 순서: 먼저 에셋 라이브러리 구축 (S2), 그 다음 스토리보드 작성 (S3) — 스토리보드는 단지 에셋을 영화 언어로 배열하는 것일 뿐이며, 캐릭터 일관성과 장면 공간 연속성을 보장합니다.
S1 각색 각본 ──script.json──▶ S2 에셋 라이브러리 ──character_manifest + scene_manifest (+ visual_manifest)──▶ S3 스토리보드 프롬프트 ──storyboard.json (에셋 + ref_images 앵커 참조)──▶ S4 오디오 ──audio_manifest──▶ S5 합성 ──완성 영상
- S1 각색 각본: 장편/원문을 '교육 또는 서사 가치 골격 + 비트 시트'로 압축하여
script.json(title / logline / characters / scenes / beats) 출력. - S2 에셋 라이브러리 (먼저 구축): 전체 각본을 읽고 캐릭터 3뷰 에셋 (
character_manifest.json: visual_lock + front/side/back 3뷰 + 앵커 이미지 팩 + fixed_prompt)과 장면 정반대 다중 뷰 에셋 (scene_manifest.json: axis_of_action + establishing/OTS A→B/reverse/insert)을 구축하고, 퍼블릭 도메인 / CC0 시각 참조 이미지 (visual_manifest.json)를配套 가져옴. IP 방화벽 부정어 적용. 이 단계의 출력물이 '에셋 라이브러리'이며, S3에서 직접 참조. - S3 스토리보드 프롬프트 (에셋 라이브러리 기반): 각 beat를 샷으로 확장. 각 샷은
character_ref(캐릭터 + 뷰)와scene_ref(장면 + 뷰)를 참조하며, 에셋 라이브러리에서 설명 + 운镜库 (camera-movements.json) + 플랫폼 프리셋을 조합하여 프롬프트 생성,negative_prompt주입,storyboard.json출력. - S4 오디오: 샷에 CC0 BGM / 효과음 매칭,
audio_manifest.json출력. - S5 합성 (완성 영상으로 마무리): S3
storyboard.json(ref_images앵커 이미지 포함) + S4audio_manifest.json을 결합하여 완성 영상 생성 — 샷별 이미지 생성/이미지→비디오 (ref_images로 얼굴 고정) → 오디오 정렬 → 편집 및 연결 (duration_s및aspect_ratio기준) → 플랫폼 내보내기 → 일관성 최종 점검. 자세한 내용은references/s5-composite.md및scripts/build_ffmpeg_concat.py참조.
사용 시기 (트리거)
- 사용자가 스토리/소설/웹소설/만화/각본을 제공하며 '만화 드라마 / 숏폼 / 스토리보드 / 애니메이션으로 만들어 달라'고 요청.
- 사용자가 '각색 각본, 스토리보드 프롬프트 작성, 비디오 스크립트 생성, 화풍 매칭, 음악 매칭'을 원함.
- 사용자가 임의의 단일 스테이션 출력만 필요 (예: 스토리보드 프롬프트만, 또는 퍼블릭 도메인 참조 이미지만).
- 사용자가 자료에 대해 '저작권 깨끗함 / 상업적 사용 가능 / IP 리스크 제로'라는 엄격한 요구 사항을 가짐.
워크플로우
전체流程는 인기 오픈 소스 솔루션의 편성 방식을 참조하지만, 코드는 자체 개발, 에셋은 자체 포함:
- ViMax (MIT, ~392 커밋의 S1→S4 편성 파이프라인) → '스토리→스토리보드→비디오'의 단계 분할 및 산출물 계약 차용.
- seedance-prompt-skill / ai-shortfilm-prompts (MIT) → SKILL 형식의 프롬프트 템플릿 구성 방식을 차용하여 S3 기반으로 사용.
- ArcReel (AGPL) → 구조만 배우고 코드는 베끼지 않음 (AGPL 전염성으로 인해 본 MIT 스타일 스킬에 통합 금지). 자세한 내용은
references/architecture-licenses.md참조.
0단계 · 요구 사항 수신
4가지 확인: ① 원천 스토리 (웹소설 / 만화 / 오리지널 각본 / 게시물 또는 경로 제공); ② 대상 플랫폼 (가로 만화 드라마 기본 Bilibili / YouTube 방향, assets/s3/platform-presets.json의 bilibili 참조; 세로 TikTok / 위챗 영상호 방향은 douyin 사용); ③ 화풍 (중국풍 만화 / 수채화 / 사실적 / 우키요에 / 동화책 삽화…); ④ 하위 유형 및 대상 (기본 가로 16:9 만화 드라마, 인기 리듬에 맞추되 오리지널; 아동용인 경우 추가로 IP 방화벽 강제 + 성인 콘텐츠 제외).
1스테이션 · S1 각색 각본
assets/s1/story-structure.md(3막 / 비트 구조 템플릿) +assets/s1/adaptation-method.md(압축 방법론: 가치 골격 유지, 중복 제거, 감정 곡선) 로드.- 필요에 따라
assets/s1/beat-sheet.md(비트 시트 작성 가능) 작성. assets/s1/example-romeo-juliet.md,example-journey-to-west.md두 가지 각색 예시 참조.script.json출력, 필드는references/workflow.md§S1 계약 참조.
2스테이션 · S2 에셋 라이브러리 (먼저 구축, 그 다음 스토리보드 작성)
- S1의 모든 beats / characters / scenes를 읽고 캐릭터 에셋 구축:
assets/s2/character-design.md로드, 각 주요 캐릭터에 대해character_manifest.json(visual_lock + fixed_prompt + 3뷰 front/side/back + 앵커 이미지 팩 ref_pack + 일관성 규칙) 출력. - 장면 에셋 구축:
assets/s2/scene-multiview.md로드, 각 주요 장면에 대해scene_manifest.json(geography + axis_of_action + views{establishing, ots_a, ots_b, reverse, insert}) 출력. - 퍼블릭 도메인 / CC0 시각 참조 이미지
visual_manifest.json配套 가져오기/생성 (다양한 화풍: 중국풍 만화 / 수채화 / 사실적 / 동화책 삽화 / Met 공개 미술…), IP 방화벽 적용. - IP 방화벽 적용:
assets/s2/negative-ip.json+assets/s2/negative-ip-firewall.md. - 라이선스 게이트:
Public Domain/CC0만 수용. 캐릭터 / 장면 에셋은 모두 오리지널이어야 하며, 동명同설정의 인기 IP를 그대로 가져오는 것을 금지 (IP 방화벽 §6 참조).
3스테이션 · S3 스토리보드 프롬프트 (에셋 라이브러리 기반 작성)
-
assets/s3/template-library.json(스토리보드 템플릿 라이브러리: 샷 유형 / 화면 크기 / 감정) +assets/s3/camera-movements.json(운镜库: 40+ 운镜 + 비트→운镜 매핑 + 플랫폼 문법) +assets/s3/platform-presets.json(각 플랫폼 프롬프트 문법, 종횡비, 시간 제한) +assets/s3/tag-stats.json(태그 빈도 통계) +assets/s3/negative-quality.md(품질 부정어) +assets/s2/negative-ip.json(IP 방화벽) 로드. -
각 beat → 최소 하나의 샷; 각 샷은 필수로
character_ref와scene_ref를 포함 (S2 에셋 라이브러리 참조), 에셋fixed_prompt에서 잠긴 캐릭터 설명 가져오기;camera-movements.json에서 1개의 주 운镜 선택 (subject_aware_map이 beat 유형별 추천); 필수로negative_prompt포함 (IP 방화벽 + 품질 부정어 결합). -
storyboard.json출력:shots[{shot_id, beat_ref, character_ref[], scene_ref, ref_images[] (선택사항 · 앵커 이미지 직접 연결, 아래 '참조 이미지 앵커' 참조), camera_movement, shot_size, speed (선택사항 · 속도 수식어 slow_motion 등, camera-movements.json의 speed_modifiers 참조), prompt, prompt_readable, negative_prompt, platform, aspect_ratio, duration_s, attribution}]. 권력 변화 샷은camera_movement: low_angle/high_angle+speed: "slow_motion"사용 (작성법은assets/s2/scene-multiview.md§3 (보충) 권력 축 참조).참조 이미지 앵커 (ref_images, 샷 간 일관성의 핵심):
ref_images는 각 샷의앵커 이미지 직접 연결 목록이며, 순수 텍스트fixed_prompt보다 더 안정적입니다 (Jimeng @引用 / Runway Gen-4 단일 이미지 얼굴 고정에 정렬). 각 항목은 문자열이며, 두 가지 작성법이 약속되어 있습니다: ① 에셋 참조 토큰char:<char_id>:<ref_pack_key 또는 three_view_key>/scene:<scene_id>:<view>(스크립트가character_manifest.ref_pack에서 자동 추출, 생성기가 실제 이미지 경로로 해석); ② 직접 이미지 경로 / URL (예:/assets/char_shen_zhao_face.png). 각 캐릭터마다 2–3장 (정면 근접 / 측면 / 전신) 권장, Jimeng 최대 9장, Runway 단일 이미지로 고정.build_storyboard.py는 기본적으로 캐릭터ref_pack을 자동으로ref_images로 추출; S5 합성 시 이미지→비디오 모델에 직접 제공하여 얼굴/의상 고정 참조로 사용 가능. -
CC BY 4.0 데이터는 attribution 필수 포함 (본 라이브러리 에셋은 모두 PD/CC0, 기본적으로 署名 면제; 외부 CC BY 데이터 도입 시 반드시 attribution 작성).
-
스캐폴딩 가속 (선택사항): 먼저 S1
script.json+ S2character_manifest.json/scene_manifest.json구축 후,python scripts/build_storyboard.py --project <DIR> --platform bilibili실행하여storyboard.json초안 자동 생성 (beat별로character_ref/scene_ref자동 채움,subject_aware_map에서 1개 주 운镜 선택, beat 유형별 화면 크기 선택,negative_prompt拼接 IP 토큰全覆盖), 이후 수동으로 카메라 각도 / 감정 / 대사 / 리듬 정밀 수정. 이 스크립트는 '에셋 우선' 순서의 자동落地이며, 출력물은validate_pipeline.py에서 직접 통과 가능.
4스테이션 · S4 오디오
assets/s4/audio-manifest.json(이미 가져온 CC0 오디오 목록, BGM / 효과음 / 감정 카테고리 포함: ambient / cinematic / playful / tense / romantic / lullaby 등) 로드.- 샷 감정에 따라 매칭: 미스터리 저음→반전 부분, 부드러운 피아노→따뜻한 부분, whoosh→전환, lullaby→잠자는 부분, cartoon bounce→활발한 부분.
audio_manifest.json출력:items[{file, license, source, duration_ms}], CC0만.
5스테이션 · S5 합성 (완성 영상으로 마무리)
references/s5-composite.md(S5 합성 SOP: 5단계闭环 + 도구 매트릭스 + 일관성 최종 점검 목록) 로드. 1.5 앵커 이미지 해석:python scripts/resolve_ref_images.py --project <DIR>실행, 각 샷의ref_images토큰 (char:<id>:<key>/scene:<id>:<view>)을 실제 이미지 경로로 확장,storyboard.resolved.json출력 (해석되지 않은 토큰은 원래 문자열 유지 및 경고).- 샷별 이미지 생성 / 이미지→비디오:
storyboard.resolved.json의ref_images(해석된 실제 이미지)를 얼굴/의상 고정 참조로 사용,fixed_prompt+camera_movement+camera-movements.json의lens/stages와 함께 Jimeng @引用 / Runway Gen-4 / Kling / Seedance에 제공하여 각 클립 생성. - 오디오 정렬: beat 감정에 따라
audio_manifest.json(CC0)에서 BGM 선택,duration_s에 맞춰 효과음 자르기. - 편집 및 연결:
python scripts/build_ffmpeg_concat.py --project <DIR> --clips-dir <DIR>/clips실행하여 concat 목록과 명령 생성,aspect_ratio(가로 16:9)에 따라 1080p 내보내기. - 일관성 최종 점검: §4 목록 (캐릭터/장면/축/권력 축/시간/IP 방화벽/오디오/비율) 확인 후 게시.
6단계 · 접근 제어 검증 (필수)
scripts/validate_pipeline.py --project <DIR> --platform bilibili [--strict] [--content-rating {normal,child}] 실행, 4스테이션 산출물 계약 + 5가지 품질 게이트 검증: S3 각 샷의 negative_prompt 반드시 assets/s2/negative-ip.json의 모든 차단 IP 토큰을 포함해야 함 (실제 타사 저작권 이미지의 필요성 충족, 누락 시 strict에서 실패); 시간은 platform-presets.json 해당 플랫폼의 유효 집합에 속해야 하고, 비율은 일치해야 함 (가로 만화 드라마 기본 16:9); S4 오디오 시간 0.3–180초 (매우 짧은 효과음 허용). --strict에서는 warn도 실패로 처리. 통과 후에야 비디오 합성 가능.
콘텐츠 등급 (중요 · 기본적으로 소재 제한 없음): 접근 제어 기본값은 --content-rating normal — 어떠한 콘텐츠 등급 제한도 하지 않으며, 전투 / 폭력 / 미스터리 / 다크 등 성인 대상 소재도 정상적으로 생산 가능, 저작권 IP 방화벽과 에셋 계약만 준수. 아동용 생산 라인에만 --content-rating child (또는 이전 별칭 --child) 추가: S1에 '가치 마무리' 유형 비트 강제 포함, S3에 아동 안전 부정 토큰 (violence/gore/horror/blood/mature/nudity/weapon…) 포함, beats에서 성인 콘텐츠 감지 (strict에서 실패). 즉: --child는 순수 선택적인 '아동 안전 스위치'이며, 전달하지 않으면 만화 드라마 콘텐츠는 완전히 자유롭고 저연령화되지 않습니다.
가져오기 스크립트 (IP 리스크 제로)
두 스크립트는 표준 라이브러리 + 시스템 curl만 사용, pip install 불필요:
# S2 시각 에셋: OBI 퍼블릭 도메인 다양한 화풍 삽화 (동화책/중국풍 만화 포함) + Openverse CC0 이미지 + Met 공개 미술
python scripts/fetch_visual_assets.py --out <DIR> --sources obi,openverse,met
# S4 오디오: Openverse CC0 (키 불필요); PIXABAY/FREESOUND 키 입력 시 확장 채널 활성화
python scripts/fetch_audio.py --out <DIR>
- 품질 게이트 내장: 라이선스 (PD/CC0), 화질 (긴 변 ≥1000 및 짧은 변 ≥600, 파일 ≥50KB), 중복 제거 (SHA256 실행 간), 출처 게이트 (기관 출처만), 민감 게이트 (Openverse
mature=true는 모두 제외, 전 플랫폼 하드 요구 사항). - OBI 전송은
curl엔진 사용 (--retry 5 --retry-all-errors -k)하여 본 환경 Pythonurllib의 간헐적 SSL 연결 끊김 우회.
5가지 품질 게이트 (전 스테이션 공통)
- 라이선스 게이트: S2/S4는
Public Domain/CC0만 수용; CC BY 4.0 도입 시 반드시 attribution 포함. - 화질 게이트: 이미지 긴 변 ≥1000 및 짧은 변 ≥600; 오디오 시간 0.3–180초, 파일 ≥100KB.
- 중복 제거 게이트: SHA256 실행 간 지속, 중복 이미지/오디오 자동 건너뛰기.
- 출처 게이트: 기관급 / 퍼블릭 도메인 출처만 (OBI, Openverse, Met, Freesound CC0…); 알 수 없는 출처 거부.
- 민감 게이트: 모든 콘텐츠에서
mature제외 (아동용 추가 강화); S2/S3에 IP 방화벽 부정어 강제 주입, 알려진 저작권 이미지 차단; 인기 만화 드라마 / 웹소설 IP에 대해 소재 / 감정 / 시원함 구조 (방법론 수준)는 참조할 수 있지만, 캐릭터별, 장면별, 명장면을 완전히 그대로 가져오는 것 (완전 표절)은 금지.
IP 방화벽 (참조하되 그대로 가져오지 않음)
- 고정 부정어는
assets/s2/negative-ip.json참조, Peppa Pig, Disney, Marvel, Sanrio, Numberblocks, My Little Pony 등 등록된 실제 타사 저작권 이미지 포함 — 이는 하드 경계이며, 참조 여부와 관계없이 재현할 수 없음 (접근 제어가 토큰 포함을 강제 검증). - 만화 드라마 특별 규율 (참조하되 그대로 가져오지 않음): 인기 만화 드라마 / 웹소설 IP의 '소재 유형, 감정 구조, 시원함 패러다임, 영화 언어, 리듬'은 방법론 수준에 속하며, 저작권이 불가능하고 창작 영양분으로 사용 가능하며, 참조 장려; 그러나 완전 표절 금지 — 즉, 캐릭터별 그대로 가져오기 (동명同설정), 장면별 명장면 구도 복제, 시그니처 화풍/대표 색상 조합 직복제, 원문 대사 차용 불가. 사용자가 특정 인기 IP를指名해도, '재사용 가능한 방법론 골격'만 추출하고 '표현'은 추출하지 않으며, 오리지널 설명으로 변환 ('강한 운명감의 흑의 남주 + 홍의 여주 대치')하여 이미지/비디오 모델에 전송하고, negative prompt 이중 보험으로 실제 타사 저작권 이미지 차단.
- 본 스킬은 저작권 텍스트를 내장하지 않으며, 구조 / 작성법 수준 패러다임만 통계; 모든 예시는 공개 도메인 또는 사용자 자체 자료.
리소스
assets/s1/: 스토리 구조 템플릿, 각색 압축 방법론, 작성 가능한 비트 시트, 각본 형식 규범, 두 가지 각색 예시.assets/s2/: 부정어 사전negative-ip.json+ IP 방화벽 설명negative-ip-firewall.md+ 캐릭터 에셋 방법론character-design.md+ 장면 에셋 방법론scene-multiview.md.assets/s3/: 스토리보드 템플릿 라이브러리template-library.json, 운镜库camera-movements.json, 플랫폼 프리셋platform-presets.json, 태그 통계tag-stats.json, 품질 부정어negative-quality.md.assets/s4/: 이미 가져온 CC0 오디오 목록audio-manifest.json.scripts/:fetch_visual_assets.py(S2 이미지 가져오기),fetch_audio.py(S4 오디오 가져오기),build_storyboard.py(S1+S2 → S3 스토리보드 스캐폴딩 자동 생성,ref_images앵커 자동 추출 /power_dynamic자동 각도 선택 /--target-duration샷 예산 /--no-growth자기 성장 제안 끄기 지원),resolve_ref_images.py(S5에서ref_images토큰을 실제 이미지 경로로 해석,storyboard.resolved.json출력),build_ffmpeg_concat.py(S5에서 storyboard.json을 기반으로 FFmpeg 연결 목록 + 명령 생성),validate_pipeline.py(스테이션 간 접근 제어, 기본--content-rating normal콘텐츠 제한 없음;--content-rating child/--child는 아동용 하드 접근 제어 트리거),collect.py(자기 성장 수집 단말: 한 번의 실행 산출물 + 인간 평가 + 실패 로그를 메모리 서버로 회송),load_learnings.py(자기 성장 회송 단말: 메모리 서버에서learnings.json을 가져와 로컬에 캐시,build_storyboard.py가 높은 빈도 실패 패턴 제안을 읽도록 제공).memory_server/:server.py(제로 의존성 메모리 서비스, 4테이블 SQLite + Bearer 인증 + 속도 제한),growth.py(집계 →snapshot/learnings.json+ priors 회송),.env.example,README.md(Caddy HTTPS / systemd / cron 배포).references/:architecture-licenses.md(오픈 소스 솔루션 참조 및 라이선스 경계),workflow.md(4스테이션 상세 계약 및 사용법),case-studies.md(인기 만화 드라마/숏폼 드라마 운镜·스토리보드 문법 참조, 방법론 문헌, IP 그대로 가져오지 않음),benchmark.md(비교 평가: NVP vs ViMax/seedance/ai-shortfilm/ArcReel 등 점수 매트릭스 + 실증 자체 테스트),s5-composite.md(S5 합성 SOP: 5단계闭环 + 도구 매트릭스 + 일관성 최종 점검 목록).
주의 사항
- 대용량 이미지 라이브러리/오디오 라이브러리는 스킬에 내장되지 않음 (휴대성 유지); 런타임 시 스크립트로 가져오거나, 자체 CC0 자료 디렉토리 (예:
./assets/characters,S4-오디오-라이브러리/samples/등 로컬 클린 배치)를 가리키도록 함. - 본 스킬은 편성 방법론 + 자체 포함 에셋이며, ViMax/ArcReel 등 외부 코드에 의존하지 않음.
- BHL key / NYPL token 획득 후,
fetch_visual_assets.py에서fetch_bhl()/fetch_nypl()채널을 자체 추가 가능 (OBI는 키 불필요 확인 완료).
자기 성장 (선택사항 · 데이터闭环)
스킬이 사용에 따라 자기 성장하도록 함: 각 생산 라인 실행 후 객관적 지표 / 인간 평가 / 실패 로그를 메모리 데이터베이스에 회송, 집계 후 '높은 빈도 실패 패턴 제안 / 점수 / 스타일 신호'를 스킬에 회송, 다음 생성 시 미리 회피. 순수 표준 라이브러리, 제로 의존성, 소형 서버에 독립 배포 가능, 스킬 본체와 분리. 전체 배포는 memory_server/README.md 참조.
단일 기계 사용? 서버 배포 불필요.
NVP_MEMORY_URL을 설정하지 않으면collect.py/load_learnings.py가 자동으로 스킬 내 SQLite에 직접 연결 (memory_server/data/nvp_memory.db)하여 수집 후 자동 집계, 제로 구성으로 완전闭环 실행. '다중 기계汇总 / 다중 인원 협업 / 원격 회송'에만server.py기동 필요 (아래 '서비스 시작' 및 README §2 참조).
闭环 3단계:
- 수집 (생산 라인 실행 후):
python scripts/collect.py --project <DIR> --platform bilibili가script.json/storyboard.json/storyboard.resolved.json에서 beats / shots / 해석율 / 시간 등 지표를 자동 읽어 메모리 데이터베이스에 기록 (기본 로컬 SQLite;NVP_MEMORY_URL설정 시 서비스로 POST). 인간 평가--feedback 5 overall "리듬이 매우 시원함"또는 실패 로그--failures fails.json추가 가능. 오프라인 기계는--mirror ./mirror.json --dry-run으로 미러 생성, 나중에collect.py --sync ./mirror.json으로 서버에 동기화.--local로 로컬 강제,--remote로 서비스 경유 강제. - 집계 (로컬 자동 / 서버 예약): 로컬 모드에서는 수집 후 이미 자동 집계; HTTP 모드에서는 cron으로 매시간
python memory_server/growth.py실행, SQLite 4테이블을snapshot/learnings.json으로 집계, 안정적인 지식을priors테이블에 upsert. - 회송 (다음 생성 전):
python scripts/load_learnings.py실행,learnings.json을 읽어.cache/learnings.json에 캐시 (기본 로컬 스냅샷 읽기; URL 설정 시 원격 가져오기;--local로컬 강제,--no-fetch캐시만 읽기);build_storyboard.py가 자동 읽어 생성 시 '자기 성장 제안' 출력 (높은 빈도 실패 패턴 → 미리 회피, 예: 해석되지 않은 참조 이미지, 권력 축 샷 누락),--no-growth로 끄기 가능.
서비스 시작: python memory_server/server.py --no-auth (로컬 테스트) 또는 python memory_server/server.py (공개 네트워크, NVP_API_TOKEN 환경 변수 / --token 필요; Caddy 리버스 프록시로 TLS 처리). 엔드포인트: GET /health, POST /ingest, GET /query, GET /snapshot, GET /export.