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

# Code Review Reference - REFACTOR

> **[IMPLEMENTING AGENT — READ FIRST]** Fill implementation-owned sections and checklist items with actual source and validation evidence. Leave review verdict, archive, complete log, and review-only checklist to the review agent.

## 개요

date=2026-07-26
task=m-agent-task-runtime-target-selector/07+06_context_review_recovery, plan=3, tag=REFACTOR

## Roadmap Targets

- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/agent-task-runtime-target-selector.md`
- Task ids: `context-failover`, `failure-budget`, `dispatch-integration`, `audit-tests`
- Completion mode: check-on-pass

## Archive Evidence Snapshot

- `plan_cloud_G09_2.log`: canonical fixed review decision과 nested audit evidence를 구현한 직전 계획.
- `code_review_cloud_G09_2.log`: Required — `latest_verdict_log()`의 mtime source selection이 reversed-mtime archive loops에서 past PLAN/work-unit을 선택했다. numeric suffix highest selection과 regression이 필요하다.
- `plan_local_G07_1.log`, `code_review_cloud_G07_1.log`: provider deny 및 최초 schema drift의 이전 evidence이며 재개 source가 아니다.

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

1. source와 implementation evidence를 대조한다.
2. verdict 뒤 active pair를 `code_review_cloud_G09_3.log`와 `plan_cloud_G09_3.log`로 아카이브한다.
3. PASS이면 `complete.log`과 task archive를 작성한다. WARN/FAIL이면 protocol의 next state만 작성하고 `complete.log`는 만들지 않는다.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|---|---|
| REFACTOR-6 Archive suffix based recovery source | [x] |
| TEST-4 Reversed-mtime archived loop recovery | [x] |

## 구현 체크리스트

- [x] canonical archive review log의 numeric suffix로 latest verdict를 결정하고 mtime 의존을 제거한다.
- [x] reversed-mtime multi-loop fixture에서 latest matching PLAN route/work-unit을 검증하고 malformed/non-verdict log를 배제한다.
- [x] focused/class/full unittest, `py_compile`, `git diff --check`, provider command/session/process `0/0/0` evidence를 기록한다.
- [x] 이 파일의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다.

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

> **[REVIEW AGENT ONLY]** 구현 에이전트는 이 항목을 변경하거나 체크하지 않는다.

- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
- [ ] 판정과 차원별 평가, Required/Suggested/Nit 분류가 일치한다.
- [ ] active `CODE_REVIEW-cloud-G09.md`를 `code_review_cloud_G09_3.log`로 아카이브한다.
- [ ] active `PLAN-cloud-G09.md`를 `plan_cloud_G09_3.log`로 아카이브한다.
- [ ] `.gitignore` Agent-Ops block을 확인한다.
- [ ] PASS이면 `complete.log`를 작성하고 active `.md`를 남기지 않는다.
- [ ] PASS이면 active task directory를 `agent-task/archive/YYYY/MM/m-agent-task-runtime-target-selector/07+06_context_review_recovery/`로 이동한다.
- [ ] PASS이면 runtime completion metadata만 보고하고 roadmap을 직접 수정하지 않는다.
- [ ] PASS split 작업이면 active parent 유지/정리를 확인한다.
- [ ] WARN/FAIL이면 next active pair 또는 USER_REVIEW 상태를 만들고 `complete.log`를 작성하지 않는다.

## 계획 대비 변경 사항

- 계획과 다르게 확장한 구현 범위는 없다. 계획에 지정된 `dispatch.py`, `test_dispatch.py`만 수정하고 이 CODE_REVIEW에 evidence를 기록했다.
- plan=2에서 반영된 canonical review decision, nested audit evidence, provider-deny guard는 보존했으며 이번 변경은 archive ordering source와 해당 회귀에만 한정했다.
- 사용자 지정 격리 조건에 따라 live provider, repo Edge-Node 진단, 보조 E2E smoke, full-cycle 실제 구동은 실행하지 않았다. 검증은 모두 `PATH=/usr/bin:/bin` Python simulation으로 수행했다.

## 주요 설계 결정

- `REVIEW_LOG_RE`는 `code_review_{local|cloud}_G{01..10}_{number}.log` 전체 이름만 허용하고 archive suffix를 정수로 파싱한다.
- `latest_verdict_log()`는 canonical regular file이면서 유일한 review verdict를 가진 후보만 모아 numeric suffix 최댓값을 선택한다. `st_mtime`은 더 이상 읽지 않으며 동일 suffix의 비정상 중복만 파일명으로 결정적으로 tie-break한다.
- verdict가 없는 canonical log와 malformed 이름은 후보에서 제외한다. 선택된 review header identity를 `matching_plan_log()`와 `official_review_plan_source()`에 전달하는 기존 fail-closed 복구, active pair 우선순위, fixed Codex review 정책은 변경하지 않았다.
- 회귀 fixture는 verdict가 있는 suffix `_9`의 mtime을 `_10`보다 새롭게 만들고, suffix `_11` non-verdict와 `_99_extra` malformed verdict를 함께 둔 뒤 `_10`의 matching PLAN route/work-unit이 복구되는지 검증한다.

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

- latest verdict가 mtime이 아니라 canonical numeric suffix 최댓값으로 결정되는가.
- matching PLAN이 선택된 verdict header identity와 일치하고 malformed/non-verdict logs는 fail closed 되는가.
- active pair 우선순위, canonical fixed Codex review, nested audit evidence가 유지되는가.
- 모든 test command가 provider-deny PATH에서 실행돼 real provider command/session/process가 0건인가.

## 검증 결과

### focused recovery ordering

명령: `env PATH=/usr/bin:/bin python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py SelectorDispatcherIntegrationTest.test_review_recovery_and_runtime_audit_evidence -v`

```text
Ran 1 test in 0.030s
OK
```

suffix `_9`/`_10`의 mtime을 역전한 상태에서 numeric `_10` review와 matching PLAN route/work-unit을 선택했고, `_11` non-verdict 및 `_99_extra` malformed log를 배제했다.

### integration and archive regressions

명령: `env PATH=/usr/bin:/bin python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py SelectorDispatcherIntegrationTest RepetitionLimitTest RouteDecisionPersistenceTest -v`

```text
Ran 15 tests in 5.306s
OK
```

active/recovery review, failure budget, generation pin/reset, nested audit 회귀를 포함해 PASS했다.

### full Python suite

명령: `env PATH=/usr/bin:/bin python3 -m unittest discover -s agent-ops/skills/project/orchestrate-agent-task-loop/tests -p 'test_*.py'`

```text
Ran 214 tests in 14.093s
OK
```

전체 stdout/stderr는 `/tmp/iop-g09-plan3-full.log`에 기록했다.

### py_compile

명령: `env PATH=/usr/bin:/bin 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`

```text
(stdout/stderr 없음, exit 0)
```

### diff check

명령: `git diff --check`

```text
(stdout/stderr 없음, exit 0)
```

### provider isolation

명령: `env PATH=/usr/bin:/bin sh -c 'for provider_name in pi agy claude codex; do command -v "$provider_name" || true; done'`

```text
(stdout/stderr 없음, exit 0)
```

- provider binary path 출력: 없음.
- focused/class test의 `invoke`/`build_command` deny guard: 호출 없음.
- full suite의 provider banner, locator, session 표시는 `/tmp` fixture와 fake runner evidence이며 실제 provider 실행이 아니다.
- real provider command/session/process 신규 실행 수: `0/0/0`.

---

> **[IMPLEMENTING AGENT — BEFORE SAVING]** Fill implementation-owned sections, then leave review-only sections unchanged.

## 섹션 소유권

| Section | Owner | Note |
|---|---|---|
| Header, 개요, Roadmap Targets, Archive Evidence Snapshot | Fixed at stub creation | Implementing agent must not modify. |
| 구현 항목별 완료 여부, 구현 체크리스트 | Implementing agent | Check only after actual implementation/evidence. |
| 코드리뷰 전용 체크리스트 | Review agent only | Implementing agent must not modify or check. |
| 계획 대비 변경 사항, 주요 설계 결정, 검증 결과 | Implementing agent | Record actual source/output only. |
| 코드리뷰 결과 | Review agent appends | Not present in stub. |

## 코드리뷰 결과

- 종합 판정: FAIL
- 차원별 평가:
  - correctness: Fail — archive suffix parser가 canonical count 표기가 아닌 leading-zero suffix도 허용해 malformed review 또는 PLAN log가 정상 loop source를 가로챌 수 있다.
  - completeness: Fail — mtime 의존 제거와 numeric review ordering은 구현됐지만 계획이 요구한 malformed filename 배제가 review/PLAN suffix 표현 전체에서 닫히지 않았다.
  - test coverage: Fail — reversed-mtime, non-verdict, `_99_extra`는 검증하지만 `_099` review와 `_010` PLAN처럼 숫자로 변환 가능한 non-canonical suffix가 recovery source가 되지 않는지는 검증하지 않는다.
  - API contract: Fail — archive count가 만드는 basename과 다른 파일이 logical loop identity로 수용되어 SDD S09의 persisted review identity와 S12의 audit source 계약을 위반한다.
  - code quality: Pass — numeric maximum 선택과 호출부 연결 자체에는 별도 Required/Suggested 문제가 없다.
  - implementation deviation: Fail — 계획의 strict canonical filename parser 및 malformed review/PLAN log 배제 요구와 달리 두 suffix 정규식이 `\d+`를 허용하고 matching PLAN 후보도 canonical name으로 제한하지 않는다.
  - verification trust: Pass — focused 1건, 관련 15건, 전체 214건과 정적 검증은 fresh 실행 결과가 제출 evidence와 일치했다.
  - spec conformance: Fail — malformed archive가 review recovery source를 바꿀 수 있어 SDD S09/S12의 결정적 identity/audit trace를 충족하지 못한다.
- 발견된 문제:
  - Required — `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py:29`: `REVIEW_LOG_RE`의 suffix `\d+`는 code-review archive count로 생성될 수 없는 leading-zero 이름(예: `code_review_cloud_G09_099.log`)도 canonical log로 수용한다. 이 파일에 verdict가 있으면 정상 최신 `code_review_cloud_G09_10.log`보다 numeric 99로 선택된다. focused probe에서 `regex_accepts_leading_zero=True`, `selected=code_review_cloud_G09_099.log`가 재현됐다. suffix를 archive count의 canonical ASCII decimal 표현(`0|[1-9][0-9]*`)으로 제한하고, leading-zero malformed verdict log가 정상 `_10` recovery source를 덮지 못하는 회귀 assertion을 추가해야 한다.
  - Required — `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py:28,811-816`: `PLAN_LOG_RE`도 leading-zero suffix를 허용하고 `matching_plan_log()`는 filename 정규형을 검사하지 않은 채 같은 header identity의 후보를 mtime으로 고른다. 정상 `plan_local_G04_10.log`보다 mtime이 큰 `plan_cloud_G10_010.log`를 두면 `plan_regex_accepts_leading_zero=True`, `matching_plan=plan_cloud_G10_010.log`가 재현됐다. PLAN suffix도 canonical ASCII decimal로 제한하고 matching 후보를 canonical regular file로 필터링하며, malformed matching PLAN이 정상 source를 덮지 못하는 회귀 assertion을 추가해야 한다.
- 다음 단계: FAIL — review/PLAN archive suffix에 canonical ASCII decimal만 허용하고 matching PLAN 후보를 canonical regular file로 제한한 뒤, reversed-mtime fixture에서 leading-zero malformed review/PLAN 후보가 정상 review/PLAN identity를 덮지 못하는지 재검증한다.
- 리뷰 검증 evidence:
  - `env PATH=/usr/bin:/bin python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py SelectorDispatcherIntegrationTest.test_review_recovery_and_runtime_audit_evidence -v` — 1 test PASS.
  - `env PATH=/usr/bin:/bin python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py SelectorDispatcherIntegrationTest RepetitionLimitTest RouteDecisionPersistenceTest -v` — 15 tests PASS.
  - `env PATH=/usr/bin:/bin python3 -m unittest discover -s agent-ops/skills/project/orchestrate-agent-task-loop/tests -p 'test_*.py'` — 214 tests PASS.
  - `env PATH=/usr/bin:/bin 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` — exit 0, 출력 없음.
  - canonical-suffix probe — `_10` 정상 verdict와 `_099` malformed verdict가 공존할 때 `regex_accepts_leading_zero=True`, `selected=code_review_cloud_G09_099.log`.
  - matching-PLAN probe — 같은 identity의 정상 `plan_local_G04_10.log`보다 mtime이 큰 `plan_cloud_G10_010.log`가 공존할 때 `plan_regex_accepts_leading_zero=True`, `matching_plan=plan_cloud_G10_010.log`.
  - provider binary path 출력 없음; real provider command/session/process 신규 실행 수 `0/0/0`.
