<!-- task=m-scheduled-market-data-refresh/03+01,02_refresh_status_model plan=0 tag=cloud-G07 -->

# Plan - Refresh Status Model

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

이 plan은 `Scheduled Market Data Refresh` milestone의 handoff 에픽 중 `refresh-status`를 바로 완료하지 않고, 먼저 worker scheduler 내부에서 재사용 가능한 refresh status 모델과 직렬화 기준을 만드는 선행 작업이다. 이 작업 자체는 roadmap 체크박스를 완료하지 않는다. 후속 `04+03_refresh_status_cli`가 API/worker socket/operator CLI까지 연결하고 `refresh-status` roadmap target을 닫는다.

## 배경

현재 SDD S04는 operator가 `last_success`, `last_error`, `next_run`, imported bar count, missing/gap/duplicate/provider_delay를 통해 success/stale/error refresh 상태를 확인할 수 있어야 한다고 요구한다. 기존 worker scheduler에는 freshness/backfill 판단 일부가 있지만, S04가 요구하는 status record를 안정적으로 만들고 검증하는 모델이 아직 없다.

## 사용자 리뷰 요청 흐름

구현 중 사용자 판단이 필요한 계약 변경, status 의미 변경, imported bar count 산정 방식 변경이 생기면 즉시 작업을 멈추고 USER_REVIEW 요청을 남긴다. 이 plan 범위에서는 public contract를 추가하지 않으므로, public API 노출은 후속 plan에서 결정한다.

## Archive Evidence Snapshot

- `agent-task/archive/2026/06/m-scheduled-market-data-refresh/01_scheduled_runner/complete.log`: S02 scheduled runner 완료 PASS. 검증에 `go test ./services/worker/...` 포함.
- `agent-task/archive/2026/06/m-scheduled-market-data-refresh/02_retry_backfill/complete.log`: S03 retry/backfill 완료 PASS. 검증에 `go test -count=1 ./services/worker/internal/scheduler`, `go test ./services/worker/...` 포함.

## 분석 결과

### 읽은 파일

- `agent-roadmap/current.md`
- `agent-roadmap/phase/backtest-loop/PHASE.md`
- `agent-roadmap/phase/backtest-loop/milestones/scheduled-market-data-refresh.md`
- `agent-roadmap/sdd/backtest-loop/scheduled-market-data-refresh/SDD.md`
- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/private/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-ops/skills/common/router.md`
- `agent-ops/skills/common/plan/SKILL.md`
- `agent-test/local/rules.md`
- `agent-test/local/profiles/worker-smoke.md`
- `agent-ops/rules/domain/worker/rules.md`
- `services/worker/internal/scheduler/backfill.go`
- `services/worker/internal/scheduler/backfill_test.go`
- `services/worker/internal/scheduler/runner.go`
- `services/worker/internal/scheduler/runner_test.go`
- `services/worker/internal/scheduler/config.go`
- `services/worker/internal/scheduler/config_test.go`
- `services/worker/cmd/alt-worker/main.go`
- `services/worker/cmd/alt-worker/main_test.go`
- `services/worker/cmd/alt-worker-schedule-check/main.go`

### SDD 기준

- S04: scheduler tick 뒤 success/stale/error refresh 상태를 operator가 확인할 수 있어야 한다.
- Evidence Map S04: headless refresh-status scenario와 JSONL evidence가 필요하다.
- 이 plan은 S04의 public evidence까지 완료하지 않고, S04 구현에 필요한 worker-local status record와 테스트 가능한 상태 산출 기준을 만든다.

### 테스트 환경 규칙

- 테스트 환경: local.
- 적용 profile: `worker-smoke`.
- 구현 후 worker scheduler 단위 테스트와 worker smoke를 실행한다.

### 테스트 커버리지 공백

- 현재 `FreshnessObservation`과 `BackfillDecision`은 stale/error 판단을 보유하지만 `last_success`, `next_run`, imported bar count를 포함한 단일 status record 테스트가 없다.
- scheduler tick 실행 결과가 operator/API로 노출되지 않으므로, 이 plan에서는 내부 모델 테스트만 채우고 후속 plan에서 통합 테스트를 추가한다.

### 심볼 참조

- 기존 public symbol 제거/rename 금지.
- 새 symbol은 worker internal scheduler package 안에 두고 후속 API/CLI plan에서만 외부 노출 여부를 결정한다.

### 분할 판단

- 이 task group은 `m-scheduled-market-data-refresh`다.
- 선행 의존성 `01_scheduled_runner`, `02_retry_backfill`은 archive complete log 기준으로 충족됐다.
- 이 plan은 `refresh-status`의 worker model foundation이다.
- 후속 `04+03_refresh_status_cli`는 이 plan의 `complete.log`가 생긴 뒤 진행한다.
- 후속 `05+04_backtest_readiness`는 `04+03_refresh_status_cli` 완료 뒤 진행한다.

### 범위 결정 근거

S04 전체를 한 번에 구현하면 worker scheduler, worker socket, protobuf contract, API forwarding, operator CLI, handoff evidence가 동시에 바뀐다. 이 plan은 불변 조건과 status 산출을 먼저 고정해 후속 contract/API 작업의 위험을 줄인다.

### 빌드 등급

`cloud-G07`. worker 내부 모델과 테스트 중심 작업이지만 scheduler/backfill 의미를 건드리므로 local worker 전체 smoke를 요구한다.

## 구현 체크리스트

### [API-1] Refresh status record 모델 추가

- 문제: scheduler/backfill 판단 결과를 S04 필드 집합으로 표현하는 단일 내부 모델이 없다.
- 해결: `services/worker/internal/scheduler/backfill.go`에 worker-local refresh status 구조체와 산출 함수를 추가한다.
- 파일 체크리스트:
  - `services/worker/internal/scheduler/backfill.go`
  - `services/worker/internal/scheduler/backfill_test.go`
- 구현 기준:
  - `RefreshStatus` 또는 동등한 내부 구조체에 schedule/name, status, `last_success`, `last_error`, `next_run`, imported bar count, missing/gap/duplicate/provider_delay를 담는다.
  - success/stale/error status 의미는 기존 `FreshnessObservation.Status`, `FreshnessObservation.LastError`, `BackfillDecision.Reason`과 충돌하지 않게 명시한다.
  - `next_run`은 `ValidationItem.NextRun` 또는 동일 schedule validation 결과에서 유래하도록 한다.
  - imported bar count는 후속 plan에서 실제 API/worker tick 결과와 연결할 수 있도록 별도 입력으로 받는다. 이 plan에서 임의 추정치를 만들지 않는다.
- 테스트 결정:
  - success/stale/error status record 산출 테스트를 추가한다.
  - imported bar count가 입력값 그대로 보존되는지 확인한다.
- 중간 검증:
  - `go test -count=1 ./services/worker/internal/scheduler`

### [API-2] Status 직렬화 헬퍼 추가

- 문제: 후속 operator/API evidence에서 필드 누락이나 이름 불일치가 발생하기 쉽다.
- 해결: scheduler package 내부에 text/JSONL 테스트용 직렬화 헬퍼를 추가하거나 기존 writer 패턴과 일치하는 방식으로 field contract를 테스트한다.
- 파일 체크리스트:
  - `services/worker/internal/scheduler/backfill.go`
  - `services/worker/internal/scheduler/backfill_test.go`
- 구현 기준:
  - JSON field name은 후속 CLI/API에서 재사용하기 쉬운 snake_case를 사용한다.
  - timestamp는 기존 코드의 시간 표현 관례를 우선한다.
  - 빈 `last_error`와 zero imported count가 누락되지 않도록 한다.
- 테스트 결정:
  - JSONL round-trip 또는 exact field assertion을 추가한다.
- 중간 검증:
  - `go test -count=1 ./services/worker/internal/scheduler`

### [TEST-1] Worker smoke 검증

- 문제: scheduler internal 변경이 worker command/tests에 영향을 줄 수 있다.
- 해결: worker smoke를 실행하고 결과를 review 파일에 기록한다.
- 파일 체크리스트:
  - `CODE_REVIEW_cloud_G07.md`
- 테스트 결정:
  - local worker smoke profile을 따른다.
- 중간 검증:
  - `go test ./services/worker/...`

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

## 수정 파일 요약

- `services/worker/internal/scheduler/backfill.go`: refresh status 내부 모델과 산출/직렬화 헬퍼 추가.
- `services/worker/internal/scheduler/backfill_test.go`: success/stale/error, imported count, JSON field coverage 추가.
- `CODE_REVIEW_cloud_G07.md`: 구현 요약, 검증 로그, 남은 위험 기록.

## 최종 검증

- `gofmt -l services/worker/internal/scheduler/backfill.go services/worker/internal/scheduler/backfill_test.go`
- `go test -count=1 ./services/worker/internal/scheduler`
- `go test ./services/worker/...`

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
