<!-- task=m-backtest-scenario-automation/03+01,02_result_handoff plan=0 tag=TEST -->

# Plan - TEST Result Handoff

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

이 plan의 구현이 끝나면 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 구현 내용, 검증 출력, 계획 대비 변경 사항으로 채운다. 구현 중 사용자 결정, 사용자 소유 외부 환경, 범위 충돌로 막히면 review stub의 `사용자 리뷰 요청` 섹션에 정확한 결정 필요 내용과 증거를 남기고 멈춘다. 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 명령 재실행이나 산출물 수집으로 해소 가능한 evidence 공백은 사용자 리뷰 요청이 아니다.

## 배경

`result-handoff`는 scenario automation 결과를 후속 운영 표면이 소비할 수 있게 fixture와 `headless_validation.md`에 남기는 작업이다. 현재 handoff 문서는 기존 backtest 단일 request/poll/result rows만 갖고 있으며, matrix batch success/failure/timeout/mismatch를 별도 evidence로 고정하지 않는다.

## 사용자 리뷰 요청 흐름

구현 중 blocker는 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 직접 사용자 prompt는 금지이며, code-review가 해당 요청을 검증하고 실제 `USER_REVIEW.md` 작성 여부를 결정한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/backtest-loop/milestones/backtest-scenario-automation.md`
- Task ids:
  - `result-handoff`: 성공, 실패, timeout, expectation mismatch 결과를 fixture와 `headless_validation.md`에 남겨 후속 운영 표면이 소비할 수 있게 한다.
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/private/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-ops/rules/project/domain/operations/rules.md`
- `agent-test/local/rules.md`
- `agent-test/local/operations-smoke.md`
- `agent-roadmap/current.md`
- `agent-roadmap/phase/backtest-loop/PHASE.md`
- `agent-roadmap/phase/backtest-loop/milestones/backtest-scenario-automation.md`
- `apps/cli/internal/operator/handoff_test.go`
- `apps/cli/testdata/operator/headless_validation.md`
- `apps/cli/testdata/operator/backtest_run_request.yaml`
- `apps/cli/testdata/operator/backtest_run_polling.yaml`
- `apps/cli/testdata/operator/backtest_result_summary.yaml`
- `apps/cli/testdata/operator/invalid_request_matrix.yaml`
- `apps/cli/testdata/operator/expected/backtest_run_request.jsonl`
- `apps/cli/testdata/operator/expected/backtest_run_polling.jsonl`
- `apps/cli/testdata/operator/expected/backtest_result_summary.jsonl`
- `apps/cli/testdata/operator/expected/invalid_request_matrix.jsonl`
- `apps/cli/internal/operator/runner_backtest_test.go`
- `apps/cli/internal/operator/runner_error_test.go`
- `apps/cli/internal/cli/cli_test.go`

### 테스트 환경 규칙

- 선택 env: `local`.
- `agent-test/local/rules.md`와 `agent-test/local/operations-smoke.md`를 읽었다.
- 적용 명령: roadmap task 검증 명령 `go test -count=1 ./apps/cli/internal/operator ./apps/cli/internal/cli` 및 `rg --sort path -n "backtest" apps/cli/testdata/operator/headless_validation.md apps/cli/testdata/operator`.
- CLI baseline으로 `go test -count=1 ./apps/cli/internal/operator ./apps/cli/internal/cli`를 실행했고 exit 0이었다.

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

- matrix batch success/failure/timeout/mismatch expected JSONL fixture existence: 기존 coverage 없음.
- handoff matrix row가 새 fixtures와 expected output keys를 참조하는지: existing `handoff_test.go` 구조로 확장 가능.
- 기존 backtest request/poll/result fixtures: existing coverage 있음.

### 심볼 참조

- renamed/removed symbol: none.

### 분할 판단

- split policy를 먼저 평가했다.
- shared task group: `agent-task/m-backtest-scenario-automation/`.
- 현재 subtask: `03+01,02_result_handoff`.
- predecessor `01`: satisfied by archived `complete.log` at `agent-task/archive/2026/06/m-backtest-scenario-automation/01_scenario_matrix/complete.log`.
- predecessor `02`: missing active/archive `complete.log`; active plan remains at `agent-task/m-backtest-scenario-automation/02+01_batch_runner/PLAN-cloud-G07.md`.
- 구현은 `02+01_batch_runner` complete evidence가 생긴 뒤 시작한다.

### 범위 결정 근거

- Runtime behavior 변경은 01/02에 속한다. 이 subtask는 fixtures, handoff docs, handoff tests만 다룬다.
- Flutter UI, chart/layout, operator console screen definition은 운영 UI gate 때문에 제외한다.
- API/worker/contracts/domain code는 제외한다.

### 빌드 등급

- build: `local-G05`, review: `local-G05`.
- 이유: docs/fixtures/test handoff change이며 deterministic file and Go tests로 검증 가능하다.

## 구현 체크리스트

- [ ] Batch result success/failure/timeout/mismatch YAML fixture와 expected JSONL fixture를 추가한다. 검증: `go test -count=1 ./apps/cli/internal/operator ./apps/cli/internal/cli`
- [ ] `headless_validation.md` handoff matrix에 새 backtest batch rows와 output key/exit-code 계약을 추가한다. 검증: `rg --sort path -n "backtest" apps/cli/testdata/operator/headless_validation.md apps/cli/testdata/operator`
- [ ] `handoff_test.go`가 새 fixtures와 promised keys를 검증하도록 확장한다. 검증: `go test -count=1 ./apps/cli/internal/operator ./apps/cli/internal/cli`
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 의존 관계 및 구현 순서

- 이 directory 이름의 runtime dependency는 `01,02`다.
- `01_scenario_matrix`는 `agent-task/archive/2026/06/m-backtest-scenario-automation/01_scenario_matrix/complete.log`로 충족됐다.
- 구현 시작 전 `02+01_batch_runner`의 `complete.log` 또는 matching archive complete가 필요하다.

## [TEST-1] Batch Fixture Set

### 문제

[headless_validation.md](/config/workspace/alt/apps/cli/testdata/operator/headless_validation.md:35)는 existing `backtest_run_request` row를 다루고, [headless_validation.md](/config/workspace/alt/apps/cli/testdata/operator/headless_validation.md:36)는 `backtest_run_polling` row를 다룬다. Batch matrix 결과 success/failure/timeout/mismatch를 대표하는 fixtures가 없다.

### 해결 방법

다음 fixture set을 추가한다.

- `apps/cli/testdata/operator/backtest_matrix_success.yaml`
- `apps/cli/testdata/operator/backtest_matrix_failed.yaml`
- `apps/cli/testdata/operator/backtest_matrix_timeout.yaml`
- `apps/cli/testdata/operator/backtest_matrix_mismatch.yaml`
- matching expected JSONL files under `apps/cli/testdata/operator/expected/`.

Before:

```text
apps/cli/testdata/operator/backtest_run_request.yaml
apps/cli/testdata/operator/backtest_run_polling.yaml
apps/cli/testdata/operator/backtest_result_summary.yaml
```

After:

```text
apps/cli/testdata/operator/backtest_matrix_success.yaml
apps/cli/testdata/operator/backtest_matrix_failed.yaml
apps/cli/testdata/operator/backtest_matrix_timeout.yaml
apps/cli/testdata/operator/backtest_matrix_mismatch.yaml
```

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

- [ ] `apps/cli/testdata/operator/backtest_matrix_success.yaml` 추가.
- [ ] `apps/cli/testdata/operator/backtest_matrix_failed.yaml` 추가.
- [ ] `apps/cli/testdata/operator/backtest_matrix_timeout.yaml` 추가.
- [ ] `apps/cli/testdata/operator/backtest_matrix_mismatch.yaml` 추가.
- [ ] matching `apps/cli/testdata/operator/expected/*.jsonl` 추가.

### 테스트 작성

- 작성: `handoff_test.go` required scenario list에 네 fixtures를 포함해 missing fixture를 fail하게 한다.

### 중간 검증

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

예상: 두 package 모두 `ok`.

## [TEST-2] Handoff Matrix Rows

### 문제

[headless_validation.md](/config/workspace/alt/apps/cli/testdata/operator/headless_validation.md:30)의 matrix는 command/input/expected output/keys/exit code를 행 단위로 관리한다. 새 batch fixtures가 있어도 matrix row가 없으면 후속 운영 표면이 어떤 evidence를 소비해야 하는지 알 수 없다.

### 해결 방법

네 batch rows를 추가하고 output keys를 batch output contract와 맞춘다.

Before:

```markdown
| `backtest_result_summary` | `alt operator scenario run --file testdata/operator/backtest_result_summary.yaml --api-url ws://127.0.0.1:18030/socket --output jsonl` | ... |
```

After:

```markdown
| `backtest_matrix_success` | `alt operator scenario run --file testdata/operator/backtest_matrix_success.yaml --api-url ws://127.0.0.1:18030/socket --output jsonl` | ... |
| `backtest_matrix_failed` | `alt operator scenario run --file testdata/operator/backtest_matrix_failed.yaml --api-url ws://127.0.0.1:18030/socket --output jsonl` | ... |
| `backtest_matrix_timeout` | `alt operator scenario run --file testdata/operator/backtest_matrix_timeout.yaml --api-url ws://127.0.0.1:18030/socket --output jsonl` | ... |
| `backtest_matrix_mismatch` | `alt operator scenario run --file testdata/operator/backtest_matrix_mismatch.yaml --api-url ws://127.0.0.1:18030/socket --output jsonl` | ... |
```

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

- [ ] `apps/cli/testdata/operator/headless_validation.md`: 새 rows 추가.
- [ ] 각 row의 expected output keys에 `matrix_run_id`, `universe`, `strategy_id`, `timeframe`, `period_id`, `run_id`, `run_status`, `exit_code` 포함.
- [ ] expected exit code는 success/failed terminal `0`, timeout `3`, mismatch `1`로 기록.

### 테스트 작성

- 기존 `TestHandoffExpectedFixturesWithMatrixPromisedKeys`를 통과하도록 matrix keys와 expected JSONL을 맞춘다.

### 중간 검증

```bash
rg --sort path -n "backtest" apps/cli/testdata/operator/headless_validation.md apps/cli/testdata/operator
```

예상: 새 batch scenario, input fixture, expected fixture path가 모두 검색된다.

## [TEST-3] Handoff Test Expansion

### 문제

[handoff_test.go](/config/workspace/alt/apps/cli/internal/operator/handoff_test.go:16)의 `requiredScenarios`는 기존 scenarios만 요구한다. 새 batch fixtures를 추가해도 test가 required handoff coverage로 강제하지 않으면 drift가 생긴다.

### 해결 방법

`requiredScenarios`와 `requiredScenarioKeys`를 새 batch scenarios로 확장하고, timeout/mismatch fixture도 valid JSONL 및 promised keys check를 통과하게 한다.

Before:

```go
// apps/cli/internal/operator/handoff_test.go:20
"backtest_run_request",
"backtest_run_polling",
"backtest_result_summary",
```

After:

```go
"backtest_run_request",
"backtest_run_polling",
"backtest_result_summary",
"backtest_matrix_success",
"backtest_matrix_failed",
"backtest_matrix_timeout",
"backtest_matrix_mismatch",
```

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

- [ ] `apps/cli/internal/operator/handoff_test.go`: `requiredScenarios` 확장.
- [ ] `apps/cli/internal/operator/handoff_test.go`: `requiredScenarioKeys` 확장.
- [ ] 필요한 경우 row-level checks를 batch rows에도 적용.

### 테스트 작성

- 기존 handoff tests 확장으로 충분하다. 별도 새 test function은 batch row-specific invariant가 필요할 때만 추가한다.

### 중간 검증

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

예상: 두 package 모두 `ok`.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `apps/cli/testdata/operator/backtest_matrix_success.yaml` | TEST-1 |
| `apps/cli/testdata/operator/backtest_matrix_failed.yaml` | TEST-1 |
| `apps/cli/testdata/operator/backtest_matrix_timeout.yaml` | TEST-1 |
| `apps/cli/testdata/operator/backtest_matrix_mismatch.yaml` | TEST-1 |
| `apps/cli/testdata/operator/expected/backtest_matrix_success.jsonl` | TEST-1 |
| `apps/cli/testdata/operator/expected/backtest_matrix_failed.jsonl` | TEST-1 |
| `apps/cli/testdata/operator/expected/backtest_matrix_timeout.jsonl` | TEST-1 |
| `apps/cli/testdata/operator/expected/backtest_matrix_mismatch.jsonl` | TEST-1 |
| `apps/cli/testdata/operator/headless_validation.md` | TEST-2 |
| `apps/cli/internal/operator/handoff_test.go` | TEST-3 |

## 최종 검증

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

```bash
rg --sort path -n "backtest" apps/cli/testdata/operator/headless_validation.md apps/cli/testdata/operator
```

예상: Go tests는 `ok`; `rg`는 새 batch fixture와 handoff rows를 포함해 backtest references를 stable path order로 출력한다.

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