<!-- task=m-scheduled-market-data-refresh/05+04_backtest_readiness plan=0 tag=cloud-G08 -->

# Code Review Reference - TEST

## 리뷰어에게

이 파일은 `PLAN_cloud_G08.md` 구현 결과를 검토하기 위한 기준이다. 이 task가 PASS하면 roadmap target `[backtest-readiness]`를 완료할 수 있다.

## Archive Evidence Snapshot

- `agent-task/archive/2026/06/m-scheduled-market-data-refresh/01_scheduled_runner/complete.log`
- `agent-task/archive/2026/06/m-scheduled-market-data-refresh/02_retry_backfill/complete.log`
- `agent-task/m-scheduled-market-data-refresh/04+03_refresh_status_cli/complete.log`

## Roadmap Targets

- `agent-roadmap/phase/backtest-loop/milestones/scheduled-market-data-refresh.md`
  - Handoff epic: `[backtest-readiness] remote runner`

## 구현 에이전트 소유 섹션

### 구현 요약

- TEST-1 완료: `scheduled_backtest_readiness` scenario를 추가했다. 첫 step은 `scheduler_refresh_status`(kr-daily)로 scheduler tick 성공과 imported bar count를 확인하고, 이어서 `start_backtest` → `poll_backtest_run` → `get_backtest_result`로 backtest가 succeeded·exit code 0에 도달함을 검증한다. **seed `import_daily_bars` step을 두지 않아** scheduler-backed 데이터로만 readiness를 증명한다. fake API 기반 expected JSONL exact-match 골든 테스트(`TestScheduledBacktestReadinessFixture`)를 추가했고, 테스트 내에서 import step 부재와 첫 step이 scheduler_refresh_status인지도 단언한다.
- TEST-2 완료: `headless_validation.md`에 `scheduled_backtest_readiness` matrix row와 "Scheduler-backed backtest readiness 절차 (SDD S05)" 원격 실행 절차를 추가했다. 절차는 scheduler enabled worker/API에서 tick 완료를 `scheduler_refresh_status`로 확인한 뒤 seed import 없이 readiness scenario를 실행하는 순서이며, endpoint는 `$ALT_OPERATOR_API_URL` placeholder로 표현한다. handoff_test의 `requiredScenarios`/`requiredScenarioKeys`에 새 scenario를 등록해 matrix·fixture·exit code 계약 테스트가 신규 row를 강제 검증한다.
- TEST-4 (local 부분) 완료: 아래 local smoke 전부 PASS.
- **TEST-3 (remote runner evidence) 미완료 / BLOCKER**: 이 환경에서는 scheduler enabled 원격 runtime에 접근할 수 없어 scheduler tick 이후 remote 실행 evidence를 수집할 수 없다. 따라서 roadmap `[backtest-readiness]` target을 체크하지 않았다(plan 사용자 리뷰 흐름 준수).

### 변경 파일

- `apps/cli/testdata/operator/scheduled_backtest_readiness.yaml` (신규): scheduler-backed readiness scenario.
- `apps/cli/testdata/operator/expected/scheduled_backtest_readiness.jsonl` (신규): expected JSONL 골든.
- `apps/cli/internal/operator/runner_backtest_test.go`: `TestScheduledBacktestReadinessFixture` 추가 (+ `os`/`path/filepath` import).
- `apps/cli/internal/operator/handoff_test.go`: `requiredScenarios`·`requiredScenarioKeys`에 신규 scenario 등록.
- `apps/cli/testdata/operator/headless_validation.md`: matrix row + S05 원격 절차 섹션 추가.

### 검증 결과

- [x] `go test ./apps/cli/internal/operator -run 'Test(ScheduledBacktestReadiness|HeadlessValidationHandoff|ExpectedOutputFixtures)'` — PASS (`ok ... 0.009s`).
- [x] `go test ./apps/cli/...` — PASS (internal/cli, internal/operator ok; cmd/alt no test files).
- [x] `go test ./services/api/...` — PASS (config, contracts, socket, workerclient ok).
- [x] `go test ./services/worker/...` — PASS (scheduler, socket, backtest 등 전 패키지 ok).
- [x] `gofmt -l apps/cli/internal/operator/` — 신규/수정 파일 clean.
- [ ] remote runner `scheduled_backtest_readiness` scenario — **미실행 (환경 미가용, BLOCKER)**.

### Evidence

- refresh status success JSONL (local 골든 첫 line):
  `{"action":"scheduler_refresh_status",...,"imported_bar_count":120,...,"scheduler_status":"success","status":"ok","step":"refresh_status","type":"step"}`
- backtest result + summary exit code 0 (local 골든):
  `{"action":"get_backtest_result","ending_equity":"1125000","run_id":"run-0001","starting_cash":"1000000","status":"ok","step":"result","total_return":"0.125","trade_count":12,"type":"step"}`
  `{"exit_code":0,"passed":4,"scenario":"scheduled_backtest_readiness","status":"ok","steps":4,"type":"summary"}`
- roadmap `[backtest-readiness]` 체크 diff: **없음** — remote evidence 미수집으로 target 미체크 유지.

### 남은 위험

- remote runner evidence 미수집: roadmap target 완료를 위해 scheduler enabled 원격 runtime에서 `headless_validation.md`의 S05 절차(Step 1 `scheduler_refresh_status` success 확인 → Step 2 `scheduled_backtest_readiness` exit 0) 실행과 transcript 기록이 필요하다.
- scheduler tick timing: 원격에서 강제 tick 수단이 없으면 cadence 만큼 대기해야 하며, kr-daily universe(005930)가 적재되기 전 readiness scenario를 실행하면 backtest가 data-missing/failed로 끝날 수 있다.
- provider delay: KIS provider 지연 시 `scheduler_status`가 stale/error로 떨어져 Step 1 PASS 기준을 만족하지 못할 수 있다.
- 선행 정합성 nit: 선행 `04+03_refresh_status_cli/complete.log`는 `refresh-status: PASS`로 기록됐으나 roadmap milestone의 `[refresh-status]` 체크박스는 미체크 상태다(기능은 코드/테스트로 구현 완료). 본 task 범위 밖이므로 손대지 않았고, 사용자 확인이 필요하면 함께 정정 권장.

## 리뷰 에이전트 소유 섹션

### 리뷰 체크리스트

- [x] readiness fixture가 seed import step 없이 scheduler-backed data를 사용한다.
- [x] scenario가 refresh status success를 먼저 확인한다.
- [x] backtest matrix/result summary가 exit code 0 evidence를 남긴다.
- [x] handoff matrix와 expected JSONL fixture가 일치한다.
- [ ] remote runner transcript/artifact가 review 파일에 기록됐다.
- [x] roadmap target은 evidence PASS 이후에만 체크됐다.

### 리뷰 결과

- [ ] PASS
- [x] CHANGES_REQUESTED

## 사용자 리뷰 요청

다음 중 하나라도 해당하면 구현/리뷰 에이전트는 작업을 멈추고 `USER_REVIEW.md`를 작성한다.

- 요구사항 또는 SDD와 충돌하는 결정을 해야 한다.
- public API/contract 필드명, status 의미, evidence 기준을 바꿔야 한다.
- 테스트로 검증할 수 없는 운영 환경 전제가 필요하다.
- roadmap target 완료 여부가 불명확하다.

## 코드리뷰 결과

- 종합 판정: FAIL
- 차원별 평가:
  - correctness: Fail
  - completeness: Fail
  - test coverage: Warn
  - API contract: Pass
  - code quality: Pass
  - implementation deviation: Fail
  - verification trust: Fail
  - spec conformance: Fail
- 발견된 문제:
  - Required: `agent-task/m-scheduled-market-data-refresh/05+04_backtest_readiness/CODE_REVIEW_cloud_G08.md:44`에서 remote runner `scheduled_backtest_readiness` scenario가 미실행으로 남아 있다. SDD S05/Evidence Map은 `backtest-readiness` 완료 증거로 scheduler tick 이후 remote runner smoke와 exit code `0` evidence를 요구하므로, 현재 상태로는 roadmap target을 완료할 수 없다. 수정: scheduler enabled remote worker/API에서 `scheduler_refresh_status` success와 `scheduled_backtest_readiness` exit code 0 transcript/artifact를 수집해 review 파일에 실제 stdout/stderr 또는 artifact 경로를 기록한다.
  - Required: `apps/cli/testdata/operator/scheduled_backtest_readiness.yaml:18`의 첫 step expect는 `scheduler_status: success`만 강제하고, 주석과 handoff PASS 기준의 `imported_bar_count > 0`은 실행 실패 조건이 아니다. 실제 runner도 `apps/cli/internal/operator/runner.go:1284`에서 scheduler status만 비교하므로, imported bar count가 0이어도 scenario가 exit code 0으로 진행할 수 있다. 수정: `scheduler_refresh_status` expect에 imported bar count 최소값을 표현할 수 있는 필드를 추가하고 runner/validation/test/YAML이 `imported_bar_count >= 1`을 강제하도록 고친다.
- 다음 단계: FAIL follow-up plan/review를 작성한다. USER_REVIEW gate는 트리거하지 않는다.

### 코드리뷰 전용 체크리스트 (최종)

- [x] `코드리뷰 결과`에 `FAIL` 판정을 append했다.
- [x] 판정과 `차원별 평가`, Required 분류가 서로 일치한다.
- [x] active `CODE_REVIEW_cloud_G08.md`를 `code_review_cloud_G08_0.log`로 아카이브했다.
- [x] active `PLAN_cloud_G08.md`를 `plan_cloud_G08_0.log`로 아카이브했다.
- [x] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인했다.
- [x] FAIL이고 user-review gate가 트리거되지 않았으므로 다음 active `PLAN_cloud_G08.md`와 `CODE_REVIEW_cloud_G08.md`를 작성했고 `complete.log`를 작성하지 않았다.
