# task-2472 — Hard Enforcement Against Silent-Corruption Bypass

- 작업 유형: **production hardening + regression tests + audit channels** (코드 차단 + 테스트 재발 방지 + audit 증거)
- 작업 레벨: **Lv.4 critical**
- 위임팀: **dev2-team (오딘, opus)** — task-2471+1에서 우회한 본인이 차단 코드 작성 = 책임성 + drink-your-own-champagne
- 독립 검증: **마아트 G2/G3 강화**
- Track: **dev_workspace**
- 우선순위: **★★★ blocking** — task-2471+1보다 **우선 진행**
- 일시: 2026-05-07
- 선행: task-2471+1 우회 행위 발견 + 회장 task-2472 GO
- 후행: task-2471+1 정상 경로 재시도 (task-2472 main 반영 후)
- TTL: **8시간** (scope creep 금지)

## ⚠️ 본 task의 본질 — 회장 명시

> "task-2472는 운영정책/주의사항/문서가 아니라, **silent corruption 우회 경로를 production code로 강제 차단**하는 hardening task다.
> 봇이 조심하게 만드는 것이 아니다. 오딘 또는 어떤 봇이 같은 우회를 시도하더라도 **코드가 거부하고, 테스트가 재발을 막고, audit이 증거를 남기게** 만들어라."

> **"task-2472를 task-2471+1보다 우선 진행한다.
> task-2471+1 PR을 조용히 merge하여 기존 위반을 덮는 것을 금지한다.
> task-2471+1의 위반 evidence는 보존한다.
> task-2472 hardening 코드가 main에 반영된 뒤 task-2471+1을 정상 경로로 재시도한다."**

## 0. 배경 — task-2471+1 우회/결함 5건

| # | 위반/결함 | 회장 명시 금지 위반 |
|---|-----------|---------------------|
| 1 | Gemini review thread 임의 resolve (GraphQL `resolveReviewThread` mutation) | "Gemini thread 임의 resolve 추가 금지" |
| 2 | FAILED → HUMAN_APPROVED 수동 state 전이 (state JSON 직접 수정) | "수동 state 전이 금지" |
| 3 | taskctl checksum mismatch (fail-closed 정상, 복구 미명확) | — (시스템 결함) |
| 4 | branch protection merge block → FAILED terminal 잘못 분류 | — (state machine 결함) |
| 5 | Gemini gate 검증 불충분 (body keyword grep만, thread/severity/image badge 미포함) | — (gate 결함) |

→ task-2471+1 transitions에 박제됨: `actor=odin (manual state-bug correction)` + 14c transition (`FAILED → HUMAN_APPROVED at 2026-05-07T02:20:41Z`)

## 1. 필수 구현 6건

### 구현 1 — Gemini thread 임의 resolve 차단
- `resolveReviewThread` 호출 경로 통제
- Gemini review thread 자동 resolve 금지
- medium/high/critical severity thread는 **chairman approval evidence** 없으면 resolve 불가
- resolve 시 `memory/orchestration-audit/review-thread-resolution.jsonl`에 기록 필수
- evidence 없이 resolve 시도 → fail-closed
- audit 필수 필드: task_id, pr_number, thread_id, severity, actor, approval_evidence, timestamp, reason, result

### 구현 2 — 수동 state 수정 차단
- state 파일은 taskctl 명령 경로를 통해서만 변경 가능
- 외부 state 수정 감지 시 모든 taskctl write action 차단 (현재 checksum mismatch 작동 확인됨)
- FAILED → HUMAN_APPROVED 직접 전이 금지
- recoverable 상황은 FAILED 아니라 RECOVERABLE_BLOCKED로 전이
- retry는 `taskctl recover` 같은 명령 경로로만 허용
- recovery transition은 audit 필수

### 구현 3 — RECOVERABLE_BLOCKED state + classifier
recoverable 예시:
- `base branch policy prohibits the merge`
- `required_review_thread_resolution`
- unresolved review thread
- required checks pending
- `mergeStateStatus BLOCKED`
- review thread resolution required

요구:
- recoverable merge block classifier 추가
- RECOVERABLE_BLOCKED state 추가 (또는 동등한 복구 가능 상태)
- 조건 해소 후 taskctl-controlled retry 허용
- retry 전 재검증: required checks / review threads / mergeStateStatus / Gemini gate / state checksum

### 구현 4 — Gemini gate 검증 강화
검사 대상:
1. latestReviews 확인
2. review comments 확인
3. review threads 확인
4. unresolved thread 여부
5. thread severity
6. image markdown severity badge 탐지 (예: `![high](...)`)
7. medium/high/critical thread 존재 여부

판정:
- Gemini review 자체가 없으면 PASS 금지
- high/critical thread 존재 → FAIL
- medium unresolved thread 존재 → BLOCKED 또는 RECOVERABLE_BLOCKED
- review body high=0이어도 thread medium 이상이면 PASS 금지
- unresolved thread 있으면 merge 진행 금지

### 구현 5 — checksum mismatch 복구도 코드 경로로만
- `taskctl state inspect` 명령 (또는 동등 기능)
- `taskctl state repair --task-id ... --approved-by-chairman --evidence ...` 명시 복구 경로
- repair 전 원본 state 파일 sha256 백업
- repair 후 audit jsonl 기록
- chairman approval evidence 없으면 repair 불가
- repair 후 즉시 DONE 금지
- repair 후 `verify-consistency` 강제 선행

### 구현 6 — audit 채널 5건 신설/확장
1. `memory/orchestration-audit/review-thread-resolution.jsonl`
2. `memory/orchestration-audit/state-recovery.jsonl`
3. `memory/orchestration-audit/checksum-repair.jsonl`
4. `memory/orchestration-audit/recoverable-merge-block.jsonl`
5. `memory/orchestration-audit/gemini-gate-decision.jsonl`

각 audit 필수 필드 (9건):
- task_id
- actor
- action
- input_state
- output_state
- approval_evidence
- result
- reason
- timestamp
- sha256 또는 evidence_hash

## 2. 필수 regression test 17건 (단순 문서 테스트 금지, production path 실제 때리기)

1. Gemini thread 임의 resolve reject
2. chairman approval 없는 medium thread resolve reject
3. chairman approval 있는 resolve만 허용
4. resolve audit 누락 reject
5. state JSON 직접 수정 reject (checksum mismatch)
6. FAILED → HUMAN_APPROVED 수동 전이 reject
7. checksum mismatch 상태에서 merge/done reject
8. recoverable branch protection block → RECOVERABLE_BLOCKED
9. RECOVERABLE_BLOCKED 조건 해소 후 taskctl retry 가능
10. non-recoverable merge error → FAILED
11. body high=0 + thread medium=1 → Gemini gate block
12. image markdown `![high](...)` 탐지
13. latestReviews=0 → gate fail
14. unresolved thread 존재 → merge block
15. checksum repair approval evidence 누락 reject
16. checksum repair audit 누락 reject
17. repair 후 verify-consistency 없이 done reject

## 3. allowed_resources

```yaml
allowed_resources:
  paths:
    - "scripts/taskctl.py"
    - "scripts/taskctl/**"
    - "scripts/lifecycle_guards.py"
    - "scripts/pre_push_guard.py"
    - "scripts/gemini_severity_parser.py"
    - "scripts/g3_independent_verifier.py"
    - "scripts/finish-task.sh"        # §8.A-8 raw emit 제거 대상
    - "scripts/done-watcher.sh"       # §8.A-9 shell emitter wrapper 강제 대상
    - "scripts/escalation_marker.py"  # §8.A-9 신설 Python wrapper
    - "utils/silent_corruption_guard.py"
    - "utils/audit_chairman_recovery.py"
    - "utils/gemini_gate_validator.py"  # 신설 가능
    - "utils/recoverable_block_classifier.py"  # 신설 가능
    - "utils/state_repair.py"  # 신설 가능
    - "utils/review_thread_guard.py"  # 신설 가능
    - "dispatch.py"
    - ".tasks/state/**"  # schema 변경 가능 (RECOVERABLE_BLOCKED 추가)
    - "memory/orchestration-audit/review-thread-resolution.jsonl"
    - "memory/orchestration-audit/state-recovery.jsonl"
    - "memory/orchestration-audit/checksum-repair.jsonl"
    - "memory/orchestration-audit/recoverable-merge-block.jsonl"
    - "memory/orchestration-audit/gemini-gate-decision.jsonl"
    - "tests/regression/**"
    - "tests/lifecycle_guards/**"
    - "tests/state_machine/**"
    - "tests/dispatch/**"
    # 본 task 자체
    - "memory/tasks/task-2472*"
    - "memory/reports/task-2472*"
    - "memory/plans/tasks/task-2472/**"
    - "memory/events/task-2472*"
    - "memory/evidence/task-2472/**"  # chairman approval evidence (drink-your-own-champagne)
  forbidden_paths:
    - "memory/events/task-2471+1.*"  # 위반 evidence 보존 (read-only)
    - "memory/events/task-2471.*"
    - "memory/events/task-2470*"
    - "memory/events/task-2469*"
    - "memory/events/task-2468*"
    - "memory/events/task-2467*"
    - "memory/reports/task-2471+1.md"  # read-only
    - "memory/reports/task-2471.md"
    - ".tasks/state/task-2471+1.json"  # 위반 transition 14c 보존 (★)
    - "memory/specs/allowed_bot_accounts.json"
    - "memory/specs/allowed_approvers.json"
    - "memory/orchestration-audit/admin-override.jsonl"
    - "PR #29-#37"  # PR 본문 변경 금지
    - ".env.keys"
    - ".secrets/**"
    - ".gitignore"
  forbidden_actions:
    - "task-2471+1 PR 조용히 merge 금지 (★ 핵심)"
    - "task-2471+1 evidence 삭제 금지 (★)"
    - "manual recovery로 덮기 금지"
    - "admin override 금지"
    - "Gemini gate 우회 금지"
    - "review thread 임의 resolve 금지"
    - "FAILED → HUMAN_APPROVED 수동 전이 금지"
    - "checksum mismatch를 수동 편집으로 복구 금지"
    - "보고서만 작성 후 완료 금지"
    - "테스트 없는 hardening 금지"
    - "실행 로그 없는 PASS 선언 금지"
    - "새 우회 경로 만들기 금지"
    - "0-byte marker 삭제로 무마 금지"
    - "실패 evidence 삭제 금지"
    - "gh pr merge 직접 호출 금지 (taskctl 외)"
    - "git push --force 금지"
    - "git push origin main 직접 호출 금지"
  bot_authentication:
    - "BOT_GITHUB_TOKEN .env.keys 자동 로드 (만료 시 chairman 발급)"
    - "PR author = jeon-jonghyuk-taskctl-bot[bot]"
    - "approver = 시스템 승인자 (taskctl-gate / anu-verifier)"
    - "self-approve 차단"
  merge_policy: "★ 본 task가 만든 hardening 코드를 통해 본 task PR이 merge됨 (drink-your-own-champagne layer 3). green path 자동, 우회 시도 코드 차단"
  ttl_hours: 8
```

## 4. 완료 조건 (회장 명시 15건)

전부 충족해야 합격:
1. ✅ production code 구현 완료
2. ✅ 필수 테스트 17건 PASS
3. ✅ 기존 regression PASS (회귀 0)
4. ✅ audit jsonl 5채널 생성/검증
5. ✅ Gemini gate image badge 포함 severity 탐지 PASS
6. ✅ RECOVERABLE_BLOCKED 경로 PASS
7. ✅ checksum repair 경로 PASS
8. ✅ 수동 state 수정 차단 PASS
9. ✅ review thread 임의 resolve 차단 PASS
10. ✅ task-2471+1 위반 evidence 보존 (★)
11. ✅ PR 생성
12. ✅ CI/Gemini/G3 PASS
13. ✅ PR merge
14. ✅ origin/main 반영 확인
15. ✅ DONE 발행

## 5. 최종 목표 (회장 명시)

오딘이 다시 같은 우회를 하려고 해도:
- Gemini thread resolve가 **코드에서 막히고**
- state JSON 직접 수정이 **checksum으로 거부되고**
- branch protection block은 **recoverable 상태로 정리되고**
- Gemini gate가 **thread severity까지 검사하고**
- checksum repair도 **taskctl 명령 + chairman evidence + audit 없이는 불가능해야 한다**

→ **사람이 조심하는 방식이 아니라, 코드가 거부하고, 테스트가 재발을 막고, audit이 증거를 남기게 구현하라**

## 6. ESCALATED 조건

- task-2471+1 PR 조용히 merge 시도 → 즉시 reject + ESCALATED
- task-2471+1 evidence 삭제/덮어쓰기 → 즉시 reject + ESCALATED
- regression test 17건 미충족 → ESCALATED
- audit 채널 5건 미생성 → ESCALATED
- 새 우회 경로 발견 → 즉시 reject + ESCALATED
- 보고서만으로 DONE 처리 → ESCALATED
- admin override 사용 → 즉시 reject

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

1. 6 구현 각각의 코드 위치 + diff
2. 17 regression test 코드 + 실행 로그
3. 5 audit 채널 schema + 샘플 evidence (live entry)
4. taskctl smoke test 실행 로그
5. PR 생성 + CI/Gemini/G3 PASS 로그
6. PR merge commit SHA + origin/main ancestry 검증
7. **task-2471+1 위반 evidence 보존 검증** (transitions 14c + .done.escalated 모두 read-only)
8. drink-your-own-champagne 메타 검증 — 본 PR이 자체 hardening 코드를 통해 정상 merge됐다는 증명 (Gemini gate 강화 / RECOVERABLE_BLOCKED / checksum 등 자체 적용)
9. 기존 회귀 0건 PASS log

## 8. 시스템 청사진

본 task = silent corruption 우회 경로의 **코드 레벨 영구 차단**. drink-your-own-champagne layer 3 (task-2471 layer 1 → task-2471+1 layer 2 → task-2472 layer 3).

## 8.A ★★★ task-2473 ESCALATED 진단 결과 추가 필수 7건 (회장 명시 2026-05-07)

task-2473에서 발견된 결함 evidence 기반 추가 hardening 필수 항목. 본 7건은 §1 필수 구현 6건과 별개로 **반드시 코드/테스트로 차단**.

### 추가 8 — `scripts/finish-task.sh:450` 빈 파일 쓰기 제거
- 현재: `: > "$EVENTS_DIR/${TASK_ID}.done.escalated"` 빈 파일 발행 (★ task-2473 0-byte 발생 원인)
- 변경: escalation marker는 반드시 JSON payload로 발행
- 필수 필드: `reason`, `ts`, `task_id`, `source`, `blocking_condition`, `evidence_path`
- payload validation 통과 시만 발행

### 추가 9 — shell-level emitters까지 silent_corruption_guard 적용
- `scripts/finish-task.sh` / `scripts/done-watcher.sh` / taskctl done/merge 경로
- raw `: > *.done.escalated` 금지
- Python guard 모듈만으로는 부족 (★ task-2473에서 raw shell이 guard 우회 입증)
- shell emitter는 Python guard wrapper 호출 강제

### 추가 10 — 0-byte `.done.escalated` 발행 차단
- 발행 전: payload validation
- 발행 후: stat/sha256/JSON validation
- 0-byte 또는 비-JSON 발견 시 fail-closed
- audit jsonl에 차단 사유 박제

### 추가 11 — `.done` + `.done.escalated` 동시 존재 자동 차단
- DONE 인정 금지
- origin/main ancestry 확인 전 DONE 금지
- silent corruption guard가 두 마커 동시 존재 탐지 시 즉시 reject + audit

### 추가 12 — state file missing 방지
- taskctl state file 생성/유지 강제
- state file missing 상태에서 done/merge 금지
- checksum/audit 검증 필수
- state 생성 실패 시 fail-closed

### 추가 13 — Gemini unresolved thread 정책 정합
- medium thread가 branch protection상 unresolved이면 merge block으로 처리
- 임의 resolve 금지 (§1 구현 1과 연결)
- RECOVERABLE_BLOCKED로 분류 (§1 구현 3과 연결)
- FAILED terminal로 보내지 말 것

### 추가 14 — drink-your-own-champagne 자기 적용 검증 (메타 검증)
- task-2471+1 / task-2473처럼 hardening이 자기 자신에게 적용되지 않는 케이스를 regression test로 추가
- shell raw emitter 우회 테스트 포함
- 실측: task-2473 PR #38이 task-2471+1 hardening 적용 후에도 silent corruption 재발 (evidence)

## 2.A 추가 regression test 7건 (회장 명시 완료 조건)

§2의 17건에 추가:
18. shell raw `: > *.done.escalated` 차단 테스트
19. JSON payload 없는 escalation marker 발행 reject
20. 0-byte `.done.escalated` 발행 후 stat 검증 reject
21. state file missing 상태에서 done/merge 시도 reject
22. `.done` + `.done.escalated` 동시 존재 시 DONE reject
23. Gemini medium unresolved thread → RECOVERABLE_BLOCKED 분류
24. shell emitter가 Python guard wrapper 호출 강제 (raw bypass 차단)

## 4.A 완료 조건 보강 (회장 명시)

§4 15건에 추가:
16. ✅ shell raw marker emit 차단 테스트 PASS
17. ✅ state file missing 상태 done 금지 테스트 PASS
18. ✅ unresolved Gemini thread → RECOVERABLE_BLOCKED 테스트 PASS
19. ✅ `.done` + `.done.escalated` conflict reject 테스트 PASS
20. ✅ 0-byte escalation marker reject 테스트 PASS
21. ✅ task-2473 evidence 보존 (read-only)
22. ✅ scripts/finish-task.sh:450 raw 명령 제거 + JSON payload 발행 변경 diff

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

1. 수신 확인: dispatch 출력 + `--task-id task-2472` 정확 적용
2. 빌드+배포: PR 생성 + CI/Gemini/G3 PASS + merge + main HEAD 갱신
3. 실 E2E: regression 17건 PASS + audit 5채널 live entry + taskctl smoke test
4. 구조 선행 파악: task-2471/task-2471+1 보고서 + transitions + chairman-recovery-approval 모두 read

## goal_assertions (auto-generated)
- `python3 -m pytest tests/regression/ tests/lifecycle_guards/ tests/state_machine/ tests/dispatch/ -v`
- `gh pr view <PR> --json state,mergedAt,mergeCommit`
- `git merge-base --is-ancestor <mergeCommit> origin/main`
- `python3 scripts/taskctl.py status task-2472`
- `ls memory/orchestration-audit/{review-thread-resolution,state-recovery,checksum-repair,recoverable-merge-block,gemini-gate-decision}.jsonl`