8.3 KiB
Plan - BACKFILL
이 파일을 읽는 구현 에이전트에게
CODE_REVIEW-local-G04.md의 구현 에이전트 소유 섹션을 채우는 것이 구현의 마지막 단계다. 검증 명령을 실행하고 실제 stdout/stderr를 붙여 넣은 뒤 active 파일을 그대로 두고 review ready 상태로 보고한다. 선택된 SDD 결정이나 선택된 Milestone 구현 잠금 > 결정 필요 항목이 막으면 직접 질문하지 말고 review stub의 사용자 리뷰 요청 섹션에 근거를 기록한다. 구현 에이전트는 USER_REVIEW.md, complete.log, archive 로그를 만들지 않는다.
배경
retry-backfill은 provider delay, missing, gap을 성공으로 숨기지 않고 stale/error 상태와 backfill window로 남겨야 한다. 현 코드에는 schedule config validation은 있지만 freshness result를 retry/backfill decision으로 바꾸는 worker-local 계산 표면이 없다. SDD S03은 fixture 또는 local smoke에서 missing/gap/provider delay 케이스가 stable text/JSONL로 구분되는 증거를 요구한다.
사용자 리뷰 요청 흐름
사용자 리뷰는 선택된 SDD decision 또는 Milestone lock decision만 active review stub의 사용자 리뷰 요청 섹션에 기록한다. 구현 중 직접 채팅 질문, 선택지 제시, request_user_input 호출은 금지한다. code-review가 요청 타당성을 검증하고 실제 USER_REVIEW.md 작성 여부를 결정한다.
Roadmap Targets
- Milestone:
agent-roadmap/phase/backtest-loop/milestones/scheduled-market-data-refresh.md - Task ids:
retry-backfill: provider 지연, 결측, gap 결과에 따라 retry와 backfill window를 계산하고 실패를 stale/error 상태로 남긴다.
- Completion mode: check-on-pass
Spec Targets
- SDD:
agent-roadmap/sdd/backtest-loop/scheduled-market-data-refresh/SDD.md - Acceptance scenarios:
S03: task=retry-backfill; evidence=missing/gap/provider delay fixture 또는 local smoke
- Completion mode: spec-check-on-pass
분석 결과
읽은 파일
agent-test/local/rules.mdagent-test/local/worker-smoke.mdagent-roadmap/phase/backtest-loop/milestones/scheduled-market-data-refresh.mdagent-roadmap/sdd/backtest-loop/scheduled-market-data-refresh/SDD.mdservices/worker/internal/scheduler/config.goservices/worker/internal/scheduler/config_test.goservices/worker/internal/jobs/marketdata_jobs.goservices/worker/internal/marketdata/importer/importer.goservices/worker/internal/storage/postgres/queries/queries.sqlservices/worker/go.mod
테스트 환경 규칙
test_env는 local이다. agent-test/local/rules.md와 agent-test/local/worker-smoke.md를 읽었다. services/worker/** 변경이므로 focused command는 go test -count=1 ./services/worker/internal/scheduler, 전체 worker smoke는 go test ./services/worker/...다. storage SQL을 바꾸지 않으므로 bin/worker-storage-check는 필수 검증이 아니다.
테스트 커버리지 공백
- schedule validation output은 현재 커버된다.
- missing/gap/provider_delay를 backfill decision으로 바꾸는 worker-local tests가 없다.
- stale/error text/JSONL output fixture가 없다.
심볼 참조
none. symbol rename/remove 없음.
분할 판단
split decision policy를 먼저 평가했다. shared task group은 m-scheduled-market-data-refresh다. 이 subtask는 02_retry_backfill이고 depends_on=[]이다. scheduled-runner와 독립적으로 pure calculator와 stable output을 만들 수 있어 predecessor complete.log를 요구하지 않는다.
범위 결정 근거
이 plan은 retry/backfill calculation과 stable evidence output만 다룬다. worker long-running loop, API/contracts schema, status CLI, remote runner smoke, backtest-readiness는 제외한다. provider live 호출과 secret 값은 다루지 않는다.
빌드 등급
local-G04. 새 계산 표면과 fixture tests가 필요하지만 worker 내부 pure logic이며 외부 runtime 없이 검증 가능하다.
구현 체크리스트
services/worker/internal/scheduler에 freshness observation -> retry/backfill decision 계산 타입과 함수를 추가한다.- missing/gap/provider_delay/error 케이스를 stable text/JSONL로 출력하는 writer와 fixture-style unit tests를 추가한다.
retry-backfill검증: fixture 또는 local smoke에서 missing/gap/provider delay 케이스가 stable text/JSONL로 구분된다.- 최종 검증으로
go test -count=1 ./services/worker/internal/scheduler와go test ./services/worker/...를 실행한다. - CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
[BACKFILL-1] Retry/Backfill Decision Calculator
문제: SDD는 provider delay나 gap을 성공으로 숨기지 말라고 고정한다(agent-roadmap/sdd/backtest-loop/scheduled-market-data-refresh/SDD.md:75). 현재 scheduler package는 validation item만 정의하고(services/worker/internal/scheduler/config.go:74) freshness observation이나 backfill decision type이 없다.
Before:
// services/worker/internal/scheduler/config.go:74
// ValidationItem is a stable text/JSONL evidence row.
type ValidationItem struct {
해결 방법: services/worker/internal/scheduler/backfill.go를 추가한다. FreshnessObservation은 schedule, provider, selector, timeframe, expected_from/to, latest, missing dates, gap buckets, duplicate count, provider_delay_days, error를 담는다. DecideBackfill(observation, window)는 success/fresh, stale/missing, stale/gap, stale/provider_delay, error를 분리하고 earliest missing/gap/latest 기준으로 inclusive backfill_from/backfill_to를 계산한다.
수정 파일 및 체크리스트:
services/worker/internal/scheduler/backfill.go:FreshnessObservation,BackfillDecision,DecideBackfill.services/worker/internal/scheduler/backfill_test.go: missing, gap, provider delay, duplicate-only, error 케이스.
테스트 작성: TestDecideBackfillDistinguishesMissingGapProviderDelay와 TestDecideBackfillPreservesErrorState를 추가한다.
중간 검증:
go test -count=1 ./services/worker/internal/scheduler
기대 결과: exit code 0. backfill calculator tests pass.
[BACKFILL-2] Stable Text/JSONL Evidence
문제: SDD S03은 stale/error 상태와 backfill window가 stable text/JSONL로 구분되어야 한다(agent-roadmap/sdd/backtest-loop/scheduled-market-data-refresh/SDD.md:87). 현재 scheduler output은 config validation용 WriteText/WriteJSONL뿐이고(services/worker/internal/scheduler/config.go:272), retry/backfill decision writer가 없다.
Before:
// services/worker/internal/scheduler/config.go:272
// WriteText renders stable operator-facing dry-run lines.
func WriteText(w io.Writer, validation Validation) error {
해결 방법: WriteBackfillText와 WriteBackfillJSONL을 추가한다. text는 schedule=<name> status=<fresh|stale|error> reason=<...> backfill_from=<YYYYMMDD> backfill_to=<YYYYMMDD> retry=<true|false> 형태로, JSONL은 같은 필드를 stable struct tag로 출력한다. tests는 expected substrings와 JSONL fields를 모두 고정한다.
수정 파일 및 체크리스트:
services/worker/internal/scheduler/backfill.go: writer 함수와 JSON field tags.services/worker/internal/scheduler/backfill_test.go: text/JSONL expected output tests.
테스트 작성: TestWriteBackfillTextAndJSONL를 추가한다.
중간 검증:
go test -count=1 ./services/worker/internal/scheduler
기대 결과: exit code 0. stable output tests pass.
수정 파일 요약
| 파일 | 항목 |
|---|---|
services/worker/internal/scheduler/backfill.go |
BACKFILL-1, BACKFILL-2 |
services/worker/internal/scheduler/backfill_test.go |
BACKFILL-1, BACKFILL-2 |
최종 검증
go test -count=1 ./services/worker/internal/scheduler
go test ./services/worker/...
Go test cache output is acceptable only for the broad second command; the focused first command must use -count=1.
모든 코드 변경 완료 후 반드시 CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.