<!-- task=m-agent-task-runtime-target-selector/04+03_failover_budget plan=12 tag=REVIEW_API -->

# Code Review Reference - REVIEW_API

> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
> The task is NOT complete until every implementation-owned section below is filled in.
> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving.
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
> If implementation is blocked, record the exact blocker, attempted commands/output, and resume condition only in implementation-owned evidence fields.
> Do not ask the user directly, present choices, call user-input tools, create control-plane stop files, or classify the next state.
> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume.
> Follow the ownership table at the bottom of this file for which sections you own.

## 개요

date=2026-07-26
task=m-agent-task-runtime-target-selector/04+03_failover_budget, plan=12, tag=REVIEW_API

## Roadmap Targets

- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/agent-task-runtime-target-selector.md`
- Milestone link: [Milestone 문서](agent-roadmap/phase/automation-runtime-bridge/milestones/agent-task-runtime-target-selector.md)
- Task ids:
  - `time-route`: local-G07~G08 KST 주야간 최초 target
  - `context-failover`: Gemini↔Laguna 단방향 logical context failover
  - `failure-budget`: target 전환 전후 동일 stage 10회 실패 예산
  - `selfcheck-policy`: 실제 worker 완료 target 기반 selfcheck
- Completion mode: check-on-pass

## Archive Evidence Snapshot

- 선행 완료: `agent-task/archive/2026/07/m-agent-task-runtime-target-selector/03+01,02_route_pin_state/complete.log` — route pin/state predecessor PASS.
- 직전 계획: `agent-task/m-agent-task-runtime-target-selector/04+03_failover_budget/plan_local_G08_11.log`.
- 직전 리뷰: `agent-task/m-agent-task-runtime-target-selector/04+03_failover_budget/code_review_cloud_G08_11.log` — FAIL, Required 5 / Suggested 0 / Nit 0.
- 영향 파일: `execution_target_policy.py`, `select_execution_target.py`, `dispatch.py`와 세 대응 테스트 파일.
- 검증 evidence: policy 5 tests PASS, selector 집중 7 tests PASS, budget helper 3 tests PASS, 전체 179 tests는 2 failures, `py_compile`/`git diff --check` PASS, SDD 후보 순서 재현 FAIL.
- 로드맵 carryover: S02/S06/S07/S10과 `time-route`, `context-failover`, `failure-budget`, `selfcheck-policy`가 미완료다.

## 이 파일을 읽는 리뷰 에이전트에게

> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다.

각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다.

1. 판정을 append한다.
2. `CODE_REVIEW-cloud-G08.md` → `code_review_cloud_G08_12.log`, `PLAN-local-G08.md` → `plan_local_G08_12.log`로 아카이브한다.
3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/m-agent-task-runtime-target-selector/04+03_failover_budget/`로 이동한다. WARN/FAIL이면 code-review skill이 요구하는 다음 filesystem state를 완전히 작성한다.
4. PASS이고 task group이 `m-<milestone-slug>`이면 완료 이벤트 메타데이터를 보고한다. roadmap 상태 체크와 `update-roadmap` 호출은 런타임 책임이다.
5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| REVIEW_API-1 Canonical KST 후보 순서 | [ ] |
| REVIEW_API-2 Dispatcher failover와 logical context 연결 | [ ] |
| REVIEW_API-3 실제 invocation budget과 completing-target selfcheck | [ ] |
| REVIEW_API-4 회귀 기대와 전체 evidence 정합성 | [ ] |

## 구현 체크리스트

- [ ] REVIEW_API-1 KST 네 경계의 canonical Gemini/Laguna 후보 순서와 selector 회귀 테스트를 구현한다.
- [ ] REVIEW_API-2 qualified failure의 단방향 selector failover, persisted transition, logical context 다음 invocation을 구현한다.
- [ ] REVIEW_API-3 실제 invocation target/transition 기준 stage budget과 completing-target selfcheck lifecycle을 구현한다.
- [ ] REVIEW_API-4 정적 route 기대를 시간 명시 matrix로 교체하고 집중·전체 검증을 통과한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다.

## 코드리뷰 전용 체크리스트

> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.
> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다.

- [x] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
- [x] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다.
- [x] active `CODE_REVIEW-*-G??.md`를 `code_review_cloud_G08_12.log`로 아카이브한다.
- [x] active `PLAN-*-G??.md`를 `plan_local_G08_12.log`로 아카이브한다.
- [x] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인한다.
- [ ] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다.
- [ ] PASS이면 active task 디렉터리 `agent-task/m-agent-task-runtime-target-selector/04+03_failover_budget/`를 `agent-task/archive/YYYY/MM/m-agent-task-runtime-target-selector/04+03_failover_budget/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다.
- [ ] PASS이고 task group이 `m-<milestone-slug>`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다.
- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/m-agent-task-runtime-target-selector/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다.
- [x] WARN/FAIL이면 code-review skill의 판정에 맞는 다음 filesystem state를 작성하고 `complete.log`를 작성하지 않는다.

## 계획 대비 변경 사항

_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._

## 주요 설계 결정

_구현 에이전트가 주요 설계 결정 사항을 기록한다._

## 리뷰어를 위한 체크포인트

- policy가 주간 Gemini→Laguna, 야간 Laguna→Gemini의 두 canonical 후보를 반환하는지 확인한다.
- qualified failure만 selector failover를 만들고 logical context가 실제 다음 invocation prompt에 전달되는지 확인한다.
- failure budget의 `last_target`/`last_transition`이 실제 invocation이며 reopen과 target 전환 뒤에도 worker stage 10회를 공유하는지 확인한다.
- Gemini→Laguna 완료만 pinned Laguna selfcheck를 실행하고 다른 completing target은 생략하는지 확인한다.
- 전체 179개 이상 suite와 SDD 집중 시나리오가 함께 PASS하고 수동 alternate fixture가 제거됐는지 확인한다.

## 검증 결과

각 명령을 정확히 실행하고 actual stdout/stderr와 exit code를 아래에 기록한다. 명령을 바꾸면 `계획 대비 변경 사항`에 대체 명령과 이유를 먼저 기록한다.

### Policy 경계

```bash
python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_execution_target_policy.py
```

결과:
_미실행_

### Selector 경계와 failover

```bash
python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_select_execution_target.py SelectorRouteMatrixTests SelectorFailoverContractTests -v
```

결과:
_미실행_

### Dispatcher 집중 lifecycle

```bash
python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py TaskStageTest RouteDecisionPersistenceTest DynamicFailoverBudgetTest DispatcherCanonicalFailoverIntegrationTest -v
```

결과:
_미실행_

### 전체 suite

```bash
python3 -m unittest discover -s agent-ops/skills/project/orchestrate-agent-task-loop/tests -p 'test_*.py'
```

결과:
_미실행_

### Python compile

```bash
python3 -m py_compile agent-ops/skills/project/orchestrate-agent-task-loop/scripts/execution_target_policy.py agent-ops/skills/project/orchestrate-agent-task-loop/scripts/select_execution_target.py agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_execution_target_policy.py agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_select_execution_target.py agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py
```

결과:
_미실행_

### Diff check

```bash
git diff --check
```

결과:
_미실행_

---

> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section?**
> If anything is blank, go back and fill it in before saving this file.
> Leave review-agent-only sections unchanged.

## 섹션 소유권

| Section | Owner | Note |
|---------|-------|------|
| Header comment, 개요, 리뷰 에이전트 지시 | Fixed at stub creation | Implementing agent must not modify or execute these (archive, complete.log, and task-directory archive move are review-agent only) |
| Roadmap Targets | Fixed at stub creation from plan when present | Implementing agent must not modify; code-review copies it into complete.log as Roadmap Completion only on PASS |
| Archive Evidence Snapshot | Fixed at stub creation from plan when present | Implementing agent uses it as default prior-loop context; read only the specific archive files cited there when more detail is required |
| Agent UI Completion | Mixed | Present only for plan-required agent-ui code work; implementing agent fills actual evidence, review agent applies 구현됨 status/evidence update on PASS and copies the section into complete.log |
| 구현 항목별 완료 여부 (item names) | Fixed at stub creation | Implementing agent checks [ ] to [x] only |
| 구현 체크리스트 (item text/order) | Fixed at stub creation from plan | Implementing agent checks [ ] to [x] only |
| 코드리뷰 전용 체크리스트 | Review agent only | Implementing agent must not modify or check this section |
| 계획 대비 변경 사항, 주요 설계 결정 | Implementing agent | Replace placeholder text with actual content |
| 리뷰어를 위한 체크포인트 | Fixed at stub creation | Pre-filled from plan |
| 검증 결과 (section headings + commands) | Fixed at stub creation | Implementing agent fills in command output only; command changes require a 계획 대비 변경 사항 entry |
| 코드리뷰 결과 | Review agent appends | Not included in stub |

## 코드리뷰 결과

### 종합 판정

FAIL

### 차원별 평가

- Correctness: Fail — canonical Gemini/Laguna 후보 쌍, dispatcher failover, actual-invocation budget, completing-target selfcheck가 실행 경로에 연결되지 않았고 persisted decision resume도 현재 환경에서 오류가 난다.
- Completeness: Fail — 구현 체크리스트와 구현 항목 완료표가 전부 미완료이고 계획 대비 변경, 설계 결정, 검증 결과가 placeholder 상태다.
- Test coverage: Fail — 계획이 요구한 `DispatcherCanonicalFailoverIntegrationTest`가 존재하지 않고 전체 181개 suite도 1건 오류로 실패한다.
- API contract: Fail — selector `failover` 입력은 존재하지만 dispatcher bridge/persistence가 `transition`과 `failure_class`를 전달하지 않아 SDD S06 계약을 소비하지 않는다.
- Code quality: Pass — 관찰 범위에서 신규 debug 출력이나 포맷 오류는 확인되지 않았고 `py_compile`과 `git diff --check`는 통과했다.
- Implementation deviation: Fail — SDD S02/S06/S07/S10과 active plan의 네 구현 항목이 실행되지 않아 이전 단일-candidate/helper-only 상태가 남아 있다.
- Verification trust: Fail — 구현 에이전트 evidence가 없고 reviewer 재실행에서도 dispatcher 집중 검증과 전체 suite가 실패했다.
- Spec conformance: Fail — 승인 SDD의 S02, S06, S07, S10 Evidence Map을 충족하는 후보 순서, transition, stage counter, completing-target evidence가 없다.

### 발견된 문제

- Required — `agent-task/m-agent-task-runtime-target-selector/04+03_failover_budget/CODE_REVIEW-cloud-G08.md:65`: 구현 체크리스트, 완료표, 계획 대비 변경, 설계 결정과 모든 검증 결과가 미완료/placeholder여서 plan 12 구현을 완료했다는 evidence가 없다. 계획의 네 구현 항목을 실제 코드와 테스트로 완료하고 각 명령의 stdout/stderr 및 exit code를 구현 소유 섹션에 기록한다.
- Required — `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/execution_target_policy.py:94`: `local-G07~G08`이 시간대별 `candidates=(target,)` 하나만 반환해 SDD S06의 주간 Gemini→Laguna, 야간 Laguna→Gemini alternate가 없다. 두 canonical target을 시간대별 역순으로 반환하고 policy/selector 네 경계 테스트에서 rank 1/2 전체 순서를 검증한다.
- Required — `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py:1099`: selector bridge와 persisted helper가 prior 유무만으로 `initial|resume`을 고르고 `transition=failover`/`failure_class`를 전달하지 않는다. qualified failure에서 selector failover decision/history를 원자적으로 저장하고 `build_context_package` 결과를 다음 invocation prompt에 연결한다.
- Required — `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py:3064`: stage budget이 실제 invocation snapshot 대신 persisted decision의 기존 `selected`/transition을 기록하고 `run_escalating`은 여전히 `promoted_spec`으로 target을 바꾼다. 각 호출 직전 decision/spec/transition snapshot으로 실패를 기록하고 primary 1회+alternate 9회가 reopen 뒤에도 같은 worker-stage budget과 audit 필드를 공유하도록 통합 검증한다.
- Required — `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py:1157`: selfcheck 여부가 실제 completing target이 아니라 정적 `local` lane과 grade로 결정된다. worker 성공 target과 pinned decision을 저장해 Gemini→Laguna 완료만 Laguna selfcheck를 resume하고 Laguna→Gemini 및 cloud 완료는 생략하도록 한다.
- Required — `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py:5264`: helper 중심 `DynamicFailoverBudgetTest`만 있고 계획에 명시된 `DispatcherCanonicalFailoverIntegrationTest` 클래스가 없다. 주간/야간 qualified failover, logical prompt context, no-bounce/quota block, actual budget audit와 completing-target selfcheck를 실제 dispatcher invocation lifecycle로 추가한다.
- Required — `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/execution_target_policy.py:96`: 현재 `IOP_FORCE_GEMINI_TODAY=2026-07-26`에서 initial decision의 `time_window=manual-gemini-today`를 만들지만 prior-decision validator가 이 값을 허용하지 않아 resume이 `malformed_prior_decision`으로 실패한다. canonical KST 정책과 수동 override의 범위를 정리하고, 유지한다면 selector schema/validator와 resume 회귀를 일치시키며 전체 suite를 hermetic하게 통과시킨다.

### 검증 근거

- Policy 경계: 6 tests PASS, exit 0.
- Selector 경계와 failover: 7 tests PASS, exit 0. 단, 시간대별 단일 후보와 수동으로 삽입한 cloud alternate fixture를 정답으로 두므로 SDD S06 evidence가 아니다.
- Dispatcher 집중 lifecycle: 22 tests 중 2 errors, exit 1. `DispatcherCanonicalFailoverIntegrationTest`가 없고 `DynamicFailoverBudgetTest.test_runtime_budget_resets_on_success_and_blocks_tenth_failure_after_reopen`이 `manual-gemini-today` prior decision을 거부한다.
- 전체 suite: 181 tests 중 1 error, exit 1. 동일한 `malformed_prior_decision` 오류가 재현됐다.
- `py_compile`: PASS, exit 0, stdout/stderr 없음.
- `git diff --check`: PASS, exit 0, stdout/stderr 없음.

### 다음 단계

- FAIL follow-up: code-review가 현재 pair를 각 active route 기반 `code_review_cloud_G08_12.log`와 `plan_local_G08_12.log`로 아카이브하고, plan skill이 S02/S06/S07/S10 구현 및 실패한 resume 회귀를 포함한 새 PLAN/CODE_REVIEW pair를 fresh routing으로 생성한다.
