<!-- task=m-agent-task-runtime-target-selector/07+06_context_review_recovery plan=0 tag=REFACTOR -->

# Plan - Context·budget 소비와 review recovery closure

## 이 파일을 읽는 구현 에이전트에게

선행 `06+05_runtime_quota_failover`의 `complete.log`가 확인된 뒤 구현한다. 구현과 검증을 끝낸 뒤 `CODE_REVIEW-cloud-G09.md`의 구현 에이전트 소유 섹션을 실제 내용과 원문 출력으로 채운다. active 파일은 그대로 두고 review 준비 완료만 보고한다. 종결은 code-review skill 전용이다. 차단되면 정확한 원인, 시도한 명령/출력, 재개 조건만 구현 에이전트 소유 evidence에 기록한다. 사용자에게 질문하거나 user-input 도구를 호출하지 않고, control-plane stop file 생성, 다음 상태 분류, archive/log 이동, `complete.log` 또는 roadmap 수정은 하지 않는다.

## 배경

runtime transition을 실제 cross-adapter continuation, stage 실패 예산, retry-blocked, review recovery와 운영 audit evidence에 연결해 dispatcher 통합 범위를 닫는다.

## 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:
  - `route-pin`: 작업 세대별 최초 route 고정과 재시작 복원
  - `context-failover`: 단방향 adapter failover와 논리적 context 이전
  - `failure-budget`: target 전환 전후 동일 stage 실패 예산 공유
  - `dispatch-integration`: persisted selector decision 기반 최초 실행·resume·failover
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py`
- `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`
- `agent-test/local/rules.md`
- `agent-roadmap/sdd/automation-runtime-bridge/agent-task-runtime-target-selector/SDD.md`

### SDD 기준

- 대상 Acceptance Scenario는 S05~S07과 S09다. 이 closure child가 context transition, stage budget, retry-blocked, review recovery와 selector audit evidence를 검증하고 원본 Roadmap Targets를 소유한다.

### 테스트 환경 규칙

- `test_env=local`; `agent-test/local/rules.md`가 존재하며 끝까지 읽었다.
- agent-ops Python dispatcher에 매칭되는 `agent-test/local/*.md` profile은 없다. 현재 checkout의 Python test manifest를 fallback 근거로 삼아 fresh-process `unittest`, `py_compile`, `git diff --check`를 사용하며 test-rule 유지보수는 필요하지 않다.
- provider subprocess는 fake runner와 임시 workspace/state/locator로 대체하고 실제 cloud/local 호출은 하지 않는다.
- 계획 시점 전체 Python suite 기준선은 169 tests PASS다.

### 테스트 커버리지 공백

- normalized context package와 selector history가 실제 continuation invocation에 연결되지 않는다.
- retry-blocked의 decision/history 보존과 동일 stage failure budget 공유가 검증되지 않는다.
- review finalization recovery와 locator/status/dry-run의 selector evidence가 없다.

### 심볼 참조

- `dispatch.py:2658-2828` continuation/budget lifecycle과 `dispatch.py:794-865,2158-2186,3665-3672,4193-4222` review recovery 및 audit output을 갱신한다.

### 분할 판단

- 원본 `05+04_dispatch_integration`의 마지막 closure child다.
- `06+05_runtime_quota_failover`의 decision/history를 소비하며 이 child PASS 뒤 selfcheck 정책 task가 시작된다.

### 범위 결정 근거

- context package, stage budget, retry-blocked, review recovery, locator/status/dry-run evidence만 변경한다.
- selector matrix와 quota probe mapping은 선행 child 결과를 소비하고 재설계하지 않는다.

### 최종 라우팅

- evaluation_mode: `isolated-reassessment`
- finalizer=`finalize-task-policy.sh`, finalizer_mode=`pair`; build/review status=`routed`.
- build closures: `scope_closed=true`(승인 SDD와 이 subtask 경계가 고정됨), `context_closed=true`(명시된 source/test 범위를 한 local 작업에서 유지 가능), `verification_closed=true`, `evidence_trusted=true`, `ownership_closed=true`, `decision_closed=true`.
- review closures: `scope_closed=true`, `context_closed=true`(동일 source/test 및 구현 evidence로 판정 가능), `verification_closed=true`, `evidence_trusted=true`, `ownership_closed=true`, `decision_closed=true`.
- build route_basis=`local-fit`; capability_gap=`none`.
- build loop-risk audit: matched signatures=`temporal_state`, `boundary_contract`, `variant_product`; 이 기록은 lane/G를 바꾸지 않는다.
- build scores(scope_coupling/state_concurrency/blast_irreversibility/evidence_diagnosis/verification_complexity)=`2/2/1/1/2`, final=`local-G08`, filename=`PLAN-local-G08.md`.
- review route_basis=`official-review`; official execution=`codex/gpt-5.6-sol xhigh`; capability_gap=`none`.
- review scores(scope_coupling/state_concurrency/blast_irreversibility/evidence_diagnosis/verification_complexity)=`2/2/1/2/2`, final=`cloud-G09`, filename=`CODE_REVIEW-cloud-G09.md`.

## 구현 체크리스트

- [ ] cross-adapter invocation이 persisted normalized-output context package를 소비하고 dynamic failover와 기존 cloud promotion 모두 같은 stage 실패 예산을 이어받는다.
- [ ] dry-run은 read-only preview이고 retry-blocked는 blocker/budget만 초기화하며 review resume/finalization recovery는 pinned Codex와 독립 budget을 유지한다.
- [ ] locator/state/status가 work unit, rule/candidate/reason, quota, transition과 stage budget을 추적하고 통합 테스트가 restart·blocker·독립 drain을 함께 검증한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다.

## 구현 항목

### [REFACTOR-3] Context, budget과 retry-blocked 소비

- 문제: `dispatch.py:2658-2687` continuation과 `dispatch.py:2708-2828` budget lifecycle은 선행 task의 normalized context package, selector history, `clear_blocked()` 보존 규칙을 실제 invocation에 연결하지 않는다.
- 해결 방법:

```python
# Before: agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py:2790
prompt = base_prompt(task, role, spec) if previous_locator is None else continuation_prompt(...)
```

```python
# After
prompt = continuation_prompt_from_package(
    context_package,
    target=decision["selected"],
    native_resume=same_pi_target,
)
```

  qualified primary failure는 count 1, alternate 추가 9회 실패가 총 10 blocker가 되며 성공 target을 state/locator에 기록하고 동일 stage 성공에서만 reset한다. 일반 primary 실패는 same-target count만 늘리고 전환하지 않는다. `--retry-blocked`는 blocker와 stage counter를 초기화하되 decision/history/used candidate를 보존하고, quota-exhausted alternate만 새 snapshot으로 재평가해 available/unknown이면 진행하며 시간 변화·실패 횟수로 새 initial/bounce/cloud 승격하지 않는다.
- 수정 파일 및 체크리스트:
  - [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py`: invocation payload, locator/result state, budget lifecycle.
  - [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`: fake runner input과 누적 failure evidence.
- 테스트 작성: `SelectorDispatcherIntegrationTest`에서 primary 1회→alternate 9회=10 blocker, restart, 성공 reset, retry-blocked exhausted→available, history 보존, 독립 branch drain을 temp state/locator로 검증한다.
- 중간 검증: `python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py SelectorDispatcherIntegrationTest -v` — context/budget/retry/drain case가 PASS해야 한다.

### [REFACTOR-4] Review recovery와 runtime audit evidence

- 문제: `dispatch.py:794-865` finalization recovery는 active review `.md`가 없을 수 있고, locator/status/dry-run(`dispatch.py:2158-2186,3665-3672,4193-4222`)에는 selector work unit/rule/candidate/reason/quota/transition/budget이 없다.
- 해결 방법:

```python
# Before: agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py:4198
spec = AgentSpec("codex", "gpt-5.6-sol", "codex/gpt-5.6-sol xhigh") if stage == "review" else route_agent(task)
```

```python
# After
decision = read_or_preview_stage_decision(task, state, stage=stage, dry_run=args.dry_run)
lines = status_lines(task, stage, "ready") + selector_evidence_lines(decision)
```

  active review initial에서 Codex decision을 stage별로 보존하고 archive recovery는 동일 header identity의 persisted decision을 resume한다. legacy state에 decision이 없으면 archived header를 검증해 official-review fixed Codex decision만 합성하며 quota probe/failover를 금지한다. locator와 persisted transition history에 `work_unit_id`, `rule_id`, priority, candidate ranks/selected target, reason codes, quota snapshot id/status, transition과 stage budget을 기록하고 status/dry-run은 secret/raw provider output 없이 같은 evidence를 표시한다.
- 수정 파일 및 체크리스트:
  - [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py`: review recovery와 locator/status/dry-run audit fields.
  - [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`: active review resume, post-archive restart와 evidence consistency.
- 테스트 작성: `SelectorDispatcherIntegrationTest`에서 review pinned Codex resume/독립 budget/no quota/no worker decision reuse, legacy fixed recovery, state-locator-status-dry-run evidence 일치를 검증한다.
- 중간 검증: `python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py SelectorDispatcherIntegrationTest -v` — review recovery와 audit assertions가 PASS해야 한다.

## 의존 관계 및 구현 순서

1. `06+05_runtime_quota_failover`의 `complete.log`가 PASS여야 한다.
2. REFACTOR-3의 context/budget 결과를 REFACTOR-4가 review recovery와 audit evidence로 닫는다.
3. 이 task PASS 후 `08+07_selfcheck_policy`를 진행한다.

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py` | REFACTOR-3, REFACTOR-4 |
| `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py` | REFACTOR-3, REFACTOR-4 |

## 최종 검증

- `python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py SelectorDispatcherIntegrationTest -v` — context/retry/review/audit 회귀 PASS.
- `python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py BlockerDrainTest -v` — 독립 branch drain 회귀 PASS.
- `python3 -m unittest discover -s agent-ops/skills/project/orchestrate-agent-task-loop/tests -p 'test_*.py'` — fresh process 전체 suite PASS.
- `python3 -m py_compile agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py 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/tests/test_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` — exit 0.
- `git diff --check` — 출력 없음.

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다.

