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

# Plan - 실제 handoff commit과 canonical sibling 재시작 회귀 보강

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

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

## 배경

현재 restart 회귀는 scheduler live-locator gate와 provider seam 0회를 확인하지만, pending handoff를 실제 `commit_retry_handoff_locator()`로 소비하지 않은 post-consume state를 직접 주입한다. 또한 sibling snapshot이 canonical local selector state가 아니어서 SDD의 persisted decision·quota evidence로 사용할 수 없다. 이번 후속은 해당 test 하나를 production StateStore commit과 canonical sibling state로 교체하며 dispatcher 구현과 정책은 바꾸지 않는다.

## Archive Evidence Snapshot

- Prior plan: `agent-task/m-agent-task-runtime-target-selector/11+10_unknown_isolation/plan_local_G06_15.log`
- Prior review: `agent-task/m-agent-task-runtime-target-selector/11+10_unknown_isolation/code_review_cloud_G06_15.log`
- Verdict: `FAIL`
- Required 1: restart regression이 actual `commit_retry_handoff_locator()` consume 대신 post-consume state를 직접 주입한다.
- Required 2: normal sibling snapshot이 Pi local canonical schema와 다르고 blocked path가 그 invalid state를 숨긴다.
- Suggested: 없음
- Nit: 없음
- Affected files: `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`
- Verification evidence: focused 3개와 selected dispatcher 20개는 PASS했다. 전체 257개는 scope 밖 `ReviewControlTest.test_final_channel_contract_is_top_level_and_singular` 1개만 FAIL했고 `py_compile`, `git diff --check`는 PASS했다.
- Ownership/dependency: 기존 split subtask `11+10_unknown_isolation`; predecessor `10+09_target_cap_removal`은 archived `complete.log`로 충족되었고 신규 사용자 결정·외부 권한은 없다.
- Roadmap carryover: `throughput-policy`, SDD S06/S09/S11의 persisted continuation, scheduler invocation, canonical sibling snapshot 불변성을 유지한다.

## 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-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py`
- `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`
- `agent-task/m-agent-task-runtime-target-selector/11+10_unknown_isolation/plan_local_G06_14.log`
- `agent-task/m-agent-task-runtime-target-selector/11+10_unknown_isolation/code_review_cloud_G06_14.log`
- `agent-task/m-agent-task-runtime-target-selector/11+10_unknown_isolation/plan_local_G06_15.log`
- `agent-task/m-agent-task-runtime-target-selector/11+10_unknown_isolation/code_review_cloud_G06_15.log`
- `agent-task/archive/2026/07/m-agent-task-runtime-target-selector/10+09_target_cap_removal/complete.log`
- `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-ops/rules/project/domain/testing/rules.md`, `agent-test/local/rules.md`, `agent-test/local/testing-smoke.md`

### SDD 기준

- SDD는 `[승인됨]`, SDD 잠금과 Milestone 구현 잠금은 `해제`이며 `USER_REVIEW.md`는 없다.
- S06 `context-failover`, S09 `dispatch-integration`, S11 `throughput-policy`의 Evidence Map은 persisted handoff, scheduler invocation, canonical decision/quota state를 결정적 Python regression으로 확인하도록 요구한다.
- checklist는 actual commit success와 close/reopen 뒤 live gate, 그리고 selector가 만든 sibling `quota_snapshot`·`execution_decisions`·`route_transition_history` JSON equality를 같은 test에서 묶는다.

### 테스트 환경 규칙

- `test_env=local`; `agent-test/local/rules.md`와 testing domain rule을 읽었다. `agent-test/local/testing-smoke.md`도 존재해 읽었지만 이 task는 Edge-Node user-flow가 아닌 dispatcher unit/integration simulation이므로 smoke/profile 명령은 적용하지 않는다.
- Python simulation은 실제 `pi`, `agy`, `claude`, `codex` provider process·session·network를 실행하지 않는다. scheduler path가 필요하므로 `invoke()`와 `asyncio.create_subprocess_exec` deny guard를 유지하고 deterministic StateStore fixture만 사용한다.
- 현재 checkout에서 focused/selected/full dispatcher unittest, `py_compile`, `git diff --check`를 fresh output으로 실행한다. Go identity는 `/config/.local/bin/go` -> `/config/opt/go/bin/go`, `go1.26.2`, `GOROOT=/config/opt/go`로 확인됐으며 Python 검증은 Go cache를 사용하지 않는다.

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

- first-record와 save-fault regression은 stable handoff ID 및 commit fault rollback을 이미 덮는다.
- current restart regression은 commit 이후 상태를 직접 주입해 commit-consume와 reopen을 연결하지 못하고, handcrafted sibling decision이 canonical Pi/local contract가 아니다.
- `test_retry_restart_does_not_duplicate_provider_or_mutate_sibling`에서 actual commit, reopened live gate, canonical sibling equality를 함께 검증해 이 공백을 닫는다.

### 심볼 참조

- renamed/removed symbol: 없음.
- 관련 경로: `StateStore.commit_retry_handoff_locator()`, `persisted_execution_decision()`, `external_active_is_live()`, `dispatch_with_store()`, `invoke()`.

### 분할 판단

- split 정책을 검토했다. 이 후속은 동일 test method 안에서만 검증 가능한 atomic commit·reopen·sibling snapshot 불변성 하나이며 production/test 또는 API/call-site 경계가 없다.
- 기존 `11+10_unknown_isolation`을 유지한다. predecessor `10`은 [complete.log](agent-task/archive/2026/07/m-agent-task-runtime-target-selector/10+09_target_cap_removal/complete.log)로 충족된다.

### 범위 결정 근거

- `test_dispatch.py`의 restart regression만 수정한다.
- `dispatch.py`, selector 정책·quota schema, `SKILL.md`의 scope 밖 full-suite failure, `WORK_LOG.md`, 다른 active task와 unrelated dirty files는 변경하지 않는다.

### 최종 라우팅

- `evaluation_mode=isolated-reassessment`, `finalizer=finalize-task-policy.sh`, `finalizer_mode=pair`.
- build/review closure는 모두 true다: exact findings와 touched test가 확정됐고, current checkout의 deterministic commands가 재현됐으며, ownership과 SDD decision은 닫혀 있다.
- build scores=`1/2/0/1/1`, route_basis=`local-fit`, capability_gap=`none`; loop-risk는 temporal_state, concurrent_consistency, boundary_contract, variant_product가 matched이고 `triggered=true`다.
- review scores=`1/2/0/1/1`, route_basis=`official-review`, capability_gap=`none`.
- finalizer output: build=`PLAN-local-G05.md`, review=`CODE_REVIEW-cloud-G05.md`, official target=`codex/gpt-5.6-sol xhigh`.

## 구현 체크리스트

- [ ] retry task의 pending context와 stable handoff ID를 실제 `commit_retry_handoff_locator()` true path로 소비해 active locator를 만든 뒤 StateStore를 close/reopen하고, scheduler live gate가 retry task의 `invoke()`와 provider seam을 다시 호출하지 않음을 deterministic regression으로 검증한다.
- [ ] independent sibling의 persisted decision과 quota snapshot을 canonical selector path로 만들고, 필요한 isolation state만 최소로 설정한 뒤 same scheduler run 전후 `quota_snapshot`, `execution_decisions`, `route_transition_history` JSON deep equality를 검증한다.
- [ ] focused handoff/restart 3개, selected dispatcher 20개, full dispatcher suite, `py_compile`, `git diff --check`의 실제 출력을 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다.

### [REVIEW_TEST-1] actual commit과 canonical sibling restart regression

- 문제: `test_dispatch.py:9903-10008`은 Pi/local contract와 다른 sibling decision을 수동 구성하고 active retry state도 post-consume 값으로 직접 주입한다. 이 방법은 `commit_retry_handoff_locator()`의 matching consume과 scheduler reopen 경계를 함께 검증하지 못한다.
- 해결 방법:
  - Before:
    ```python
    store.update_task(
        t_task,
        retry_quota_refresh_pending=False,
        retry_quota_refresh_context=None,
        active_locator=str(first_locator_path),
    )
    ```
  - After:
    ```python
    consumed = store.commit_retry_handoff_locator(
        t_task, handoff_id, str(first_locator_path),
    )
    self.assertTrue(consumed)
    self.assertFalse(store.task_state(t_task)["retry_quota_refresh_pending"])
    ```
  - sibling은 `persisted_execution_decision()`으로 valid local decision/quota를 만든 뒤, scheduler가 test-owned invariant를 깨지 않도록 필요한 isolation field만 설정한다.
- 수정 파일 및 체크리스트:
  - [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`: `test_retry_restart_does_not_duplicate_provider_or_mutate_sibling`의 retry setup과 sibling fixture/assertions를 교체한다.
- 테스트 작성: 작성. 같은 test에서 commit true, pending/context clear, active locator persistence, close/reopen, active task provider seam 0회, canonical sibling JSON deep equality를 assert한다.
- 중간 검증: `python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py ThroughputQuotaBatchTest.test_retry_restart_does_not_duplicate_provider_or_mutate_sibling -v` — PASS.

## 수정 파일 요약

| 파일 | 변경 항목 |
|---|---|
| `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py` | `REVIEW_TEST-1` actual handoff commit 및 canonical sibling restart assertions |

## 최종 검증

```bash
python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py ThroughputQuotaBatchTest.test_retry_handoff_first_locator_record_and_commit_guard ThroughputQuotaBatchTest.test_retry_handoff_production_save_fault_preserves_pending ThroughputQuotaBatchTest.test_retry_restart_does_not_duplicate_provider_or_mutate_sibling -v
python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py DynamicFailoverBudgetTest DispatcherCanonicalFailoverIntegrationTest BlockerDrainTest -v
python3 -m unittest discover -s agent-ops/skills/project/orchestrate-agent-task-loop/tests -p 'test_*.py'
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
git diff --check
```

Focused/selected/compile/diff는 PASS가 필요하다. full suite는 `ReviewControlTest.test_final_channel_contract_is_top_level_and_singular`의 현재 scope 밖 failure 외 새 failure가 없어야 하며, 구현 에이전트는 원문 출력을 기록한다. 모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다.
