alt/apps/cli/testdata/operator/headless_validation.md
toki 1c11a17eff feat: operator headless workflow validation and backtest support
- Implement backtest workflow validation for headless operator mode
- Add handoff evidence tracking for backtest runs
- Update operator client, runner, scenario, and output modules
- Add test files for handoff, backtest runner, and error handling
- Add test data for backtest scenarios and validation
2026-06-01 13:21:20 +09:00

54 lines
5.8 KiB
Markdown

# Headless Validation Handoff
이 문서는 `operator-headless-workflow-validation` 마일스톤의 handoff table 기준
(`agent-roadmap/phase/operator-surface/milestones/operator-headless-workflow-validation.md`)
을 충족하는 검증 evidence를 한곳에 모은다. 후속 `Flutter Operator Console MVP`
실화면을 만들기 전에 이 matrix로 각 scenario의 command/input/expected output/exit
code/protobuf field를 확인한다.
ALT 운영 UI 게이트(`agent-ops/rules/project/rules.md`의 "운영 UI 구현 게이트")에 따라
모든 검증은 화면 없이 CLI와 machine-readable 출력으로 먼저 수행한다.
## 공통 실행 형식
- validate(offline, 소켓 없이 dry-run): `alt operator scenario validate --file <yaml>`
- run(실 API 연결): `alt operator scenario run --file <yaml> --api-url ws://127.0.0.1:8080/socket --output jsonl`
- 로컬 개발에서는 `cd apps/cli && go run ./cmd/alt <위 인자>`로 실행한다(`bin/dev` 참고).
- exit code 계약: `0` 전 step 기대 일치, `1` typed error/expectation mismatch, `2` parse/validation/flag 오류, `3` transport 실패.
- expected output fixture는 `--output jsonl` 기준의 step/summary line이다. `run_id`,
`count`, `starting_cash`, `ending_equity`, `total_return`, `trade_count`,
`error_message` 값은 seed 데이터에 따라 달라지는 illustrative 값이며, 후속 MVP가
계약으로 의존하는 부분은 line별 `scenario`/`step`/`action`/`status` key와 step별로
검증하는 protobuf field의 존재 여부다.
## Scenario evidence matrix
| Scenario | Command | Input fixture | Expected output fixture | Expected exit code | Checked protobuf/view-model field | Remaining Flutter wireframe dependency |
|----------|---------|---------------|-------------------------|--------------------|-----------------------------------|----------------------------------------|
| `api_connection_smoke` | `alt operator scenario run --file testdata/operator/api_connection_smoke.yaml --api-url ws://127.0.0.1:8080/socket --output jsonl` | `testdata/operator/api_connection_smoke.yaml` | `testdata/operator/expected/api_connection_smoke.jsonl` | `0` (성공), `3` (transport 실패 시) | `HelloResponse.capabilities` (`alt.v1`); summary `status`/`exit_code` | connection status / capability 표시 화면 layout 미정 |
| `market_data_status_query` | `alt operator scenario run --file testdata/operator/market_data_status_query.yaml --api-url ws://127.0.0.1:8080/socket --output jsonl` | `testdata/operator/market_data_status_query.yaml` | `testdata/operator/expected/market_data_status_query.jsonl` | `0` (성공/empty), `1` (mismatch) | `ListInstrumentsResponse.instruments`, `ListBarsResponse.bars` (step `count`), `ErrorInfo.code` | market data status card / 빈 상태·unavailable 시각화 미정 |
| `backtest_run_request` | `alt operator scenario run --file testdata/operator/backtest_run_request.yaml --api-url ws://127.0.0.1:8080/socket --output jsonl` | `testdata/operator/backtest_run_request.yaml` | `testdata/operator/expected/backtest_run_request.jsonl` | `0` (성공), `1` (typed error/mismatch) | `StartBacktestResponse.run.id`, `BacktestRun.status` (step `run_id`/`run_status`), `ErrorInfo.code` | backtest 생성 form 입력/검증 화면 미정 |
| `backtest_run_polling` | `alt operator scenario run --file testdata/operator/backtest_run_polling.yaml --api-url ws://127.0.0.1:8080/socket --output jsonl` | `testdata/operator/backtest_run_polling.yaml` | `testdata/operator/expected/backtest_run_polling.jsonl` | `0` (terminal 도달), `3` (polling timeout) | `GetBacktestRunResponse.run.status` 전이(pending→running→succeeded/failed/canceled) | run 진행 상태/전이 표시(진행바, 상태 칩) 화면 미정 |
| `backtest_result_summary` | `alt operator scenario run --file testdata/operator/backtest_result_summary.yaml --api-url ws://127.0.0.1:8080/socket --output jsonl` | `testdata/operator/backtest_result_summary.yaml` | `testdata/operator/expected/backtest_result_summary.jsonl` | `0` (성공), `1` (missing run/typed error) | `GetBacktestResultResponse.result.summary` (`starting_cash`, `ending_equity`, `total_return`, `trade_count`) | result summary metrics / chart 시각화 화면 미정 |
| `invalid_request_matrix` | `alt operator scenario run --file testdata/operator/invalid_request_matrix.yaml --api-url ws://127.0.0.1:8080/socket --output jsonl` | `testdata/operator/invalid_request_matrix.yaml` | `testdata/operator/expected/invalid_request_matrix.jsonl` | `0` (기대한 typed error 도달), `2` (malformed scenario는 `testdata/operator/malformed_scenario.yaml`로 validate 시 parse error) | `ErrorInfo.code` (`invalid_request`, `not_found`) | error/validation 메시지 노출 및 비정상 입력 가드 화면 미정 |
## Exit code 계약 보강 노트
- `invalid_request_matrix.yaml`은 typed error가 "도착하는지"를 검증하므로, 의도한
error code가 오면 step은 통과하고 run은 exit `0`으로 끝난다. 이는 API가 올바른
typed `ErrorInfo`를 돌려준다는 evidence다.
- 잘못된 fixture 자체(필수 step id 누락 등)의 non-zero exit는
`testdata/operator/malformed_scenario.yaml``alt operator scenario validate`
돌리면 exit code `2`로 재현된다.
## 남은 wireframe 의존성 요약
마일스톤 비범위(out-of-scope) 항목과 직접 연결된다:
- Flutter 실화면 구현 및 dashboard layout/navigation/card/chart/form 시각 디자인 확정.
- 위 matrix의 scenario별 "Remaining Flutter wireframe dependency" 열에 적힌 화면 정의.
- push notification, production 운영 자동화는 이번 마일스톤 handoff 범위 밖이다.
이 화면 정의는 `Flutter Operator Console UX Plan` / `Flutter Operator Console MVP`에서
wireframe 또는 동등한 화면 정의 산출물과 사용자 승인 기준이 준비되어야 구현 잠금이
풀린다(운영 UI 구현 게이트).