# task-3011 — 유튜브 파이프라인 러너 배포 (머지된 코드가 6시간마다 잠들고 있다)

**레벨**: Lv.2 · **팀**: dev2-team (오딘) · **회장 승인 완료** (2026-08-25)
**저장소**: `Jeon-Jonghyuk/InsuWiki` (`/home/jay/workspace/projects/insuwiki`, 기본 브랜치 **master**)

## 배경 — 코드는 완성됐는데 한 번도 실행되지 않았다

task-3001(PR #6, master `4911a99`)로 **유튜브 전사 → 요약 → wiki 카드 자동 게시** 경로가 완성됐다.
`firestore_writer.py` 가 `documents` 컬렉션에 `visibility='public'` · `docType='wiki'` 로 카드를 쓴다.

**그런데 실제 생성된 카드는 0건이다.**

### ANU 실측 (2026-08-25)
```
insuwiki-youtube-pipeline.timer   active · 6시간 주기 (마지막 13:38, 다음 19:38)
insuwiki-youtube-pipeline.service 매 실행 즉시 종료:

  [bootstrap] Phase 1 러너 미배포
    (/home/jay/projects/insuwiki/scripts/youtube-pipeline/run_pipeline.sh)
    — 구버전 실행 방지를 위해 보류
  → exit 0

부트스트랩: /home/jay/.local/bin/insuwiki-youtube-pipeline
  SCRIPT="${PIPELINE_RUNNER:-/home/jay/projects/insuwiki/scripts/youtube-pipeline/run_pipeline.sh}"
  [ -f "$SCRIPT" ] || { echo "...미배포..."; exit 0; }

실측: run_pipeline.sh 가
  - /home/jay/projects/insuwiki/scripts/youtube-pipeline/          에 없음
  - /home/jay/workspace/projects/insuwiki/scripts/youtube-pipeline/ 에도 없음
  - origin/master 에도 없음 (있는 것은 functions/run_pipeline.js — 다른 것)
```

★★ **`exit 0` 이라 systemd 는 `Finished`(성공)로 표시한다.** 실패로 잡히지 않는다.
즉 **타이머는 돌고, 서비스는 성공이라 하고, 실제로는 아무 일도 안 하는** 상태가 지속됐다.

이는 2026-08-25 하루에 발견된 **다섯 번째 "조용한 실패"** 다
(복합설계 저장 `ok:true`인데 전송 0 · 트렌드 `exit=0`인데 수집 0 · 백업 실패 무관측 ·
드리프트 알림 미배선 · **그리고 이것**).

---

## 할 일

### ① `run_pipeline.sh` 실체 파악 — 먼저 조사하라
- **원래 있었는데 사라진 것인가, 애초에 만들어지지 않은 것인가?**
  git 이력(`git log --all -- '*run_pipeline.sh'`)과 관련 태스크 기록을 확인하라
- 부트스트랩이 기대하는 **인터페이스(인자·환경변수·종료코드)** 를 파악하라
- Phase 1 파이프라인이 실제로 무엇을 해야 하는지는
  `scripts/youtube-pipeline/youtube_pipeline/main.py` 가 단일 소스다

★ 조사 결과 **"러너를 새로 써야 한다"** 면 그 사실을 명확히 보고하라.
기존 것을 복원하는 것과 새로 만드는 것은 위험도가 다르다.

### ② 러너 배포
- `run_pipeline.sh` 를 저장소에 두고(**단일 소유**), 부트스트랩이 찾는 경로에서 실행되게 한다
- ★ **경로 이원화 주의**: 부트스트랩은 `/home/jay/projects/insuwiki/` 를 본다.
  실제 작업 저장소는 `/home/jay/workspace/projects/insuwiki/` 다. **둘 다 존재하며 같은 master 를 가리킨다.**
  어느 쪽이 정본인지 확인하고, **한쪽만 최신인 상태를 만들지 마라**
- 전제조건(yt-dlp · Whisper GPU 서비스 · 자격증명) 검사를 러너가 하고,
  **못 갖춰졌으면 그 이유를 남기고 실패로 끝내라**

### ③ ★ `exit 0` 조용한 실패 제거 (핵심)
현재 부트스트랩은 러너가 없으면 **성공(exit 0)** 으로 끝난다. 이걸 고쳐라.
- 러너 부재·전제조건 미충족은 **실패로 종료**해 systemd 가 `failed` 로 잡게 한다
- ★ 단, **무한 재시도 루프를 만들지 마라.** 6시간 주기 타이머이므로 한 번 실패로 충분하다
- ★ InsuRo 쪽 `alert_notify` 배선(task-3008)은 **다른 저장소**다. 여기에 그대로 쓸 수 없다.
  실패를 알릴 수단이 있는지 조사하고 **제안만** 하라(구현은 별도)

### ④ 실제 1회 실행 성공 실증
- 러너를 배포한 뒤 **실제로 한 번 돌려** 파이프라인이 진행되는지 확인하라
- **wiki 카드가 실제로 생성되는지** 확인하라 (Firestore `documents`)
- ★ 영상 처리는 시간이 걸린다. 전체 완주가 어려우면 **어디까지 갔는지** 단계별로 기록하라.
  "실행됐다"와 "카드가 생겼다"를 **구분해서** 보고하라

---

## 범위 · 금지
**수정 허용**: `scripts/youtube-pipeline/**`(러너 신설) · `~/.local/bin/insuwiki-youtube-pipeline` ·
`~/.config/systemd/user/insuwiki-youtube-pipeline.*` · `memory/reports/task-3011.md`

**금지**:
- `firestore_writer.py` · `summarizer.py` · `drive_uploader.py` **로직 변경** — task-3001 결과물이다.
  러너는 이들을 **호출**만 한다. 결함을 발견하면 **보고만** 하라
- **요약 규격 변경**(1,500~2,000자 핵심 논지 재구성 · 숫자/면책 축약 금지) — 회장 확정 사항
- `.github/workflows/**` 백업 워크플로 — task-3009 결과물, 방금 성공 궤도에 올랐다
- `functions/**` (Cloud Functions `crawlYoutubeChannels` 는 별개 경로)
- **프로덕션 Firestore 데이터 삭제·대량 변경**
- 자격증명 값을 저장소에 커밋

## allowed_resources

```yaml
allowed_resources:
  paths:
    - "scripts/youtube-pipeline/**"
    - "docs/**"
    - "memory/reports/task-3011.md"
  forbidden_paths:
    - "scripts/youtube-pipeline/youtube_pipeline/firestore_writer.py"
    - "scripts/youtube-pipeline/youtube_pipeline/summarizer.py"
    - "scripts/youtube-pipeline/youtube_pipeline/drive_uploader.py"
    - ".github/workflows/**"
    - "functions/**"
    - "nextapp/**"
    - "firestore.rules"
  commands:
    - "bash"
    - "python3"
    - "systemctl"
    - "gh"
  merge_policy: "tiered"
  ttl_hours: 72
```

## 검증
1. **현재 상태 재현** — 지금 타이머 실행이 `bootstrap ... exit 0` 으로 끝나는 것을 기록
2. **러너 배포 후** — 실행이 실제로 진행되는지 로그로 제시
3. **wiki 카드 생성 확인** — Firestore `documents` 에서 신규 카드 실재 확인(있으면 문서 id 제시)
4. **실패가 실패로 잡히는지** — 전제조건을 일부러 깨고 실행해 systemd 가 `failed` 로 표시하는지
5. **기존 경로 무손상** — 임베딩/벡터검색(task-2989) · 백업(task-3009) 에 영향 없음 확인
6. **봉인** — `exit 0` 조용한 실패로 되돌아가면 FAIL 하는 테스트. **변이로 실증**하라

## 운영 계약
- `origin/master`(=`41190d5`) 기준 `git pull --ff-only` 후 시작
- ★ `gh` 호출 시 `GH_TOKEN="$BOT_GITHUB_TOKEN"` 주입 필수 (회장 개인 PAT 금지 — 감사기록 오염)
- 워크플로우 `/home/jay/workspace/prompts/DIRECT-WORKFLOW.md` · QC `/home/jay/workspace/teams/shared/QC-RULES.md`
- `WORKSPACE_ROOT=/home/jay/workspace` · `CHAT_ID=6937032012` · 수집자 key `ANU_KEY=c119085addb0f8b7`
- 완료 경로는 `finish-task.sh` 실행이 유일하다. 수동 `.done` 금지.
- **명세와 실측이 다르면 임의 판단하지 말고 ANU 에 보고하라.**

## 보고
**★★★ PR 생성까지가 범위다. 머지는 ANU 가 한다. 절대 직접 머지하지 마라.**
★ CI 워처가 `MERGE_READY` 를 내더라도 **자동 머지하지 마라.** 2026-08-25 에 워처 경로
자동 머지가 **4회**(t3006·t3007·t3008·t3009) 발생했고 그 통제를 복구하는 중이다.
`memory/reports/task-3011.md` 작성 후 표준 완료 콜백 등록. 콜백 프롬프트 **UTF-8 3900 bytes 이하**.
★ 봉투 첫 줄에 **"파이프라인 실제 실행 여부 + wiki 카드 생성 여부"** 를 **구분해서** 담아라.