# task-3013 — 트렌드 수집 0건 원인 규명 (4개월째 · exit=0 인데 수집 0)

**레벨**: Lv.2 · **팀**: dev4-team (비슈누) · **회장 승인 완료** (2026-08-25)

## 배경 — 매일 도는데 4개월째 아무것도 안 쌓인다

**ANU 실측 (2026-08-25)**
```
public.trend_data          1,626행  마지막 유입 2026-04-30 19:21
public.trend_collection_runs   11행  마지막 2026-04-30 19:00
public.keywords            3,704행  마지막 2026-04-30 01:45
public.keyword_jobs             5행  마지막 2026-04-28
public.trend_keywords          30행  마지막 2026-04-23

cron:  0 6 * * *  /home/jay/projects/InsuRo/server/scripts/run_trend_pipeline.sh
→ 매일 정상 실행됨. 2026-08-25 06:00 로그:

  Step 0 season_calendar_check       완료 (exit=0)
  Step 1 daily_trend_collect         완료 (exit=0)     ← ★ 성공 코드인데
  Step 2 daily_saturation_collect    완료 (exit=0)
  Step 3 daily_ranking_calc          exit=1  "선행 작업 미완료로 종료"
  Step 4 daily_health_check          완료 (exit=0)

헬스체크 실측:
  ⚠️ 트렌드 수집: 0/2,000건 (기준 1,800)      ← 실제 수집 0
  ⚠️ 포화도 수집: 1,000/2,000건 (기준 1,800)  ← 절반만
  ⚠️ 랭킹 산출: 0건 (기준 1+)

daily_ranking_calc 로그:
  "keyword_trends 최근 7일(period_end >= 2026-08-18) 데이터가 없습니다"
  → 선행 데이터 부재로 정상 중단. 즉 Step 3 실패는 결과이지 원인이 아니다.
```

## ★ 핵심 — 두 겹의 문제다. 섞지 마라

### 문제 A: 트렌드 수집이 실제로 0건이다 (기능 고장)
Step 1(`daily_trend_collect.py`)이 **아무것도 못 가져온다.** 원인 미규명.

### 문제 B: 0건인데 `exit=0` 을 반환한다 (조용한 성공)
Step 1 이 실패를 성공으로 보고하므로 파이프라인이 계속 진행되고, **아무도 모른 채 4개월이 지났다.**
2026-08-25 하루에 발견된 같은 유형이 **다섯 건**이다(복합설계 저장 · 백업 · 드리프트 알림 ·
유튜브 러너 · 그리고 이것).

**A 를 고쳐도 B 를 안 고치면 다음 고장을 또 몇 달 뒤에 안다. 둘 다 대상이다.**

★ 참고: 알림 배선은 **이미 복구됐다**(task-3008, `alert_notify`).
내일 06:00 부터 이 경고가 회장 채팅방에 도달하기 시작한다. **정상이며 의도된 것이다.**

---

## 할 일

### ① 수집 0건 원인 규명 (조사 우선 · 추정 금지)
`server/scripts/daily_trend_collect.py` 가 왜 0건인지 **로그·실행으로 확정**하라.
흔한 원인:
- 외부 API 자격증명 만료/무효 (구글 트렌드 · 네이버 등)
- API 응답 형식 변경 → 파싱 결과 빈 배열
- 쿼터·레이트리밋 소진
- 입력 키워드 목록이 비어 있음(`keywords` 도 4/30 이후 정지 — **선행 단계가 먼저 죽었을 수 있다**)
- 예외를 삼키고 빈 결과 반환

★ **어느 단계에서 0 이 되는지** 짚어라. 입력이 0인가, 호출이 실패하는가, 파싱이 0인가.
★ `keyword_saturation` 은 **오늘도 쌓이고 있다**(116,000행). 즉 **일부 경로는 살아 있다.**
  살아 있는 경로와 죽은 경로의 **차이**가 원인의 실마리다.

### ② 조용한 성공 제거
0건 수집을 **성공으로 보고하지 않게** 한다.
- 기대 건수 대비 실제 건수를 판정해 **미달이면 실패로 종료**
- 기준치는 임의로 정하지 말고 **헬스체크가 이미 쓰는 기준**(1,800/2,000)과 정합을 맞춰라
- ★ 다만 **정상적으로 적은 날**(주말·공휴일·계절성)에 오탐이 나지 않게 하라.
  `season_calendar_check.py` 가 이미 있으니 그 맥락을 확인하라

### ③ 자격증명이 필요하면 보고
API 키 만료가 원인이면 **직접 발급·추측하지 말고 ANU 에 보고**하라.
무엇이 왜 필요한지, 어디서 발급받는지 명확히 적어라.

---

## ★ 이 태스크가 하지 않는 것
- **알림 배선**(task-3008 완료) · **백업**(task-3009 완료) · **유튜브 러너**(task-3011 진행 중) — 전부 범위 밖
- 트렌드 **기능 확장·UI 변경** — 지금은 "왜 안 되는가"만 본다
- `daily_ranking_calc.py` 수정 — Step 3 실패는 **결과**다. 선행이 살아나면 자연히 풀린다.
  다만 조사 중 별개 결함을 발견하면 **보고**하라

## 범위 · 금지
**수정 허용**: `server/scripts/daily_trend_collect.py` · `server/trend_collector.py` ·
`server/scripts/run_trend_pipeline.sh`(종료코드 판정부) · 관련 테스트

**금지**:
- `server/scripts/daily_health_check.py` · `alert_notify.py` — task-3008 결과물, 방금 복구됐다
- `server/policy_analyzer.py` · `server/silson/**` · `server/main.py` — 타 태스크 영역
- `src/**` · `extension/**` · `scripts/youtube-pipeline/**`
- 자격증명 값을 저장소에 커밋
- **DB 데이터 대량 삭제·변경** (조사는 읽기로)

## allowed_resources

```yaml
allowed_resources:
  paths:
    - "server/scripts/daily_trend_collect.py"
    - "server/scripts/run_trend_pipeline.sh"
    - "server/trend_collector.py"
    - "server/scripts/**"
    - "server/tests/**"
    - "memory/reports/task-3013.md"
  forbidden_paths:
    - "server/scripts/daily_health_check.py"
    - "server/scripts/alert_notify.py"
    - "server/policy_analyzer.py"
    - "server/silson/**"
    - "server/main.py"
    - "src/**"
    - "extension/**"
  commands:
    - "python3"
    - "pytest"
    - "bash"
  merge_policy: "tiered"
  ttl_hours: 72
```

## 검증
1. **0 이 되는 지점 특정** — 입력·호출·파싱 중 어디인지 로그로 제시
2. **살아 있는 경로와의 차이** — `keyword_saturation` 은 되는데 `trend_data` 는 안 되는 이유
3. **수정 후 실제 수집** — 실행해서 **행이 실제로 쌓이는지** 확인. 건수를 수치로 제시
   ★ 안 되면 "왜 안 되는지"를 확정해 보고하라. **고쳤다고 추정하지 마라**
4. **조용한 성공 제거 실증** — 0건 상황을 만들어 **exit≠0** 이 되는지 확인
5. **오탐 없음** — 정상적으로 적은 날에 실패로 잡히지 않는지 확인
6. **봉인** — `exit=0` 조용한 성공으로 되돌아가면 FAIL 하는 테스트. **변이로 실증**하라

## 운영 계약
- `origin/main`(=`997fa5d`) 기준 `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 에 보고하라.**

★ 백엔드는 2026-08-25 14:40 KST `997fa5d` 로 배포됐다. cron 은 **디스크 파일**을 직접 실행하므로
`/home/jay/projects/InsuRo` 가 최신인지 확인하라(ANU 실측: 오늘 이 저장소가 `2038bfb` 에 멈춰
`git pull` 이 조용히 실패하고 있던 사례가 있었다).

## 보고
**★★★ PR 생성까지가 범위다. 머지는 ANU 가 한다. 절대 직접 머지하지 마라.**
★ CI 워처가 `MERGE_READY` 를 내더라도 **자동 머지하지 마라.** 오늘 워처 경로 자동 머지가
**4회** 발생했고 그 통제를 복구하는 중이다(task-3012).
`memory/reports/task-3013.md` 작성 후 표준 완료 콜백 등록. 콜백 프롬프트 **UTF-8 3900 bytes 이하**.
★ 봉투 첫 줄에 **"0건 원인 규명 여부 + 수정 후 실제 수집 건수"** 를 담아라.