<!-- task=m-agent-task-runtime-target-selector/11+10_unknown_isolation plan=5 tag=REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REFACTOR -->

# Plan - Retry blocker evidence와 task-local snapshot commit 완결

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

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

## 배경

다섯 번째 리뷰에서도 구현 에이전트 소유 evidence와 계획된 source/test 변경이 반영되지 않아 이전 Required가 그대로 재현됐다. terminal blocker typed evidence, qualified-only retry, persisted-unused pending snapshot, locator continuation과 deterministic dispatcher 회귀를 하나의 task-local 상태 수명으로 실제 구현해 반복되는 미착수 상태를 닫는다.

## Archive Evidence Snapshot

- Prior plan: `agent-task/m-agent-task-runtime-target-selector/11+10_unknown_isolation/plan_local_G07_4.log`
- Prior review: `agent-task/m-agent-task-runtime-target-selector/11+10_unknown_isolation/code_review_cloud_G07_4.log`
- Verdict: `FAIL`
- Required:
  - 야간 retry 회귀의 최초 decision에 deterministic snapshot이 없어 실제 `iop-node quota-probe`가 1회 호출되고 focused 13개 및 전체 251개 중 같은 1개가 실패함.
  - production recovery-limit blocker가 typed `blocker_evidence`를 기록하지 않으며 evidence 부재를 `provider-quota`로 기본 처리하고, 저장한 retry locator를 worker continuation에서 소비하지 않음.
  - retry admission이 persisted unused route가 아니라 현재 시각 policy candidates를 계산하고 shared snapshot을 정상 sibling에도 전달해 sibling quota/history를 갱신함.
  - 구현 완료 여부, 설계 결정, 계획 대비 변경, 검증 출력 등 구현 에이전트 소유 섹션이 미작성 상태임.
- Suggested: 없음
- Nit: 없음
- Affected files: `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py`, `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`
- Verification evidence: focused retry/throughput는 13개 중 1개 FAIL, `BlockerDrainTest`는 6개 PASS, 전체 Python suite는 251개 중 같은 1개 FAIL, `py_compile`과 `git diff --check`는 PASS였다.
- Roadmap carryover: `throughput-policy`와 SDD S11의 task-local explicit retry, pinned route/history, same-batch quota snapshot, unknown 격리 evidence를 유지한다.

## 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:
  - `throughput-policy`: target별 정적 cap 없이 ready task dispatch와 batch quota snapshot 재사용
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-task/m-agent-task-runtime-target-selector/11+10_unknown_isolation/plan_local_G07_4.log`
- `agent-task/m-agent-task-runtime-target-selector/11+10_unknown_isolation/code_review_cloud_G07_4.log`
- `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py`
- `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`
- `agent-ops/rules/project/domain/testing/rules.md`
- `agent-test/local/rules.md`
- `agent-test/local/testing-smoke.md`
- `agent-ops/rules/common/philosophy.md`
- `agent-roadmap/phase/automation-runtime-bridge/milestones/agent-task-runtime-target-selector.md`
- `agent-roadmap/sdd/automation-runtime-bridge/agent-task-runtime-target-selector/SDD.md`
- `agent-contract/index.md` — agent-task dispatcher에 매칭되는 계약 문서 없음.
- `agent-ops/rules/common/rules-agent-spec.md`
- `agent-spec/index.md` — agent-task dispatcher에 매칭되는 living spec 없음.
- `agent-task/archive/2026/07/m-agent-task-runtime-target-selector/10+09_target_cap_removal/complete.log` — split 선행 의존성 완료 확인.

### SDD 기준

- `agent-roadmap/sdd/automation-runtime-bridge/agent-task-runtime-target-selector/SDD.md`는 `[승인됨]`, SDD 잠금과 Milestone 구현 잠금은 `해제`다.
- 대상 Acceptance Scenario와 Evidence Map은 S11 → `throughput-policy` → 동시 dispatch와 same-batch quota snapshot evidence다.
- explicit retry는 기존 work unit의 route history와 pinned identity를 보존하고, 실제 qualified failure에 한해서만 fresh quota evidence로 아직 사용하지 않은 단방향 alternate를 평가해야 한다. 이 기준을 구현 체크리스트의 typed evidence, pending-only snapshot, sibling 불변과 deterministic dispatcher 검증으로 역산했다.

### 테스트 환경 규칙

- `test_env=local`; `agent-test/local/rules.md`와 testing route인 `agent-test/local/testing-smoke.md`를 읽었다.
- dispatcher 내부 persisted-state simulation이므로 Edge/Node user-flow, mock smoke, live provider preflight는 적용하지 않는다. repository Python unittest와 `agent-ops/rules/project/domain/testing/rules.md`의 provider 격리 guard를 검증 기준으로 사용한다.
- 실제 provider CLI/session/network/host quota subprocess를 실행하지 않고 runner, quota provider, subprocess seam을 deterministic fake/deny로 고정한다. 외부 checkout이나 remote preflight는 필요하지 않다.

### 원인과 경계

- `run_escalating`의 terminal recovery-limit 경로는 blocker 문자열과 locator만 저장하고 마지막 failure class, role, selected target, work unit identity를 typed evidence로 남기지 않는다.
- `StateStore.mark_retry_quota_refresh`는 evidence가 없을 때 failure class를 `provider-quota`로 가정하므로 generic recovery exhaustion도 qualified failover intent가 된다.
- retry context의 locator는 `persisted_execution_decision`에서 failure class 선택에만 일부 쓰이고 `run_worker(..., resume_locator=...)`/`run_escalating(initial_resume_locator=...)`로 전달되지 않는다.
- `build_admission_batch_snapshot`은 retry context의 persisted decision/history가 아니라 평가 시각의 policy candidates를 사용한다. scheduler는 결과 snapshot을 pending 여부와 무관하게 모든 worker에 전달해 ordinary resume도 quota/history를 재commit한다.
- `commit_execution_decision`은 commit과 동시에 retry context를 지우므로 decision 또는 continuation 준비가 실패하면 intent를 보존해야 한다.

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

- 야간 initial decision은 deterministic snapshot 없이 selector quota subprocess에 닿고, deny 예외가 `unknown`으로 정규화된 뒤 최종 `assert_not_called`에서 실패한다.
- retry dispatcher-path fake runner는 decision helper만 호출해 실제 `run_worker`에서 locator가 `run_escalating`으로 이어지는지 증명하지 않는다.
- 정상 sibling은 selected target만 비교해 quota snapshot, execution decision 전체, transition history, retry marker/context의 불변을 놓친다.
- current-time policy와 persisted unused route가 달라지는 KST 경계 variant가 없어 bounce 방지 계약을 검증하지 못한다.

### 심볼 참조

- rename/remove 없음.
- 영향 경계: terminal blocker 생성, `StateStore.mark_retry_quota_refresh`, `build_admission_batch_snapshot`, `persisted_execution_decision`, `commit_execution_decision`, `dispatch_with_store`, `run_worker`, `run_escalating`.

### 범위 결정 근거

- `select_execution_target.py`의 공개 decision schema와 route matrix는 변경하지 않는다. dispatcher 내부 state evidence와 기존 `transition="failover"` 입력 계약만 연결한다.
- global quota cache, target semaphore, reverse failover, generic stderr 추론, 새로운 route 정책은 범위 밖이다.
- unrelated dirty worktree와 sibling task artifact는 수정하지 않는다.

### 분할 판단

- terminal evidence 기록, pending admission, worker continuation, decision commit/consume는 같은 task-local retry intent의 원자적 수명이다. production/test를 분리하면 exactly-once와 sibling 불변을 중간 상태에서 검증할 수 없으므로 단일 plan을 유지한다.
- 선행 index `10`은 archived `complete.log`로 충족됐다.

### 최종 라우팅

- evaluation_mode=`isolated-reassessment`; prior route는 입력으로 재사용하지 않았다.
- finalizer=`finalize-task-policy.sh`, finalizer_mode=`pair`; build/review status=`routed`.
- build/review closures: `scope_closed=true`, `context_closed=true`, `verification_closed=true`, `evidence_trusted=true`, `ownership_closed=true`, `decision_closed=true`.
- build route_basis=`local-fit`; capability_gap=`none`.
- loop-risk observations: ordered transitions=`terminal blocker → retry intent → pending-only snapshot → qualified failover/ordinary resume → worker continuation → commit/consume`; actors=`scheduler admission + worker StateStore`; components=`terminal recovery + StateStore + admission provider + selector handoff + runner`; variants=`qualified/generic`, `blocked/normal`, `KST boundary`, `explicit retry/ordinary resume/new generation`. matched=`temporal_state`, `concurrent_consistency`, `boundary_contract`, `variant_product`; triggered=`true`, 라우팅 점수에는 영향 없음.
- build scores(scope_coupling/state_concurrency/blast_irreversibility/evidence_diagnosis/verification_complexity)=`1/2/1/1/2`, final=`local-G07`, filename=`PLAN-local-G07.md`.
- review route_basis=`official-review`; official execution=`codex/gpt-5.6-sol xhigh`; review scores=`1/2/1/1/2`, final=`cloud-G07`, filename=`CODE_REVIEW-cloud-G07.md`.

## 구현 체크리스트

- [ ] terminal blocker가 실제 role/failure class/locator/decision identity를 typed evidence로 기록하고 qualified failure만 failover intent로 승격한다.
- [ ] retry locator와 fresh snapshot을 actual worker continuation에 전달하고 successful commit 뒤에만 marker/context를 exactly once 소비한다.
- [ ] persisted unused candidates만 probe하고 snapshot을 pending worker에만 전달해 정상 sibling과 ordinary resume state를 보존한다.
- [ ] 고정 KST dispatcher-path 회귀와 외부 호출 deny assertion을 보강하고 focused/전체 suite를 통과한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다.

## 구현 항목

### [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REFACTOR-1] Terminal blocker evidence와 qualified retry intent

- 문제: production terminal blocker에는 typed failure evidence가 없고 retry 준비가 evidence 부재를 quota failure로 가정한다.
- 해결 방법:
  - recovery budget exhaustion이 blocker를 쓰는 시점에 role, 마지막 normalized failure class, locator, current selected target, work unit identity를 task-local `blocker_evidence`로 함께 기록한다.
  - retry 준비는 canonical qualified failure class와 유효한 current decision identity가 있을 때만 failover context를 만든다. generic/불완전 evidence는 quota failover로 추정하지 않고 기존 same-target retry semantics를 유지한다.
  - blocker clear/counter reset과 retry intent 생성의 순서를 하나의 StateStore update로 유지하고 다른 task state는 수정하지 않는다.
- 수정 파일 및 체크리스트:
  - [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py`: terminal blocker typed evidence를 기록한다.
  - [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py`: evidence validation과 qualified-only retry context 생성을 구현한다.
  - [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`: qualified/generic/incomplete evidence variant와 task-local state를 검증한다.
- 테스트 작성: 작성. 실제 `run_escalating` terminal exhaustion으로 생성한 evidence를 재시도 입력으로 사용하고 generic failure가 failover로 바뀌지 않음을 검증한다.
- 중간 검증: `python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py DynamicFailoverBudgetTest ThroughputQuotaBatchTest.test_retry_blocked_scopes_to_blocked_worker_and_refreshes_pinned_alternate -v` — PASS.

### [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REFACTOR-2] Pending-only snapshot과 locator continuation commit

- 문제: retry probe가 현재 시각 route를 재계산하고 shared snapshot이 정상 sibling에도 전달되며 locator는 worker 실행 경계에서 유실된다.
- 해결 방법:
  - pending retry는 persisted decision의 promotion/used history에서 아직 사용하지 않은 canonical cloud alternate만 추출해 probe한다. 현재 시각 initial policy로 route를 재선정하지 않는다.
  - scheduler는 retry snapshot을 해당 pending worker에만 전달한다. 정상 sibling, ordinary resume, review/selfcheck의 decision/quota/history/marker/context는 byte-equivalent state로 유지한다.
  - `run_worker`는 validated retry context의 locator를 `run_escalating(initial_resume_locator=...)`에 전달하고 fresh snapshot과 qualified failure class로 selector failover를 commit한다.
  - context package와 decision commit이 성공한 뒤 marker/context/blocker evidence를 함께 소비한다. selector/context/commit 실패 시 재시도 intent와 locator를 보존한다.
- 수정 파일 및 체크리스트:
  - [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py`: persisted-unused probe와 pending-only snapshot 전달을 구현한다.
  - [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py`: locator continuation과 success-only consume 경계를 연결한다.
  - [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`: full sibling state 불변, KST 경계, commit 실패/성공 전후를 검증한다.
- 테스트 작성: 작성. blocked Laguna work unit의 exact Gemini alternate probe 1회, failover history 1회, continuation locator와 sibling state 불변을 검증한다.
- 중간 검증: `python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py ThroughputQuotaBatchTest -v` — PASS.

### [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REFACTOR-3] Deterministic dispatcher-path evidence와 제출 완결

- 문제: 최초 selection이 host subprocess에 닿고 fake runner가 worker continuation 경계를 우회하며 구현 evidence가 비어 있다.
- 해결 방법:
  - 최초 야간 Laguna decision에 deterministic snapshot을 주입하고 KST 시각을 고정한다.
  - `dispatch_with_store(..., retry_blocked=True)`에서 실제 `run_worker`/`run_escalating` 경계를 통과하되 `invoke`, `build_command`, selector subprocess, provider CLI/session/network는 fake/deny로 격리한다.
  - exact probe key/count, transition trigger/failure class, selected target, work unit, used/promotion/history, locator continuation, marker/context exactly-once, normal sibling full state 불변을 assertion한다.
  - ordinary resume probe 0회와 새 generation fresh initial 규칙을 별도 variant로 보존한다.
  - 구현 후 active review의 완료 표, 체크리스트, 설계 결정, 계획 대비 변경, 검증 명령의 원문 출력과 exit code를 모두 채운다.
- 수정 파일 및 체크리스트:
  - [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`: deterministic initial snapshot과 actual worker-path regression을 작성한다.
  - [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`: 모든 external deny 및 sibling/state assertion을 추가한다.
  - [ ] `agent-task/m-agent-task-runtime-target-selector/11+10_unknown_isolation/CODE_REVIEW-cloud-G07.md`: 구현 에이전트 소유 evidence를 완성한다.
- 테스트 작성: 작성. production provider/subprocess는 실행하지 않는다.
- 중간 검증: `python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py ThroughputQuotaBatchTest SelectorDispatcherIntegrationTest.test_context_budget_and_retry_blocked_lifecycle -v` — PASS.

## 의존 관계 및 구현 순서

1. REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REFACTOR-1에서 신뢰 가능한 terminal evidence와 qualified-only intent를 만든다.
2. REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REFACTOR-2에서 intent를 pending-only snapshot과 actual continuation/commit에 연결한다.
3. REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REFACTOR-3에서 deterministic dispatcher 경계와 제출 evidence를 고정한다.
4. 전체 회귀로 SDD S11, unknown isolation과 독립 branch drain을 확인한다.

## 수정 파일 요약

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

## 최종 검증

- `python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py ThroughputQuotaBatchTest SelectorDispatcherIntegrationTest.test_context_budget_and_retry_blocked_lifecycle -v` — retry/ordinary/new-generation, exact alternate probe/failover, locator continuation, sibling state, 모든 deny guard 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 전체 Python 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/tests/test_dispatch.py` — exit 0.
- `git diff --check` — 출력 없음.

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