# .cokacdir/debug 로그 회전 + runaway guard 정책안 (2026-06-05)

> 상태: **PROPOSAL (read-only 분석·정책안만). 실행 승인 전 시스템 미적용.**
> 인가 범위: 정책안 작성. 금지: 데몬 kill/restart·코어 수정·worktree 삭제·msg/claude truncate·GitHub write·정책 없는 설정 변경.

## 0. 배경 / 1차 정리 결과 (closed PASS)
- cron.log 55G runaway → truncate로 회수. worktree 127G + cron.log 55G = **~182G 회수**, 루트 여유 4.5G→**187G**.
- 그러나 cron.log은 truncate 후 **~4.3GB/일 재증가**(8분 24MB 실측) → 근본 방지 필요.

## 1. RCA 요약 — scheduler DEBUG 폭주 (인가 #5)
- writer: **PID `/usr/local/bin/cokacdir --ccserver`** (봇 서버/스케줄러 데몬, 코어).
- 파일 fd 상시 open 아님(lsof/fuser 무출력) = **append-then-close** 방식 → 외부 회전에 유리.
- 폭주 패턴: scheduler_loop가 **매 tick × 전 schedule 엔트리**마다 verbose DEBUG 기록:
  `[scheduler_loop] is_already_pending` / `[should_trigger] type=cron, schedule=…, last_run=…` /
  `[cron_matches] expr=…, minute(N)!=… → false` / `[read_schedule_entry] reading/result`
- 동시 write로 타임스탬프 겹침(`[[13:03:11.781…]`) → 고빈도 append. **크래시 아님 = verbosity 설계 자체가 원인.**
- 규모: cron.log ≈4.3GB/일 (주범). msg.log 3.8G(완만 증가). claude.log 625M(정체). 일자별 `YYYY-MM-DD.log`는 각 ~0.1–0.4MB(정상).

## 2. 설계 원칙
- **데몬 무중단**: kill/restart/코어 수정 없이 적용 가능한 외부 안전장치 우선 (인가 #6).
- append-close + 만일의 버퍼 보유 대비 → 회전은 **`copytruncate`** (원본 inode 유지·즉시 회수, 데몬 reopen 불필요).
- user 권한만으로 적용 (root /etc/logrotate.d 수정 불필요).

## 3. 1차 안전책 (외부, 즉시 적용 가능) — 인가 #1·#2·#6
### 옵션 A (권장): user logrotate + copytruncate
- 설정 파일(예): `~/.cokacdir/debug-logrotate.conf`
```
/home/jay/.cokacdir/debug/cron.log {
    size 500M
    rotate 5
    copytruncate
    compress
    delaycompress
    missingok
    notifempty
    nomail
}
/home/jay/.cokacdir/debug/msg.log {
    size 500M
    rotate 3
    copytruncate
    compress
    delaycompress
    missingok
    notifempty
    nomail
}
```
- 실행(독립 state, root 불필요): `logrotate -s ~/.cokacdir/logrotate.state ~/.cokacdir/debug-logrotate.conf`
- 스케줄: user crontab에 **매시** 추가(기존 `cleanup-stale-tasks.sh` hourly와 동일 cadence):
  `5 * * * * /usr/sbin/logrotate -s /home/jay/.cokacdir/logrotate.state /home/jay/.cokacdir/debug-logrotate.conf`
- 효과(추정): cron.log 4.3GB/일 → size 500M 도달 시 회전(매시 점검 ≈2.5h마다 1회), gzip ~10:1 → 보관본 5개 ≈ 압축 250MB + 활성 ≤500MB = **상한 ~0.8GB 유지**.

### 옵션 B (대안): 독립 shell guard (logrotate 미가용/보강 시)
- `~/.cokacdir/debug/log_guard.sh` (hourly cron):
  - 각 대상 로그 size 점검 → 상한(예 500M) 초과 시 **tail 보존(예 3000줄)→`truncate -s 0`** (rm 금지).
  - tail 보존본은 `_evidence/`에 회전 보관(7일).
- 장점: 의존성 0, 데몬 무관. 단점: logrotate 표준기능(gzip/rotate count) 직접 구현 필요.

### 보관/압축 파라미터 제안 (인가 #2)
- cron.log: max **500M**, rotate **5**, gzip(delaycompress).
- msg.log: max **500M**, rotate **3**, gzip.
- claude.log: 급하지 않음 → 모니터만(원인 확인 후 필요 시 동일 정책).
- 일자별 `*.log`(YYYY-MM-DD): 정상 크기 → **14일 경과분 정리**만 옵션.
- 보관 기간: 압축본 **7일 또는 rotate count 우선**(size-driven이라 count 기준 권장).

## 4. Guard 제안 (인가 #3·#4) — runaway/디스크 조기경보
독립 shell guard(hourly, read-mostly) 단일 스크립트로 통합:
1. **단일 로그 5G 초과 경고**(#3): `find debug -size +5G` → runaway marker(`memory/events/debug_runaway_<ts>.json`) 생성 + 회장 보고 1회.
2. **루트 여유 20G 미만 경고**(#4): `df --output=avail /` < 20G → disk_low marker + 회장 보고.
3. **증가율 감시(3차)**: cron.log size 스냅샷 비교, 시간당 증가 > 임계(예 1GB/h)면 `RUNAWAY_CONFIRMED` marker + 회장 보고.
- guard는 **읽기+marker+보고**만. 자동 truncate는 옵션 B 채택 시에만, 그것도 tail 보존 후.

## 5. 2차 근본해결 (별도 코드 수정 task로 분리) — 인가 #7
- 대상: scheduler `should_trigger`/`cron_matches`/`read_schedule_entry`/`scheduler_loop` **per-tick·per-entry DEBUG**.
- 방향: (a) 미매칭(`→ false`) 케이스 **미기록 또는 sampling**(예 1/N tick) (b) DEBUG→TRACE 강등 후 기본 OFF (c) log level 환경변수화.
- **코어 데몬 수정 = 별도 task·신중·회장 승인.** 본 정책안 범위 밖(분리 발행).

## 6. 단계별 권장 실행 순서 (승인 시)
1. 옵션 A logrotate + hourly cron (즉시·저위험·데몬 무관) → cron.log/msg.log 상한 관리.
2. guard 스크립트 hourly(5G·20G·증가율 경보).
3. (별도 task) scheduler verbosity 하향/sampling 코드 수정.

## 7. 리스크 / 검증
- copytruncate race: 복사~truncate 사이 수 줄 유실 가능 — debug 로그라 수용.
- 검증: 적용 후 24–48h cron.log/msg.log 상한 유지 + 보관본 gzip 정상 + guard marker 오탐 0 확인.
- 롤백: cron 1줄·conf 1파일 제거로 즉시 원복(데몬 영향 0).

## 8. 미적용 확인
- 본 문서는 제안서. logrotate 설정·cron·guard **미생성/미적용**. 실행은 회장 승인 후 별도 위임.
