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

# Plan - REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08 S05 Remote Evidence Closure

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

이 follow-up plan은 직전 code review FAIL의 Required finding 두 개만 해결한다. 사용자에게 직접 질문하지 말고, selected Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 막는 경우에만 `CODE_REVIEW_cloud_G08.md`의 `사용자 리뷰 요청` 섹션을 채운다. remote endpoint, token, credential, 개인 host 원문은 tracked 파일에 기록하지 않는다.

## 테스트 환경 인지 필수

- 구현을 시작하기 전에 `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 재시작은 사용자가 명시하지 않았으면 피한다. 필요하면 공유 runtime 재시작이 아니라 task 전용 transient process로 처리하고, 어떤 프로세스를 기동/종료했는지 safe summary와 cleanup 여부를 기록한다.

## 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_5.log`
- Current archived review: `agent-task/m-scheduled-market-data-refresh/05+04_backtest_readiness/code_review_cloud_G08_5.log`
- Verdict: FAIL
- Required summary:
  - `code_review_cloud_G08_5.log`: G08-2 remains incomplete. The active review left the remote `scheduled_backtest_readiness` run unchecked and recorded the required final command as not executed, so SDD S05 has no current-binary remote runner exit `0` transcript.
  - `code_review_cloud_G08_5.log`: the S05 gate is still not proven reproducible because `scheduled_backtest_readiness.yaml` uses fixed `2025-05-01..2025-05-15` dates while the handoff only says the scheduler must load the universe; the implementation itself records that current scheduler backfill may not cover that fixed period.
- Affected files:
  - `apps/cli/testdata/operator/scheduled_backtest_readiness.yaml`
  - `apps/cli/testdata/operator/headless_validation.md`
  - `apps/cli/testdata/operator/expected/scheduled_backtest_readiness.jsonl`
  - `agent-task/m-scheduled-market-data-refresh/05+04_backtest_readiness/CODE_REVIEW_cloud_G08.md`
  - Only change CLI source/tests if the S05 gate cannot be made reproducible with fixture/config/handoff changes alone.
- Verification evidence:
  - Reviewer local 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.011s`.
  - Reviewer package rerun passed: `go test -count=1 ./apps/cli/internal/operator` -> `ok git.toki-labs.com/toki/alt/apps/cli/internal/operator 0.386s`.
  - Reviewer confirmed SDD S05 requires `remote runner smoke after scheduler tick` with `backtest-readiness` exit code `0` evidence.
- 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_5.log`
  - `agent-task/m-scheduled-market-data-refresh/05+04_backtest_readiness/code_review_cloud_G08_5.log`

## 범위 결정 근거

- follow-up route는 `cloud-G08`을 유지한다. 완료 여부가 scheduler-enabled remote runner, current-binary transcript, field runtime process setup, scheduler tick, KIS command-lifetime secret boundary, sanitized evidence trust에 걸려 있어 local-only review 조건을 만족하지 않는다.
- 이 follow-up은 SDD S05 evidence closure 전용이다. S04 `scheduler_refresh_status.yaml` deterministic fixture를 다시 live S05 gate로 되돌리지 않는다.

## 구현 체크리스트

- [x] [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08-1] S05 gate의 fixture/handoff/field runtime 전제가 같은 date range와 universe를 보장하도록 정리한다.
- [x] [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08-2] current checkout/binary에서 remote `scheduled_backtest_readiness`를 실행하고 exact sanitized JSONL transcript와 process exit `0` evidence를 기록한다. (live transient worker tick → exit 0 수집 완료, CODE_REVIEW 검증 결과 참고)
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 구현 항목

### [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08-1] S05 reproducible gate contract

- 문제: `apps/cli/testdata/operator/scheduled_backtest_readiness.yaml`은 `from_unix_ms: 1746057600000` to `1747267200000` fixed backtest range를 사용하지만, `apps/cli/testdata/operator/headless_validation.md`는 scheduler가 `kr-backtest-smoke` universe bar를 적재해야 한다고만 말한다. 직전 review evidence도 current scheduler tick/backfill window가 fixed range를 채운다는 보장이 없다고 기록했다.
- 해결:
  - field scheduler config/backfill window가 `scheduled_backtest_readiness.yaml`의 fixed range와 `kr-backtest-smoke` universe를 실제로 보장하는지 safe summary로 확인한다. raw config endpoint/secret은 기록하지 않는다.
  - 보장되지 않으면 S05 gate를 재현 가능한 방향으로 좁게 고친다. 후보는 둘 중 하나다: field scheduler config/handoff에 fixed range를 채우는 task 전용 scheduler runbook을 명시하거나, `scheduled_backtest_readiness.yaml`과 expected JSONL을 scheduler가 실제로 적재한 range와 맞추도록 수정한다.
  - 어떤 방향을 선택하든 `scheduler_refresh_status.yaml`을 S05 live exit `0` gate로 되돌리지 않는다.
  - 변경 시 관련 targeted tests와 expected fixture를 함께 갱신한다.
- 중간 검증:
  - `rg --sort path -n "scheduled_backtest_readiness|from_unix_ms|to_unix_ms|kr-backtest-smoke|backfill_window|S05" apps/cli/testdata/operator/scheduled_backtest_readiness.yaml apps/cli/testdata/operator/headless_validation.md services/worker`
  - `go test -count=1 ./apps/cli/internal/operator -run 'Test(ScheduledBacktestReadiness|HeadlessValidationHandoff|ExpectedOutputFixtures)'`

### [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08-2] Exact current-binary remote S05 transcript

- 문제: SDD S05 Evidence Map은 remote runner smoke after scheduler tick과 exit code `0` evidence를 요구한다. 직전 구현은 local tests만 통과했고, remote `scheduled_backtest_readiness` command는 미실행이었다.
- 해결:
  - 먼저 `agent-test/local/rules.md`와 `agent-ops/rules/private/testing-env.md`를 읽었다는 safe confirmation을 `CODE_REVIEW_cloud_G08.md`에 남긴다. raw private 값은 남기지 않는다.
  - private testing-env 경계를 따라 field runner에서 current checkout/dirty set 또는 built binary가 이번 변경을 반영했는지 확인한다.
  - 이미 기동된 operator control plane이 있으면 그것을 사용하고, 없으면 공유 runtime/container restart 없이 task 전용 transient API/worker process를 기동한다. process를 기동했다면 safe summary와 cleanup을 기록한다.
  - scheduler-enabled worker가 `scheduled_backtest_readiness`의 target universe/date range를 채운 뒤 아래 command를 실행한다. command line의 raw endpoint, token, credential, 개인 host 원문은 숨겨도 되지만 JSONL stdout/stderr의 비민감 필드(`last_error`, `missing_count`, `gap_count`, `duplicate_count`, `provider_delay_days` 등)는 삭제하지 않는다.
  - transcript 또는 artifact path에는 생성 명령, binary/checksum 또는 git HEAD/dirty set 확인, summary `exit_code=0`, process exit `0`을 남긴다.
  - remote access, endpoint, scheduler tick, provider delay, host-key trust 문제로 실행할 수 없으면 이 항목을 체크하지 않는다. 실제 명령, 실제 출력, 미실행 사유를 `검증 결과`에 남기고 USER_REVIEW는 요청하지 않는다.
- remote 검증:
  - `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`
- local guard:
  - `go test -count=1 ./apps/cli/internal/operator -run 'Test(ScheduledBacktestReadiness|RunScenarioRefreshStatus|HeadlessValidationHandoff|ExpectedOutputFixtures)'`
  - `go test -count=1 ./apps/cli/internal/operator`

## 최종 검증

- `go test -count=1 ./apps/cli/internal/operator -run 'Test(ScheduledBacktestReadiness|RunScenarioRefreshStatus|HeadlessValidationHandoff|ExpectedOutputFixtures)'`
- `go test -count=1 ./apps/cli/internal/operator`
- `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`

모든 증거 기록 완료 후 반드시 `CODE_REVIEW_cloud_G08.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
