매뉴스크립트 · 컨텍스트 · 런타임의 3계층 분리
소설을 그대로 컨텍스트 윈도우에 밀어 넣지 않는다. 분석에서 추출한 구조화된 사실만 폴더에 적고,
그것을 MCP project-scoped facts로 sync하여 생성 시점에 search_facts로
필요한 만큼만 회수한다. 원본은 외부에 남는다.
매뉴스크립트는 외부에
raw 소설 파일은 --source 인자로 절대경로만 전달. 레포 안 source/·uploads/·private/는 git-ignore. MCP에도 동기화 금지.
컨텍스트는 폴더에
novel당 한 폴더(memory-bank/novels/{novel_id}/). canon, persona, world, visual seed가 사람이 읽고 수정 가능한 JSON/MD로 누적. ledger로 변경 추적.
런타임은 MCP에
sync 스크립트가 폴더를 project-scoped facts로 upsert. 생성·스토리보드·렌더링 시점에 search_facts / trace_fact로 회수.
소스 → 빌더 → 메모리뱅크 → MCP → 소비자
novel-builder.py가 매뉴스크립트를 분해하고,
memory-bank/novels/{novel_id}/를 작성한 뒤
novel-memory-bank-mcp-sync.mjs가 MCP에 facts를 upsert한다.
소비자는 storyboard, lettering, visual seed 매칭, continuity 검증.
novel-builder.py 내부 단계
extract_title → extract_characters → extract_chapters로 매뉴스크립트를 분해한 뒤,
profile에 정의된 known persona/world 정보와 병합하여 build_* 단계가 deterministic seed를 포함한 구조체를 생성한다.
마지막으로 run_sync가 Node 스크립트를 호출해 MCP에 upsert.
10개 컨텍스트 영역과 MCP 네임스페이스 매핑
각 영역은 한 가지 책임만 진다. 사실은 canon.md에,
변경 이력은 continuity-ledger.md에,
추측은 research/analysis-log.md에. 영역과 entity_id로 MCP 네임스페이스가 결정된다.
| Area | Path | Role | MCP namespace |
|---|---|---|---|
| manifest | manifest.json | id · version · ownership · analysis 상태 · context index | novel-toon:{id}:manifest:root |
| canon | context/canon.md | 변경 불가 스토리 사실. 분석 증거 있을 때만 추가 | novel-toon:{id}:canon:{fact_id} |
| timeline | context/timeline.md | chapter · episode · era · absolute date 단위 사건 | novel-toon:{id}:timeline:{event_id} |
| ledger | context/continuity-ledger.md | 결정 · retcon · contradiction · fix 이력 | novel-toon:{id}:ledger:{decision_id} |
| unresolved | context/unresolved-questions.md | 미해결 연구 질문 · ambiguity | novel-toon:{id}:unresolved:{q_id} |
| characters | characters/{char_id}.json | persona · goals · fears · speech · appearance anchor · 관계도 | novel-toon:{id}:character:{char_id} |
| world | world/{eras,settings,culture} | era · setting · culture · technology · magic · politics | novel-toon:{id}:world:{entity_id} |
| visual | visual/style-bible.md + image-seeds.json | style anchor · seed · photo seed · 음성 negative prompt | novel-toon:{id}:visual:{seed_id} |
| production | production/episodes/* · panels/* | episode 기획 · storyboard json · panel 메타데이터 | novel-toon:{id}:production:{ep_id} |
| research | research/{analysis-log,source-notes} | 분석 진행 로그 · 확증 전 speculation | novel-toon:{id}:research:{note_id} |
| source · uploads · private | source/ · uploads/ · private/ | raw 매뉴스크립트 · binary references · 비공개 | — ignored · sync 금지 — |
결정론적 sync, project-scoped retrieval
sync는 idempotent. 같은 폴더 상태로 두 번 실행해도 같은 facts. retrieval은 MCP의 4개 도구로 좁힌다 — 전체 컨텍스트를 끌어오지 않는다.
# 1) 매뉴스크립트 → 컨텍스트 폴더 + MCP 동기화 python3 scripts/novel-builder.py \ --project-root . \ --source /Users/me/blood-inheritance.md \ --novel-id blood-inheritance \ --sync --json # 2) 완료 게이트 — 통과 못하면 “완료” 선언 금지 python3 scripts/validate-novel-builder.py \ --project-root . \ --source /Users/me/blood-inheritance.md \ --novel-id blood-inheritance \ --require-mcp-sync --json # 3) 생성 시점 — MCP search_facts 로 좁혀 회수 project=/Users/jung-wankim/Project/novel-toon query="novel_id=blood-inheritance character=han-seoyun visual seed"
컨텍스트 부패를 막는 운영 규칙
장기 연재에서 가장 비싼 실패는 페르소나·비주얼 시드의 미세한 drift다. 규칙은 단순하다 — 바뀌면 ledger에 적고, raw는 절대 들어오지 않는다.
persona / visual drift 방지
- character persona 또는 image seed 변경 시
continuity-ledger.md에 entry 필수 - seed는
stable_seed(parts...)로 결정론적 파생 → 재실행해도 동일 시드 - seed 레코드에
locked=true표시된 항목은 ledger entry 없이 변경 금지 - style-bible 변경은 모든 후속 episode 재검토를 트리거
분석 신뢰도 분리
- 확증된 사실 →
canon.md - 분석 중 가설 →
research/analysis-log.md - 답 안 나온 질문 →
unresolved-questions.md - canon으로 승격하려면 evidence 인용 필수
privacy boundary (HARD)
memory-bank/novels/*/source/·uploads/·private/·visual/references/*는 git-ignore- raw 매뉴스크립트 MCP sync 절대 금지 (
sync_raw_manuscripts: false) - 구조화 요약(canon · persona · world · seed 메타)만 sync
- private 이미지 reference는 ID로만 참조
scope 격리
- novel 하나당 폴더 하나 — 글로벌 character/seed 파일 사용 금지
- MCP scope_type은
project고정 → cross-novel leak 차단 - namespace에
novel_id를 강제로 포함 - retrieval 쿼리에
novel_id=명시 권장
렌더링 단계로 흘러가는 두 가지 계약
memory-bank에서 회수한 컨텍스트는 storyboard JSON으로 결정화되고, 그 다음 두 계약을 통과해야 이미지/영상으로 나간다.
한국 웹툰 핸드 레터링 규약
- 일반 문서/자막/UI/세리프 폰트 금지. 한국 웹툰 핸드 레터링 톤만.
- 말풍선 안에는 대사 텍스트만. 화자명·콜론·괄호·캡션·메타데이터 금지.
- JSON의
speaker는 메타데이터로만 유지, 풍선에는text값만 렌더링. - 흰색 라운드 풍선 + 짧은 꼬리 + 충분한 패딩.
- 풍선은 네거티브 스페이스에 배치 — 얼굴·눈·중요한 손·증거 prop 위 금지.
- 짧은 자연스러운 한국어 라인 선호. 길면 한 풍선 안에서 두 줄로 분할.
- 한국어 최종 레터링은 Remotion / post-composition 텍스트 오버레이로 — 이미지 생성에 의존하지 않음.
패널 시각 다양성 규약
- 패널 2개 이상 생성 시 각각 고유한
visual_signature필수. - 인접 패널은 setting · camera distance · character set · core action · emotional beat 중 최소 1가지 이상 차이.
- 연속 패널에서 동일한 “앉은 사무실” 구도 재사용 금지.
- 한국어 대사는 Remotion 결정론적 풍선으로 — 이미지가 텍스트 렌더하지 않음.
- 영상 출력에는 텍스트 없는 배경 이미지 + 결정론적 오버레이 풍선 선호.