# task-3041 — 시스템 스펙 자동 업데이트 (6시간 주기 정기 실행)

- **실행 시각**: 2026-08-28 00:15 KST
- **명령**: `python3 /home/jay/workspace/scripts/update-system-spec.py`
- **종료 코드**: `1` (알려진 `cron` 섹션 거짓 양성 — 데이터 손실 없음, Critical 7 아님)
- **판정**: **정상 완료**. 회장 보고 불필요.

## 1. 실행 결과

```
  [FAIL] cron: ANU_CHAT 환경변수가 설정되지 않았습니다.
  [OK] skills / services / projects / scripts / task_stats
변경 감지: ['cron', 'task_stats']
문서 업데이트 완료 / 변경 로그 기록 완료
```

`cron` FAIL 은 10회 연속 동일한 기존 거짓 양성이다
(`collect_cron()` 이 `ANU_CHAT`/`ANU_KEY` 를 요구하나 크론 환경에 미주입 →
`new=None` vs `old=non-None` → 무조건 "데이터 변경" 계상. 정작 문서 갱신 루프는
`if section not in new_state: continue` 로 건너뛰므로 블록은 손대지 않음).

## 2. 검증 (실행 전 `cp` 스냅샷 ↔ 실행 후 전문 대조)

스냅샷: `memory/reports/task-3041/anu-system-spec.before.md`

### 2-1. 전문 diff — 16줄, 단일 hunk, `task_stats` 뿐

| 항목 | before | after |
|---|---|---|
| 총 작업 수 | 2281 | 2284 |
| 완료된 작업 | 2217 | 2219 |
| 완료율 | 97.2% | 97.2% (무변) |
| 평균 소요시간 | 1시간 10분 19초 | 1시간 10분 17초 |

증가분 +3 중 **1건은 본 task 자신**의 타이머 start 다(자기참조 — 외부 활동량으로 읽지 말 것).

### 2-2. `AUTO:cron` 블록 보존 확인 (동일 실행 내 before↔after 대조)

```
BEFORE: af7090faa1da20f713b9f6e31ae7eb8c
AFTER : af7090faa1da20f713b9f6e31ae7eb8c   → 일치, 보존됨 (10회 연속)
```

블록 `created_at` 은 `2026-04-16 11:16:10` 동결 유지.

### 2-3. `services` — 변경 감지 목록에 없음, 스펙 17 = 실측 17 (집합 diff 0)

`systemctl --user list-units --state=running --type=service` 실측 17개가
스펙 블록 17개와 **완전 일치**(집합 diff 0줄).

- 플래핑 후보 3종(`at-spi-dbus-bus`·`dbus`·`gpg-agent`) **6회 연속 present**.
  회차 수가 쌓여도 승격하지 않는다 — "세션이 안 끊겼을 뿐"이라는 대안 설명을
  배제하지 못한다. 승격 조건은 회차가 아니라 *세션 재시작을 관통한 생존*이다.
- `cloudflared-whisper.service` 는 t3038 이 잡아낸 정지 상태 **그대로 지속**(아래 3절).

## 3. 잠복결함 추적

### 3-1. `cloudflared-whisper.service` 정지 지속 — 약 9시간 40분째, 무알림

```
ActiveState=inactive / SubState=dead / ExecMainStatus=0
InactiveEnterTimestamp = 2026-08-27 14:35:05 KST
Restart=on-failure
```

`Restart=on-failure` 는 exit 0 정상종료에 미발동 → **수동 개입 전까지 영구 정지**.
t3038 이 발견한 뒤 6시간이 더 지났고 자동 복구는 일어나지 않았다(설계상 일어날 수 없음).

**실피해는 여전히 0건**: canonical 소비자 `scripts/youtube-transcribe.py:32` 는
`http://localhost:8200/v1/transcribe` 를 직접 호출하므로 튜널과 무관하고,
`whisper-gpu.service` 는 정상이다(GET 프로브 **HTTP 405** = alive. 이전 회차 404 와
코드가 다른 것은 메서드 불일치 응답 차이일 뿐 생존 판정은 동일).
quick tunnel 이라 URL 이 매 재시작 변경되어 하드코딩 소비자가 존재할 수 없다.

→ **긴급도 낮음. 처방 전 선행질문 유지: 이 튜널의 외부 소비자가 실재하는가?**
실재하지 않으면 유닛 비활성화가, 실재하면 `Restart=always` 승격이 처방이다. ANU 판단 몫.

### 3-2. `collect_services()` returncode 미검사 — 미해소, 실발생 0회

세션버스 실패 시 `services` 블록 21줄 → 2줄 소실 가능(재현 완료). 위임 대상 계류 중.

## 4. 백업 격자 (별개 스케줄 `EE825F5E`)

08-25_00 ~ 08-28_00 **13개 기대 슬롯 중 12개 존재**.

- 결번 = `2026-08-26_12` **1건뿐이며, 기존 모드B 결번 그대로**. 신규 결번 0.
- 08-27_12 · 08-27_18 · 08-28_00 **3회 연속 정상**.
- 단 연속 ok 를 세어 "고장 아님"으로 승격하지 않는다(t3036 정정 사항).
  모드B 는 로그 레코드 자체가 없어 `grep error` 로 안 잡히며,
  **기대 슬롯 격자 ↔ 백업 디렉터리 실재 대조**만이 탐지법이다.
- ★ 누락 버킷 사후 임의 생성 금지(갱신 *이후* 내용이 담겨 "실행 전 상태" 의미가 뒤집힘).

## 5. 변경 로그 기록

`memory/specs/anu-system-spec-changelog.md` 최상단에 기록됨:

```
## [2026-08-28 00:15] 변경 내역
- [cron] `cron` 데이터 변경        ← 거짓 양성 (문서 미변경)
- [task_stats] `task_stats` 데이터 변경   ← 실변경
```

## 6. 결론

| 항목 | 결과 |
|---|---|
| 스펙 문서 갱신 | 성공 (`task_stats` 만 실변경) |
| changelog 기록 | 완료 |
| `AUTO:cron` 블록 | 보존 (md5 before=after, 10회 연속) |
| `services` 정합성 | 스펙 17 = 실측 17, 집합 diff 0 |
| 백업 격자 | 신규 결번 0 (기존 08-26_12 1건 유지) |
| 회장 보고 | **불필요** — exit 1 은 알려진 거짓 양성, 데이터 손실 0 |
