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

# Plan - REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08 S05 Handoff and Evidence Trust Recovery

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

이 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 재시작은 사용자가 명시하지 않았으면 피한다. 필요하면 어떤 프로세스를 기동/종료했는지 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_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`

## 범위 결정 근거

- follow-up route는 `cloud-G08`을 유지한다. 완료 여부가 scheduler-enabled remote runner, current-binary transcript, runtime endpoint, scheduler tick, sanitized evidence trust에 걸려 있어 local-only review 조건을 만족하지 않는다.
- SDD S05는 `scheduled_backtest_readiness` 같은 result/readiness scenario의 exit code `0` evidence를 요구한다. S04 `scheduler_refresh_status.yaml`의 deterministic 3-state fixture를 live S05 exit `0` gate로 유지하지 않는다.

## 구현 체크리스트

- [ ] [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를 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 구현 항목

### [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_cloud-G08-1] S05 handoff command contract

- 문제: `apps/cli/testdata/operator/headless_validation.md`의 S05 절차가 `scheduler_refresh_status.yaml`을 원격 Step 1처럼 안내하지만, 이 fixture는 SDD S04 success/stale/error expected JSONL 검증용이다. single-schedule live runner에서는 stale/error rows가 없어 exit `1`이 정상적으로 발생할 수 있으므로 S05 live PASS gate로 두면 완료 조건이 모순된다.
- 해결:
  - `scheduled_backtest_readiness.yaml`의 첫 `scheduler_refresh_status` step이 `scheduler_status: success`와 `min_imported_bar_count: 1`을 강제한다는 점을 S05의 required live tick evidence로 문서화한다.
  - `scheduler_refresh_status.yaml`은 S04 deterministic fixture/expected-output 검증으로 유지하고, S05 final verification에서 standalone exit `0` 필수 명령으로 요구하지 않는다.
  - 별도 live-only refresh status scenario가 정말 필요하다고 판단하면 새 fixture와 expected JSONL, handoff row, targeted tests를 함께 추가한다. 그렇지 않으면 새 파일을 만들지 말고 기존 `scheduled_backtest_readiness`로 S05를 닫는다.
  - `CODE_REVIEW_cloud_G08.md`의 계획 대비 변경 사항에는 source/doc/test 변경 여부를 사실대로 기록한다.
- 중간 검증:
  - `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`

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

- 문제: 직전 remote transcript는 S05 success 방향을 보여주지만, 현재 JSONL writer가 항상 출력하는 non-sensitive scheduler fields가 빠져 있어 exact stdout으로 신뢰할 수 없다.
- 해결:
  - 먼저 `agent-test/local/rules.md`와 `agent-ops/rules/private/testing-env.md`를 읽었다는 safe confirmation을 `CODE_REVIEW_cloud_G08.md`에 남긴다. raw private 값은 남기지 않는다.
  - 현재 checkout/diff가 반영된 CLI binary를 사용해 remote scheduler-enabled worker/API runtime에서 `scheduled_backtest_readiness.yaml`을 다시 실행한다.
  - 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`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
