# task-2479 — CI pytest -x 제거 (failure visibility 복구)

- 작업 유형: **infrastructure / CI workflow change** (failure matrix 가시성 복구)
- 작업 레벨: **Lv.2**
- 위임팀: **dev1-team** (헤르메스)
- Track: **insuro**
- 우선순위: **★★ blocking** — merge chain 선행
- 일시: 2026-05-07
- 선행: PR #105/#106 mutual lock 발생 + first-fail 가시성 부재
- 후행: task-2479 main 반영 후 PR #106/#105 rebase

## ⚠️ 본 task의 본질 — 회장 명시 (A안)

> task-2479는 **green 보장 PR이 아니라 CI failure visibility 복구 PR**로 정의한다. pytest -x 제거 + 필요 시 `--maxfail=10`만 허용한다.
> task-2479 CI가 기존 사전 회귀로 fail하더라도, **첫 실패에서 멈추지 않고 full failure matrix를 출력**하면 본질 검증 PASS로 본다.
> 단, branch protection상 failing required check 때문에 정상 머지가 불가능하면 강행하지 말고 **fallback-2479a로 전환**한다.

## 0. 배경

- main HEAD 사전 회귀 2건 (`test_blocks_recruitment_keyword`, `test_generate_stub`) 동시 존재
- pytest -x first-fail 구조로 두 회귀가 서로 가려져 본질 검증 불가
- PR #105 (task-2476)와 PR #106 (task-2477) mutual lock

## 1. 작업 범위 (회장 명시)

1. GitHub Actions workflow 또는 로컬 CI 스크립트에서 **`pytest -x` 제거**
2. 필요 시 **`--maxfail=10`** 적용
3. 전체 failure matrix가 출력되도록 유지
4. 테스트 실행 대상 자체는 변경하지 않는다
5. PR #105, PR #106 코드 변경과 섞지 않는다

## 2. fallback-2479a (회장 명시)

required CI가 first-fail 미통과로 task-2479 자체 머지가 차단되면:
- **기존 required CI는 유지**
- **pytest -x 없는 diagnostic workflow를 non-required로 추가**
- full failure matrix 확보
- 이후 PR #106/#105 해결 후 required CI 교체는 별도 task로 진행 (★ task-2479의 본 PR 머지 후 task-2479+1)

판정 기준:
- task-2479 본 변경(required CI에서 -x 제거)으로 머지 가능 → **본 PR 진행**
- 머지 불가 → **fallback-2479a 적용** (별도 commit으로 본 PR 갱신, diagnostic workflow 추가)

## 3. 엄격 금지 (회장 명시)

- `server/main.py` 변경
- task-2476 forbidden_paths 변경
- slowapi limiter fixture 변경
- merge policy 변경
- PR #105/#106 fix 코드 포함
- **임시 xfail/skip 금지**
- **admin override 금지**
- **branch protection bypass 금지**

## 4. allowed_resources

```yaml
allowed_resources:
  paths:
    - ".github/workflows/**"
    - ".github/workflows/ci.yml"
    - ".github/workflows/diagnostic*.yml"  # fallback-2479a 신설 가능
    - "scripts/ci.sh"  # 로컬 CI 스크립트 있으면
    # 본 task 자체
    - "memory/tasks/task-2479*"
    - "memory/reports/task-2479*"
    - "memory/plans/tasks/task-2479/**"
    - "memory/events/task-2479*"
  forbidden_paths:
    - "server/main.py"  # task-2475/2477 영역
    - "server/scripts/keyword_pool_refresh.py"  # task-2476 영역
    - "server/tests/**"  # task-2477 격리 fixture 영역
    - "src/app/keyword-analysis/**"  # task-2475 영역
    - "scripts/finish-task.sh"
    - "scripts/done-watcher.sh"
    - "utils/silent_corruption_guard.py"
    - "scripts/taskctl.py"
    - "memory/specs/allowed_bot_accounts.json"
    - "memory/specs/allowed_approvers.json"
    - "memory/orchestration-audit/admin-override.jsonl"
    - ".env.keys"
    - ".secrets/**"
    - ".gitignore"
  forbidden_actions:
    - "PR #105/#106 fix 코드 포함 금지"
    - "임시 xfail/skip 금지"
    - "admin override 금지"
    - "branch protection bypass 금지"
    - "force merge 금지"
    - "merge policy 변경 금지"
    - "test 대상 자체 변경 금지"
    - "git push --force 금지"
  bot_authentication:
    - "BOT_GITHUB_TOKEN .env.keys 자동 로드 (50분 systemd timer 자동 갱신)"
    - "PR author = jeon-jonghyuk-taskctl-bot[bot]"
  merge_policy: "★ failure matrix PASS 시 머지 (사전 회귀 fail은 visibility 복구가 본질). branch protection 막히면 fallback-2479a로 전환"
  ttl_hours: 4
```

## 5. 완료 조건

1. ✅ CI가 첫 실패 후에도 계속 실행되어 full failure matrix 출력
2. ✅ required check 의미 유지 (테스트 대상 자체 변경 없음)
3. ✅ task-2479 단독 PR로 머지 OR fallback-2479a 진행 + main 반영
4. ✅ admin override 0건 / branch protection bypass 0건
5. ✅ PR #105/#106 코드 미수정 (diff에 포함 X)

## 6. 판정 기준 (failure visibility PASS)

- pytest -x 제거 적용 확인 (workflow diff)
- failure matrix 출력 확인 (CI log에 2개 이상 실패 동시 노출)
- branch protection 통과 시 본 PR 머지
- 막히면 fallback-2479a 적용

## 7. ESCALATED 조건

- PR #105/#106 fix 코드 포함 → 즉시 reject
- 임시 xfail/skip 사용 → 즉시 reject
- admin override 사용 → 즉시 reject + 보안 알람
- merge policy 변경 → 즉시 reject
- failure matrix 미출력 → ESCALATED

## 8. 보고서 필수 항목 (`memory/reports/task-2479.md`)

1. workflow diff (pytest -x 제거)
2. failure matrix CI log evidence (2개 이상 실패 동시 출력)
3. 머지 결과 또는 fallback-2479a 적용 사유
4. branch protection 통과 evidence (강행 0건)
5. PR 번호 + merge SHA (머지 시) 또는 fallback PR 번호
6. PR #105/#106 후속 진행 가능 여부

## 9. 위임 완결성 4대 규칙

1. 수신 확인: dispatch 출력
2. 빌드+배포: PR 생성 + (head fix는 visibility) + merge OR fallback-2479a
3. 실 E2E: failure matrix 출력 확인 (CI log)
4. 구조 선행 파악: 현재 .github/workflows/ci.yml 구조 + pytest 실행 위치

## goal_assertions
- workflow에서 `pytest -x` 패턴 0건 (`grep -rn "pytest.*-x" .github/workflows/`)
- CI run에서 failure matrix 2개 이상 발견
- `gh pr view <PR> --json state,mergedAt,mergeCommit` (state=MERGED 또는 fallback 적용)
- admin override audit 0건