<!-- task=m-paper-trading-readiness/02+01_worker_paper_runtime plan=2 tag=REVIEW_REVIEW_PAPER_WORKER -->

# Plan - REVIEW_REVIEW_PAPER_WORKER

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

이 계획은 `code_review_local_G08_1.log`의 FAIL Required 이슈만 좁게 해결한다. 구현 중 사용자에게 직접 질문하지 않는다. 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 범위 충돌 없이는 안전하게 진행할 수 없으면 active `CODE_REVIEW-*-G??.md`의 `사용자 리뷰 요청` 섹션을 증거와 함께 채우고 중단한다. 구현 완료의 마지막 단계는 active review stub의 구현 에이전트 소유 섹션에 실제 구현 내용과 검증 stdout/stderr를 채우는 것이다. 최종 판정, log rename, `complete.log`, archive 이동은 code-review-skill 전용이다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-readiness.md`
- Task ids:
  - `strategy-run`: 전략을 paper execution loop에서 실행할 수 있다.
- Completion mode: check-on-pass

## 배경

G08은 기존 three Required를 대부분 해결했지만, strategy가 현재 bar와 다른 `OrderIntent.InstrumentID`를 반환할 때 pending bucket이 여전히 현재 `bar.InstrumentID`로 잡힌다. 또한 루트 `go.mod`가 작업 범위 밖 untracked 파일로 생겨 Go 1.22 `go.work` workspace 계약과 충돌한다.

## 범위 결정 근거

- Include: `services/worker/internal/papertrading/engine.go`, `services/worker/internal/papertrading/engine_test.go`.
- Include: 루트 `go.mod`가 이번 구현 산출물로 생성된 경우 제거한다.
- Exclude: domain model shape 변경, API/CLI/contracts, `go.work` 수정, worker persistence.

## 빌드 등급

- build: `local-G09`, review: `local-G09`.
- 근거: 반복 FAIL이지만 남은 이슈는 deterministic unit test와 workspace file cleanup으로 검증 가능한 local follow-up이다.

## 구현 체크리스트

- [x] Strategy가 반환한 pending order를 `bar.InstrumentID`가 아니라 각 `order.InstrumentID` bucket에 저장하고 cross-instrument order 회귀 테스트를 추가한다.
- [x] 루트 `go.mod` 범위 이탈을 정리하고, 사용자 소유 unrelated 파일로 판단되면 증거와 함께 `사용자 리뷰 요청`에 남긴다.
- [x] `go test ./services/worker/internal/papertrading ./services/worker/internal/backtest -count=1`, `go test ./services/worker/... -count=1`, `go test ./packages/domain/... -count=1`, `git diff --check`, `gofmt -l services/worker/internal/papertrading/engine.go services/worker/internal/papertrading/engine_test.go`, `git status --short --untracked-files=all`를 실행한다.
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## [REVIEW_REVIEW_PAPER_WORKER-1] Order Instrument Pending Key

### 문제

`services/worker/internal/papertrading/engine.go:183`는 strategy가 반환한 주문들을 `pendingOrders[bar.InstrumentID]`에 저장한다. `OrderIntent`는 자체 `InstrumentID`를 가지므로 strategy가 현재 input bar와 다른 instrument 주문을 반환할 수 있다. 이 경우 주문은 잘못된 bucket에 들어가고, 이후 다른 instrument bar 가격으로 체결될 수 있다.

### 해결 방법

- `strategyOrders`를 순회하며 각 order를 `pendingOrders[order.InstrumentID]`에 저장한다.
- `order.InstrumentID`가 비어 있으면 현재 bar instrument로 보정할지 reject할지 정책을 코드와 `주요 설계 결정`에 명확히 남긴다. 권장: 빈 instrument는 현재 `bar.InstrumentID`로 보정하지 말고 rejected 또는 error로 처리해 strategy bug를 드러낸다.
- 기존 same-instrument tests는 유지한다.

### 테스트 작성

- 현재 bar가 instrument A인 strategy call에서 instrument B 주문을 반환하는 test strategy를 추가한다.
- instrument A 다음 bar에서 B 주문이 체결되지 않고, instrument B 다음 bar에서 B open price로 체결되는지 검증한다.
- 필요하면 빈 `OrderIntent.InstrumentID` 정책 회귀 테스트를 추가한다.

## [REVIEW_REVIEW_PAPER_WORKER-2] Root go.mod Scope Cleanup

### 문제

루트 `go.mod:1`이 untracked로 존재한다.

```text
module git.toki-labs.com/toki/alt
go 1.26.2
```

프로젝트 규칙은 Go 1.22 multi-module workspace via `go.work`이고, 이 작업 범위는 worker paper runtime package에 한정되어 있다. 루트 module file은 이번 task 산출물로 남으면 안 된다.

### 해결 방법

- 루트 `go.mod`가 이번 구현 과정에서 accidental로 생성된 파일이면 제거한다.
- 만약 사용자 소유 unrelated 파일이라고 판단할 확실한 증거가 있으면 삭제하지 말고, active review stub의 `사용자 리뷰 요청`에 증거, 자동 후속 불가 이유, 재개 조건을 남긴다.
- nested module files such as `services/worker/go.mod`는 건드리지 않는다.

### 테스트 작성

- `git status --short --untracked-files=all` 결과에 루트 `go.mod`가 남지 않거나, 사용자 리뷰 요청 근거가 명확히 남아야 한다.

## 중간 검증

```bash
go test ./services/worker/internal/papertrading ./services/worker/internal/backtest -count=1
gofmt -l services/worker/internal/papertrading/engine.go services/worker/internal/papertrading/engine_test.go
```

Expected: `go test` exit 0, `gofmt -l` no output.

## 최종 검증

```bash
go test ./services/worker/... -count=1
go test ./packages/domain/... -count=1
git diff --check
gofmt -l services/worker/internal/papertrading/engine.go services/worker/internal/papertrading/engine_test.go
git status --short --untracked-files=all
```

Expected: tests exit 0; `git diff --check` and `gofmt -l` no output; status has no root `go.mod` unless `사용자 리뷰 요청` documents it as user-owned unrelated.

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