# malfoy-meme-kit pipeline.yaml — 노드 정본: 설명/05_배선도/roster.json(v2). 생성 후 kit/pipeline/verify.py로 검증 version: malfoy-meme-kit/pipeline v1 title: 악역영애 말포이 영상 5편 — 에이전트 배선도 source: roster: /설명/05_배선도/roster.json (v2) graph_doc: /설명/03_파이프라인_그래프.md tools_doc: /설명/04_도구별_파이프라인.md paths: project_root: note: tool.script·input은 기준 상대경로. 키트 사본은 kit/tools/ 참조 actor_types: main: 메인 Claude (오케스트레이터·판정·병합) sub: Claude 서브에이전트 codex: codex CLI (gpt-image-2 이미지) flow: Google Flow · Gemini Omni (Aside 브라우저로 조작) eleven: ElevenLabs API (음악·대사·효과음) gpu: 로컬 GPU / 스크립트 큐 user: 사용자 (지시·반려 = 인터럽트) stages: - id: S0 name: 기획·리서치 nodes: [ref, r_meme, r_flow, r_pin, sb, sb3] - id: S1 name: 이미지 (codex) nodes: [img_design, img_frames, img_outfits, img_s6, img_v3, img_fix] - id: S2 name: 영상 (Flow via Aside) nodes: [flow_test, flow_b_v1, flow_b_ref, flow_b_extra, flow_b_v3, flow_b_v4] - id: S3 name: 매팅 (사람만 오려내기) nodes: [matte_rd, matte_gpu, matte_q1, matte_q2, matte_q4] - id: S4 name: 소리 (ElevenLabs) nodes: [au_v1_bgm, au_v1_vo, au_v1_sfx, au_v3_song, au_v3_vo, au_v4, au_v5_song] - id: S5 name: 코드 배경·효과 nodes: [mo_a, mo_b, mo_c, gpu_render] - id: S6 name: 편별 합성·render nodes: [c_v1, c_v2, c_v2_fix, c_v3o, c_v3, c_v4, c_v5, sema] - id: S7 name: 분석 정리 (효과·레이어) nodes: [fx_A, fx_B, fx_C, fx_D, fx_E, fx_merge, lay_v1, lay_v2, lay_v3, lay_v4, lay_merge] - id: S8 name: 문서·뉴스레터·배선도 nodes: - pr_P1 - pr_P2 - pr_P3 - pr_P4 - pr_merge - pipe_T1 - pipe_T2 - pipe_T3 - pipe_T4 - pipe_T5 - pipe_T6 - pipe_merge - graph - news_S1 - news_S2 - news_S3 - news_S4 - news_S5 - news_S6 - news_JA - news_JB - news_merge - wire - wire_prev counts: nodes: 77 edges: 113 interrupts: 15 nodes: - id: ref stage: S0 stage_name: 기획·리서치 name: 레퍼런스 확보 actor: main task: 인스타 릴스 로그인 벽 → 임베드 페이지에서 영상 주소 추출(Aside repl) → curl 다운로드 → 프레임 시트·스펙트로그램 분석 out: 00_ref/ref_DeKsEh0sBPy.mp4 (10초, ZZZ 쇼케이스 패러디) handler: research tool: name: Aside repl + curl + ffmpeg note: 인스타 임베드 페이지에서 영상 src 추출 → curl → 프레임 시트·스펙트로그램 reads: [] writes: [brief.reference] concurrency: null retry: null - id: r_meme stage: S0 stage_name: 기획·리서치 name: 밈 조사 actor: sub task: 악역영애 말포이 기원·해외 확산·바이럴 영상 형식·검색어 out: 00_ref/research-meme.md handler: research tool: name: Claude 서브에이전트 + Aside note: 웹 조사는 Aside(firecrawl 금지) reads: [rules] writes: [brief.meme_research] concurrency: &id001 limit: 8 slot: subagents note: 제작 서브에이전트 최대 8기 + 매팅 큐 2줄 retry: &id002 max: 1 'on': 워커 중단(재부팅·didn't finish) how: 산출 폴더 확인 후 '이어서 진행'(산출 멱등) - id: r_flow stage: S0 stage_name: 기획·리서치 name: Flow 조사 actor: sub task: Gemini Omni 크레딧 단가·에셋/첫프레임·정책·자동화 함정 out: 00_ref/research-flow.md handler: research tool: name: Claude 서브에이전트 + Aside reads: [rules] writes: [brief.flow_research] concurrency: *id001 retry: *id002 - id: r_pin stage: S0 stage_name: 기획·리서치 name: 핀터레스트 수집 actor: sub task: Aside로 검색어 15개 → 122장 수집·컨택트시트·시각 요소 노트 out: 00_ref/pinterest/NOTES.md handler: research tool: name: Claude 서브에이전트 + Aside + curl note: 검색어 15개, 무관 결과(Gacha Life 등) 전량 삭제 후 검색어 교체 reads: [rules] writes: [brief.pinterest] concurrency: *id001 retry: *id002 - id: sb stage: S0 stage_name: 기획·리서치 name: 스토리보드·EDL actor: main task: 편별 컷·박자·의상·소스 결정, 1편 편집 결정표 out: STORYBOARD.md · V1-EDL.md handler: plan tool: name: 메인 Claude out_files: [STORYBOARD.md, V1-EDL.md, 06_flow/*_jobs.json] reads: [brief.reference, brief.meme_research, brief.flow_research, brief.pinterest, rules, feedback] writes: - plan.episodes - plan.storyboard - plan.edl - plan.beat_grid - plan.image_batches - plan.flow_jobs - plan.credit_plan - budget.flow_credits - budget.eleven_credits concurrency: null retry: null - id: sb3 stage: S0 stage_name: 기획·리서치 name: 3편 OP 기획 (opus) actor: sub task: 160BPM 22컷 컷리스트·가사·이미지/Flow 프롬프트 설계 out: V3-STORYBOARD.md · v3_images.jsonl · v3_jobs.json handler: plan tool: name: Claude 서브에이전트(opus) out_files: [V3-STORYBOARD.md, v3_images.jsonl, 06_flow/v3_jobs.json] reads: [plan.storyboard, brief.pinterest, rules] writes: [plan.storyboard, plan.beat_grid, plan.image_batches, plan.flow_jobs] concurrency: *id001 retry: *id002 - id: img_design stage: S1 stage_name: 이미지 (codex) name: 캐릭터 시안 4종 actor: codex task: 포니·드릴·생머리·올백, 레퍼런스 프레임 -i 첨부, 병렬 4 out: 01_design/canon_*.png stat: 2.3분 handler: codex_batch tool: name: codex exec (gpt-image-2 $imagegen) script: _tools/imagegen_runner.py input: 01_design/design_r1.jsonl reads: [plan.image_batches, brief.reference, brief.pinterest, rules] writes: [assets.images, qa.verdicts, qa.retries] concurrency: &id003 limit: 4 slot: codex note: imagegen_runner.py PARALLEL=4, codex 전역 동시 8 상한 안쪽 retry: &id004 max: 1 'on': timeout how: 실패 행만 TIMEOUT=600으로 재실행(있는 파일 건너뜀, 멱등) counter: qa.retries fanout: kind: send dispatch: img_design__dispatch worker: img_design__job over: plan.image_batches.img_design sim_items: 4 gate: check: rows 전부 파일 존재·timeout 0 on_fail: send_failed_items_to_worker max_retries: 1 counter: qa.retries.img_design pass_node: img_design__pass - id: img_frames stage: S1 stage_name: 이미지 (codex) name: 1편 첫 프레임 8장 actor: codex task: '블루 #1E3CFF 배경, 카드 일러·클로즈업·전신·부채·헤어플립·대연회장·엔딩·턴어라운드' out: 02_frames/*.png stat: 3.9분 handler: codex_batch tool: name: codex exec (gpt-image-2 $imagegen) script: _tools/imagegen_runner.py input: 02_frames/frames_r1.jsonl reads: [plan.image_batches, assets.images, rules] writes: [assets.images, qa.verdicts, qa.retries] concurrency: *id003 retry: *id004 fanout: kind: send dispatch: img_frames__dispatch worker: img_frames__job over: plan.image_batches.img_frames sim_items: 8 gate: check: rows 전부 파일 존재·timeout 0 on_fail: send_failed_items_to_worker max_retries: 1 counter: qa.retries.img_frames pass_node: img_frames__pass - id: img_outfits stage: S1 stage_name: 이미지 (codex) name: 의상 7벌 actor: codex task: 교복·무도회·빗자루·귀족 드레스·겨울·배틀·아이돌 out: 02_frames/outfits/*.png stat: 5.0분 handler: codex_batch tool: name: codex exec (gpt-image-2 $imagegen) script: _tools/imagegen_runner.py input: 02_frames/outfits_r1.jsonl reads: [plan.image_batches, assets.images, rules] writes: [assets.images, qa.verdicts, qa.retries] concurrency: *id003 retry: *id004 fanout: kind: send dispatch: img_outfits__dispatch worker: img_outfits__job over: plan.image_batches.img_outfits sim_items: 7 gate: check: rows 전부 파일 존재·timeout 0 on_fail: send_failed_items_to_worker max_retries: 1 counter: qa.retries.img_outfits pass_node: img_outfits__pass - id: img_s6 stage: S1 stage_name: 이미지 (codex) name: 대연회장 귀족 드레스 1장 actor: codex task: S6 인월드 컷 재생성(1차 300초 타임아웃 → 600초 재시도 269초) out: 02_frames/S6_rococo.png stat: 4.5분 handler: codex_batch tool: name: codex exec (gpt-image-2 $imagegen) script: _tools/imagegen_runner.py input: 02_frames/s6_r2.jsonl reads: [plan.image_batches, assets.images, rules] writes: [assets.images, qa.verdicts, qa.retries] concurrency: *id003 retry: max: 1 'on': timeout how: 실패 행만 TIMEOUT=600으로 재실행(있는 파일 건너뜀, 멱등) counter: qa.retries observed: 1차 302초 timeout → TIMEOUT=600 재시도 269초 성공 gate: check: 파일 존재·timeout 0 on_fail: self_loop max_retries: 1 counter: qa.retries.img_s6 pass_node: img_s6__pass sim_retries: 1 - id: img_v3 stage: S1 stage_name: 이미지 (codex) name: 3편 일러 15장 actor: codex task: 대연회장·비 복도·로켓·무도회·빗자루·묘약·키아트 등 out: 02_frames/v3/*.png stat: 6.6분 handler: codex_batch tool: name: codex exec (gpt-image-2 $imagegen) script: _tools/imagegen_runner.py input: v3_images.jsonl note: 처음부터 TIMEOUT=600 reads: [plan.image_batches, assets.images, rules] writes: [assets.images, qa.verdicts, qa.retries] concurrency: *id003 retry: *id004 fanout: kind: send dispatch: img_v3__dispatch worker: img_v3__job over: plan.image_batches.img_v3 sim_items: 15 gate: check: rows 전부 파일 존재·timeout 0 on_fail: send_failed_items_to_worker max_retries: 1 counter: qa.retries.img_v3 pass_node: img_v3__pass - id: img_fix stage: S1 stage_name: 이미지 (codex) name: 내용↔파일명 대조 actor: main task: 병렬 생성 오귀속 교정(4/4, 3/8, 4/7, 8/15) out: 이름 교정된 이미지 handler: name_check tool: name: 메인 Claude + 컨택트시트 note: 내용↔파일명 육안 대조 → 임시 이름 거쳐 mv 교정 → 시트 재생성·재대조 reads: [assets.images] writes: [assets.images, qa.verdicts, qa.retries] concurrency: null retry: max: 2 'on': 내용↔파일명 불일치 how: 교정 후 재대조(자기 루프) counter: qa.retries gate: check: 컨택트시트 내용↔파일명 전부 일치 on_fail: self_loop max_retries: 2 counter: qa.retries.img_fix pass_node: img_fix__pass - id: flow_test stage: S2 stage_name: 영상 (Flow via Aside) name: Flow 정찰·360p 테스트 actor: sub task: 새 프로젝트·UI 셀렉터 문서화·T1/T2 테스트 out: 06_flow/FLOW-UI.md stat: 10 크레딧 handler: flow_test tool: name: Google Flow · Gemini Omni (Aside 브라우저) script: 06_flow/FLOW-UI.md note: 360p T1·T2, 크레딧 상한 30 reads: [assets.images, brief.flow_research, plan.flow_jobs, budget.flow_credits, rules] writes: [assets.clips, qa.verdicts, qa.retries, rules, budget.flow_credits, runtime.toolchain] concurrency: limit: 2 slot: flow retry: max: 1 'on': 테스트 불합격(scene>0.25 컷 분할 검출·블루 붕괴·얼굴 불일치) how: 교훈(프레임 모드·flat solid blue·One continuous shot)을 rules에 넣고 재테스트 counter: qa.retries gate: check: '테스트 게이트: 컷 분할 0(scene>0.25 검출 0)·블루 유지·얼굴 일관' on_fail: self_loop max_retries: 1 counter: qa.retries.flow_test pass_node: flow_test__pass - id: flow_b_v1 stage: S2 stage_name: 영상 (Flow via Aside) name: 1편 첫 프레임 11컷 actor: sub task: 720p 첫 프레임 모드, 재생성 0 out: 06_flow/v1 stat: 88 크레딧 was: flow_v1 handler: flow_batch tool: name: Google Flow · Gemini Omni (Aside 브라우저) script: 06_flow/FLOW-UI.md input: 06_flow/v1_jobs.json mode: first_frame credit_cap: 110 reads: [plan.flow_jobs, assets.images, runtime.toolchain, budget.flow_credits, rules] writes: [assets.clips, qa.verdicts, qa.retries, budget.flow_credits] concurrency: &id005 limit: 5 slot: flow note: 사용자 지시 동시 5~6, 정책·레이트 경고 0 retry: max: 1 'on': verdict=regen(컷 분할·블루 붕괴·얼굴 붕괴·기괴한 손/몸) how: 그 컷만 _r2 재생성 1회, 2회째도 흠이면 '채택(주의)'로 내려보내 후반 크롭·구간 선택으로 회피 counter: qa.retries observed: 재생성 0 fanout: kind: send dispatch: flow_b_v1__dispatch worker: flow_b_v1__job over: plan.flow_jobs.flow_b_v1 sim_items: 11 gate: check: '클립 판정: regen 대상 0' on_fail: send_failed_items_to_worker max_retries: 1 counter: qa.retries.flow_b_v1 pass_node: flow_b_v1__pass - id: flow_b_ref stage: S2 stage_name: 영상 (Flow via Aside) name: 참조(Ingredients) 4컷 actor: sub task: '@Malfoy 캐릭터 등록·동작 참조 영상, 블루 유지 약함 → 2컷 재생성' out: 06_flow/ref stat: 88 크레딧 was: flow_v1 handler: flow_batch tool: name: Google Flow · Gemini Omni (Aside 브라우저) script: 06_flow/FLOW-UI.md input: 06_flow/ref_jobs.json mode: ingredients credit_cap: '+60' reads: [plan.flow_jobs, assets.images, runtime.toolchain, budget.flow_credits, rules] writes: [assets.clips, qa.verdicts, qa.retries, budget.flow_credits] concurrency: *id005 retry: max: 1 'on': verdict=regen(컷 분할·블루 붕괴·얼굴 붕괴·기괴한 손/몸) how: 그 컷만 _r2 재생성 1회, 2회째도 흠이면 '채택(주의)'로 내려보내 후반 크롭·구간 선택으로 회피 counter: qa.retries observed: 블루 유지 약함 → 2컷 재생성(R1_orbit_blue_r2 등) fanout: kind: send dispatch: flow_b_ref__dispatch worker: flow_b_ref__job over: plan.flow_jobs.flow_b_ref sim_items: 4 sim_regen: 2 gate: check: '클립 판정: regen 대상 0' on_fail: send_failed_items_to_worker max_retries: 1 counter: qa.retries.flow_b_ref pass_node: flow_b_ref__pass - id: flow_b_extra stage: S2 stage_name: 영상 (Flow via Aside) name: 추가 9컷 + 2편 변신 actor: sub task: 첫+끝 프레임 V2_morph(드릴→포니) + 클립월용 의상 동작 8 out: 06_flow/extra stat: 71 크레딧 was: flow_v1 handler: flow_batch tool: name: Google Flow · Gemini Omni (Aside 브라우저) script: 06_flow/FLOW-UI.md input: 06_flow/extra_jobs.json mode: first_frame|first_last credit_floor: 650 reads: [plan.flow_jobs, assets.images, runtime.toolchain, budget.flow_credits, rules] writes: [assets.clips, qa.verdicts, qa.retries, budget.flow_credits] concurrency: *id005 retry: max: 1 'on': verdict=regen(컷 분할·블루 붕괴·얼굴 붕괴·기괴한 손/몸) how: 그 컷만 _r2 재생성 1회, 2회째도 흠이면 '채택(주의)'로 내려보내 후반 크롭·구간 선택으로 회피 counter: qa.retries fanout: kind: send dispatch: flow_b_extra__dispatch worker: flow_b_extra__job over: plan.flow_jobs.flow_b_extra sim_items: 9 gate: check: '클립 판정: regen 대상 0' on_fail: send_failed_items_to_worker max_retries: 1 counter: qa.retries.flow_b_extra pass_node: flow_b_extra__pass - id: flow_b_v3 stage: S2 stage_name: 영상 (Flow via Aside) name: 3편 7컷 actor: sub task: 무도회 컷 배경 흔들림 1회 재생성 out: 06_flow/v3 stat: 59 크레딧 was: flow_v1 handler: flow_batch tool: name: Google Flow · Gemini Omni (Aside 브라우저) script: 06_flow/FLOW-UI.md input: 06_flow/v3_jobs.json mode: first_frame credit_floor: 650 reads: [plan.flow_jobs, assets.images, runtime.toolchain, budget.flow_credits, rules] writes: [assets.clips, qa.verdicts, qa.retries, budget.flow_credits] concurrency: *id005 retry: max: 1 'on': verdict=regen(컷 분할·블루 붕괴·얼굴 붕괴·기괴한 손/몸) how: 그 컷만 _r2 재생성 1회, 2회째도 흠이면 '채택(주의)'로 내려보내 후반 크롭·구간 선택으로 회피 counter: qa.retries observed: 무도회 컷 배경 흔들림 1회 재생성 fanout: kind: send dispatch: flow_b_v3__dispatch worker: flow_b_v3__job over: plan.flow_jobs.flow_b_v3 sim_items: 7 sim_regen: 1 gate: check: '클립 판정: regen 대상 0' on_fail: send_failed_items_to_worker max_retries: 1 counter: qa.retries.flow_b_v3 pass_node: flow_b_v3__pass - id: flow_b_v4 stage: S2 stage_name: 영상 (Flow via Aside) name: 4편 빠른 동작 10컷 actor: sub task: 동시 5, 파일명 id 대조, Downloads 사본 삭제 out: 06_flow/v4 stat: 70 크레딧 was: flow_v4 handler: flow_batch tool: name: Google Flow · Gemini Omni (Aside 브라우저) script: 06_flow/FLOW-UI.md input: 06_flow/v4_jobs.json mode: first_frame credit_cap: 90 note: 3중 대조(프롬프트·제안 파일명·타일 의상), Downloads 사본 삭제 reads: [plan.flow_jobs, assets.images, runtime.toolchain, budget.flow_credits, rules] writes: [assets.clips, qa.verdicts, qa.retries, budget.flow_credits] concurrency: *id005 retry: max: 1 'on': verdict=regen(컷 분할·블루 붕괴·얼굴 붕괴·기괴한 손/몸) how: 그 컷만 _r2 재생성 1회, 2회째도 흠이면 '채택(주의)'로 내려보내 후반 크롭·구간 선택으로 회피 counter: qa.retries observed: 재생성 0, 734 → 664 fanout: kind: send dispatch: flow_b_v4__dispatch worker: flow_b_v4__job over: plan.flow_jobs.flow_b_v4 sim_items: 10 gate: check: '클립 판정: regen 대상 0' on_fail: send_failed_items_to_worker max_retries: 1 counter: qa.retries.flow_b_v4 pass_node: flow_b_v4__pass - id: matte_rd stage: S3 stage_name: 매팅 (사람만 오려내기) name: 매팅 방식 비교 actor: sub task: chromakey / rembg / HF remove-bg / 하이브리드 → matte.sh out: 05_matte/matte.sh handler: matte_dev tool: name: Claude 서브에이전트 script: 05_matte/matte.sh note: chromakey / rembg / HF remove-bg / 하이브리드 비교 reads: [assets.clips] writes: [runtime.toolchain] concurrency: *id001 retry: *id002 - id: matte_gpu stage: S3 stage_name: 매팅 (사람만 오려내기) name: GPU 포팅 actor: sub task: Windows Python + onnxruntime-directml (RX 6600) out: matte.sh --gpu stat: 1.4 → 0.09~0.5 초/프레임 handler: matte_dev tool: name: Windows Python + onnxruntime-directml script: 05_matte/bin/aimask_dml.py note: matte.sh --gpu, venv·모델·pip 캐시는 D:\_cache reads: [runtime.toolchain] writes: [runtime.toolchain] concurrency: *id001 retry: *id002 - id: matte_q1 stage: S3 stage_name: 매팅 (사람만 오려내기) name: 매팅 큐 1 (1편→추가) actor: gpu task: v1 10컷 → extra 9컷, CPU에서 시작해 GPU로 전환 out: 05_matte/v1 · extra was: matte_q handler: matte_queue tool: name: 로컬 GPU 큐 script: _tools/matte_queue.sh input: 06_flow/v1 → 06_flow/extra worker: 05_matte/matte.sh reads: [assets.clips, runtime.toolchain, runtime.slots] writes: [assets.mattes, runtime.incidents] concurrency: &id006 limit: 1 slot: matte_lines note: 큐 1줄 = 폴더 1개, 전체 2줄 retry: &id007 max: 1 'on': GPU 실패 how: 그 컷만 WSL CPU(rembg)로 재시도, .part.webm → 완료 시 이름 변경 - id: matte_q2 stage: S3 stage_name: 매팅 (사람만 오려내기) name: 매팅 큐 2 (참조·3편) actor: gpu task: ref 6 → 3편 블루 컷, 같은 폴더 이중 처리 막으려 체인 부모만 종료 out: 05_matte/ref · v3 was: matte_q handler: matte_queue tool: name: 로컬 GPU 큐 script: _tools/matte_queue.sh input: 06_flow/ref → 06_flow/v3 worker: 05_matte/matte.sh note: 같은 폴더 이중 처리 금지(체인 부모 PID만 종료) reads: [assets.clips, runtime.toolchain, runtime.slots] writes: [assets.mattes, runtime.incidents] concurrency: *id006 retry: *id007 - id: matte_q4 stage: S3 stage_name: 매팅 (사람만 오려내기) name: 매팅 큐 4편 actor: gpu task: Flow 결과가 떨어지는 대로 1분 간격 폴링, 10컷 out: 05_matte/v4 stat: 0.09 초/프레임 was: matte_q handler: matte_queue tool: name: 로컬 GPU 큐 script: _tools/matte_queue.sh input: 06_flow/v4 worker: 05_matte/matte.sh note: 1분 간격 폴링, 다운로드 중 파일은 20초 지나야 집음, 60분 새 파일 없으면 종료 reads: [assets.clips, runtime.toolchain, runtime.slots] writes: [assets.mattes, runtime.incidents] concurrency: *id006 retry: *id007 - id: au_v1_bgm stage: S4 stage_name: 소리 (ElevenLabs) name: 1편 BGM actor: eleven task: 후보 7 → 128BPM 일렉트로 스윙, 앞 0.92초 잘라 드롭 7.48초 정렬 out: 04_audio/bgm stat: 3,101 크레딧(1편 전체) was: au_v1 handler: eleven_music tool: name: ElevenLabs Music (composition_plan) script: 04_audio/_work/gen_music.py input: 04_audio/_work/bgm_*.request.json analyze: 04_audio/_work/analyze.py episode_cap: 25000 reads: [plan.beat_grid, plan.storyboard, budget.eleven_credits, rules] writes: [audio.candidates, audio.tracks, audio.beats, budget.eleven_credits, qa.verdicts, qa.retries] concurrency: &id008 limit: 2 slot: eleven note: 3개 이상 동시 요청 시 429 retry: &id009 max: 2 'on': 기준 충족 후보 0 또는 HTTP 429 how: 요청 JSON(composition_plan) 고쳐 다시 생성, 429는 동시 2개로 낮춰 재요청 counter: qa.retries gate: check: '후보 실측: BPM 128 근접 + 드롭 직전 숨 고르기' on_fail: self_loop max_retries: 2 counter: qa.retries.au_v1_bgm pass_node: au_v1_bgm__pass - id: au_v1_vo stage: S4 stage_name: 소리 (ElevenLabs) name: 1편 VO 오디션 actor: eleven task: 영국 10대 3명 → Emmaline, ASR로 gems 발음 필터, 1.2배 압축 out: 04_audio/vo was: au_v1 handler: eleven_tts tool: name: ElevenLabs TTS v4 script: 04_audio/_work/tts.py note: 오디션 3명 → Emmaline, ASR로 gems 오인식 테이크 _rejected/, 1.2배 압축 reads: [plan.storyboard, budget.eleven_credits, rules] writes: [audio.vo, audio.candidates, budget.eleven_credits, qa.verdicts] concurrency: *id008 retry: max: 1 'on': ASR 오인식 how: 테이크 2개씩, 오인식 테이크 버리고 재생성 - id: au_v1_sfx stage: S4 stage_name: 소리 (ElevenLabs) name: 효과음 19개 actor: eleven task: 가챠 클릭·금색 임팩트·망토 whoosh·도장·글리치 out: 04_audio/sfx was: au_v1 handler: eleven_sfx tool: name: ElevenLabs SFX script: 04_audio/_work/sfx.py input: 04_audio/_work/sfx_prompts.json reads: [plan.edl, budget.eleven_credits] writes: [audio.sfx, budget.eleven_credits] concurrency: *id008 retry: null - id: au_v3_song stage: S4 stage_name: 소리 (ElevenLabs) name: 3편 한국어 OP곡 actor: eleven task: 후보 21 → 보컬 분리 후 ASR 13자 중 11자, 브레이크 실측 out: 04_audio/v3/song stat: 9,938 크레딧(3편 전체) was: au_v3 handler: eleven_music tool: name: ElevenLabs Music + demucs + whisper script: 04_audio/v3/_work/gen_song.py analyze: 04_audio/v3/_work/analyze3.py asr: 04_audio/v3/_work/asr2.py master: 04_audio/v3/_work/build_master.py episode_cap: 25000 reads: [plan.beat_grid, plan.storyboard, budget.eleven_credits, rules] writes: [audio.candidates, audio.tracks, audio.beats, budget.eleven_credits, qa.verdicts, qa.retries] concurrency: *id008 retry: *id009 gate: check: '후보 실측: 정지 브레이크 + 정시 훅 + 가사 인식(보컬 분리 후 ASR)' on_fail: self_loop max_retries: 2 counter: qa.retries.au_v3_song pass_node: au_v3_song__pass - id: au_v3_vo stage: S4 stage_name: 소리 (ElevenLabs) name: 3편 한국어 VO actor: eleven task: 영애 Chaemong · 소년 Taemin, 엔딩 배치 제안 out: 04_audio/v3/vo was: au_v3 handler: eleven_tts tool: name: ElevenLabs TTS v4 script: 04_audio/v3/_work/tts.py eval: 04_audio/v3/_work/vo_eval.py fit: 04_audio/v3/_work/fit_vo.py reads: [plan.storyboard, budget.eleven_credits, rules] writes: [audio.vo, audio.candidates, budget.eleven_credits, qa.verdicts] concurrency: *id008 retry: max: 1 'on': ASR 오인식 how: 오인식 테이크 버리고 재생성 - id: au_v4 stage: S4 stage_name: 소리 (ElevenLabs) name: 4편 170BPM 곡 actor: eleven task: 후보 4 → 편집으로 브레이크·끝 히트 정렬 out: 04_audio/v4 stat: 1,324 크레딧 handler: eleven_music tool: name: ElevenLabs Music script: 04_audio/v4/_work/gen_music_v4.py analyze: 04_audio/v4/_work/analyze4.py master: 04_audio/v4/_work/build_master4.py sfx: 04_audio/v4/_work/sfx4.py episode_cap: 8000 reads: [plan.beat_grid, budget.eleven_credits, rules] writes: [audio.candidates, audio.tracks, audio.beats, audio.sfx, budget.eleven_credits, qa.verdicts, qa.retries] concurrency: *id008 retry: *id009 gate: check: '후보 실측: 빌드업 대비 드롭 크기' on_fail: self_loop max_retries: 2 counter: qa.retries.au_v4 pass_node: au_v4__pass - id: au_v5_song stage: S4 stage_name: 소리 (ElevenLabs) name: 5편 영어 곡 actor: eleven task: 후보 12 → E11, 3편과 같은 박 격자로 1.5초 잘라 정렬 out: 04_audio/v3/song/SONG_MAIN_EN stat: 5,112 크레딧 was: au_v5 handler: eleven_music tool: name: ElevenLabs Music + whisper script: 04_audio/v3/_work/gen_song_en.py asr: 04_audio/v3/_work/asr_en.py episode_cap: 10000 note: E11 채택, 3편과 같은 박 격자로 1.5초 잘라 정렬 reads: [audio.beats, audio.tracks, budget.eleven_credits, rules, feedback] writes: [audio.candidates, audio.tracks, audio.beats, budget.eleven_credits, qa.verdicts, qa.retries] concurrency: *id008 retry: *id009 gate: check: '후보 실측: 영어 가사 인식 + 3편 박 격자 정합' on_fail: self_loop max_retries: 2 counter: qa.retries.au_v5_song pass_node: au_v5_song__pass - id: mo_a stage: S5 stage_name: 코드 배경·효과 name: 모션 워커 A actor: sub task: 가챠 화면·S랭크 카드·이름판 + 공용 mm-lib out: 03_motion/compositions handler: motion_block tool: name: HyperFrames + Claude 서브에이전트 script: 03_motion/compositions/gacha_build.html lib: 03_motion/compositions/mm-lib.js lint: hyperframes check (lint 0) reads: [plan.storyboard, plan.edl, rules] writes: [blocks] concurrency: *id001 retry: *id002 - id: mo_b stage: S5 stage_name: 코드 배경·효과 name: 모션 워커 B actor: sub task: 키네틱 월·의상 변신 배경(박마다 패턴 교체) out: kinetic_wall · beat_cutin handler: motion_block tool: name: HyperFrames + Claude 서브에이전트 script: 03_motion/compositions/kinetic_wall.html also: 03_motion/compositions/beat_cutin.html note: 'audio.beats는 배선 없는 점선 의존: beats.json 실측(드롭 7.484)을 상수로 박음' reads: [plan.storyboard, blocks, audio.beats, rules] writes: [blocks] concurrency: *id001 retry: *id002 - id: mo_c stage: S5 stage_name: 코드 배경·효과 name: 모션 워커 C actor: sub task: 엔딩 도장·CRT 클립 월(생성 클립 12개) out: ending_stamp · clip_wall handler: motion_block tool: name: HyperFrames + Claude 서브에이전트 script: 03_motion/compositions/clip_wall.html also: 03_motion/compositions/ending_stamp.html note: 클립월 모니터 12대·ffmpeg 순차 reads: [plan.storyboard, blocks, assets.clips, rules] writes: [blocks] concurrency: *id001 retry: *id002 - id: gpu_render stage: S5 stage_name: 코드 배경·효과 name: render 가속 실측 actor: sub task: WSL/Windows GPU 실측 → 효과 없음, workers 수가 효과 out: _tools/RENDER-FAST.md · render-win.sh handler: render_bench tool: name: HyperFrames render 실측 script: _tools/render-win.sh doc: _tools/RENDER-FAST.md note: GPU 효과 없음, --workers 수가 효과 reads: [runtime.toolchain] writes: [runtime.toolchain] concurrency: *id001 retry: *id002 - id: c_v1 stage: S6 stage_name: 편별 합성·render name: 1편 합성 actor: sub task: HF 배경·전경 2패스 + ffmpeg 알파 + 덕킹 out: V1_SRANK_PULL.mp4 26.5초 handler: composite tool: name: HyperFrames 2패스 + ffmpeg 알파 + 덕킹 script: 07_render/v1/composite.py hf: 07_render/v1/hf sync: 07_render/v1/sync.sh qc: 07_render/v1/_qc reads: [assets.mattes, audio.tracks, audio.vo, audio.sfx, audio.beats, blocks, plan.edl, runtime.heavy, rules] writes: [renders, qa.verdicts, qa.retries] concurrency: &id010 limit: 2 slot: heavy note: _tools/heavy.sh flock 2슬롯 + nice, HyperFrames --workers ≤ 2(긴급)/4(슬롯 2개)/6(단독) retry: &id011 max: 3 'on': 컨택트시트 판정 실패(배치·박 정합·자막 안전지대) how: 드래프트 540p 라운드 r1→r2→r3, 합성 단계로 복귀 counter: qa.retries gate: check: '컨택트시트: 배치·박 정합·자막 안전지대' on_fail: self_loop max_retries: 3 counter: qa.retries.c_v1 pass_node: c_v1__pass - id: c_v2 stage: S6 stage_name: 편별 합성·render name: 2편 합성 actor: sub task: HF 배경 + 파이썬 가상 카메라·플래시·글리치 out: V2_AGENT_SHOWCASE.mp4 15.7초 handler: composite tool: name: HyperFrames 배경 + 파이썬 가상 카메라 script: 07_render/v2/tools/comp.py contact: 07_render/v2/tools/contact.sh reads: [assets.mattes, blocks, audio.tracks, runtime.heavy, rules] writes: [renders, qa.verdicts, qa.retries] concurrency: *id010 retry: max: 3 'on': 컨택트시트 판정 실패(배치·박 정합·자막 안전지대) how: 드래프트 540p 라운드 r1→r2→r3, 합성 단계로 복귀 counter: qa.retries observed: contact_r1~r2 gate: check: '컨택트시트: 배치·박 정합·자막 안전지대' on_fail: self_loop max_retries: 3 counter: qa.retries.c_v2 pass_node: c_v2__pass sim_retries: 1 - id: c_v2_fix stage: S6 stage_name: 편별 합성·render name: 2편 수정 actor: main task: 하단 자막 제거 재합성 · 음량 -13.3 LUFS · 업로드본 out: V2_AGENT_SHOWCASE.mp4 handler: fix tool: name: 메인 Claude + ffmpeg script: 07_render/v2/tools/comp.py note: 하단 자막 제거 재합성, -13.3 LUFS, 업로드본 reads: [renders, feedback, rules] writes: [renders] concurrency: *id010 retry: null - id: c_v3o stage: S6 stage_name: 편별 합성·render name: 3편 오버레이 actor: sub task: 타이틀 로고·가사 카라오케·크레딧·이름 카드 out: v3/overlays handler: motion_block tool: name: HyperFrames 오버레이 script: 07_render/v3/tools/sync_overlays.sh dir: 07_render/v3/overlays credits: 04_audio/v3/_work/credits.py reads: [audio.tracks, audio.beats, audio.vo, plan.storyboard] writes: [blocks] concurrency: *id001 retry: *id002 - id: c_v3 stage: S6 stage_name: 편별 합성·render name: 3편 장면 조립 actor: sub task: 22컷 Ken Burns·파티클·OP 전환, 실제 박 재정렬 out: V3_ROFAN_OP.mp4 30초 handler: composite tool: name: HyperFrames + ffmpeg overlay script: 07_render/v3/tools/build.py charcomp: 07_render/v3/tools/charcomp.sh finalize: 07_render/v3/tools/finalize.sh prep: 07_render/v3/tools/prep_assets.py reads: [blocks, assets.images, assets.clips, assets.mattes, audio.tracks, audio.vo, audio.beats, runtime.heavy, rules] writes: [renders, qa.verdicts, qa.retries] concurrency: *id010 retry: *id011 gate: check: '컨택트시트: 배치·박 정합·자막 안전지대' on_fail: self_loop max_retries: 3 counter: qa.retries.c_v3 pass_node: c_v3__pass - id: c_v4 stage: S6 stage_name: 편별 합성·render name: 4편 하이퍼 에딧 actor: sub task: 동작 정점 자동 추출 141조각 → 78컷 edl → comp4 out: V4_HYPER_EDIT.mp4 20.4초 handler: composite tool: name: 파이썬 numpy 프레임 합성 script: 07_render/v4/tools/comp4.py edl: 07_render/v4/tools/edl.py shots: 07_render/v4/tools/shots.py sheet: 07_render/v4/tools/sheet.py typo: 07_render/v4/tools/typo_build.py note: 동작 정점 141조각 → 78컷 edl reads: [assets.mattes, audio.tracks, audio.beats, audio.sfx, blocks, runtime.heavy, rules] writes: [plan.edl, renders, qa.verdicts, qa.retries] concurrency: *id010 retry: max: 3 'on': 컨택트시트 판정 실패(배치·박 정합·자막 안전지대) how: 드래프트 540p 라운드 r1→r2→r3, 합성 단계로 복귀 counter: qa.retries observed: v4_540_r1→r3 3라운드 gate: check: '컨택트시트: 배치·박 정합·자막 안전지대' on_fail: self_loop max_retries: 3 counter: qa.retries.c_v4 pass_node: c_v4__pass sim_retries: 2 - id: c_v5 stage: S6 stage_name: 편별 합성·render name: 5편 영어판 재render actor: sub task: v3를 v5로 복사 → 영어 카라오케 · 곡 교체 · 컷 격자 복원 out: V5_ROFAN_OP_EN.mp4 30초 was: au_v5 handler: composite tool: name: HyperFrames + ffmpeg overlay script: 07_render/v5/tools/build.py charcomp: 07_render/v5/tools/charcomp.sh finalize: 07_render/v5/tools/finalize.sh note: v3 복사 → 영어 카라오케·곡 교체·컷 격자 복원 reads: [renders, audio.tracks, audio.beats, blocks, runtime.heavy, rules] writes: [renders, qa.verdicts, qa.retries] concurrency: *id010 retry: *id011 gate: check: '컨택트시트: 배치·박 정합·자막 안전지대' on_fail: self_loop max_retries: 3 counter: qa.retries.c_v5 pass_node: c_v5__pass - id: sema stage: S6 stage_name: 편별 합성·render name: heavy.sh 세마포어 actor: gpu task: 무거운 render·ffmpeg 동시 2개 제한(과부하 사고 후 도입) out: WSL 재부팅 방지 handler: semaphore tool: name: flock 세마포어 script: _tools/heavy.sh note: 과부하(로드 160·RAM 2GB) 사고 후 도입, env -u TMPDIR reads: [runtime.toolchain, runtime.incidents] writes: [runtime.heavy, runtime.slots] concurrency: null retry: null - id: fx_A stage: S7 stage_name: 분석 정리 (효과·레이어) name: 효과 A 배경 블록 actor: sub task: 띠·마퀴·패턴 정리 out: _effects/A_blocks.md handler: section_worker tool: name: Claude 서브에이전트 reads: [renders, blocks, assets.mattes, audio.tracks] writes: [docs] concurrency: &id012 limit: 12 slot: doc_subagents note: 읽기 위주 문서 워커 순간 10~12기 retry: *id002 section_group: fx - id: fx_B stage: S7 stage_name: 분석 정리 (효과·레이어) name: 효과 B 1·2편 actor: sub task: 전환·임팩트·카메라 out: _effects/B_v1v2.md handler: section_worker tool: name: Claude 서브에이전트 reads: [renders, blocks, assets.mattes, audio.tracks] writes: [docs] concurrency: *id012 retry: *id002 section_group: fx - id: fx_C stage: S7 stage_name: 분석 정리 (효과·레이어) name: 효과 C 3·5편 actor: sub task: 반짝임·OP 전환·카라오케 out: _effects/C_v3v5.md handler: section_worker tool: name: Claude 서브에이전트 reads: [renders, blocks, assets.mattes, audio.tracks] writes: [docs] concurrency: *id012 retry: *id002 section_group: fx - id: fx_D stage: S7 stage_name: 분석 정리 (효과·레이어) name: 효과 D 4편 actor: sub task: 78컷 효과 횟수 집계 out: _effects/D_v4.md handler: section_worker tool: name: Claude 서브에이전트 reads: [renders, blocks, assets.mattes, audio.tracks] writes: [docs] concurrency: *id012 retry: *id002 section_group: fx - id: fx_E stage: S7 stage_name: 분석 정리 (효과·레이어) name: 효과 E 매팅·오디오 actor: sub task: 키잉·덕킹·LUFS out: _effects/E_matte_audio_gen.md handler: section_worker tool: name: Claude 서브에이전트 reads: [renders, blocks, assets.mattes, audio.tracks] writes: [docs] concurrency: *id012 retry: *id002 section_group: fx - id: fx_merge stage: S7 stage_name: 분석 정리 (효과·레이어) name: 효과 병합 actor: sub task: 367행 → 278 용어, 누락 0 대조 out: EFFECTS.md handler: merge tool: name: Claude 서브에이전트 note: 367행 → 278 용어, 누락 0 대조 reads: [docs] writes: [docs, qa.verdicts] concurrency: null retry: null - id: lay_v1 stage: S7 stage_name: 분석 정리 (효과·레이어) name: 레이어 1편 actor: sub task: 코드|AI|완성 비교 6장 out: _layers/v1 handler: section_worker tool: name: Claude 서브에이전트 + ffmpeg 프레임 추출 note: ffmpeg 순차, /mnt/d 전체 find 금지 reads: [renders, blocks, assets.images, assets.clips, assets.mattes, plan.edl] writes: [docs] concurrency: *id012 retry: *id002 section_group: lay - id: lay_v2 stage: S7 stage_name: 분석 정리 (효과·레이어) name: 레이어 2편 actor: sub task: 비교 6장 out: _layers/v2 handler: section_worker tool: name: Claude 서브에이전트 + ffmpeg 프레임 추출 note: ffmpeg 순차, /mnt/d 전체 find 금지 reads: [renders, blocks, assets.images, assets.clips, assets.mattes, plan.edl] writes: [docs] concurrency: *id012 retry: *id002 section_group: lay - id: lay_v3 stage: S7 stage_name: 분석 정리 (효과·레이어) name: 레이어 3·5편 actor: sub task: 비교 6장 out: _layers/v3 handler: section_worker tool: name: Claude 서브에이전트 + ffmpeg 프레임 추출 note: ffmpeg 순차, /mnt/d 전체 find 금지 reads: [renders, blocks, assets.images, assets.clips, assets.mattes, plan.edl] writes: [docs] concurrency: *id012 retry: *id002 section_group: lay - id: lay_v4 stage: S7 stage_name: 분석 정리 (효과·레이어) name: 레이어 4편 actor: sub task: 78컷 출처 집계 + 비교 6장 out: _layers/v4 handler: section_worker tool: name: Claude 서브에이전트 + ffmpeg 프레임 추출 note: ffmpeg 순차, /mnt/d 전체 find 금지 reads: [renders, blocks, assets.images, assets.clips, assets.mattes, plan.edl] writes: [docs] concurrency: *id012 retry: *id002 section_group: lay - id: lay_merge stage: S7 stage_name: 분석 정리 (효과·레이어) name: 레이어 병합 actor: main task: 24장 + 편별 요약 out: 설명/01_코드vsAI.md handler: merge tool: name: 메인 Claude reads: [docs] writes: [docs] concurrency: null retry: null - id: pr_P1 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 원문집 이미지 actor: sub task: codex 프롬프트 33개 out: _prompts/P1 handler: section_worker tool: name: Claude 서브에이전트 reads: [assets.images, plan.image_batches] writes: [docs] concurrency: *id012 retry: *id002 section_group: pr - id: pr_P2 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 원문집 영상 actor: sub task: Flow 프롬프트 43개 out: _prompts/P2 handler: section_worker tool: name: Claude 서브에이전트 reads: [assets.clips, plan.flow_jobs] writes: [docs] concurrency: *id012 retry: *id002 section_group: pr - id: pr_P3 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 원문집 소리 actor: sub task: 곡·대사·효과음 원문 out: _prompts/P3 handler: section_worker tool: name: Claude 서브에이전트 reads: [audio.candidates, audio.tracks, audio.vo, audio.sfx] writes: [docs] concurrency: *id012 retry: *id002 section_group: pr - id: pr_P4 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 원문집 규칙·공식 actor: sub task: 지시 타임라인·조립 공식 out: _prompts/P4 handler: section_worker tool: name: Claude 서브에이전트 reads: [rules, feedback] writes: [docs] concurrency: *id012 retry: *id002 section_group: pr - id: pr_merge stage: S8 stage_name: 문서·뉴스레터·배선도 name: 원문집 병합 actor: main task: 2,300줄·비밀값 검사 0 out: 설명/02_프롬프트_원문집.md handler: merge tool: name: 메인 Claude note: 비밀값 검사 0 reads: [docs] writes: [docs, qa.verdicts] concurrency: null retry: null - id: pipe_T1 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 파이프라인 Aside actor: sub task: Flow 자동화 함정 23개 out: _pipeline/T1 handler: section_worker tool: name: Claude 서브에이전트 reads: [runtime.toolchain, runtime.incidents, runtime.resume_log, qa.verdicts, budget] writes: [docs] concurrency: *id012 retry: *id002 section_group: pipe - id: pipe_T2 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 파이프라인 codex actor: sub task: 병렬 러너·오귀속 out: _pipeline/T2 handler: section_worker tool: name: Claude 서브에이전트 reads: [runtime.toolchain, runtime.incidents, runtime.resume_log, qa.verdicts, budget] writes: [docs] concurrency: *id012 retry: *id002 section_group: pipe - id: pipe_T3 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 파이프라인 매팅 actor: sub task: GPU 큐 out: _pipeline/T3 handler: section_worker tool: name: Claude 서브에이전트 reads: [runtime.toolchain, runtime.incidents, runtime.resume_log, qa.verdicts, budget] writes: [docs] concurrency: *id012 retry: *id002 section_group: pipe - id: pipe_T4 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 파이프라인 합성 actor: sub task: 편별 합성·render 함정 out: _pipeline/T4 handler: section_worker tool: name: Claude 서브에이전트 reads: [runtime.toolchain, runtime.incidents, runtime.resume_log, qa.verdicts, budget] writes: [docs] concurrency: *id012 retry: *id002 section_group: pipe - id: pipe_T5 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 파이프라인 오디오 actor: sub task: 후보→실측→정렬 out: _pipeline/T5 handler: section_worker tool: name: Claude 서브에이전트 reads: [runtime.toolchain, runtime.incidents, runtime.resume_log, qa.verdicts, budget] writes: [docs] concurrency: *id012 retry: *id002 section_group: pipe - id: pipe_T6 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 파이프라인 지휘 actor: sub task: 에이전트 53기·메시지 29통 out: _pipeline/T6 handler: section_worker tool: name: Claude 서브에이전트 reads: [runtime.toolchain, runtime.incidents, runtime.resume_log, qa.verdicts, budget] writes: [docs] concurrency: *id012 retry: *id002 section_group: pipe - id: pipe_merge stage: S8 stage_name: 문서·뉴스레터·배선도 name: 파이프라인 병합 actor: main task: 6섹션 1,300줄 out: 설명/04_도구별_파이프라인.md handler: merge tool: name: 메인 Claude reads: [docs] writes: [docs] concurrency: null retry: null - id: graph stage: S8 stage_name: 문서·뉴스레터·배선도 name: 파이프라인 그래프 actor: sub task: LangGraph식 그래프·시퀀스·의사코드, mmdc 3장 out: 설명/03_파이프라인_그래프.md handler: section_worker tool: name: Claude 서브에이전트 + mmdc note: 렌더 시 env -u TMPDIR reads: [docs, plan.storyboard, feedback] writes: [docs] concurrency: *id012 retry: *id002 - id: news_S1 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 뉴스레터 도입 actor: sub task: gn-voice 작성 out: _newsletter/S1 handler: section_worker tool: name: Claude 서브에이전트 + gn-voice reads: [docs] writes: [docs] concurrency: *id012 retry: *id002 section_group: news - id: news_S2 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 뉴스레터 이미지 actor: sub task: gn-voice 작성 out: _newsletter/S2 handler: section_worker tool: name: Claude 서브에이전트 + gn-voice reads: [docs] writes: [docs] concurrency: *id012 retry: *id002 section_group: news - id: news_S3 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 뉴스레터 영상 actor: sub task: gn-voice 작성 out: _newsletter/S3 handler: section_worker tool: name: Claude 서브에이전트 + gn-voice reads: [docs] writes: [docs] concurrency: *id012 retry: *id002 section_group: news - id: news_S4 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 뉴스레터 코드 actor: sub task: gn-voice 작성 out: _newsletter/S4 handler: section_worker tool: name: Claude 서브에이전트 + gn-voice reads: [docs] writes: [docs] concurrency: *id012 retry: *id002 section_group: news - id: news_S5 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 뉴스레터 소리 actor: sub task: gn-voice 작성 out: _newsletter/S5 handler: section_worker tool: name: Claude 서브에이전트 + gn-voice reads: [docs] writes: [docs] concurrency: *id012 retry: *id002 section_group: news - id: news_S6 stage: S8 stage_name: 문서·뉴스레터·배선도 name: 뉴스레터 지휘 actor: sub task: gn-voice 작성 out: _newsletter/S6 handler: section_worker tool: name: Claude 서브에이전트 + gn-voice reads: [docs] writes: [docs] concurrency: *id012 retry: *id002 section_group: news - id: news_JA stage: S8 stage_name: 문서·뉴스레터·배선도 name: 문체 판정 앞 actor: sub task: C → 수정 12문장 out: 판정 결과 handler: judge tool: name: Claude 서브에이전트 (gn-voice-judge) note: C 등급 → 문장 단위 수정 지시 reads: [docs] writes: [qa.verdicts] concurrency: *id012 retry: null - id: news_JB stage: S8 stage_name: 문서·뉴스레터·배선도 name: 문체 판정 뒤 actor: sub task: C → 수정 14문장 out: 판정 결과 handler: judge tool: name: Claude 서브에이전트 (gn-voice-judge) note: C 등급 → 문장 단위 수정 지시 reads: [docs] writes: [qa.verdicts] concurrency: *id012 retry: null - id: news_merge stage: S8 stage_name: 문서·뉴스레터·배선도 name: 뉴스레터 병합·반영 actor: main task: 1인칭 교정·이미지 삽입·문장 26개 수정 out: 설명/00_뉴스레터.md handler: merge tool: name: 메인 Claude note: 1인칭 교정·이미지 삽입·문장 26개 수정 reads: [docs, qa.verdicts, feedback] writes: [docs] concurrency: null retry: null - id: wire stage: S8 stage_name: 문서·뉴스레터·배선도 name: 배선도 actor: sub task: 노드·배선·반려·시안 갤러리 out: 설명/05_배선도/index.html handler: section_worker tool: name: Claude 서브에이전트 note: 노드·배선·반려·시안 갤러리, roster.json 정본 reads: [docs, feedback] writes: [docs] concurrency: *id012 retry: *id002 - id: wire_prev stage: S8 stage_name: 문서·뉴스레터·배선도 name: 배선도 시안 에셋 actor: sub task: 노드별 썸네일·클립·곡 발췌 out: 05_배선도/assets handler: section_worker tool: name: Claude 서브에이전트 + ffmpeg note: 노드별 썸네일·클립·곡 발췌 reads: [assets.images, assets.clips, audio.tracks, renders] writes: [docs] concurrency: *id012 retry: *id002 edges: - [ref, sb] - [r_meme, sb] - [r_flow, sb] - [r_pin, sb] - [sb, sb3] - [sb, img_design] - [img_design, img_frames] - [img_design, img_outfits] - [img_frames, img_s6] - [img_outfits, img_s6] - [sb3, img_v3] - [img_frames, img_fix] - [img_outfits, img_fix] - [img_v3, img_fix] - [img_s6, img_fix] - [img_fix, flow_test] - [flow_test, flow_b_v1] - [flow_test, flow_b_ref] - [flow_test, flow_b_extra] - [flow_test, flow_b_v3] - [img_fix, flow_b_v4] - [matte_rd, matte_gpu] - [matte_gpu, matte_q1] - [matte_gpu, matte_q2] - [matte_gpu, matte_q4] - [flow_b_v1, matte_q1] - [flow_b_extra, matte_q1] - [flow_b_ref, matte_q2] - [flow_b_v3, matte_q2] - [flow_b_v4, matte_q4] - [sb, au_v1_bgm] - [sb, au_v1_vo] - [sb, au_v1_sfx] - [sb3, au_v3_song] - [sb3, au_v3_vo] - [au_v3_song, au_v5_song] - [sb, mo_a] - [mo_a, mo_b] - [mo_a, mo_c] - [gpu_render, sema] - [matte_q1, c_v1] - [au_v1_bgm, c_v1] - [au_v1_vo, c_v1] - [au_v1_sfx, c_v1] - [mo_a, c_v1] - [mo_b, c_v1] - [mo_c, c_v1] - [matte_q1, c_v2] - [mo_b, c_v2] - [mo_c, c_v2] - [c_v2, c_v2_fix] - [au_v3_song, c_v3o] - [c_v3o, c_v3] - [img_v3, c_v3] - [flow_b_v3, c_v3] - [matte_q2, c_v3] - [au_v3_vo, c_v3] - [c_v3, c_v5] - [au_v5_song, c_v5] - [matte_q4, c_v4] - [au_v4, c_v4] - [matte_q1, c_v4] - [mo_b, c_v4] - [sema, c_v4] - [c_v1, fx_A] - [c_v1, fx_B] - [mo_a, fx_A] - [c_v3, fx_C] - [c_v4, fx_D] - [matte_q1, fx_E] - [fx_A, fx_merge] - [fx_B, fx_merge] - [fx_C, fx_merge] - [fx_D, fx_merge] - [fx_E, fx_merge] - [c_v1, lay_v1] - [c_v2_fix, lay_v2] - [c_v5, lay_v3] - [c_v4, lay_v4] - [lay_v1, lay_merge] - [lay_v2, lay_merge] - [lay_v3, lay_merge] - [lay_v4, lay_merge] - [pr_P1, pr_merge] - [pr_P2, pr_merge] - [pr_P3, pr_merge] - [pr_P4, pr_merge] - [img_fix, pr_P1] - [flow_b_v4, pr_P2] - [au_v5_song, pr_P3] - [pipe_T1, pipe_merge] - [pipe_T2, pipe_merge] - [pipe_T3, pipe_merge] - [pipe_T4, pipe_merge] - [pipe_T5, pipe_merge] - [pipe_T6, pipe_merge] - [lay_merge, graph] - [news_S1, news_JA] - [news_S2, news_JA] - [news_S3, news_JA] - [news_S4, news_JB] - [news_S5, news_JB] - [news_S6, news_JB] - [lay_merge, news_S4] - [news_JA, news_merge] - [news_JB, news_merge] - [graph, news_merge] - [pr_merge, news_merge] - [pipe_merge, news_merge] - [graph, wire] - [pipe_merge, wire] - [wire_prev, wire] - [wire, news_merge] interrupts: - id: I01 quote: flow에는 이미지 기반 제작해야지 왜 순수 flow로 만들어 to: flow_test effect: 텍스트만 영상 생성 금지, 모든 컷 첫 프레임 지정 rule: 텍스트만 영상 생성 금지, 모든 컷 첫 프레임 지정 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' - id: I02 quote: 포니테일 많은 게 좋아, 40% 정도 to: img_design effect: 머리 비율 규칙 rule: 머리 비율 규칙 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' - id: I03 quote: 옷이 다 고정이잖아!!! 여러 옷 입히고 다양한 거 만들어야지 to: img_outfits effect: 의상 7벌 추가 rule: 의상 7벌 추가 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' - id: I04 quote: 뒤에 확확 올라오고 변화하는 거, 어썸 AI 모션 잘 써 to: mo_b effect: 코드 키네틱 배경 블록 7종 rule: 코드 키네틱 배경 블록 7종 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' - id: I05 quote: flow 레퍼런스로도 만들어봐 to: flow_b_ref effect: 참조(Ingredients) 모드 4건 rule: 참조(Ingredients) 모드 4건 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' - id: I06 quote: flow는 한 번에 5~6개 돌려도 됨 to: flow_b_v1 effect: 동시 5개 제출 rule: 동시 5개 제출 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' - id: I07 quote: 그냥 GPU 쓰면 되잖아 to: matte_gpu effect: DirectML 포팅 rule: DirectML 포팅 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' - id: I08 quote: 왜 아래쪽에 악역영애 말포이 좀 없애봐 to: c_v2_fix effect: 2편 하단 자막 제거 재합성 rule: 2편 하단 자막 제거 재합성 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' - id: I09 quote: 음악 영어로 (한국어 보컬 반려) to: au_v5_song effect: 영어판 5편 분리 rule: 영어판 5편 분리 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' - id: I10 quote: 도는 거 멋없다, 확확 바뀌는 거 v4로 to: c_v4 effect: 4편 하이퍼 에딧 신설 rule: 4편 하이퍼 에딧 신설 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' - id: I11 quote: 그 개쩌는 효과들 다 정리해서 MD로 줘봐, 멀티에이전트로 정리시키고 합치면 되잖아 to: fx_merge effect: 효과 섹션 5기 병렬 + 병합 rule: 효과 섹션 5기 병렬 + 병합 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' - id: I12 quote: 코드로 만든 부분과 이미지로 만든 부분의 차이를 확인할 거야 to: lay_merge effect: 편별 레이어 비교 24장 rule: 편별 레이어 비교 24장 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' - id: I13 quote: 뉴스레터는 내 스타일로, 멀티에이전트 넉넉히 to: news_merge effect: gn-voice 6섹션 병렬 + 판정 2 rule: gn-voice 6섹션 병렬 + 판정 2 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' - id: I14 quote: 예쁜 배선도로 각 에이전트 업무 확인, 각 부분 찍어서 보여줘 to: wire effect: 배선도 + 부분 캡처 rule: 배선도 + 부분 캡처 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' - id: I15 quote: 누르면 시안도 좀 뜨게, 더 세세하게 나눠, 옆 선 없애고 넓게 to: wire effect: 시안 갤러리·노드 세분화·배선 정리 rule: 시안 갤러리·노드 세분화·배선 정리 resume: 'rewind_to(to): 체크포인트 이력에서 to가 next인 지점으로 되감고 rules 추가 후 재실행' graph: realization: fanout_node: X → X__dispatch(Send) → X__job(워커, 아이템당 1회) → X(수집·판정) gated_node: 'X --조건 엣지--> {retry: X__job(실패 아이템만 Send) 또는 X(자기 루프), pass: X__pass}; X의 배선 출구는 X__pass' section_group: 멤버들의 선행 노드 합집합 → __dispatch(Send) → 멤버 N기 동시 → 병합 노드(대기 엣지) fan_in: 선행이 2개 이상인 노드는 대기 엣지 add_edge([preds], node) user_review: 산출물(deliverables) 출구 → user_review(interrupt) → END, 반려는 드라이버가 rewind_to(to) section_groups: fx: members: [fx_A, fx_B, fx_C, fx_D, fx_E] merge: fx_merge observed: 5기 동시 21:43 기동 → 21:46~21:49 전원 완료 lay: members: [lay_v1, lay_v2, lay_v3, lay_v4] merge: lay_merge observed: 10-08 11:00 레이어 4기 동시 pr: members: [pr_P1, pr_P2, pr_P3, pr_P4] merge: pr_merge observed: 12:02 프롬프트 4기 동시 pipe: members: [pipe_T1, pipe_T2, pipe_T3, pipe_T4, pipe_T5, pipe_T6] merge: pipe_merge observed: 12:02 파이프라인 6기 동시 news: members: [news_S1, news_S2, news_S3, news_S4, news_S5, news_S6] merge: news_merge judges: [news_JA, news_JB] observed: 11:00 기동 → 11:01 전원 완료 deliverables: [c_v1, c_v2_fix, c_v3, c_v4, c_v5, news_merge, wire] review_modes: none: 검토 정지 없음 deliverables: user_review 노드에서만 interrupt() all: deliverables + interrupt_after=[반려 대상 노드 14개(15건, wire 2건)] dotted_dependencies: - from: au_v1_bgm to: mo_b note: beats.json 실측 박 시각을 상수로 박음(배선 없음, 03 문서 점선) concurrency: subagents: limit: 8 why: 제작 서브에이전트 최대 8기 확인(19:56~19:58), 이 시점 과부하 사고 doc_subagents: limit: 12 why: 읽기 위주·출력 1파일, 순간 10~12기 heavy: limit: 2 why: 12코어·WSL RAM 11.7G에서 렌더 3기 동시가 병목 script: _tools/heavy.sh hf_workers: emergency: 2 two_slots: 4 solo: 6 matte_lines: limit: 2 why: 색차 키가 CPU라 한 줄로는 GPU 점유율 낮음 script: _tools/matte_queue.sh flow: limit: 5 max: 6 why: 사용자 지시 5~6, 정책·레이트 경고 0 eleven: limit: 2 why: 3개 이상 동시 요청 시 HTTP 429 codex: limit: 4 global_cap: 8 why: 러너 기본 PARALLEL=4, 한도는 계정 단위라 스폰 늘려도 처리량 복제 안 됨 budgets: flow_credits: start: 1050 end: 664 spent: 386 by_batch: flow_test: 10 flow_b_v1: 88 flow_b_ref: 88 flow_b_extra: 71 flow_b_v3: 59 flow_b_v4: 70 caps: flow_test: 30 flow_b_v1: 110 flow_b_ref: '+60' flow_b_extra: 잔액 650 아래 금지 flow_b_v3: 잔액 650 아래 금지 flow_b_v4: 90 unit_price_720p_frame_mode: 4s: 7 6s: 10 8s: 12 unit_price_ingredients_video_ref: 20 guard: 생성 직전 화면 비용 표시값으로 단가 검증, '실패·오류·정책' 표시 시 중단, 재생성은 컷당 1회 eleven_credits: unit: character_count spent: 19475 by_episode: V1: 3101 V3: 9938 V4: 1324 V5: 5112 caps: V1: 25000 V3: 25000 V4: 8000 V5: 10000 codex: parallel: 4 timeout_s: default: 300 retry: 600 global_cap: 8 effort: medium 이하 images: 약 35장(배치 5회 + timeout 재시도 1회)