<!-- task=m-backtest-multi-timeframe-coverage/01_import_timeframe_contract plan=0 tag=API -->

# Plan - Import Timeframe Contract

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

구현 마지막 단계는 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 변경 내용과 검증 출력으로 채우는 것이다. 구현 후 active 파일을 그대로 두고 리뷰 준비를 보고한다. 종결, archive 이동, `complete.log` 작성은 code-review 전용이다.

선택된 SDD 결정 또는 Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 막을 때만 review stub의 `사용자 리뷰 요청` 섹션을 채우고 멈춘다. 구현 중 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 환경/secret/서비스 차단, 일반 범위 조정, 검증 공백은 사용자 리뷰 요청이 아니라 `검증 결과` 또는 `계획 대비 변경 사항`에 기록한다.

## 배경

`ImportDailyBarsRequest`는 이름과 실제 importer가 모두 일봉 중심이라 현재 요청자가 `minute_1`/`minute_5` import를 명시할 계약 필드가 없다. SDD S03의 stable typed rejection을 만들려면 먼저 proto 요청에 timeframe을 additive하게 실어야 한다. 이 계획은 downstream 동작 변경 없이 contract와 generated output만 준비하는 선행 작업이다.

## 사용자 리뷰 요청 흐름

사용자 리뷰 요청은 active `CODE_REVIEW-*-G??.md`의 `사용자 리뷰 요청` 섹션에만 기록한다. 이 섹션은 `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` 내용을 따른다. 직접 사용자 프롬프트는 금지하며, code-review가 요청 타당성을 검증하고 실제 `USER_REVIEW.md` 작성을 소유한다.

## 분석 결과

### 읽은 파일

- `AGENTS.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-ops/skills/common/_templates/implementation-user-review-request-section.md`
- `agent-roadmap/phase/backtest-loop/milestones/backtest-multi-timeframe-coverage.md`
- `agent-roadmap/sdd/backtest-loop/backtest-multi-timeframe-coverage/SDD.md`
- `agent-test/local/rules.md`
- `agent-test/local/contracts-smoke.md`
- `agent-test/local/api-smoke.md`
- `agent-test/local/worker-smoke.md`
- `agent-test/local/operations-smoke.md`
- `packages/contracts/proto/alt/v1/market.proto`
- `apps/cli/internal/operator/runner.go`
- `apps/cli/internal/operator/scenario.go`
- `apps/cli/internal/operator/scenario_test.go`
- `apps/cli/internal/operator/runner_market_test.go`
- `services/worker/internal/socket/market.go`
- `services/worker/internal/socket/market_test.go`
- `services/worker/internal/jobs/marketdata_jobs.go`
- `services/worker/internal/jobs/marketdata_jobs_test.go`
- `bin/contracts-gen`
- `bin/contracts-check`

### 테스트 환경 규칙

- `test_env=local`.
- `agent-test/local/rules.md`를 읽었고, `.proto` 변경이므로 `agent-test/local/contracts-smoke.md`를 적용한다.
- public proto socket request가 바뀌므로 `api-smoke`, worker call site 계획이 이어지므로 `worker-smoke`, generator/check script 검증 때문에 `operations-smoke`도 참고했다.
- 적용 명령: `.proto` 변경 후 `bin/contracts-gen`, generated drift는 `bin/contracts-check`, generated Go는 `go test ./packages/contracts/gen/go/...`.
- fallback 없음. `<확인 필요>` 값 없음.

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

- `ImportDailyBarsRequest.timeframe` field addition: 기존 parser map은 메시지 타입 등록만 검증하고 필드별 round-trip은 없다. generated Go compile와 downstream dependent plan에서 request propagation test로 보완한다.
- Generated Dart output: `bin/contracts-check` drift로 확인한다. Dart unit은 이 작업에서 직접 추가하지 않는다.

### 심볼 참조

- renamed/removed symbol 없음.
- 추가 필드 call site 후보: `apps/cli/internal/operator/runner.go:257`, `services/worker/internal/socket/market.go:69`, `services/worker/internal/jobs/marketdata_jobs.go:27`. 이 계획에서는 field만 추가하고, propagation/rejection은 `02+01_minute_import_rejection`에서 처리한다.

### 분할 판단

- split policy를 plan 작성 전에 평가했다.
- 공유 task group: `agent-task/m-backtest-multi-timeframe-coverage/`
- sibling split:
  - `01_import_timeframe_contract`: proto/generator 선행 작업, 독립.
  - `02+01_minute_import_rejection`: `01` 완료 후 request propagation과 typed rejection 구현.
  - `03_monthly_aggregation`: 월봉 aggregation 구현, `01`과 독립.
- 이 plan은 Milestone 기능 Task 자체를 닫지 않는 선행 하위 작업이므로 `Roadmap Targets`와 `Spec Targets`를 쓰지 않는다.

### 범위 결정 근거

- worker socket, jobs, CLI scenario validation 동작은 제외한다. contract field가 먼저 생성되어야 downstream 구현이 컴파일 가능하다.
- provider KIS 실제 분봉 import는 제외한다. SDD는 미지원 typed rejection도 허용한다.
- 월봉 aggregation은 `03_monthly_aggregation`으로 분리한다.

### 빌드 등급

- `local-G06`: public proto contract와 generated output을 바꾸지만, 변경은 additive field 하나이고 검증 명령이 명확하다.

## 구현 체크리스트

- [ ] `packages/contracts/proto/alt/v1/market.proto`의 `ImportDailyBarsRequest`에 additive `Timeframe timeframe = 9;`를 추가한다.
- [ ] `bin/contracts-gen`으로 Go/Dart generated contracts를 갱신한다. generated 파일은 손으로 수정하지 않는다.
- [ ] `bin/contracts-check`와 `go test ./packages/contracts/gen/go/...`를 실행해 generated drift와 compile을 확인한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [API-1] ImportDailyBarsRequest Timeframe Field

#### 문제

`packages/contracts/proto/alt/v1/market.proto:62`의 `ImportDailyBarsRequest`는 provider/selector/date만 갖고 있어 import 요청에서 timeframe 후보를 표현할 수 없다.

Before:

```proto
62 message ImportDailyBarsRequest {
63   string provider = 1;
64   string selector_kind = 2;
65   Market market = 3;
66   Venue venue = 4;
67   string name = 5;
68   repeated string symbols = 6;
69   string from_yyyymmdd = 7;
70   string to_yyyymmdd = 8;
71 }
```

#### 해결 방법

필드 번호 9에 `Timeframe timeframe = 9;`를 추가한다. `TIMEFRAME_UNSPECIFIED`는 downstream에서 backward-compatible daily default로 처리하게 두고, 이 plan은 schema와 generated output만 만든다.

After:

```proto
62 message ImportDailyBarsRequest {
63   string provider = 1;
64   string selector_kind = 2;
65   Market market = 3;
66   Venue venue = 4;
67   string name = 5;
68   repeated string symbols = 6;
69   string from_yyyymmdd = 7;
70   string to_yyyymmdd = 8;
71   Timeframe timeframe = 9;
72 }
```

#### 수정 파일 및 체크리스트

- [ ] `packages/contracts/proto/alt/v1/market.proto`: additive field 추가.
- [ ] `packages/contracts/gen/go/alt/v1/market.pb.go`: `bin/contracts-gen` 결과 반영.
- [ ] Dart generated contract 파일: `bin/contracts-gen` 결과 반영.

#### 테스트 작성

- 새 수동 unit test는 작성하지 않는다. protobuf generated accessor/descriptor compile과 `bin/contracts-check`가 field generation drift를 검증한다.
- dependent plan `02+01_minute_import_rejection`에서 CLI/worker propagation boundary test를 작성한다.

#### 중간 검증

```bash
bin/contracts-gen
bin/contracts-check
go test ./packages/contracts/gen/go/...
```

기대 결과: 세 명령 모두 exit code 0.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `packages/contracts/proto/alt/v1/market.proto` | API-1 |
| `packages/contracts/gen/go/alt/v1/market.pb.go` | API-1 |
| generated Dart contract files | API-1 |

## 최종 검증

```bash
bin/contracts-check
go test ./packages/contracts/gen/go/...
```

기대 결과: generated drift 없음, generated Go contract package test 통과.

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