<!-- task=m-scheduled-market-data-refresh/04+03_refresh_status_cli plan=1 tag=REVIEW_API -->

# Plan - Review Follow-up: Refresh Status Runtime Wiring And S04 Evidence

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

이 plan은 `code_review_cloud_G08_0.log`의 FAIL 판정을 닫기 위한 후속 작업이다. 사용자에게 직접 질문하지 말고, Milestone lock 결정이 필요한 경우에만 `CODE_REVIEW-local-G06.md`의 `사용자 리뷰 요청` 섹션을 채운 뒤 멈춘다. 현재 발견 사항은 repo 안에서 구현과 검증으로 해결 가능한 문제이므로 기본 경로는 자동 follow-up이다.

## Review Route

- route: `local-G06`
- 근거: worker runtime wiring, socket handler, operator JSONL/handoff test 보강, roadmap artifact 복구로 범위가 좁고 deterministic local Go/contract/client lint 명령으로 검증 가능하다.

## Archive Evidence Snapshot

- archived plan: `agent-task/m-scheduled-market-data-refresh/04+03_refresh_status_cli/plan_cloud_G08_0.log`
- archived review: `agent-task/m-scheduled-market-data-refresh/04+03_refresh_status_cli/code_review_cloud_G08_0.log`
- verdict: FAIL
- Required summary:
  - worker process does not inject `RefreshStatus`, so `SchedulerRefreshStatusRequest` handler is not registered in real runtime.
  - scheduler loop does not record tick results into the refresh status store.
  - operator JSONL omits required `last_error` when empty, and handoff required keys do not enforce `last_error`/`next_run_unix_ms`.
  - SDD S04 success/stale/error exact evidence is incomplete.
  - roadmap `[refresh-status]` was checked before PASS/`complete.log`.
- affected files:
  - `services/worker/cmd/alt-worker/main.go`
  - `services/worker/internal/scheduler/status_store.go`
  - `services/worker/internal/scheduler/backfill.go`
  - `services/worker/internal/socket/handlers.go`
  - `services/worker/internal/socket/market.go`
  - `apps/cli/internal/operator/output.go`
  - `apps/cli/internal/operator/handoff_test.go`
  - `apps/cli/internal/operator/runner_market_test.go`
  - `apps/cli/testdata/operator/scheduler_refresh_status.yaml`
  - `apps/cli/testdata/operator/expected/scheduler_refresh_status.jsonl`
  - `apps/cli/testdata/operator/headless_validation.md`
  - `agent-roadmap/phase/backtest-loop/milestones/scheduled-market-data-refresh.md`
- verification evidence from failed loop:
  - `bin/contracts-check` PASS
  - `go test ./packages/contracts/gen/go/...` PASS
  - `go test ./services/api/...` PASS
  - `go test ./services/worker/...` PASS
  - `go test -count=1 ./apps/cli/internal/operator -run 'Test(RunScenarioRefreshStatus|HeadlessValidationHandoff|ExpectedOutputFixtures|HandoffExpectedFixtures)'` PASS
  - `bin/lint` exit code 0 with existing Flutter analyzer info in Mattermost integration

## Roadmap Targets

- `agent-roadmap/phase/backtest-loop/milestones/scheduled-market-data-refresh.md`
  - Handoff epic: `[refresh-status] success/stale/error status`

## 범위 결정 근거

이 follow-up은 새 public contract를 추가하지 않는다. 이미 추가된 refresh status contract를 실제 worker runtime에 연결하고, SDD S04 evidence가 항상 검증되도록 operator fixture/test와 premature roadmap artifact만 바로잡는다.

## 구현 항목

### [REVIEW_API-1] Worker runtime refresh status wiring

- 문제: `storeBackedDeps()`가 `socket.Deps.RefreshStatus`를 채우지 않고, `runSchedulerLoop()`도 `RunTick()` 결과를 store에 기록하지 않아 실제 worker process에서 refresh status handler가 등록되지 않는다.
- 해결:
  - worker startup에서 하나의 `scheduler.RefreshStatusStore`를 생성하고 socket deps와 scheduler loop가 같은 store를 공유하게 한다.
  - `storeBackedDeps` 또는 별도 wiring 함수가 `Deps.RefreshStatus`를 채우게 한다.
  - scheduler tick이 끝난 뒤 schedule별 status를 기록한다. `last_success`, `last_error`, `next_run`, imported bar count, missing/gap/duplicate/provider_delay가 S04 의미에 맞지 않으면 성공 evidence를 만들지 말고 필요한 모델 필드를 확장한다.
  - `capabilitiesForDeps()`가 refresh status surface를 드러내야 한다면 dependency 존재 시 안정적인 capability 문자열을 추가한다.
  - `RefreshStatusStore.RecordTick()`가 계속 쓰이면 no-item success, zero imported bar count, next_run 누락 같은 false evidence를 만들지 않도록 수정한다.
- 테스트 결정:
  - worker cmd wiring test가 `Deps.RefreshStatus` non-nil을 확인한다.
  - scheduler loop test가 tick 이후 store entry를 확인한다.
  - worker socket test가 handler 등록, capability, response field mapping을 확인한다.
- 중간 검증:
  - `go test -count=1 ./services/worker/cmd/alt-worker ./services/worker/internal/scheduler ./services/worker/internal/socket -run 'Test(StoreBackedDeps|SchedulerLoop|RefreshStatus|MarketHandlers|HandleSchedulerRefreshStatus|WorkerHelloCapabilities)'`

### [REVIEW_API-2] Operator S04 JSONL/handoff evidence completeness

- 문제: `last_error`가 빈 값이면 JSONL/text output에서 빠지고, handoff required keys도 `last_error`와 `next_run_unix_ms`를 강제하지 않는다. 또한 success/stale/error `SchedulerRefreshStatusEntry` evidence가 모두 exact-match로 검증되지 않는다.
- 해결:
  - `scheduler_refresh_status` step output은 `last_error`를 빈 문자열이어도 JSONL에 항상 포함한다.
  - text output도 S04 필수 field set을 stable하게 보여준다.
  - `requiredScenarioKeys["scheduler_refresh_status"]`에 `last_error`와 `next_run_unix_ms`를 포함한다.
  - fixture 또는 tests가 success, stale, error entry를 모두 구분하고 필수 field set을 검증하게 한다.
  - expected JSONL을 갱신할 때 key order는 기존 fixture style에 맞추고 summary line은 유지한다.
- 테스트 결정:
  - exact-match fixture test가 `last_error`, `next_run_unix_ms`, stale/error entry를 확인한다.
  - typed `ErrorInfo` test는 유지하되 scheduler status `"error"` entry test와 혼동하지 않게 이름/expect를 정리한다.
- 중간 검증:
  - `go test -count=1 ./apps/cli/internal/operator -run 'Test(RunScenarioRefreshStatus|HeadlessValidationHandoff|ExpectedOutputFixtures|HandoffExpectedFixtures)'`

### [REVIEW_API-3] Premature roadmap target check 복구

- 문제: active milestone의 `[refresh-status]`가 PASS 전 `[x]`로 체크됐다.
- 해결:
  - `agent-roadmap/phase/backtest-loop/milestones/scheduled-market-data-refresh.md`에서 `[refresh-status]`만 `[ ]`로 되돌린다. 이전 subtask에서 완료된 `schedule-config`, `scheduled-runner`, `retry-backfill` 체크는 건드리지 않는다.
  - 구현 에이전트는 follow-up 중 roadmap target을 다시 체크하지 않는다. 최종 PASS 시 code-review의 `complete.log` Roadmap Completion을 runtime이 소비한다.
- 테스트 결정:
  - diff로 `[refresh-status]`만 복구됐는지 확인한다.
- 중간 검증:
  - `git diff -- agent-roadmap/phase/backtest-loop/milestones/scheduled-market-data-refresh.md`

### [TEST-1] Final verification and review evidence

- 문제: FAIL 후속은 실제 stdout/stderr evidence를 다시 남겨야 한다.
- 해결:
  - 아래 최종 검증을 실행하고 `CODE_REVIEW-local-G06.md`에 실제 출력 또는 차단 사유를 붙인다.
- 최종 검증:
  - `bin/contracts-check`
  - `go test ./packages/contracts/gen/go/...`
  - `go test ./services/api/...`
  - `go test ./services/worker/...`
  - `go test -count=1 ./apps/cli/internal/operator -run 'Test(RunScenarioRefreshStatus|HeadlessValidationHandoff|ExpectedOutputFixtures|HandoffExpectedFixtures)'`
  - `bin/lint`

## 구현 체크리스트

- [ ] [REVIEW_API-1] Worker runtime refresh status store is wired into `alt-worker`, scheduler tick recording, handler registration, capabilities, and worker tests.
- [ ] [REVIEW_API-2] Operator JSONL/text/handoff fixtures always cover S04 required fields and success/stale/error entries.
- [ ] [REVIEW_API-3] Active roadmap `[refresh-status]` premature check is restored to unchecked without touching unrelated completed tasks.
- [ ] [TEST-1] Final verification commands are run and actual outputs are recorded in `CODE_REVIEW-local-G06.md`.
- [ ] `CODE_REVIEW-local-G06.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

