<!-- task=m-backtest-multi-timeframe-coverage/01_domain_capability_matrix plan=2 tag=REVIEW_REVIEW_API -->

# Plan - REVIEW_REVIEW_API

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

`CODE_REVIEW-local-G05.md`의 구현 에이전트 소유 섹션을 채우는 것이 구현의 마지막 단계다. 코드를 바꾸고 검증을 실행한 뒤 실제 구현 내용과 stdout/stderr를 리뷰 stub에 남기고, active 파일은 그대로 둔 채 리뷰 준비를 보고한다. 선택된 SDD 결정 또는 Milestone `구현 잠금 > 결정 필요` 항목이 막으면 리뷰 stub의 `사용자 리뷰 요청` 섹션에 정확한 연결 대상, 근거, 명령 출력, 재개 조건을 기록하고 멈춘다. 구현 중 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`, `USER_REVIEW.md` 작성, log archive, `complete.log` 작성을 하지 않는다. 환경/secret/service 차단과 검증 증거 공백은 사용자 리뷰가 아니라 `검증 결과` 또는 후속 plan 대상으로 남긴다.

## 배경

두 번째 리뷰에서 `CheckBars`의 rules-only 동작 자체는 고쳐졌지만, 계획이 요구한 KR/US daily accepted rules-only 회귀 테스트 중 US/NASDAQ accepted 케이스가 빠졌다. 이 후속은 테스트 fixture와 case만 보강해 rules-only capability가 KIS의 다중 시장 coverage를 검증하도록 만든다.

## 사용자 리뷰 요청 흐름

사용자 리뷰 요청은 선택된 SDD 결정 또는 선택된 Milestone lock 결정이 실구현을 차단할 때만 active `CODE_REVIEW-local-G05.md`의 `사용자 리뷰 요청` 섹션에 기록한다. 직접 chat 질문은 금지이며, code-review가 검증 후 실제 `USER_REVIEW.md` 작성 여부를 판단한다.

## Archive Evidence Snapshot

- Archived plan: `agent-task/m-backtest-multi-timeframe-coverage/01_domain_capability_matrix/plan_local_G05_1.log`
- Archived review: `agent-task/m-backtest-multi-timeframe-coverage/01_domain_capability_matrix/code_review_local_G05_1.log`
- Verdict: FAIL
- Required summary:
  - `packages/domain/market/types_test.go:217`의 `rulesOnlyKIS` fixture가 KR/KRX rule만 포함한다.
  - `packages/domain/market/types_test.go:305` 이후 rules-only accepted case도 KR daily만 검증해, 계획상 필수였던 US/NASDAQ daily accepted 회귀 검증이 빠졌다.
- Affected files:
  - `packages/domain/market/types_test.go`
- Verification evidence:
  - 리뷰 중 `gofmt -l packages/domain/market/types.go packages/domain/market/types_test.go`가 처음에는 `packages/domain/market/types_test.go`를 출력했고, 리뷰어가 `gofmt -w packages/domain/market/types_test.go`로 포맷 drift를 직접 정리했다.
  - 포맷 정리 후 `gofmt -l packages/domain/market/types.go packages/domain/market/types_test.go`는 출력 없음.
  - `go test -count=1 ./packages/domain/market` exit code 0.
  - `go test ./packages/domain/... ./services/worker/...` exit code 0.
- Narrow reread allowed if needed:
  - `agent-task/m-backtest-multi-timeframe-coverage/01_domain_capability_matrix/code_review_local_G05_1.log`
  - `agent-task/m-backtest-multi-timeframe-coverage/01_domain_capability_matrix/plan_local_G05_1.log`

## 분석 결과

### 읽은 파일

- `AGENTS.md`
- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/private/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-roadmap/current.md`
- `agent-ops/skills/common/router.md`
- `agent-ops/skills/common/code-review/SKILL.md`
- `agent-ops/skills/common/plan/SKILL.md`
- `agent-ops/skills/common/_templates/implementation-user-review-request-section.md`
- `agent-ops/rules/project/domain/domain-model/rules.md`
- `agent-ops/rules/project/domain/worker/rules.md`
- `agent-test/local/rules.md`
- `agent-test/local/domain-model-smoke.md`
- `agent-test/local/worker-smoke.md`
- `agent-task/m-backtest-multi-timeframe-coverage/01_domain_capability_matrix/PLAN-local-G05.md` (archived to `plan_local_G05_1.log`)
- `agent-task/m-backtest-multi-timeframe-coverage/01_domain_capability_matrix/CODE_REVIEW-local-G05.md` (archived to `code_review_local_G05_1.log`)
- `packages/domain/market/types.go`
- `packages/domain/market/types_test.go`
- `services/worker/internal/providers/kis/daily_itemchartprice.go`
- `services/worker/internal/jobs/marketdata_jobs.go`

### 테스트 환경 규칙

- test_env: `local`
- env rules: `agent-test/local/rules.md` 존재 및 정독 완료
- matched profiles: `agent-test/local/domain-model-smoke.md`; worker compatibility 검증 때문에 `agent-test/local/worker-smoke.md`도 읽음
- 적용 명령:
  - test-only regression 확인: `go test -count=1 ./packages/domain/market`
  - compatibility 확인: `go test ./packages/domain/... ./services/worker/...`
  - formatting 확인: `gofmt -l packages/domain/market/types.go packages/domain/market/types_test.go`
- Go test cache 정책: 첫 번째 회귀 명령은 fresh 실행을 위해 `-count=1`을 사용한다. 두 번째 compatibility 명령의 cache output은 허용한다.
- fallback: 없음

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

- `CheckBars` rules-only KR/KRX daily accepted와 monthly/minute rejected reason은 현재 테스트가 검증한다.
- `CheckBars` rules-only US/NASDAQ daily accepted는 현재 테스트가 검증하지 않는다. 이번 후속에서 `rulesOnlyKIS`에 US/NASDAQ rule을 추가하고 US/NASDAQ ETF daily accepted case를 추가한다.

### 심볼 참조

- renamed/removed symbols: 없음
- 관련 심볼: `market.ProviderCapability.CheckBars`
- 관련 call sites:
  - `packages/domain/market/types_test.go`
  - `services/worker/internal/jobs/marketdata_jobs.go`는 아직 `RequireDailyBars` compatibility wrapper를 사용한다.
  - `services/worker/internal/providers/kis/daily_itemchartprice.go`는 legacy `Venues`/`Timeframes` capability를 반환하며 이번 후속 범위 밖이다.

### 분할 판단

- split decision policy를 후속 plan 작성 전에 적용했다.
- 기존 split task group `agent-task/m-backtest-multi-timeframe-coverage/`와 subtask `01_domain_capability_matrix`를 유지한다.
- 변경은 `packages/domain/market/types_test.go`의 fixture와 case 보강으로 제한되어 별도 subtask로 쪼개지 않는다.

### 범위 결정 근거

- 포함: `packages/domain/market/types_test.go`
- 제외: `packages/domain/market/types.go`, `services/worker/**`, `services/worker/internal/providers/kis/**`, `.proto`, API socket, CLI runner, 실제 KIS capability table rollout. 이번 후속은 누락된 회귀 테스트만 보강한다.

### 빌드 등급

- build: `local-G05`
- review: `local-G05`
- 근거: 변경은 테스트 한 파일로 좁지만 public domain capability matrix의 필수 회귀 조건을 닫는 작업이다.

## 구현 체크리스트

- [ ] `rulesOnlyKIS` fixture에 `MarketUS`/`VenueNASDAQ` daily equity/ETF rule을 추가한다.
- [ ] rules-only test cases에 US/NASDAQ ETF daily accepted case를 추가해 `Venues` 없이 US daily path가 accepted 되는지 검증한다.
- [ ] `gofmt -l packages/domain/market/types.go packages/domain/market/types_test.go`, `go test -count=1 ./packages/domain/market`, `go test ./packages/domain/... ./services/worker/...`를 실행해 formatting, domain regression, worker compatibility를 확인한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_REVIEW_API-1] Cover rules-only US daily accepted

문제:
- `packages/domain/market/types_test.go:217`의 `rulesOnlyKIS` fixture는 KR/KRX rule만 포함한다.
- `packages/domain/market/types_test.go:305` 이후 rules-only accepted case는 KR/KRX equity/ETF daily만 검증한다.
- 이전 계획은 rules-only capability에서 KR/US daily accepted를 모두 요구했으므로 US/NASDAQ daily accepted 회귀 coverage가 아직 닫히지 않았다.

해결 방법:
- `rulesOnlyKIS.Rules`에 `MarketUS`/`VenueNASDAQ` rule을 추가한다.
- 해당 rule의 `AssetTypes`는 `AssetTypeEquity`, `AssetTypeETF`를 true로 두고, `Timeframes`는 daily true, monthly/minute false로 기존 KIS matrix와 맞춘다.
- `rulesOnlyCases`에 US/NASDAQ ETF daily accepted case를 추가한다.

Before (`packages/domain/market/types_test.go:220`):

```go
Rules: []ProviderCapabilityRule{
	{
		Market: MarketKR,
		Venue:  VenueKRX,
		AssetTypes: map[AssetType]bool{
			AssetTypeEquity: true,
			AssetTypeETF:    true,
		},
		Timeframes: map[Timeframe]bool{
			TimeframeDaily:   true,
			TimeframeMonthly: false,
			TimeframeMin1:    false,
			TimeframeMin5:    false,
		},
	},
},
```

After 방향:

```go
Rules: []ProviderCapabilityRule{
	{
		Market: MarketKR,
		Venue:  VenueKRX,
		// unchanged
	},
	{
		Market: MarketUS,
		Venue:  VenueNASDAQ,
		AssetTypes: map[AssetType]bool{
			AssetTypeEquity: true,
			AssetTypeETF:    true,
		},
		Timeframes: map[Timeframe]bool{
			TimeframeDaily:   true,
			TimeframeMonthly: false,
			TimeframeMin1:    false,
			TimeframeMin5:    false,
		},
	},
}
```

수정 파일 및 체크리스트:
- [ ] `packages/domain/market/types_test.go`: `rulesOnlyKIS`에 US/NASDAQ rule을 추가한다.
- [ ] `packages/domain/market/types_test.go`: `rulesOnlyCases`에 US/NASDAQ ETF daily accepted case를 추가한다.

테스트 작성:
- 작성: `packages/domain/market/types_test.go`
- test name: 기존 `TestProviderCapabilityMatrix`의 `rules-only/...` subcase
- assertion goal:
  - `ProviderCapability{Provider: ProviderKIS, Venues: empty, Rules: ...}`만으로 US/NASDAQ ETF daily accepted
  - 기존 KR accepted와 monthly/minute rejected reason은 계속 통과

중간 검증:

```bash
gofmt -l packages/domain/market/types.go packages/domain/market/types_test.go
go test -count=1 ./packages/domain/market
```

기대 결과: `gofmt -l` 출력 없음, `go test` exit code 0.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `packages/domain/market/types_test.go` | REVIEW_REVIEW_API-1 |

## 최종 검증

```bash
gofmt -l packages/domain/market/types.go packages/domain/market/types_test.go
go test -count=1 ./packages/domain/market
go test ./packages/domain/... ./services/worker/...
```

기대 결과: `gofmt -l` 출력 없음. 두 Go test 명령 모두 exit code 0. 첫 번째 Go test는 fresh 실행이어야 하며, 두 번째 compatibility 명령의 Go test cache output은 허용한다.

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