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

# Code Review Reference - REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08

> **[IMPLEMENTING AGENT - READ FIRST] Filling in this file is the mandatory final step of implementation.**
> The task is NOT complete until every implementation-owned section below is filled in.
> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving.
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
> If implementation is blocked by a selected Milestone `구현 잠금 > 결정 필요` item, fill `사용자 리뷰 요청` with evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`. Environment/secret/service setup, generic scope conflicts, loop exhaustion, and evidence gaps that a follow-up agent can close are normal follow-up issues, not user-review blockers by themselves.
> Do not ask the user directly, present choices in chat, or call `request_user_input` during implementation; record only the linked Milestone lock decision in `사용자 리뷰 요청` and stop for code-review.
> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume.
> Follow the ownership table at the bottom of this file for which sections you own.

## 테스트 환경 인지 필수

- 구현을 시작하기 전에 `agent-test/local/rules.md`와 `agent-ops/rules/private/testing-env.md`를 반드시 읽는다. private 문서의 host, IP, credential, secret-store 항목명, raw endpoint 값은 plan/review/log/docs에 복사하지 않는다.
- 현재 Codex local checkout은 field runtime이 아니다. local Go unit test는 `/config/workspace/alt`에서 실행하되, S05 scheduler/API/worker/KIS live smoke는 private testing-env가 지정한 field runner와 runtime 경계를 따른다.
- `ALT_OPERATOR_API_URL`이 local shell에서 UNSET인 것만으로 remote smoke 불가라고 결론내리지 않는다. private testing-env의 field runner에서 API/worker를 직접 기동하거나, 이미 기동된 operator control plane endpoint를 raw 값 출력 없이 확인한다.
- worker/API/scheduler smoke에서 DB/Redis는 repo 기본 localhost 값과 field/container network 값이 다를 수 있다. private testing-env가 지정한 경계를 따라 command lifetime env로만 주입하고, tracked 산출물에는 `DB/Redis route: private field runtime`처럼 safe summary만 남긴다.
- KIS credential은 private testing-env의 SOPS/age command-lifetime secret boundary를 따른다. raw key, token, account, password, secret item name을 stdout/stderr, task log, docs, roadmap에 남기지 않는다.
- code-server container와 macOS/field host의 역할을 혼동하지 않는다. 어떤 runner에서 어떤 command root로 실행했는지 safe summary로 기록하되, 개인 host 원문은 남기지 않는다.
- 공유 runtime/container 재시작은 사용자가 명시하지 않았으면 피한다. 필요하면 어떤 프로세스를 기동/종료했는지 safe summary와 cleanup 여부를 기록한다.

## 개요

date=2026-06-23
task=m-scheduled-market-data-refresh/05+04_backtest_readiness, plan=5, tag=REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08

## Roadmap Targets

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

## Archive Evidence Snapshot

- Current archived plan: `agent-task/m-scheduled-market-data-refresh/05+04_backtest_readiness/plan_cloud_G08_4.log`
- Current archived review: `agent-task/m-scheduled-market-data-refresh/05+04_backtest_readiness/code_review_cloud_G08_4.log`
- Verdict: FAIL
- Required summary:
  - `code_review_cloud_G08_4.log`: S05 handoff/final verification still treats `scheduler_refresh_status.yaml` as an exit `0` live remote step, while the same implementation evidence shows that fixture exits `1` on a single-schedule live runner because it is the S04 success/stale/error deterministic fixture.
  - `code_review_cloud_G08_4.log`: the recorded `scheduled_backtest_readiness` remote JSONL omits non-sensitive fields that current `apps/cli/internal/operator/output.go` always emits for `scheduler_refresh_status` steps (`last_error`, `missing_count`, `gap_count`, `duplicate_count`, `provider_delay_days`), so the remote transcript is not trusted as exact current-binary stdout.
- Affected files:
  - `apps/cli/testdata/operator/headless_validation.md`
  - `agent-task/m-scheduled-market-data-refresh/05+04_backtest_readiness/CODE_REVIEW_cloud_G08.md`
  - `apps/cli/testdata/operator/scheduled_backtest_readiness.yaml`
  - `apps/cli/testdata/operator/expected/scheduled_backtest_readiness.jsonl`
  - Only change CLI source/tests if the handoff contract cannot be made self-consistent with the existing `scheduled_backtest_readiness` scenario.
- Verification evidence:
  - Implementer local guard in archived review passed: `ok git.toki-labs.com/toki/alt/apps/cli/internal/operator 0.013s`.
  - Reviewer rerun passed: `go test -count=1 ./apps/cli/internal/operator -run 'Test(ScheduledBacktestReadiness|RunScenarioRefreshStatus|HeadlessValidationHandoff|ExpectedOutputFixtures)'` -> `ok git.toki-labs.com/toki/alt/apps/cli/internal/operator 0.015s`.
  - Reviewer package rerun passed: `go test -count=1 ./apps/cli/internal/operator` -> `ok git.toki-labs.com/toki/alt/apps/cli/internal/operator 0.388s`.
  - Reviewer compared archived remote transcript to `apps/cli/internal/operator/output.go` and found missing mandatory scheduler JSONL fields.
- Roadmap carryover:
  - Do not modify `agent-roadmap/**` in this follow-up. PASS completion metadata will carry `backtest-readiness`; runtime owns roadmap updates.
  - USER_REVIEW gate is not triggered by missing endpoint/secret/service setup, repeated loop failure, or evidence trust gaps. Record the blocker and leave the task failing if exact S05 evidence still cannot be collected.
- Allowed narrow archive reread:
  - `agent-task/m-scheduled-market-data-refresh/05+04_backtest_readiness/plan_cloud_G08_4.log`
  - `agent-task/m-scheduled-market-data-refresh/05+04_backtest_readiness/code_review_cloud_G08_4.log`

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

> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다.

각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다.

1. 판정을 append한다.
2. `CODE_REVIEW_cloud_G08.md` -> `code_review_cloud_G08_N.log`, `PLAN_cloud_G08.md` -> `plan_cloud_G08_M.log`로 아카이브한다.
3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/m-scheduled-market-data-refresh/05+04_backtest_readiness/`로 이동한다. WARN/FAIL이면 user-review gate를 확인한 뒤 다음 active plan/review 파일 또는 `USER_REVIEW.md`를 작성한다.
4. PASS이면 완료 이벤트 메타데이터를 보고한다. roadmap 수정이나 `update-roadmap` 직접 호출은 하지 않는다.
5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08-1] S05 handoff/final verification 계약을 live runner에서 재현 가능한 `scheduled_backtest_readiness` 중심으로 정리하고, `scheduler_refresh_status.yaml`을 S05 exit `0` gate로 요구하지 않게 한다. | [x] |
| [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08-2] 현재 checkout/binary에서 S05 remote `scheduled_backtest_readiness`를 다시 실행하고, 현재 JSONL writer와 일치하는 exact sanitized transcript/artifact evidence를 기록한다. | [ ] (remote scheduler tick 재현 불가로 차단; `검증 결과` 참고) |

## 구현 체크리스트

- [x] [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08-1] S05 handoff/final verification 계약을 live runner에서 재현 가능한 `scheduled_backtest_readiness` 중심으로 정리하고, `scheduler_refresh_status.yaml`을 S05 exit `0` gate로 요구하지 않게 한다.
- [ ] [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08-2] 현재 checkout/binary에서 S05 remote `scheduled_backtest_readiness`를 다시 실행하고, 현재 JSONL writer와 일치하는 exact sanitized transcript/artifact evidence를 기록한다. (remote scheduler tick 재현 불가로 차단; `검증 결과`에 실제 명령/출력/미실행 사유 기록)
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

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

> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.
> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다.

- [x] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
- [x] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다.
- [x] active `CODE_REVIEW-*-G??.md`를 `code_review_cloud_G08_N.log`로 아카이브한다.
- [x] active `PLAN-*-G??.md`를 `plan_cloud_G08_M.log`로 아카이브한다.
- [x] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인한다.
- [ ] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다.
- [ ] PASS이면 active task 디렉터리 `agent-task/m-scheduled-market-data-refresh/05+04_backtest_readiness/`를 `agent-task/archive/YYYY/MM/m-scheduled-market-data-refresh/05+04_backtest_readiness/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다.
- [ ] PASS이고 task group이 `m-scheduled-market-data-refresh`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다.
- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/m-scheduled-market-data-refresh/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다.
- [x] WARN/FAIL이고 user-review gate가 트리거되지 않았으면 다음 active `PLAN_cloud_G08.md`와 `CODE_REVIEW_cloud_G08.md`를 작성하고 `complete.log`를 작성하지 않는다.
- [ ] USER_REVIEW이면 `agent-ops/skills/common/code-review/templates/user-review-template.md` 기준으로 `USER_REVIEW.md`를 작성하고 active `PLAN-*.md`, `CODE_REVIEW-*.md`, `complete.log`를 남기지 않는다.
- [ ] USER_REVIEW가 연결된 Milestone 결정으로 완료/PASS 해소되면 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log`를 작성한 뒤 task directory를 archive로 이동한다.

## 계획 대비 변경 사항

- G08-1: 계획대로 doc-only 변경. `apps/cli/testdata/operator/headless_validation.md`의
  "Scheduler-backed backtest readiness 절차 (SDD S05)" 섹션에서 `scheduler_refresh_status.yaml`을
  live exit-0 Step 1으로 안내하던 2-step 절차를 제거하고, `scheduled_backtest_readiness.yaml`
  단일 scenario를 유일한 S05 live exit-0 gate로 명시했다. CLI source/test는 변경하지 않았다
  (handoff 계약이 기존 `scheduled_backtest_readiness` scenario만으로 self-consistent하게
  정리되어 새 fixture/expected JSONL이 필요 없었다).
- 추가로 "scheduler_refresh_status S04 검증 노트" 하위 섹션을 신설해, 해당 fixture가 SDD S04
  deterministic 3-state(success/stale/error) expected-output 검증용이며 single-schedule live
  runner에서는 stale/error row 부재로 exit `1`이 정상임을 명시했다(unit test/expected-output
  비교로 검증).
- G08-2: 계획의 remote 검증 명령(`scheduled_backtest_readiness.yaml` 단일 실행)을 임의 대체하지
  않았다. 다만 현재 환경에서 deterministic live S05 transcript를 신뢰성 있게 수집할 수 없어
  실행하지 못했고, 실제 시도 명령/출력/미실행 사유를 `검증 결과`에 기록했다. PLAN G08-2의
  "remote access/endpoint/scheduler tick/provider delay로 실행 불가 시 체크하지 않고 사유 기록,
  USER_REVIEW 미요청" 지침을 따랐다.

## 주요 설계 결정

- S05 live gate를 단일 scenario(`scheduled_backtest_readiness`)로 축소한 근거: 이 scenario의
  첫 step(`scheduler_refresh_status` action)이 `scheduler_status: success` + `min_imported_bar_count: 1`을
  fixture expect로 강제하므로, scheduler tick 성공과 적재 bar 수가 시각 확인이 아니라 runner의
  PASS 조건으로 보장된다. 별도의 standalone `scheduler_refresh_status.yaml` live 단계는 불필요할
  뿐 아니라 모순(single-schedule runner에서 stale/error 부재 → exit 1)을 유발하므로 제거했다.
- 새 live-only refresh-status scenario를 만들지 않은 근거: 기존 readiness scenario가 scheduler
  tick 성공 evidence를 이미 강제하므로 새 fixture/expected JSONL/handoff row/test를 추가할 정당성이
  없다(PLAN G08-1의 "그렇지 않으면 새 파일을 만들지 말고 기존 scheduled_backtest_readiness로 S05를
  닫는다"를 따름).
- G08-2 미실행 판단의 구조적 근거: (1) readiness backtest 기간은 2025-05-01~2025-05-15로 고정인데
  live scheduler tick은 backfill_window 기준 현재 시점 데이터를 적재하므로 fixed 과거 구간을
  deterministic하게 채우지 못한다. (2) `scheduler_refresh_status` action은 scheduler status_store에
  기록된 실제 tick 결과를 조회하므로 scheduler-enabled worker의 완료된 live tick이 선행되어야 한다.
  (3) 현재 원격 field runtime에 operator control plane(API/worker)이 기동되어 있지 않아, 이를
  새로 띄우고 KIS live tick을 강제하는 것은 공유 runtime 기동/재시작과 KIS live credential을
  요구한다(testing-env: 사용자 미지정 시 공유 runtime 재시작 회피).

## 테스트 환경 확인

_구현 에이전트가 private 값을 노출하지 않고 아래 항목을 채운다._

- 읽은 규칙: `agent-test/local/rules.md`, `agent-ops/rules/private/testing-env.md`
- local checkout root: `/config/workspace/alt`
- remote/field runner 사용 여부: 사용(probe 한정). field 호스트에 SSH 접속해 공유 volume git parity와 control plane 기동 여부만 확인. 실 scenario run은 미수행.
- API endpoint source: local shell UNSET. 원격 field runtime에 operator control plane(API/worker) 미기동 확인 → run 대상 endpoint 부재.
- DB/Redis route: `private field runtime` (code-server network DNS). 본 작업에서 직접 사용하지 않음.
- KIS secret boundary: `SOPS/age command-lifetime env` 미주입(live tick 미실행). raw key/token/account/secret item 출력 없음.
- runtime/process cleanup: 신규 기동/종료한 공유 runtime 프로세스 없음. SSH는 read-only probe만 수행.

## 사용자 리뷰 요청

_기본값은 `없음`이다. 구현 중 새 결정이 필요해 보여도 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 이 섹션은 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 차단할 때만 채운다. 외부 환경/secret/서비스 준비, 검증 증거 공백, 반복 실패, 일반 범위 조정은 사용자 리뷰 요청이 아니며 `검증 결과`, `계획 대비 변경 사항`, 또는 code-review의 일반 follow-up plan으로 처리한다._

- 상태: 없음
- 사유 유형: 없음
- 연결 대상: 없음
- 결정 필요: 없음
- 차단 근거: 없음
- 실행한 검증/명령: 없음
- 자동 후속 불가 이유: 없음
- 재개 조건: 없음

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

- S05 handoff/final verification이 standalone `scheduler_refresh_status.yaml` exit `0`을 요구하지 않는지 확인한다.
- `scheduled_backtest_readiness.yaml` 첫 step이 scheduler tick success와 `imported_bar_count >= 1`을 fixture contract로 강제하는지 확인한다.
- remote transcript의 scheduler JSONL line이 현재 `output.go`의 always-emitted non-sensitive fields와 일치하는지 확인한다.
- raw endpoint, token, credential, 개인 host 원문이 기록되지 않았는지 확인한다.

## 검증 결과

_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._

필수 규칙:
- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다.
- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다.
- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다.
- 사용자 리뷰 요청으로 명령을 끝까지 실행하지 못했다면 `사용자 리뷰 요청`에 실행한 명령, 실제 출력, 미실행 명령의 사유를 기록한다.
- mobile/UI hang, timeout, 또는 2분 무진행은 blind retry를 중단하고 focused rerun 명령과 screenshot/window/UI-tree evidence path를 남기며, 불가능하면 정확한 사유를 남긴다.

### 테스트 환경 인지 확인
```text
rules_read=agent-test/local/rules.md,agent-ops/rules/private/testing-env.md
local_checkout=/config/workspace/alt
remote_field_runner=field macOS host via SSH (read-only probe only)
api_endpoint_source=UNSET locally; no operator control plane running on remote field runtime
db_redis_route=private field runtime (not exercised)
kis_secret_boundary=SOPS/age command-lifetime env not injected (live tick not run); no raw secrets emitted
cleanup=no shared runtime process started or stopped; SSH probe only
```

### REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08-1 중간 검증
```bash
$ rg --sort path -n "scheduler_refresh_status.yaml|scheduled_backtest_readiness|S05|exit code" apps/cli/testdata/operator/headless_validation.md apps/cli/testdata/operator/scheduled_backtest_readiness.yaml apps/cli/testdata/operator/scheduler_refresh_status.yaml
apps/cli/testdata/operator/headless_validation.md:17:- exit code 계약: `0` 전 step 기대 일치, `1` typed error/expectation mismatch, `2` parse/validation/flag 오류, `3` transport 실패.
apps/cli/testdata/operator/headless_validation.md:30:| Scenario | Command | Input fixture | Expected output fixture | Expected output keys | Expected exit code | ... |
apps/cli/testdata/operator/headless_validation.md:52:| `scheduler_refresh_status` | ... testdata/operator/scheduler_refresh_status.yaml ... | `0` (성공·status 일치), `1` (typed error/mismatch) | ... (S04 evidence 패널) ...
apps/cli/testdata/operator/headless_validation.md:53:| `scheduled_backtest_readiness` | ... testdata/operator/scheduled_backtest_readiness.yaml ... | `0` (성공·scheduler tick 적재 데이터로 backtest succeeded) | ... (S05 evidence) ...
apps/cli/testdata/operator/headless_validation.md:91:## Scheduler-backed backtest readiness 절차 (SDD S05)
apps/cli/testdata/operator/headless_validation.md:93:`scheduled_backtest_readiness` scenario는 **seed import 없이** scheduler tick이 적재한
apps/cli/testdata/operator/headless_validation.md:97:backtest가 exit code 0으로 succeeded에 도달함을 확인한다. 첫 step expect는
apps/cli/testdata/operator/headless_validation.md:102:**S05 live exit-0 gate는 `scheduled_backtest_readiness.yaml` 단일 scenario뿐이다.**
apps/cli/testdata/operator/headless_validation.md:103:`scheduler_refresh_status.yaml`은 S05 live gate가 아니다. 그 fixture는 SDD S04용
apps/cli/testdata/operator/headless_validation.md:106:발생할 수 있다. 따라서 S04 fixture를 S05 final verification의 standalone exit-0 단계로
apps/cli/testdata/operator/headless_validation.md:119:# 단일 S05 명령: scheduler 적재 데이터로 readiness scenario를 실행한다 (seed import 없음).
apps/cli/testdata/operator/headless_validation.md:121:  --file testdata/operator/scheduled_backtest_readiness.yaml \
apps/cli/testdata/operator/headless_validation.md:126:#   step ok, summary status=ok 이며 process exit code 0.
apps/cli/testdata/operator/headless_validation.md:137:- `scheduler_refresh_status.yaml`은 success/stale/error 세 schedule을 모두 조회하는 SDD S04
apps/cli/testdata/operator/headless_validation.md:141:  실행하면 mismatch로 exit `1`이 날 수 있다. 이는 S04 fixture의 정상 동작이며 S05 readiness
apps/cli/testdata/operator/scheduled_backtest_readiness.yaml:1:name: scheduled_backtest_readiness
apps/cli/testdata/operator/scheduled_backtest_readiness.yaml:23:  #    terminal succeeded status with exit code 0 result evidence.

# (요약) S05 절차 섹션에서 scheduler_refresh_status.yaml을 live Step 1 exit-0 gate로
#   안내하던 블록을 제거하고, scheduled_backtest_readiness.yaml 단일 명령으로 정리.
#   scheduler_refresh_status.yaml은 S04 deterministic fixture로만 명시.

# 현재 바이너리가 두 fixture를 정상 파싱함을 offline validate로 확인 (real stdout):
$ /tmp/alt-cli operator scenario validate --file testdata/operator/scheduled_backtest_readiness.yaml
scenario=scheduled_backtest_readiness status=valid steps=4   # validate_exit=0
$ /tmp/alt-cli operator scenario validate --file testdata/operator/scheduler_refresh_status.yaml
scenario=scheduler_refresh_status status=valid steps=3       # validate_exit=0
```

### REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08-2 중간 검증
```bash
$ go test -count=1 ./apps/cli/internal/operator -run 'Test(ScheduledBacktestReadiness|RunScenarioRefreshStatus|HeadlessValidationHandoff|ExpectedOutputFixtures)'
ok  	git.toki-labs.com/toki/alt/apps/cli/internal/operator	0.017s

$ go test -count=1 ./apps/cli/internal/operator
ok  	git.toki-labs.com/toki/alt/apps/cli/internal/operator	0.389s
```

### 최종 검증
```bash
$ go run ./apps/cli/cmd/alt operator scenario run --file apps/cli/testdata/operator/scheduled_backtest_readiness.yaml --api-url "$ALT_OPERATOR_API_URL" --output jsonl
# 미실행(차단). 사유: deterministic live S05 transcript를 현재 환경에서 신뢰성 있게 수집할 수 없음.
# 실제 수행한 시도와 출력 (private 원문 비노출):

# 1) field runner SSH 접근 확인
$ ssh <field-host> 'uname -s'
SSH_OK
Darwin

# 2) 공유 volume git parity 확인 (current binary 기준 동일)
$ ssh <field-host> 'docker exec -u abc code-server bash -lc "cd /config/workspace/alt && git rev-parse HEAD && git status --short | head"'
bdbfe8228ea68d435ec790b8b32a318f45fb2bc4
 M apps/cli/internal/operator/runner.go
 M apps/cli/internal/operator/scenario.go
 M apps/cli/testdata/operator/headless_validation.md
 ... (현재 local dirty set과 동일)

# 3) operator control plane(API/worker) 기동 여부 확인
$ ssh <field-host> 'docker exec code-server bash -lc "ss -ltn | grep -E :3000|:18030|:18031 || echo NO_ALT_PORTS"'
NO_ALT_PORTS
$ ssh <field-host> 'docker exec code-server bash -lc "ps -eo pid,args | grep -E alt-api|alt-worker|cmd/alt | grep -v grep || echo NO_ALT_PROCS"'
NO_ALT_PROCS

# 4) 현재 바이너리 build/parse 확인
$ go build -o /tmp/alt-cli ./cmd/alt && echo BUILD_OK
BUILD_OK
$ /tmp/alt-cli operator scenario validate --file testdata/operator/scheduled_backtest_readiness.yaml
scenario=scheduled_backtest_readiness status=valid steps=4   # exit 0
```

#### G08-2 미실행 사유 (USER_REVIEW 아님, 일반 follow-up 차단)
- `$ALT_OPERATOR_API_URL` 로컬 UNSET이며, 원격 field runtime에 operator control plane이
  기동되어 있지 않아 run 대상 endpoint가 없다(위 NO_ALT_PORTS/NO_ALT_PROCS).
- `scheduled_backtest_readiness`의 첫 step(`scheduler_refresh_status`)은 scheduler status_store에
  기록된 실제 tick 결과를 조회하므로 scheduler-enabled worker의 완료된 live tick이 선행되어야
  한다. tick을 강제 트리거할 수단 없이 cadence 대기 + KIS live credential(SOPS/age) 주입이 필요하다.
- readiness backtest 기간은 2025-05-01~2025-05-15 고정인데, live scheduler tick은 backfill_window
  기준 현재 시점(2026-06) 데이터를 적재하므로 해당 fixed 과거 구간을 seed import 없이 deterministic
  하게 채워 backtest succeeded(exit 0)에 도달시키는 것이 현재 구성에서 보장되지 않는다.
- control plane을 새로 띄우고 KIS live tick을 강제하는 것은 공유 runtime 기동/재시작을 수반한다.
  testing-env 규칙상 사용자 미지정 시 공유 runtime 재시작을 피하므로, evidence 공백으로 남기고
  G08-2를 미체크 상태로 보고한다(PLAN G08-2 지침에 따라 USER_REVIEW는 요청하지 않는다).

---

> **[IMPLEMENTING AGENT - BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?**
> If anything is blank, go back and fill it in before saving this file.
> Leave review-agent-only sections unchanged.

## Sections and Ownership

| 섹션 | 소유자 | 설명 |
|------|--------|------|
| 헤더 주석, 개요(date/task/plan/tag), 리뷰 에이전트 지시 | 스텁 생성 시 고정 | 구현 에이전트가 수정하거나 실행하지 않음 |
| Roadmap Targets | follow-up plan에서 복사해 스텁 생성 시 고정 | 구현 에이전트가 수정하지 않음; PASS 시 code-review가 `complete.log`의 `Roadmap Completion`으로 복사 |
| Archive Evidence Snapshot | follow-up plan에서 복사해 스텁 생성 시 고정 | 구현 에이전트의 기본 이전 루프 컨텍스트; 추가 확인이 필요할 때 여기에 명시된 archive 파일만 좁게 읽음 |
| 구현 항목별 완료 여부 | 구현 에이전트 | `[ ]` -> `[x]` 체크만 수행 |
| 구현 체크리스트 | 구현 에이전트 | `[ ]` -> `[x]` 체크만 수행; 마지막 체크박스는 저장 전 필수 |
| 코드리뷰 전용 체크리스트 | Review agent only | Implementing agent must not modify or check this section |
| 계획 대비 변경 사항, 주요 설계 결정 | 구현 에이전트 | placeholder 텍스트를 실제 내용으로 교체 |
| 사용자 리뷰 요청 | 구현 에이전트 | 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 차단할 때만 채움 |
| 리뷰어를 위한 체크포인트 | 스텁 생성 시 고정 | 계획에서 추출한 리뷰 포인트 |
| 검증 결과 | 구현 에이전트 | 실행 출력만 구현 에이전트가 채움 |
| 코드리뷰 결과 | 리뷰 에이전트 | 스텁에 포함하지 않음 |

## 코드리뷰 결과

- 종합 판정: FAIL
- 차원별 평가:
  - Correctness: Fail
  - Completeness: Fail
  - Test coverage: Fail
  - 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_5.log:80` / `agent-task/m-scheduled-market-data-refresh/05+04_backtest_readiness/code_review_cloud_G08_5.log:240` - 계획의 G08-2와 SDD S05 Evidence Map이 요구하는 `scheduled_backtest_readiness` remote runner exit `0` transcript가 아직 없다. 구현 파일도 G08-2를 미체크로 남겼고 최종 검증 명령은 "미실행(차단)"으로 기록되어 있어 `backtest-readiness` 완료 증거로 쓸 수 없다. Fix: current checkout/binary가 반영된 scheduler-enabled remote API/worker runtime에서 `go run ./apps/cli/cmd/alt operator scenario run --file apps/cli/testdata/operator/scheduled_backtest_readiness.yaml --api-url "$ALT_OPERATOR_API_URL" --output jsonl`을 실행하고, raw endpoint/secret 없이 full JSONL(stdout/stderr), process exit `0`, summary `exit_code=0`, binary/git parity를 기록한다.
  - Required: `apps/cli/testdata/operator/scheduled_backtest_readiness.yaml:30` / `apps/cli/testdata/operator/headless_validation.md:131` - 현재 S05 handoff는 scheduler가 `kr-backtest-smoke` universe bar를 적재해야 한다고만 말하지만, scenario는 fixed range `2025-05-01` to `2025-05-15`를 사용한다. 구현 증거도 current scheduler tick/backfill window가 이 fixed range를 seed 없이 deterministic하게 채운다는 보장이 없다고 기록한다. Fix: remote S05 실행 전에 field scheduler config/backfill window와 scenario 기간이 같은 bar range를 보장하도록 정리하거나, S05 fixture/handoff를 scheduler가 실제로 적재한 range와 맞춘 뒤 exact remote exit `0` evidence를 남긴다. Local fake API success만으로 이 항목을 닫지 않는다.
- 다음 단계: FAIL 후속으로 active `PLAN_cloud_G08.md`와 `CODE_REVIEW_cloud_G08.md`를 새로 작성한다. USER_REVIEW gate는 트리거하지 않는다.
