<!-- task=m-us-market-expansion/03+01_shared_query_surface plan=0 tag=US_QUERY -->

# Implementation Plan - US_QUERY

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

구현 완료의 마지막 단계는 active `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채우는 것이다. `01_market_foundation` 완료 전에는 구현하지 않는다. 사용자-only 결정이 필요하면 review stub의 `사용자 리뷰 요청` 섹션에 기록하고 멈춘다. finalization은 code-review 전용이다.

## 배경

US instruments와 bars가 들어와도 operator/API/worker read surface가 KR과 다른 경로를 쓰면 milestone의 shared-query 목표를 만족하지 못한다. 현재 API와 worker는 US enum을 대부분 받아들이지만, headless scenario와 focused tests는 KR 중심이다. 이 작업은 market selector만 바꿔 같은 query pattern을 쓰는 것을 fixtures와 tests로 잠근다.

## 사용자 리뷰 요청 흐름

구현 중 차단은 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 구현 에이전트는 사용자에게 직접 질문하지 않는다. code-review가 실제 user-review stop 여부를 판단한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/trading-expansion/milestones/us-market-expansion.md`
- Task ids:
  - `shared-query`: 한국장과 미국장이 같은 query/contract pattern을 공유
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-test/local/rules.md`
- `agent-test/local/api-smoke.md`
- `agent-test/local/worker-smoke.md`
- `agent-test/local/operations-smoke.md`
- `services/api/internal/socket/market.go`
- `services/api/internal/socket/market_test.go`
- `services/worker/internal/socket/market.go`
- `services/worker/internal/socket/market_mapping.go`
- `services/worker/internal/socket/market_test.go`
- `apps/cli/internal/operator/scenario.go`
- `apps/cli/internal/operator/runner.go`
- `apps/cli/internal/operator/scenario_test.go`
- `apps/cli/internal/operator/runner_market_test.go`
- `apps/cli/testdata/operator/market_data_status_query.yaml`
- `apps/cli/testdata/operator/expected/market_data_status_query.jsonl`

### 테스트 환경 규칙

`test_env=local`. api-smoke, worker-smoke, operations-smoke를 적용한다. API socket boundary는 `go test ./services/api/...`, worker socket은 `go test ./services/worker/...`, CLI operator는 package focused `go test -count=1 ./apps/cli/internal/operator`, milestone smoke는 `bin/test`를 적용한다.

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

- API `isValidMarketFilter`와 `isValidVenueFilter`는 US enum을 허용하지만 US import/list forwarding test가 없다.
- Worker `filterInstruments`는 provider + market filter를 다루지만 US-only list/query fixture가 약하다.
- CLI operator는 이 작업 시작 전 작은 패치로 `nasdaq`/`nyse` venue validation/mapping을 추가했지만, US end-to-end headless scenario fixture는 아직 없다.

### 심볼 참조

Renamed/removed symbol: none. New fixture/action symbols only.

### 분할 판단

Shared task group: `m-us-market-expansion`. This subtask is `03+01_shared_query_surface` and depends on `01_market_foundation`. Predecessor status at plan creation: missing complete.log. It can run in parallel with `02+01_kis_us_daily_bars` only after 01 completes.

### 범위 결정 근거

이 작업은 read/query surface와 headless scenario만 다룬다. KIS provider fetch implementation은 02, US backtest result smoke는 04에서 다룬다. Flutter UI는 operational UI gate에 따라 제외한다.

### 빌드 등급

`local-G06`: API/worker/CLI 경계가 여러 개지만 대부분 existing enum pass-through와 test/fixture 강화이며 deterministic local tests로 리뷰 가능하다.

## 구현 체크리스트

- [ ] [US_QUERY-1] API/worker socket tests가 `Market_US`와 provider filter로 US instruments를 같은 ListInstruments contract에서 조회하는지 검증한다. 검증: market selector만 바꿔도 공통 query path를 사용한다.
- [ ] [US_QUERY-2] CLI headless fixture에 US market data status query를 추가하고 expected JSONL을 잠근다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 의존 관계 및 구현 순서

`03+01_shared_query_surface`는 디렉터리명 기준으로 `01_market_foundation`의 `complete.log`가 필요하다. 추가 dependency를 만들지 않는다.

### [US_QUERY-1] API And Worker US Query Contract Tests

문제: [services/api/internal/socket/market.go](/config/workspace/alt/services/api/internal/socket/market.go:159)는 US market/venue enum을 허용하지만 test는 KR import fixture 중심이다. [services/worker/internal/socket/market.go](/config/workspace/alt/services/worker/internal/socket/market.go:148)의 `filterInstruments`는 provider+market filter를 지원하지만 US read contract가 충분히 잠겨 있지 않다.

해결 방법: API forwarding tests와 worker socket tests에 `Market_US`, `Venue_NASDAQ`, `ProviderSymbols["kis"]`, `AssetType`이 포함된 instruments를 추가한다. implementation code는 existing contract path를 우선 재사용하고, 새 request type을 만들지 않는다.

수정 파일 및 체크리스트:

- [ ] `services/api/internal/socket/market_test.go`: US `ImportDailyBarsRequest` validation/forwarding test 추가.
- [ ] `services/worker/internal/socket/market_test.go`: US list instruments provider filter와 US list bars response mapping test 추가.
- [ ] `services/worker/internal/socket/market_mapping_test.go`: asset_type 포함 proto mapping 검증이 01에서 누락됐다면 보강.

테스트 작성: 작성한다. 새 public contract path가 아니라 기존 path의 US coverage를 추가한다.

중간 검증:

```bash
go test -count=1 ./services/api/internal/socket ./services/worker/internal/socket
```

### [US_QUERY-2] Operator US Headless Query Fixture

문제: [apps/cli/internal/operator/scenario.go](/config/workspace/alt/apps/cli/internal/operator/scenario.go:119)와 [runner.go](/config/workspace/alt/apps/cli/internal/operator/runner.go:62)는 US venue string을 받을 수 있어야 한다. 현재 작은 선행 패치로 `nasdaq`/`nyse` mapping은 추가됐지만, [apps/cli/testdata/operator/market_data_status_query.yaml](/config/workspace/alt/apps/cli/testdata/operator/market_data_status_query.yaml:1)은 KR-only status workflow다.

해결 방법: `us_market_data_status_query.yaml`과 expected JSONL을 추가한다. Steps는 `import_daily_bars` with `market: us`, `venue: nasdaq`, `symbols: ["AAPL"]`, `list_instruments market: us`, `list_bars instrument_id: NASDAQ:AAPL` 순서로 구성한다.

수정 파일 및 체크리스트:

- [ ] `apps/cli/testdata/operator/us_market_data_status_query.yaml`: US query fixture 추가.
- [ ] `apps/cli/testdata/operator/expected/us_market_data_status_query.jsonl`: expected output 추가.
- [ ] `apps/cli/testdata/operator/headless_validation.md`: fixture matrix에 US query row 추가.
- [ ] `apps/cli/internal/operator/runner_market_test.go`: fixture run test 추가 또는 기존 fake API test 확장.

테스트 작성: 작성한다. Fake API로 transport 없이 runner output과 call order를 검증한다.

중간 검증:

```bash
go test -count=1 ./apps/cli/internal/operator
```

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `services/api/internal/socket/market_test.go` | US_QUERY-1 |
| `services/worker/internal/socket/market_test.go` | US_QUERY-1 |
| `services/worker/internal/socket/market_mapping_test.go` | US_QUERY-1 |
| `apps/cli/testdata/operator/us_market_data_status_query.yaml` | US_QUERY-2 |
| `apps/cli/testdata/operator/expected/us_market_data_status_query.jsonl` | US_QUERY-2 |
| `apps/cli/testdata/operator/headless_validation.md` | US_QUERY-2 |
| `apps/cli/internal/operator/runner_market_test.go` | US_QUERY-2 |

## 최종 검증

```bash
go test -count=1 ./services/api/internal/socket ./services/worker/internal/socket ./apps/cli/internal/operator
go test -count=1 ./services/api/... ./services/worker/...
bin/test
git diff --check
```

`go test` cache는 허용하지 않는다.

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