# task-681.1: QC MANDATORY Blocklist + Skip 로그 추적

## 목표
qc_verify.py에 MANDATORY blocklist를 추가하여 핵심 체크의 --skip 우회를 차단하고, 모든 --skip 사용 시 추적 로그를 남긴다.

## 배경
- 2팀이 `--skip test_runner`로 FAIL을 우회하여 .done 생성 → 카드뉴스 업로드 실패
- 에이전트 미팅(5사이클) 합의: MANDATORY 체크는 skip 불가
- 미팅 기록: `memory/meetings/2026-03-18-qc-skip-bypass-prevention.md`

## 수정 대상
`/home/jay/workspace/teams/dev1/qc/qc_verify.py`

## 요구사항

### 1. MANDATORY blocklist (핵심)
```python
# 파일 상단, ALL_CHECKS 아래에 추가
MANDATORY_CHECKS = {"test_runner", "data_integrity", "file_check"}
```

- `run_check()` 함수 (line 166~)에서 skip 처리 전에 MANDATORY 체크:
  ```python
  if name in skip_list:
      if name in MANDATORY_CHECKS:
          print(f"[QC] ERROR: '{name}'은 MANDATORY 체크입니다. --skip 불가.", file=sys.stderr)
          return {"status": "FAIL", "details": [f"MANDATORY check '{name}' cannot be skipped"]}
      return {"status": "SKIP", "details": ["Skipped via --skip flag"]}
  ```

- `main()` 함수에서 skip_list 파싱 후, MANDATORY 체크가 포함된 경우 경고 + 자동 제거:
  ```python
  # skip_list에서 MANDATORY 항목 감지
  mandatory_in_skip = [s for s in skip_list if s in MANDATORY_CHECKS]
  if mandatory_in_skip:
      print(f"[QC] ⚠️  MANDATORY 체크 skip 시도 차단: {', '.join(mandatory_in_skip)}", file=sys.stderr)
      print(f"[QC] MANDATORY 체크(test_runner, data_integrity, file_check)는 skip할 수 없습니다.", file=sys.stderr)
      skip_list = [s for s in skip_list if s not in MANDATORY_CHECKS]
  ```

### 2. Skip 로그 추적 (제이회장님 요청)
모든 --skip 사용 시 로그 파일에 기록. 어디서 문제가 발생하는지 사후 추적 가능.

로그 파일: `/home/jay/workspace/memory/logs/qc-skip-log.jsonl` (JSONL 형식, append)

`main()` 함수에서 skip_list가 비어있지 않을 때:
```python
import json
from datetime import datetime

if skip_list:
    log_entry = {
        "timestamp": datetime.now().strftime("%Y-%m-%dT%H:%M:%S"),
        "task_id": task_id,
        "team": args.team,
        "skipped_checks": skip_list,
        "blocked_mandatory": mandatory_in_skip,  # MANDATORY 차단된 항목
        "gate_mode": args.gate,
    }
    log_dir = os.path.join(
        os.environ.get("WORKSPACE_ROOT", "/home/jay/workspace"),
        "memory", "logs"
    )
    os.makedirs(log_dir, exist_ok=True)
    log_path = os.path.join(log_dir, "qc-skip-log.jsonl")
    with open(log_path, "a", encoding="utf-8") as f:
        f.write(json.dumps(log_entry, ensure_ascii=False) + "\n")
    print(f"[QC] Skip 사용 기록: {log_path}", file=sys.stderr)
```

### 3. .done 파일에 skip 정보 기록
`_handle_gate()` 함수에서 .done 생성 시 skip 정보 포함:

```python
def _handle_gate(result: dict, task_id: str, team: str, skipped: list = None) -> None:
```
- `done_data`에 `"skipped_checks": skipped or []` 필드 추가
- `main()`에서 호출 시 skip_list 전달: `_handle_gate(result, task_id, args.team, skipped=skip_list)`

## 테스트 방법
```bash
# 1. MANDATORY skip 차단 테스트
python3 qc_verify.py --task-id test-mandatory --skip test_runner --team dev1-team
# 기대: "MANDATORY 체크 skip 시도 차단" 경고, test_runner는 정상 실행

# 2. SKIPPABLE skip 허용 테스트
python3 qc_verify.py --task-id test-skippable --skip pyright_check,style_check --team dev1-team
# 기대: pyright_check, style_check만 SKIP, 로그 기록

# 3. 로그 파일 확인
cat /home/jay/workspace/memory/logs/qc-skip-log.jsonl
# 기대: JSONL 형식으로 skip 기록 존재

# 4. .done에 skip 정보 포함 확인 (--gate 모드)
python3 qc_verify.py --task-id test-gate --skip pyright_check --gate --team dev1-team
cat /home/jay/workspace/memory/events/test-gate.done
# 기대: "skipped_checks": ["pyright_check"] 필드 존재
```

## 주의사항
- 기존 동작 깨뜨리지 않기: --skip 없이 실행 시 동작 변화 없어야 함
- MANDATORY_CHECKS는 상수로 상단에 선언 (PROTECTED 파일이므로 변경 추적 용이)
- 로그 디렉토리 없으면 자동 생성
- 기존 verifiers/ 하위 파일은 수정 불필요
