From 1314fe290be53036ff8c4eb9a4863c7b6e6363c5 Mon Sep 17 00:00:00 2001 From: toki Date: Wed, 3 Jun 2026 19:02:19 +0900 Subject: [PATCH] Plan command-first operator workflow --- agent-roadmap/current.md | 2 +- agent-roadmap/phase/operator-surface/PHASE.md | 2 +- .../command-first-operator-workflow.md | 8 +- .../CODE_REVIEW-cloud-G08.md | 155 +++++++ .../PLAN-cloud-G08.md | 429 ++++++++++++++++++ .../CODE_REVIEW-cloud-G07.md | 159 +++++++ .../PLAN-cloud-G07.md | 301 ++++++++++++ .../CODE_REVIEW-cloud-G07.md | 142 ++++++ .../PLAN-cloud-G07.md | 250 ++++++++++ .../CODE_REVIEW-cloud-G08.md | 156 +++++++ .../PLAN-cloud-G08.md | 330 ++++++++++++++ .../CODE_REVIEW-local-G05.md | 134 ++++++ .../PLAN-local-G05.md | 203 +++++++++ 13 files changed, 2267 insertions(+), 4 deletions(-) create mode 100644 agent-task/m-command-first-operator-workflow/01_import_contract_worker_api/CODE_REVIEW-cloud-G08.md create mode 100644 agent-task/m-command-first-operator-workflow/01_import_contract_worker_api/PLAN-cloud-G08.md create mode 100644 agent-task/m-command-first-operator-workflow/02+01_import_cli_scenario/CODE_REVIEW-cloud-G07.md create mode 100644 agent-task/m-command-first-operator-workflow/02+01_import_cli_scenario/PLAN-cloud-G07.md create mode 100644 agent-task/m-command-first-operator-workflow/03+02_market_status_scenario/CODE_REVIEW-cloud-G07.md create mode 100644 agent-task/m-command-first-operator-workflow/03+02_market_status_scenario/PLAN-cloud-G07.md create mode 100644 agent-task/m-command-first-operator-workflow/04+02_backtest_runtime_flow/CODE_REVIEW-cloud-G08.md create mode 100644 agent-task/m-command-first-operator-workflow/04+02_backtest_runtime_flow/PLAN-cloud-G08.md create mode 100644 agent-task/m-command-first-operator-workflow/05+03,04_operator_handoff/CODE_REVIEW-local-G05.md create mode 100644 agent-task/m-command-first-operator-workflow/05+03,04_operator_handoff/PLAN-local-G05.md diff --git a/agent-roadmap/current.md b/agent-roadmap/current.md index b7a905f..711bc20 100644 --- a/agent-roadmap/current.md +++ b/agent-roadmap/current.md @@ -7,7 +7,7 @@ ## 활성 Milestone -- [계획] Command-First Operator Workflow +- [진행중] Command-First Operator Workflow - Phase: `agent-roadmap/phase/operator-surface/PHASE.md` - 경로: `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` diff --git a/agent-roadmap/phase/operator-surface/PHASE.md b/agent-roadmap/phase/operator-surface/PHASE.md index b2d017c..5c32060 100644 --- a/agent-roadmap/phase/operator-surface/PHASE.md +++ b/agent-roadmap/phase/operator-surface/PHASE.md @@ -31,7 +31,7 @@ Flutter 실화면 전에 API 서버 중심 proto-socket rail과 CLI/YAML/log/tes - [완료] KIS Live Data Collection Pipeline - 경로: `agent-roadmap/archive/phase/operator-surface/milestones/kis-live-data-collection-pipeline.md` - 요약: Flutter 실화면 전에 KIS 실 API 기반 한국장 일봉 수집, worker import/storage, `StorageBarSource` 입력 조회 경계까지 검증한다. -- [계획] Command-First Operator Workflow +- [진행중] Command-First Operator Workflow - 경로: `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` - 요약: Flutter 실화면을 보류하고 KIS live data, worker storage, market status, backtest 실행/결과 확인을 CLI/YAML/log 중심의 반복 가능한 operator workflow로 묶는다. diff --git a/agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md b/agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md index 06186cd..a586e21 100644 --- a/agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md +++ b/agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md @@ -11,7 +11,7 @@ Flutter 실화면을 보류한 상태에서 KIS live data, worker storage, marke ## 상태 -[계획] +[진행중] ## 구현 잠금 @@ -33,7 +33,7 @@ Flutter 실화면을 보류한 상태에서 KIS live data, worker storage, marke 화면 없이도 운영자가 KIS 데이터 수집, 상태 조회, 백테스트 실행/결과 확인을 반복할 수 있는 command path를 만든다. -- [ ] [kis-smoke-runbook] KIS paper/real daily smoke와 Go live-provider smoke 실행 경로가 command runbook으로 정리되어 있다. 검증: secret 원문 없이 readiness/smoke/evidence key가 문서화되고 smoke command가 dry failure와 live-gated success 경로를 구분한다. +- [x] [kis-smoke-runbook] KIS paper/real daily smoke와 Go live-provider smoke 실행 경로가 command runbook으로 정리되어 있다. 검증: secret 원문 없이 readiness/smoke/evidence key가 문서화되고 smoke command가 dry failure와 live-gated success 경로를 구분한다. - [ ] [live-import-command] KIS live daily bars를 worker storage에 import하는 command 또는 YAML scenario가 있다. 검증: fake/provider test와 필요한 integration smoke가 import result와 storage upsert를 확인한다. - [ ] [market-status-scenario] imported market data를 CLI/YAML로 조회할 수 있다. 검증: `alt operator scenario validate/run` 또는 동등한 command가 instrument/bar count와 typed unavailable/error key를 출력한다. - [ ] [backtest-command-flow] imported daily bars를 입력으로 backtest start/poll/result를 command workflow에서 확인할 수 있다. 검증: start/poll/result scenario가 run id, terminal status, result summary key를 출력한다. @@ -65,6 +65,10 @@ Flutter 실화면을 보류한 상태에서 KIS live data, worker storage, marke - 표준선(선택): 현재 운영은 화면보다 CLI/YAML/log/test fixture를 우선한다. Flutter MVP는 command workflow에서 반복 운영 항목, 상태 key, 우선순위가 충분히 표면화되어 정리 가능한 뒤에 다시 연다. - 표준선(선택): command output은 사람이 읽을 수 있으면서도 `jsonl`/status key처럼 script가 grep 가능한 형태를 유지한다. - 표준선(선택): KIS secret은 SOPS + age command-lifetime env 주입 경계만 사용하고 tracked 문서에는 sanitized evidence만 남긴다. +- 최근 evidence: `docs/kis-live-secret-handoff.md`와 `docs/kis-live-secret-guide.md`에 paper/real readiness, 일봉 smoke, Go live-provider smoke 명령과 sanitized evidence key가 정리되어 있다. +- 최근 evidence: `bin/kis-paper-daily-smoke`는 `KIS_ACTIVE_ENV=paper|real`을 명시하지 않거나 필수 env가 없으면 외부 호출 전에 실패하고, SOPS 주입 live 경로에서는 `env`, `provider`, `endpoint`, `symbol`, `bar_count`, `msg_cd` 요약만 출력한다. +- 현재 작업 지점: 작은 작업인 `kis-smoke-runbook`은 완료 처리했고, 남은 큰 작업은 `agent-task/m-command-first-operator-workflow/` 아래 split plan으로 대기한다. +- 현재 작업 지점: `01_import_contract_worker_api` -> `02+01_import_cli_scenario` -> `03+02_market_status_scenario`, `04+02_backtest_runtime_flow` -> `05+03,04_operator_handoff` 순서로 진행한다. - 선행 작업: Operator Headless Workflow Validation, Operator Client API/Core Integration Validation, KIS Live Data Collection Pipeline - 후속 작업: Paper Trading Readiness, Paper Trading Command Workflow, US Market Expansion, Live Trading Boundary, Flutter Operator Console MVP - 확인 필요: 없음 diff --git a/agent-task/m-command-first-operator-workflow/01_import_contract_worker_api/CODE_REVIEW-cloud-G08.md b/agent-task/m-command-first-operator-workflow/01_import_contract_worker_api/CODE_REVIEW-cloud-G08.md new file mode 100644 index 0000000..2081554 --- /dev/null +++ b/agent-task/m-command-first-operator-workflow/01_import_contract_worker_api/CODE_REVIEW-cloud-G08.md @@ -0,0 +1,155 @@ + + +# Code Review Reference - API + +> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.** +> The task is NOT complete until every implementation-owned section below is filled in. +> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving. +> Fill implementation-owned sections, then stop with active files in place and report ready for review. +> If implementation is blocked by a user-only decision, user-owned external environment prerequisite, or scope conflict, fill `사용자 리뷰 요청` with evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`. Evidence gaps that a follow-up agent can close by rerunning commands or collecting artifacts are normal follow-up issues, not user-review blockers by themselves. +> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume. +> Follow the ownership table at the bottom of this file for which sections you own. + +## 개요 + +date=2026-06-03 +task=m-command-first-operator-workflow/01_import_contract_worker_api, plan=0, tag=API + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다. + +각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요. +리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다. + +1. 판정을 append한다. +2. `CODE_REVIEW-cloud-G08.md` → `code_review_cloud_G08_N.log`, `PLAN-cloud-G08.md` → `plan_cloud_G08_M.log`로 아카이브한다. +3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/m-command-first-operator-workflow/01_import_contract_worker_api/`로 이동한다. WARN/FAIL이면 user-review gate를 확인한 뒤 다음 active plan/review 파일 또는 `USER_REVIEW.md`를 작성한다. `USER_REVIEW.md`가 사용자 결정으로 완료/PASS 해소되면 code-review가 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log` 작성 후 archive 이동한다. +4. PASS이고 task group이 `m-`이면 완료 이벤트 메타데이터를 보고한다. roadmap 상태 체크와 `update-roadmap` 호출은 런타임 책임이다. +5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [API-1] Contract And Parser Surface | [ ] | +| [API-2] API Forwarding | [ ] | +| [API-3] Worker Import Handler | [ ] | +| [API-4] Worker Entrypoint Wiring | [ ] | +| [API-5] Focused Verification | [ ] | + +## 구현 체크리스트 + +- [ ] [API-1] Add `ImportDailyBarsRequest/Response` protobuf messages, regenerate contracts, and register parsers in API/worker/CLI maps. +- [ ] [API-2] Add API workerclient and API socket forwarding for import daily bars with typed unavailable/timeout/internal errors. +- [ ] [API-3] Add worker socket import handler that validates request shape, calls the importer dependency, and returns instrument/bar counts. +- [ ] [API-4] Wire `alt-worker` store-backed deps with the KIS importer command surface without exposing secrets. +- [ ] [API-5] Run focused contract/API/worker verification and `git diff --check`. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. +> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다. + +- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. +- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다. +- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_cloud_G08_N.log`로 아카이브한다. +- [ ] active `PLAN-*-G??.md`를 `plan_cloud_G08_M.log`로 아카이브한다. +- [ ] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하여 plan/review/archive 산출물이 추적 가능한지 확인한다. +- [ ] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다. +- [ ] PASS이면 active task 디렉터리 `agent-task/m-command-first-operator-workflow/01_import_contract_worker_api/`를 `agent-task/archive/YYYY/MM/m-command-first-operator-workflow/01_import_contract_worker_api/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다. +- [ ] PASS이고 task group이 `m-`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다. +- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/m-command-first-operator-workflow/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다. +- [ ] WARN/FAIL이고 user-review gate가 트리거되지 않았으면 다음 active `PLAN-cloud-G08.md`와 `CODE_REVIEW-cloud-G08.md`를 작성하고 `complete.log`를 작성하지 않는다. +- [ ] USER_REVIEW이면 `agent-ops/skills/common/code-review/templates/user-review-template.md` 기준으로 `USER_REVIEW.md`를 작성하고 active `PLAN-*.md`, `CODE_REVIEW-*.md`, `complete.log`를 남기지 않는다. +- [ ] USER_REVIEW가 사용자 결정으로 완료/PASS 해소되면 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log`를 작성한 뒤 task directory를 archive로 이동한다. + +## 계획 대비 변경 사항 + +_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ + +## 주요 설계 결정 + +_구현 에이전트가 주요 설계 결정 사항을 기록한다._ + +## 사용자 리뷰 요청 + +_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._ + +- 상태: 없음 +- 사유 유형: 없음 +- 결정 필요: 없음 +- 차단 근거: 없음 +- 실행한 검증/명령: 없음 +- 자동 후속 불가 이유: 없음 +- 재개 조건: 없음 + +## 리뷰어를 위한 체크포인트 + +- Protobuf change is additive and generated files were regenerated rather than hand-edited. +- API remains a thin validator/forwarder and does not import worker internals. +- Worker owns import execution and returns typed `ErrorInfo` instead of handler errors. +- Capability strings match registered handlers and available deps. +- No secret/account/token/raw KIS payload is logged or written. + +## 검증 결과 + +_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._ + +필수 규칙: +- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다. +- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다. +- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다. +- 사용자 리뷰 요청으로 명령을 끝까지 실행하지 못했다면 `사용자 리뷰 요청`에 실행한 명령, 실제 출력, 미실행 명령의 사유를 기록한다. +- mobile/UI hang, timeout, 또는 2분 무진행은 blind retry를 중단하고 focused rerun 명령과 screenshot/window/UI-tree evidence path를 남기며, 불가능하면 정확한 사유를 남긴다. + +### API-1 중간 검증 +```bash +$ bin/contracts-check +$ go test ./packages/contracts/gen/go/... -count=1 +$ go test ./services/api/internal/contracts ./services/worker/internal/contracts ./apps/cli/internal/operator -run ParserMap -count=1 +(output) +``` + +### API-2 중간 검증 +```bash +$ go test ./services/api/... -count=1 +(output) +``` + +### API-3 중간 검증 +```bash +$ go test ./services/worker/internal/socket -count=1 +(output) +``` + +### API-4 중간 검증 +```bash +$ go test ./services/worker/... -count=1 +(output) +``` + +### API-5 중간 검증 +```bash +$ git diff --check +(output) +``` + +### 최종 검증 +```bash +$ bin/contracts-check +$ go test ./packages/contracts/gen/go/... -count=1 +$ go test ./services/api/... -count=1 +$ go test ./services/worker/... -count=1 +$ git diff --check +(output) +``` + +--- + +> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?** +> If anything is blank, go back and fill it in before saving this file. +> Leave review-agent-only sections unchanged. diff --git a/agent-task/m-command-first-operator-workflow/01_import_contract_worker_api/PLAN-cloud-G08.md b/agent-task/m-command-first-operator-workflow/01_import_contract_worker_api/PLAN-cloud-G08.md new file mode 100644 index 0000000..dfdb429 --- /dev/null +++ b/agent-task/m-command-first-operator-workflow/01_import_contract_worker_api/PLAN-cloud-G08.md @@ -0,0 +1,429 @@ + + +# Plan - Import Contract Worker API + +## 이 파일을 읽는 구현 에이전트에게 + +이 plan은 구현 지시서이며, 구현 완료 전 active `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 반드시 실제 내용과 검증 출력으로 채운다. 검증은 아래 명령을 실행하고 실제 stdout/stderr를 review stub에 붙인다. 최종 판정, archive 이동, `complete.log` 작성은 code-review-skill 전용이다. 사용자 결정, 사용자 소유 외부 환경/secret, 또는 범위 충돌 없이는 진행할 수 없을 때만 review stub의 `사용자 리뷰 요청`을 채우고 멈춘다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 증거 공백은 사용자 리뷰 요청이 아니다. + +## 배경 + +현재 KIS provider와 importer는 준비되어 있지만 operator가 API/worker socket을 통해 daily bars import를 명령할 contract가 없다. 이 작업은 CLI/YAML이 호출할 수 있는 typed request/response와 API forwarding, worker import handler를 추가한다. 이 foundation만으로는 마일스톤의 `live-import-command`를 완료하지 않으며, 후속 `02+01_import_cli_scenario`가 command surface를 완성한다. + +## 사용자 리뷰 요청 흐름 + +구현 중 사용자-only blocker는 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 이 섹션은 `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` 기준이며, code-review가 검증 후 실제 `USER_REVIEW.md` 작성 여부를 결정한다. + +## 분석 결과 + +### 읽은 파일 + +- `agent-ops/rules/project/rules.md` +- `agent-ops/rules/private/rules.md` +- `agent-ops/rules/common/rules-roadmap.md` +- `agent-ops/skills/common/router.md` +- `agent-ops/skills/common/plan/SKILL.md` +- `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` +- `agent-test/local/rules.md` +- `agent-test/local/contracts-smoke.md` +- `agent-test/local/api-smoke.md` +- `agent-test/local/worker-smoke.md` +- `agent-test/local/operations-smoke.md` +- `agent-ops/rules/project/domain/contracts/rules.md` +- `agent-ops/rules/project/domain/api/rules.md` +- `agent-ops/rules/project/domain/worker/rules.md` +- `agent-ops/rules/project/domain/operations/rules.md` +- `agent-ops/rules/private/kis-api-local-cache.md` +- `agent-ops/rules/private/testing-env.md` +- `agent-roadmap/current.md` +- `agent-roadmap/phase/operator-surface/PHASE.md` +- `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` +- `packages/contracts/proto/alt/v1/common.proto` +- `packages/contracts/proto/alt/v1/market.proto` +- `packages/contracts/proto/alt/v1/backtest.proto` +- `services/api/internal/contracts/parser_map.go` +- `services/api/internal/contracts/parser_map_test.go` +- `services/api/internal/socket/handlers.go` +- `services/api/internal/socket/market.go` +- `services/api/internal/socket/market_test.go` +- `services/api/internal/socket/backtest_test.go` +- `services/api/internal/socket/server_test.go` +- `services/api/internal/workerclient/client.go` +- `services/api/internal/workerclient/client_test.go` +- `services/worker/internal/contracts/parser_map.go` +- `services/worker/internal/contracts/parser_map_test.go` +- `services/worker/internal/socket/handlers.go` +- `services/worker/internal/socket/backtest.go` +- `services/worker/internal/socket/market.go` +- `services/worker/internal/socket/market_mapping.go` +- `services/worker/internal/socket/market_test.go` +- `services/worker/internal/socket/server_test.go` +- `services/worker/internal/jobs/marketdata_jobs.go` +- `services/worker/internal/jobs/runner.go` +- `services/worker/internal/marketdata/importer/importer.go` +- `services/worker/cmd/alt-worker/main.go` +- `bin/contracts-gen` +- `bin/contracts-check` +- `bin/test` +- `go.work` +- `services/api/go.mod` +- `services/worker/go.mod` +- `packages/contracts/gen/go/go.mod` + +### 테스트 환경 규칙 + +- test_env: `local`. +- `agent-test/local/rules.md` present/read. Matched profiles: `contracts-smoke`, `api-smoke`, `worker-smoke`, `operations-smoke`. +- Applied commands: `bin/contracts-gen` for proto changes, `bin/contracts-check`, `go test ./packages/contracts/gen/go/...`, `go test ./services/api/...`, `go test ./services/worker/...`. +- Fallback: none. No `<확인 필요>` command values in matched profiles. + +### 테스트 커버리지 공백 + +- Import protobuf parser coverage: existing parser map tests cover required messages but must be extended for `ImportDailyBarsRequest/Response`. +- API forwarding: existing market handler and workerclient tests cover list requests; import request tests are missing and must be added. +- Worker import handler: existing market read tests and importer/job tests cover adjacent behavior; direct socket import command tests are missing and must be added. +- Live KIS end-to-end command smoke remains outside this foundation; fake importer tests are sufficient here because KIS provider live smoke is already covered by the completed predecessor milestone. + +### 심볼 참조 + +- Renamed/removed symbols: none. This is additive. +- New message registration call sites must be added in API, worker, and CLI parser maps so proto-socket decoding does not drift. + +### 분할 판단 + +- Split policy evaluated before writing files. +- Shared task group: `agent-task/m-command-first-operator-workflow/`. +- Siblings: + - `01_import_contract_worker_api`: foundation, no predecessor. + - `02+01_import_cli_scenario`: waits for this contract/API/worker rail. + - `03+02_market_status_scenario`: waits for import CLI scenario. + - `04+02_backtest_runtime_flow`: waits for import CLI scenario. + - `05+03,04_operator_handoff`: waits for status and backtest flow. +- This plan has no predecessor. It intentionally has no `Roadmap Targets` because it does not by itself complete a Milestone 기능 Task. + +### 범위 결정 근거 + +- Excludes CLI YAML action implementation; that belongs to `02+01_import_cli_scenario`. +- Excludes market status fixture updates; that belongs to `03+02_market_status_scenario`. +- Excludes backtest runtime wiring and strategy resolver; that belongs to `04+02_backtest_runtime_flow`. +- Excludes Flutter UI, wireframes, production scheduling, and raw KIS secret handling per milestone scope. + +### 빌드 등급 + +- build=`cloud-G08`, review=`cloud-G08`: additive but cross-domain protobuf/API/worker protocol work with parser registration and generated-output drift risk. + +## 구현 체크리스트 + +- [ ] [API-1] Add `ImportDailyBarsRequest/Response` protobuf messages, regenerate contracts, and register parsers in API/worker/CLI maps. +- [ ] [API-2] Add API workerclient and API socket forwarding for import daily bars with typed unavailable/timeout/internal errors. +- [ ] [API-3] Add worker socket import handler that validates request shape, calls the importer dependency, and returns instrument/bar counts. +- [ ] [API-4] Wire `alt-worker` store-backed deps with the KIS importer command surface without exposing secrets. +- [ ] [API-5] Run focused contract/API/worker verification and `git diff --check`. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## [API-1] Contract And Parser Surface + +### 문제 + +[packages/contracts/proto/alt/v1/market.proto](/config/workspace/alt/packages/contracts/proto/alt/v1/market.proto:39) only has market read messages. There is no typed import command request/response for CLI/API/worker use. Parser maps currently register only list/read and backtest messages in [services/api/internal/contracts/parser_map.go](/config/workspace/alt/services/api/internal/contracts/parser_map.go:18), [services/worker/internal/contracts/parser_map.go](/config/workspace/alt/services/worker/internal/contracts/parser_map.go:14), and [apps/cli/internal/operator/parser_map.go](/config/workspace/alt/apps/cli/internal/operator/parser_map.go:20). + +### 해결 방법 + +Add messages after `ListBarsResponse` using new field numbers only. + +Before (`market.proto:49`): + +```proto +message ListBarsRequest { + string instrument_id = 1; + Timeframe timeframe = 2; + int64 from_unix_ms = 3; + int64 to_unix_ms = 4; +} +``` + +After: + +```proto +message ImportDailyBarsRequest { + string provider = 1; + string selector_kind = 2; + Market market = 3; + Venue venue = 4; + string name = 5; + repeated string symbols = 6; + string from_yyyymmdd = 7; + string to_yyyymmdd = 8; +} + +message ImportDailyBarsResponse { + string provider = 1; + int32 instrument_count = 2; + int32 bar_count = 3; + ErrorInfo error = 4; +} +``` + +Run `bin/contracts-gen`. Do not hand-edit generated files. + +### 수정 파일 및 체크리스트 + +- [ ] `packages/contracts/proto/alt/v1/market.proto`: add request/response. +- [ ] `packages/contracts/gen/go/alt/v1/market.pb.go`: regenerated only. +- [ ] `apps/client/lib/src/generated/alt/v1/market.pb*.dart`: regenerated only if `bin/contracts-gen` updates them. +- [ ] `services/api/internal/contracts/parser_map.go`: register both messages. +- [ ] `services/api/internal/contracts/parser_map_test.go`: require both messages. +- [ ] `services/worker/internal/contracts/parser_map.go`: register both messages. +- [ ] `services/worker/internal/contracts/parser_map_test.go`: require both messages. +- [ ] `apps/cli/internal/operator/parser_map.go`: register both messages for later CLI action. +- [ ] `apps/cli/internal/operator/parser_map_test.go`: require at least the response parser. + +### 테스트 작성 + +Write/extend parser map tests in API, worker, and CLI to assert `protoSocket.TypeNameOf(&altv1.ImportDailyBarsRequest{})` and response are registered and parse. + +### 중간 검증 + +```bash +bin/contracts-check +go test ./packages/contracts/gen/go/... -count=1 +go test ./services/api/internal/contracts ./services/worker/internal/contracts ./apps/cli/internal/operator -run ParserMap -count=1 +``` + +Expected: all commands exit 0. + +## [API-2] API Forwarding + +### 문제 + +[services/api/internal/workerclient/client.go](/config/workspace/alt/services/api/internal/workerclient/client.go:25) has no import method in `WorkerClient`, and [services/api/internal/socket/market.go](/config/workspace/alt/services/api/internal/socket/market.go:22) only registers list/read handlers. + +### 해결 방법 + +Add `ImportDailyBars(ctx, *altv1.ImportDailyBarsRequest)` to `WorkerClient`, implement it as a one-line `sendTyped`, and add an API market handler that validates minimal shape then forwards. Validation should reject empty provider, empty selector kind, empty symbols, unsupported market/venue, and malformed date strings before connecting to worker. + +Before (`client.go:39`): + +```go +// Market query surface. +ListInstruments(ctx context.Context, req *altv1.ListInstrumentsRequest) (*altv1.ListInstrumentsResponse, error) +ListBars(ctx context.Context, req *altv1.ListBarsRequest) (*altv1.ListBarsResponse, error) +``` + +After: + +```go +ImportDailyBars(ctx context.Context, req *altv1.ImportDailyBarsRequest) (*altv1.ImportDailyBarsResponse, error) +ListInstruments(ctx context.Context, req *altv1.ListInstrumentsRequest) (*altv1.ListInstrumentsResponse, error) +ListBars(ctx context.Context, req *altv1.ListBarsRequest) (*altv1.ListBarsResponse, error) +``` + +### 수정 파일 및 체크리스트 + +- [ ] `services/api/internal/workerclient/client.go`: interface and socket client method. +- [ ] `services/api/internal/workerclient/client_test.go`: fake worker server round-trip and unavailable guard. +- [ ] `services/api/internal/socket/market.go`: import handler registration, validation, forwarding, nil response mapping. +- [ ] `services/api/internal/socket/market_test.go`: forwarding, validation, nil worker, connect failure. +- [ ] `services/api/internal/socket/backtest_test.go`: update `fakeWorkerClient` to implement the new interface. +- [ ] `services/api/internal/socket/server_test.go`: capability/handler sync if capability is advertised. + +### 테스트 작성 + +Add `TestWorkerClient_ImportDailyBars_Success`, `TestHandleImportDailyBarsForwards`, validation table, nil worker response, and socket typed validation tests. + +### 중간 검증 + +```bash +go test ./services/api/... -count=1 +``` + +Expected: API tests pass and no fake worker interface compile failure remains. + +## [API-3] Worker Import Handler + +### 문제 + +[services/worker/internal/socket/market.go](/config/workspace/alt/services/worker/internal/socket/market.go:23) only exposes reads. [services/worker/internal/marketdata/importer/importer.go](/config/workspace/alt/services/worker/internal/marketdata/importer/importer.go:73) already returns import counts, but no socket handler returns them. + +### 해결 방법 + +Add a narrow socket dependency interface for `ImportDailyBars`, add it to `Deps`, register `ImportDailyBarsRequest`, validate and convert request fields into `importer.DailyBarRequest`, call the importer, and map errors to `ErrorInfo`. Add `venueFromProto` next to `venueToProto`. + +Before (`backtest.go:38`): + +```go +type Deps struct { + Starter BacktestStarter + Analysis storage.BacktestAnalysisStore + Results storage.BacktestResultStore + Instruments storage.InstrumentStore + Bars storage.BarStore +} +``` + +After: + +```go +type DailyBarImporter interface { + ImportDailyBars(ctx context.Context, request importer.DailyBarRequest) (importer.Result, error) +} + +type Deps struct { + Starter BacktestStarter + Analysis storage.BacktestAnalysisStore + Results storage.BacktestResultStore + Instruments storage.InstrumentStore + Bars storage.BarStore + DailyBarImport DailyBarImporter +} +``` + +Use a gofmt-friendly field name such as `DailyBarImporter` if preferred; keep the capability name stable. + +### 수정 파일 및 체크리스트 + +- [ ] `services/worker/internal/socket/backtest.go`: add dependency interface/field. +- [ ] `services/worker/internal/socket/market.go`: handler registration, validation, conversion, error mapping. +- [ ] `services/worker/internal/socket/market_mapping.go`: add `venueFromProto`. +- [ ] `services/worker/internal/socket/market_test.go`: fake importer, success counts, validation, unavailable, socket round-trip. +- [ ] `services/worker/internal/socket/server_test.go`: capability expectations. + +### 테스트 작성 + +Add tests for: + +- success count response from fake importer, +- request conversion provider/selector/date range, +- missing provider/selector/symbol and unsupported market/venue, +- importer nil returns `unavailable`, +- socket request returns typed response without timeout. + +### 중간 검증 + +```bash +go test ./services/worker/internal/socket -count=1 +``` + +Expected: worker socket tests pass. + +## [API-4] Worker Entrypoint Wiring + +### 문제 + +[services/worker/cmd/alt-worker/main.go](/config/workspace/alt/services/worker/cmd/alt-worker/main.go:40) creates the KIS live provider and registers the job handler, but [services/worker/cmd/alt-worker/main.go](/config/workspace/alt/services/worker/cmd/alt-worker/main.go:42) does not expose the importer through socket deps. + +### 해결 방법 + +Create one importer instance and pass it both to `jobs.RegisterDailyBarImportHandler` and the socket dependency field. Do not log app key, token, account, raw headers, or secret item names. Add an `import_daily_bars` or `market-import` capability only when the importer dependency exists. + +Before (`main.go:40`): + +```go +kisProvider := kis.NewLiveProvider(kis.NewClient(kis.ConfigFromEnv())) +jobs.RegisterDailyBarImportHandler(runner, market.ProviderKIS, importer.New(kisProvider, store)) +deps = socket.Deps{ + Analysis: store, + Results: store, + Instruments: store, + Bars: store, +} +``` + +After: + +```go +kisImporter := importer.New(kisProvider, store) +jobs.RegisterDailyBarImportHandler(runner, market.ProviderKIS, kisImporter) +deps = socket.Deps{ + Analysis: store, + Results: store, + Instruments: store, + Bars: store, + DailyBarImporter: kisImporter, +} +``` + +### 수정 파일 및 체크리스트 + +- [ ] `services/worker/cmd/alt-worker/main.go`: reuse importer and set deps. +- [ ] `services/worker/internal/socket/handlers.go`: add capability if implemented. +- [ ] `services/worker/internal/socket/server_test.go`: capability only present when import dependency exists. + +### 테스트 작성 + +Entrypoint has no current direct main test. Cover behavior through `capabilitiesForDeps` and worker socket handler tests. + +### 중간 검증 + +```bash +go test ./services/worker/... -count=1 +``` + +Expected: worker module passes. + +## [API-5] Focused Verification + +### 문제 + +Protocol and parser changes can pass local unit tests while generated files drift. The matched contract profile requires generated drift checks. + +### 해결 방법 + +Run the exact final commands and paste output into the review stub. + +### 수정 파일 및 체크리스트 + +- [ ] No extra files. + +### 테스트 작성 + +No new test beyond items above. + +### 중간 검증 + +```bash +git diff --check +``` + +Expected: no whitespace or patch-format warnings. + +## 수정 파일 요약 + +| 파일 | 항목 | +|------|------| +| `packages/contracts/proto/alt/v1/market.proto` | API-1 | +| `packages/contracts/gen/go/alt/v1/market.pb.go` | API-1 | +| `apps/client/lib/src/generated/alt/v1/market.pb*.dart` | API-1 | +| `services/api/internal/contracts/parser_map.go` | API-1 | +| `services/api/internal/contracts/parser_map_test.go` | API-1 | +| `services/worker/internal/contracts/parser_map.go` | API-1 | +| `services/worker/internal/contracts/parser_map_test.go` | API-1 | +| `apps/cli/internal/operator/parser_map.go` | API-1 | +| `apps/cli/internal/operator/parser_map_test.go` | API-1 | +| `services/api/internal/workerclient/client.go` | API-2 | +| `services/api/internal/workerclient/client_test.go` | API-2 | +| `services/api/internal/socket/market.go` | API-2 | +| `services/api/internal/socket/market_test.go` | API-2 | +| `services/api/internal/socket/backtest_test.go` | API-2 | +| `services/api/internal/socket/server_test.go` | API-2 | +| `services/worker/internal/socket/backtest.go` | API-3 | +| `services/worker/internal/socket/market.go` | API-3 | +| `services/worker/internal/socket/market_mapping.go` | API-3 | +| `services/worker/internal/socket/market_test.go` | API-3 | +| `services/worker/internal/socket/server_test.go` | API-3, API-4 | +| `services/worker/internal/socket/handlers.go` | API-4 | +| `services/worker/cmd/alt-worker/main.go` | API-4 | + +## 최종 검증 + +```bash +bin/contracts-check +go test ./packages/contracts/gen/go/... -count=1 +go test ./services/api/... -count=1 +go test ./services/worker/... -count=1 +git diff --check +``` + +Expected: all commands exit 0. Fresh `go test -count=1` is required; cached output is not acceptable for this protocol change. + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/agent-task/m-command-first-operator-workflow/02+01_import_cli_scenario/CODE_REVIEW-cloud-G07.md b/agent-task/m-command-first-operator-workflow/02+01_import_cli_scenario/CODE_REVIEW-cloud-G07.md new file mode 100644 index 0000000..0ae6733 --- /dev/null +++ b/agent-task/m-command-first-operator-workflow/02+01_import_cli_scenario/CODE_REVIEW-cloud-G07.md @@ -0,0 +1,159 @@ + + +# Code Review Reference - CLI + +> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.** +> The task is NOT complete until every implementation-owned section below is filled in. +> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving. +> Fill implementation-owned sections, then stop with active files in place and report ready for review. +> If implementation is blocked by a user-only decision, user-owned external environment prerequisite, or scope conflict, fill `사용자 리뷰 요청` with evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`. Evidence gaps that a follow-up agent can close by rerunning commands or collecting artifacts are normal follow-up issues, not user-review blockers by themselves. +> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume. +> Follow the ownership table at the bottom of this file for which sections you own. + +## 개요 + +date=2026-06-03 +task=m-command-first-operator-workflow/02+01_import_cli_scenario, plan=0, tag=CLI + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` +- Task ids: + - `live-import-command`: KIS live daily bars를 worker storage에 import하는 command 또는 YAML scenario가 있다. +- Completion mode: check-on-pass + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다. + +각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요. +리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다. + +1. 판정을 append한다. +2. `CODE_REVIEW-cloud-G07.md` → `code_review_cloud_G07_N.log`, `PLAN-cloud-G07.md` → `plan_cloud_G07_M.log`로 아카이브한다. +3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/m-command-first-operator-workflow/02+01_import_cli_scenario/`로 이동한다. +4. PASS이고 task group이 `m-`이면 완료 이벤트 메타데이터를 보고한다. roadmap 상태 체크와 `update-roadmap` 호출은 런타임 책임이다. +5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [CLI-1] Scenario Schema | [ ] | +| [CLI-2] API Client Method | [ ] | +| [CLI-3] Runner And Output | [ ] | +| [CLI-4] Import Fixture | [ ] | +| [CLI-5] Verification | [ ] | + +## 구현 체크리스트 + +- [ ] [CLI-1] Add `import_daily_bars` scenario schema fields and dry-run validation. +- [ ] [CLI-2] Add CLI `APIClient.ImportDailyBars` and fake API test support. +- [ ] [CLI-3] Execute import action in runner and emit `provider`, `instrument_count`, and `bar_count` output keys. +- [ ] [CLI-4] Add import smoke YAML and expected JSONL fixture. 검증: fake/provider test and scenario validation confirm import result counts are emitted. +- [ ] [CLI-5] Run CLI-focused verification and `git diff --check`. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. +> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다. + +- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. +- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다. +- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_cloud_G07_N.log`로 아카이브한다. +- [ ] active `PLAN-*-G??.md`를 `plan_cloud_G07_M.log`로 아카이브한다. +- [ ] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하여 plan/review/archive 산출물이 추적 가능한지 확인한다. +- [ ] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다. +- [ ] PASS이면 active task 디렉터리 `agent-task/m-command-first-operator-workflow/02+01_import_cli_scenario/`를 `agent-task/archive/YYYY/MM/m-command-first-operator-workflow/02+01_import_cli_scenario/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다. +- [ ] PASS이고 task group이 `m-`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다. +- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/m-command-first-operator-workflow/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다. +- [ ] WARN/FAIL이고 user-review gate가 트리거되지 않았으면 다음 active `PLAN-cloud-G07.md`와 `CODE_REVIEW-cloud-G07.md`를 작성하고 `complete.log`를 작성하지 않는다. +- [ ] USER_REVIEW이면 `agent-ops/skills/common/code-review/templates/user-review-template.md` 기준으로 `USER_REVIEW.md`를 작성하고 active `PLAN-*.md`, `CODE_REVIEW-*.md`, `complete.log`를 남기지 않는다. +- [ ] USER_REVIEW가 사용자 결정으로 완료/PASS 해소되면 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log`를 작성한 뒤 task directory를 archive로 이동한다. + +## 계획 대비 변경 사항 + +_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ + +## 주요 설계 결정 + +_구현 에이전트가 주요 설계 결정 사항을 기록한다._ + +## 사용자 리뷰 요청 + +_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._ + +- 상태: 없음 +- 사유 유형: 없음 +- 결정 필요: 없음 +- 차단 근거: 없음 +- 실행한 검증/명령: 없음 +- 자동 후속 불가 이유: 없음 +- 재개 조건: 없음 + +## 리뷰어를 위한 체크포인트 + +- `import_daily_bars` validation fails offline before any socket call for malformed fixtures. +- CLI output contains stable `provider`, `instrument_count`, and `bar_count` keys. +- Expected typed errors still exit 0 when declared in YAML expectations. +- New fixture contains no raw KIS response, token, account, or secret values. +- Roadmap completion target is only `live-import-command`. + +## 검증 결과 + +_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._ + +필수 규칙: +- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다. +- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다. +- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다. +- 사용자 리뷰 요청으로 명령을 끝까지 실행하지 못했다면 `사용자 리뷰 요청`에 실행한 명령, 실제 출력, 미실행 명령의 사유를 기록한다. +- mobile/UI hang, timeout, 또는 2분 무진행은 blind retry를 중단하고 focused rerun 명령과 screenshot/window/UI-tree evidence path를 남기며, 불가능하면 정확한 사유를 남긴다. + +### CLI-1 중간 검증 +```bash +$ go test ./apps/cli/internal/operator -run 'Scenario|ImportDailyBars' -count=1 +(output) +``` + +### CLI-2 중간 검증 +```bash +$ go test ./apps/cli/internal/operator -run APIClientImportDailyBars -count=1 +(output) +``` + +### CLI-3 중간 검증 +```bash +$ go test ./apps/cli/internal/operator -run 'RunScenario.*Import|ExpectedTypedError' -count=1 +(output) +``` + +### CLI-4 중간 검증 +```bash +$ go test ./apps/cli/internal/operator -run 'Handoff|ImportDailyBars' -count=1 +$ go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/kis_daily_import_smoke.yaml +(output) +``` + +### CLI-5 중간 검증 +```bash +$ git diff --check +(output) +``` + +### 최종 검증 +```bash +$ go test ./apps/cli/... -count=1 +$ go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/kis_daily_import_smoke.yaml +$ git diff --check +(output) +``` + +--- + +> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?** +> If anything is blank, go back and fill it in before saving this file. +> Leave review-agent-only sections unchanged. diff --git a/agent-task/m-command-first-operator-workflow/02+01_import_cli_scenario/PLAN-cloud-G07.md b/agent-task/m-command-first-operator-workflow/02+01_import_cli_scenario/PLAN-cloud-G07.md new file mode 100644 index 0000000..6187d1a --- /dev/null +++ b/agent-task/m-command-first-operator-workflow/02+01_import_cli_scenario/PLAN-cloud-G07.md @@ -0,0 +1,301 @@ + + +# Plan - Import CLI Scenario + +## 이 파일을 읽는 구현 에이전트에게 + +이 plan은 구현 지시서이며, 구현 완료 전 active `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 반드시 실제 내용과 검증 출력으로 채운다. 이 task는 `01_import_contract_worker_api`의 `complete.log`가 생긴 뒤 구현한다. 최종 판정, archive 이동, `complete.log` 작성은 code-review-skill 전용이다. 사용자-only blocker가 있으면 review stub의 `사용자 리뷰 요청`을 채우고 멈춘다. 후속 에이전트가 재실행으로 해소할 수 있는 증거 공백은 사용자 리뷰 요청이 아니다. + +## 배경 + +Foundation 작업이 import request/response를 열어도 운영자는 아직 YAML scenario로 import를 실행할 수 없다. 이 작업은 `alt operator scenario validate/run`에 `import_daily_bars` action을 추가하고, import result를 JSONL evidence key로 출력한다. PASS 시 현재 마일스톤의 `live-import-command` 기능 Task를 완료 대상으로 삼는다. + +## 사용자 리뷰 요청 흐름 + +구현 중 사용자-only blocker는 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. code-review가 이를 검증하고 실제 `USER_REVIEW.md` 작성 여부를 결정한다. + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` +- Task ids: + - `live-import-command`: KIS live daily bars를 worker storage에 import하는 command 또는 YAML scenario가 있다. +- Completion mode: check-on-pass + +## 분석 결과 + +### 읽은 파일 + +- `agent-test/local/rules.md` +- `agent-test/local/contracts-smoke.md` +- `agent-test/local/api-smoke.md` +- `agent-test/local/worker-smoke.md` +- `agent-test/local/operations-smoke.md` +- `agent-ops/rules/project/domain/contracts/rules.md` +- `agent-ops/rules/project/domain/api/rules.md` +- `agent-ops/rules/project/domain/worker/rules.md` +- `agent-ops/rules/project/domain/operations/rules.md` +- `agent-roadmap/current.md` +- `agent-roadmap/phase/operator-surface/PHASE.md` +- `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` +- `apps/cli/internal/operator/scenario.go` +- `apps/cli/internal/operator/scenario_test.go` +- `apps/cli/internal/operator/runner.go` +- `apps/cli/internal/operator/runner_market_test.go` +- `apps/cli/internal/operator/runner_error_test.go` +- `apps/cli/internal/operator/client.go` +- `apps/cli/internal/operator/client_test.go` +- `apps/cli/internal/operator/output.go` +- `apps/cli/internal/operator/parser_map.go` +- `apps/cli/internal/operator/parser_map_test.go` +- `apps/cli/internal/cli/cli.go` +- `apps/cli/internal/cli/cli_test.go` +- `apps/cli/testdata/operator/headless_validation.md` +- `apps/cli/testdata/operator/market_data_status_query.yaml` +- `apps/cli/testdata/operator/expected/market_data_status_query.jsonl` +- `services/api/internal/socket/market.go` +- `services/api/internal/socket/market_test.go` +- `services/api/internal/workerclient/client.go` +- `services/worker/internal/socket/market.go` +- `services/worker/internal/marketdata/importer/importer.go` +- `docs/kis-live-secret-handoff.md` +- `docs/kis-live-secret-guide.md` + +### 테스트 환경 규칙 + +- test_env: `local`. +- Matched profiles: `operations-smoke` for CLI and fixtures, plus `api-smoke`/`worker-smoke`/`contracts-smoke` inherited from predecessor surface. +- Applied commands: `go test ./apps/cli/...`, focused API/worker tests if interface signatures change, and `git diff --check`. +- External real KIS smoke is not required for this CLI action because prior milestone already proved paper/real provider access, and this plan verifies the command rail with fake socket responses. + +### 테스트 커버리지 공백 + +- CLI scenario validation currently covers list/backtest actions, not `import_daily_bars`; add dry-run tests. +- `APIClient` has no import method until predecessor completes; add round-trip fake API test. +- Runner output has count/run/result fields but no `provider`, `instrument_count`, or `bar_count`; add output tests. +- Live import against a running API/worker remains an integration follow-up and should use sanitized SOPS evidence only when available. + +### 심볼 참조 + +- Renamed/removed symbols: none. Additive `ActionImportDailyBars` and request fields only. + +### 분할 판단 + +- Shared task group: `agent-task/m-command-first-operator-workflow/`. +- This subtask directory is `02+01_import_cli_scenario`; predecessor index `01` is `01_import_contract_worker_api`. +- Predecessor completion status at plan creation: missing active/archive `complete.log`; implementation must wait until `agent-task/m-command-first-operator-workflow/01_import_contract_worker_api/complete.log` or matching archive path exists. + +### 범위 결정 근거 + +- Excludes protobuf/API/worker foundation implementation; it is in predecessor `01`. +- Excludes imported data status scenario beyond import result; it is in `03+02_market_status_scenario`. +- Excludes real secret handling and raw KIS payload capture; only sanitized command evidence is allowed. +- Excludes Flutter UI. + +### 빌드 등급 + +- build=`cloud-G07`, review=`cloud-G07`: CLI/YAML/JSONL exit contract and stdout key behavior are central. + +## 의존 관계 및 구현 순서 + +- Wait for predecessor `01_import_contract_worker_api` complete.log. Directory dependency is authoritative: `02+01_import_cli_scenario`. +- After predecessor completion, implement CLI schema/client/runner/output, then fixtures/tests. + +## 구현 체크리스트 + +- [ ] [CLI-1] Add `import_daily_bars` scenario schema fields and dry-run validation. +- [ ] [CLI-2] Add CLI `APIClient.ImportDailyBars` and fake API test support. +- [ ] [CLI-3] Execute import action in runner and emit `provider`, `instrument_count`, and `bar_count` output keys. +- [ ] [CLI-4] Add import smoke YAML and expected JSONL fixture. 검증: fake/provider test and scenario validation confirm import result counts are emitted. +- [ ] [CLI-5] Run CLI-focused verification and `git diff --check`. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## [CLI-1] Scenario Schema + +### 문제 + +[apps/cli/internal/operator/scenario.go](/config/workspace/alt/apps/cli/internal/operator/scenario.go:23) enumerates known actions, but `import_daily_bars` is absent. [apps/cli/internal/operator/scenario.go](/config/workspace/alt/apps/cli/internal/operator/scenario.go:145) has request fields for reads/backtests, not provider/selector/date import input. + +### 해결 방법 + +Add `ActionImportDailyBars Action = "import_daily_bars"` to the action set. Extend `Request` with `Provider`, `SelectorKind`, `Venue`, `Name`, `Symbols`, `FromYYYYMMDD`, and `ToYYYYMMDD`. Add closed validation maps for provider (`kis`), selector kind (`watchlist` for now), and venue (`krx`, `unspecified`). Validate non-empty provider, selector kind, symbols, valid market/venue, and optional dates matching `YYYYMMDD`. + +Before (`scenario.go:23`): + +```go +const ( + ActionHello Action = "hello" + ActionListInstruments Action = "list_instruments" + ActionListBars Action = "list_bars" +) +``` + +After: + +```go +const ( + ActionHello Action = "hello" + ActionImportDailyBars Action = "import_daily_bars" + ActionListInstruments Action = "list_instruments" + ActionListBars Action = "list_bars" +) +``` + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/internal/operator/scenario.go`: action, request fields, validation helpers. +- [ ] `apps/cli/internal/operator/scenario_test.go`: valid import parse and invalid provider/selector/symbol/date tests. + +### 테스트 작성 + +Add `TestValidateImportDailyBars` and table-driven invalid cases. + +### 중간 검증 + +```bash +go test ./apps/cli/internal/operator -run 'Scenario|ImportDailyBars' -count=1 +``` + +Expected: scenario tests pass. + +## [CLI-2] API Client Method + +### 문제 + +[apps/cli/internal/operator/client.go](/config/workspace/alt/apps/cli/internal/operator/client.go:104) starts market read methods but has no import request method. Fake API server in [apps/cli/internal/operator/client_test.go](/config/workspace/alt/apps/cli/internal/operator/client_test.go:91) has no import listener. + +### 해결 방법 + +Add `ImportDailyBars(ctx, req)` one-line `sendTyped` method. Extend `fakeAPI` with `importDailyBarsResp`, recorded request, and a request listener. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/internal/operator/client.go`: add import method. +- [ ] `apps/cli/internal/operator/client_test.go`: fake response/recording and method round-trip test. +- [ ] `apps/cli/internal/operator/parser_map_test.go`: assert import response parser is available if not already covered by predecessor. + +### 테스트 작성 + +Add `TestAPIClientImportDailyBars` checking provider and symbols round-trip. + +### 중간 검증 + +```bash +go test ./apps/cli/internal/operator -run APIClientImportDailyBars -count=1 +``` + +Expected: fake API receives request and response counts round-trip. + +## [CLI-3] Runner And Output + +### 문제 + +[apps/cli/internal/operator/runner.go](/config/workspace/alt/apps/cli/internal/operator/runner.go:191) has no case for import. [apps/cli/internal/operator/output.go](/config/workspace/alt/apps/cli/internal/operator/output.go:23) has no fields for import counts, so scripts cannot grep import evidence keys. + +### 해결 방법 + +Map scenario strings to `altv1.ImportDailyBarsRequest`, call `client.ImportDailyBars`, and evaluate typed error the same way market actions do. Add `Provider`, `InstrumentCount`, and `BarCount` to `StepEvent`; render JSONL keys `provider`, `instrument_count`, `bar_count` and text keys `provider=`, `instrument_count=`, `bar_count=`. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/internal/operator/runner.go`: mapping, runStep case, evaluation helper. +- [ ] `apps/cli/internal/operator/output.go`: output fields and rendering. +- [ ] `apps/cli/internal/operator/runner_market_test.go`: import success and expected typed error tests. +- [ ] `apps/cli/internal/operator/runner_error_test.go`: mismatch/error exit behavior if needed. + +### 테스트 작성 + +Add runner tests for success counts and expected typed error `unavailable`. + +### 중간 검증 + +```bash +go test ./apps/cli/internal/operator -run 'RunScenario.*Import|ExpectedTypedError' -count=1 +``` + +Expected: import output keys appear and expected typed errors exit 0. + +## [CLI-4] Import Fixture + +### 문제 + +[apps/cli/testdata/operator/headless_validation.md](/config/workspace/alt/apps/cli/testdata/operator/headless_validation.md:24) has no import scenario row, and there is no import YAML fixture. + +### 해결 방법 + +Add `kis_daily_import_smoke.yaml` with one `import_daily_bars` step for provider `kis`, market `kr`, venue `krx`, selector kind `watchlist`, symbol `005930`, and date range `20240527`-`20240528`. Add expected JSONL fixture with `provider`, `instrument_count`, `bar_count`, and summary. Add it to the handoff matrix as command-first evidence, but leave UI dependency deferred. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/testdata/operator/kis_daily_import_smoke.yaml`: new fixture. +- [ ] `apps/cli/testdata/operator/expected/kis_daily_import_smoke.jsonl`: new expected fixture. +- [ ] `apps/cli/testdata/operator/headless_validation.md`: add matrix row. +- [ ] `apps/cli/internal/operator/handoff_test.go`: include required scenario. + +### 테스트 작성 + +Extend handoff tests to include the new fixture and JSONL keys. Do not include raw KIS payload or secret values. + +### 중간 검증 + +```bash +go test ./apps/cli/internal/operator -run 'Handoff|ImportDailyBars' -count=1 +go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/kis_daily_import_smoke.yaml +``` + +Expected: tests pass and validate prints `scenario=kis_daily_import_smoke status=valid`. + +## [CLI-5] Verification + +### 문제 + +CLI output contracts are easy to regress through fixture drift or parse-only tests. + +### 해결 방법 + +Run full CLI tests and diff check. Record optional live run instructions only in docs/handoff if actual running API/worker and SOPS env are available; do not block this fake-socket task on user secrets. + +### 수정 파일 및 체크리스트 + +- [ ] No extra files. + +### 테스트 작성 + +No additional tests beyond above. + +### 중간 검증 + +```bash +git diff --check +``` + +Expected: no whitespace warnings. + +## 수정 파일 요약 + +| 파일 | 항목 | +|------|------| +| `apps/cli/internal/operator/scenario.go` | CLI-1 | +| `apps/cli/internal/operator/scenario_test.go` | CLI-1 | +| `apps/cli/internal/operator/client.go` | CLI-2 | +| `apps/cli/internal/operator/client_test.go` | CLI-2 | +| `apps/cli/internal/operator/parser_map_test.go` | CLI-2 | +| `apps/cli/internal/operator/runner.go` | CLI-3 | +| `apps/cli/internal/operator/output.go` | CLI-3 | +| `apps/cli/internal/operator/runner_market_test.go` | CLI-3 | +| `apps/cli/internal/operator/runner_error_test.go` | CLI-3 | +| `apps/cli/testdata/operator/kis_daily_import_smoke.yaml` | CLI-4 | +| `apps/cli/testdata/operator/expected/kis_daily_import_smoke.jsonl` | CLI-4 | +| `apps/cli/testdata/operator/headless_validation.md` | CLI-4 | +| `apps/cli/internal/operator/handoff_test.go` | CLI-4 | + +## 최종 검증 + +```bash +go test ./apps/cli/... -count=1 +go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/kis_daily_import_smoke.yaml +git diff --check +``` + +Expected: all commands exit 0. Fresh `go test -count=1` is required for CLI behavior. + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/agent-task/m-command-first-operator-workflow/03+02_market_status_scenario/CODE_REVIEW-cloud-G07.md b/agent-task/m-command-first-operator-workflow/03+02_market_status_scenario/CODE_REVIEW-cloud-G07.md new file mode 100644 index 0000000..c5a1ba4 --- /dev/null +++ b/agent-task/m-command-first-operator-workflow/03+02_market_status_scenario/CODE_REVIEW-cloud-G07.md @@ -0,0 +1,142 @@ + + +# Code Review Reference - CLI + +> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.** +> The task is NOT complete until every implementation-owned section below is filled in. +> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving. +> Fill implementation-owned sections, then stop with active files in place and report ready for review. +> If implementation is blocked by a user-only decision, user-owned external environment prerequisite, or scope conflict, fill `사용자 리뷰 요청` with evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`. Evidence gaps that a follow-up agent can close by rerunning commands or collecting artifacts are normal follow-up issues, not user-review blockers by themselves. +> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume. +> Follow the ownership table at the bottom of this file for which sections you own. + +## 개요 + +date=2026-06-03 +task=m-command-first-operator-workflow/03+02_market_status_scenario, plan=0, tag=CLI + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` +- Task ids: + - `market-status-scenario`: imported market data를 CLI/YAML로 조회할 수 있다. +- Completion mode: check-on-pass + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다. + +각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [CLI-1] Import Before Status Reads | [ ] | +| [CLI-2] Status Evidence Tests | [ ] | +| [CLI-3] Handoff Discoverability | [ ] | +| [CLI-4] Verification | [ ] | + +## 구현 체크리스트 + +- [ ] [CLI-1] Update `market_data_status_query.yaml` to run import before instrument/bar status reads. +- [ ] [CLI-2] Update expected JSONL and tests to require import counts, instrument count, bar count, and typed unavailable/error keys. 검증: `alt operator scenario validate/run` 또는 동등한 command가 instrument/bar count와 typed unavailable/error key를 출력한다. +- [ ] [CLI-3] Update handoff matrix and CLI dev hints so the command-first status scenario is discoverable. +- [ ] [CLI-4] Run CLI verification and `git diff --check`. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. +> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다. + +- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. +- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다. +- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_cloud_G07_N.log`로 아카이브한다. +- [ ] active `PLAN-*-G??.md`를 `plan_cloud_G07_M.log`로 아카이브한다. +- [ ] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하여 plan/review/archive 산출물이 추적 가능한지 확인한다. +- [ ] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다. +- [ ] PASS이면 active task 디렉터리 `agent-task/m-command-first-operator-workflow/03+02_market_status_scenario/`를 `agent-task/archive/YYYY/MM/m-command-first-operator-workflow/03+02_market_status_scenario/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다. +- [ ] PASS이고 task group이 `m-`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다. +- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/m-command-first-operator-workflow/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다. +- [ ] WARN/FAIL이고 user-review gate가 트리거되지 않았으면 다음 active `PLAN-cloud-G07.md`와 `CODE_REVIEW-cloud-G07.md`를 작성하고 `complete.log`를 작성하지 않는다. +- [ ] USER_REVIEW이면 `agent-ops/skills/common/code-review/templates/user-review-template.md` 기준으로 `USER_REVIEW.md`를 작성하고 active `PLAN-*.md`, `CODE_REVIEW-*.md`, `complete.log`를 남기지 않는다. +- [ ] USER_REVIEW가 사용자 결정으로 완료/PASS 해소되면 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log`를 작성한 뒤 task directory를 archive로 이동한다. + +## 계획 대비 변경 사항 + +_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ + +## 주요 설계 결정 + +_구현 에이전트가 주요 설계 결정 사항을 기록한다._ + +## 사용자 리뷰 요청 + +_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._ + +- 상태: 없음 +- 사유 유형: 없음 +- 결정 필요: 없음 +- 차단 근거: 없음 +- 실행한 검증/명령: 없음 +- 자동 후속 불가 이유: 없음 +- 재개 조건: 없음 + +## 리뷰어를 위한 체크포인트 + +- `market_data_status_query` imports before reading market status. +- JSONL fixture has import counts plus instrument/bar counts. +- Typed `unavailable` or equivalent error code is asserted in tests. +- Handoff docs still defer UI and do not describe screen implementation. + +## 검증 결과 + +_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._ + +필수 규칙: +- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다. +- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다. +- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다. +- 사용자 리뷰 요청으로 명령을 끝까지 실행하지 못했다면 `사용자 리뷰 요청`에 실행한 명령, 실제 출력, 미실행 명령의 사유를 기록한다. +- mobile/UI hang, timeout, 또는 2분 무진행은 blind retry를 중단하고 focused rerun 명령과 screenshot/window/UI-tree evidence path를 남기며, 불가능하면 정확한 사유를 남긴다. + +### CLI-1 중간 검증 +```bash +$ go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/market_data_status_query.yaml +(output) +``` + +### CLI-2 중간 검증 +```bash +$ go test ./apps/cli/internal/operator -run 'MarketDataStatus|MarketStatusTypedUnavailable|Handoff' -count=1 +(output) +``` + +### CLI-3 중간 검증 +```bash +$ go test ./apps/cli/internal/operator -run Handoff -count=1 +(output) +``` + +### CLI-4 중간 검증 +```bash +$ git diff --check +(output) +``` + +### 최종 검증 +```bash +$ go test ./apps/cli/... -count=1 +$ go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/market_data_status_query.yaml +$ git diff --check +(output) +``` + +--- + +> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?** +> If anything is blank, go back and fill it in before saving this file. +> Leave review-agent-only sections unchanged. diff --git a/agent-task/m-command-first-operator-workflow/03+02_market_status_scenario/PLAN-cloud-G07.md b/agent-task/m-command-first-operator-workflow/03+02_market_status_scenario/PLAN-cloud-G07.md new file mode 100644 index 0000000..dde1d8c --- /dev/null +++ b/agent-task/m-command-first-operator-workflow/03+02_market_status_scenario/PLAN-cloud-G07.md @@ -0,0 +1,250 @@ + + +# Plan - Market Status Scenario + +## 이 파일을 읽는 구현 에이전트에게 + +이 plan은 구현 지시서이며, 구현 완료 전 active `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 내용과 검증 출력으로 채운다. 이 task는 `02+01_import_cli_scenario` 완료 뒤 구현한다. 최종 판정, archive 이동, `complete.log` 작성은 code-review-skill 전용이다. 사용자-only blocker가 있으면 review stub의 `사용자 리뷰 요청`을 채우고 멈춘다. + +## 배경 + +현재 `market_data_status_query`는 저장된 market data를 조회하지만, 같은 scenario 안에서 import가 먼저 되었는지는 보장하지 않는다. 이 작업은 import action 후 instruments/bars를 조회하는 command-first status scenario로 바꾼다. PASS 시 `market-status-scenario` 기능 Task를 완료 대상으로 삼는다. + +## 사용자 리뷰 요청 흐름 + +구현 중 사용자-only blocker는 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. code-review가 이를 검증하고 실제 `USER_REVIEW.md` 작성 여부를 결정한다. + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` +- Task ids: + - `market-status-scenario`: imported market data를 CLI/YAML로 조회할 수 있다. +- Completion mode: check-on-pass + +## 분석 결과 + +### 읽은 파일 + +- `agent-test/local/rules.md` +- `agent-test/local/operations-smoke.md` +- `agent-test/local/api-smoke.md` +- `agent-test/local/worker-smoke.md` +- `agent-ops/rules/project/domain/operations/rules.md` +- `agent-roadmap/current.md` +- `agent-roadmap/phase/operator-surface/PHASE.md` +- `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` +- `apps/cli/internal/operator/scenario.go` +- `apps/cli/internal/operator/runner.go` +- `apps/cli/internal/operator/runner_market_test.go` +- `apps/cli/internal/operator/runner_error_test.go` +- `apps/cli/internal/operator/client_test.go` +- `apps/cli/internal/operator/output.go` +- `apps/cli/internal/operator/handoff_test.go` +- `apps/cli/testdata/operator/market_data_status_query.yaml` +- `apps/cli/testdata/operator/expected/market_data_status_query.jsonl` +- `apps/cli/testdata/operator/headless_validation.md` +- `bin/dev` + +### 테스트 환경 규칙 + +- test_env: `local`. +- Matched profile: `operations-smoke` for CLI fixtures; `api-smoke`/`worker-smoke` are covered by predecessor rail and not changed here unless implementation touches API/worker. +- Applied commands: `go test ./apps/cli/...`, `go run ./apps/cli/cmd/alt operator scenario validate ...`, `git diff --check`. + +### 테스트 커버리지 공백 + +- Existing `TestRunScenarioMarketDataStatus` covers list instruments/bars but not import-before-read. +- Handoff tests validate expected JSONL shape but do not require `instrument_count`/`bar_count` until the fixture is updated. +- Typed unavailable/error key is covered generically by runner tests; add explicit status scenario test with `ErrorInfo{Code:"unavailable"}` for import or list. + +### 심볼 참조 + +- Renamed/removed symbols: none. + +### 분할 판단 + +- Shared task group: `agent-task/m-command-first-operator-workflow/`. +- This subtask directory is `03+02_market_status_scenario`; predecessor index `02` is `02+01_import_cli_scenario`. +- Predecessor completion status at plan creation: missing active/archive `complete.log`; implementation waits for predecessor completion. + +### 범위 결정 근거 + +- Excludes implementing `import_daily_bars`; predecessor owns it. +- Excludes backtest start/poll/result; `04+02_backtest_runtime_flow` owns it. +- Excludes UI layout and wireframes; handoff stays command evidence only. + +### 빌드 등급 + +- build=`cloud-G07`, review=`cloud-G07`: command workflow and machine-readable terminal output are the success surface. + +## 의존 관계 및 구현 순서 + +- Wait for `02+01_import_cli_scenario` complete.log. +- Update status fixture and fake API tests after import action is available. + +## 구현 체크리스트 + +- [ ] [CLI-1] Update `market_data_status_query.yaml` to run import before instrument/bar status reads. +- [ ] [CLI-2] Update expected JSONL and tests to require import counts, instrument count, bar count, and typed unavailable/error keys. 검증: `alt operator scenario validate/run` 또는 동등한 command가 instrument/bar count와 typed unavailable/error key를 출력한다. +- [ ] [CLI-3] Update handoff matrix and CLI dev hints so the command-first status scenario is discoverable. +- [ ] [CLI-4] Run CLI verification and `git diff --check`. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## [CLI-1] Import Before Status Reads + +### 문제 + +[apps/cli/testdata/operator/market_data_status_query.yaml](/config/workspace/alt/apps/cli/testdata/operator/market_data_status_query.yaml:1) reads instruments/bars but does not import first. That makes the scenario a generic status query rather than an imported market data status workflow. + +### 해결 방법 + +Prepend an `import_daily_bars` step after `hello`, using the same KIS symbol/date range as the import smoke. Keep the existing `list_instruments` and `list_bars` steps so status still reports counts. + +Before (`market_data_status_query.yaml:9`): + +```yaml + - id: hello + action: hello +``` + +After: + +```yaml + - id: hello + action: hello + - id: import_kr_daily_bars + action: import_daily_bars + request: + provider: kis + selector_kind: watchlist + market: kr + venue: krx + symbols: ["005930"] + from_yyyymmdd: "20240527" + to_yyyymmdd: "20240528" +``` + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/testdata/operator/market_data_status_query.yaml`: add import step. +- [ ] `apps/cli/testdata/operator/expected/market_data_status_query.jsonl`: add import output line and step count. + +### 테스트 작성 + +Existing handoff JSONL parser test should catch malformed fixture. Add a runner test that loads this fixture and asserts fake API call order: import, list instruments, list bars. + +### 중간 검증 + +```bash +go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/market_data_status_query.yaml +``` + +Expected: `scenario=market_data_status_query status=valid`. + +## [CLI-2] Status Evidence Tests + +### 문제 + +[apps/cli/internal/operator/runner_market_test.go](/config/workspace/alt/apps/cli/internal/operator/runner_market_test.go:34) verifies status count output for list/read only. It does not prove `import_daily_bars` counts and typed unavailable keys survive the scenario run. + +### 해결 방법 + +Update fake API support from predecessor if needed, then adjust `TestRunScenarioMarketDataStatus` to expect import, list, and bars output. Add a second test where import or list returns `ErrorInfo{Code:"unavailable"}` and the step expects `status: error`, proving the JSON/text output includes `error_code`. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/internal/operator/runner_market_test.go`: update happy path and add unavailable typed error case. +- [ ] `apps/cli/internal/operator/client_test.go`: expose last import request if not already available. +- [ ] `apps/cli/internal/operator/handoff_test.go`: assert expected JSONL step lines include import count keys for status scenario. + +### 테스트 작성 + +Write focused runner tests: + +- `TestRunScenarioMarketDataStatusImportsBeforeReads` +- `TestRunScenarioMarketStatusTypedUnavailable` + +### 중간 검증 + +```bash +go test ./apps/cli/internal/operator -run 'MarketDataStatus|MarketStatusTypedUnavailable|Handoff' -count=1 +``` + +Expected: tests pass and output key assertions are covered. + +## [CLI-3] Handoff Discoverability + +### 문제 + +[apps/cli/testdata/operator/headless_validation.md](/config/workspace/alt/apps/cli/testdata/operator/headless_validation.md:29) describes `market_data_status_query` as list-only. [bin/dev](/config/workspace/alt/bin/dev:20) points to this scenario, so the developer hint should match the new import-before-read behavior. + +### 해결 방법 + +Update matrix text for `market_data_status_query` to mention `ImportDailyBarsResponse.instrument_count`, `ImportDailyBarsResponse.bar_count`, `ListInstrumentsResponse.instruments`, and `ListBarsResponse.bars`. Keep UI dependency deferred. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/testdata/operator/headless_validation.md`: update checked fields and scenario description. +- [ ] `bin/dev`: no path change expected; update text only if it says read-only. + +### 테스트 작성 + +No new test beyond handoff coverage; existing doc/fixture tests validate referenced paths. + +### 중간 검증 + +```bash +go test ./apps/cli/internal/operator -run Handoff -count=1 +``` + +Expected: handoff tests pass. + +## [CLI-4] Verification + +### 문제 + +Fixture drift can make the scenario validate but leave expected JSONL stale. + +### 해결 방법 + +Run CLI tests, validate the scenario, and diff check. + +### 수정 파일 및 체크리스트 + +- [ ] No extra files. + +### 테스트 작성 + +No additional tests. + +### 중간 검증 + +```bash +git diff --check +``` + +Expected: no warnings. + +## 수정 파일 요약 + +| 파일 | 항목 | +|------|------| +| `apps/cli/testdata/operator/market_data_status_query.yaml` | CLI-1 | +| `apps/cli/testdata/operator/expected/market_data_status_query.jsonl` | CLI-1 | +| `apps/cli/internal/operator/runner_market_test.go` | CLI-2 | +| `apps/cli/internal/operator/client_test.go` | CLI-2 | +| `apps/cli/internal/operator/handoff_test.go` | CLI-2 | +| `apps/cli/testdata/operator/headless_validation.md` | CLI-3 | +| `bin/dev` | CLI-3 | + +## 최종 검증 + +```bash +go test ./apps/cli/... -count=1 +go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/market_data_status_query.yaml +git diff --check +``` + +Expected: all commands exit 0. + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/agent-task/m-command-first-operator-workflow/04+02_backtest_runtime_flow/CODE_REVIEW-cloud-G08.md b/agent-task/m-command-first-operator-workflow/04+02_backtest_runtime_flow/CODE_REVIEW-cloud-G08.md new file mode 100644 index 0000000..e23b9e3 --- /dev/null +++ b/agent-task/m-command-first-operator-workflow/04+02_backtest_runtime_flow/CODE_REVIEW-cloud-G08.md @@ -0,0 +1,156 @@ + + +# Code Review Reference - API + +> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.** +> The task is NOT complete until every implementation-owned section below is filled in. +> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving. +> Fill implementation-owned sections, then stop with active files in place and report ready for review. +> If implementation is blocked by a user-only decision, user-owned external environment prerequisite, or scope conflict, fill `사용자 리뷰 요청` with evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`. Evidence gaps that a follow-up agent can close by rerunning commands or collecting artifacts are normal follow-up issues, not user-review blockers by themselves. +> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume. +> Follow the ownership table at the bottom of this file for which sections you own. + +## 개요 + +date=2026-06-03 +task=m-command-first-operator-workflow/04+02_backtest_runtime_flow, plan=0, tag=API + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` +- Task ids: + - `backtest-command-flow`: imported daily bars를 입력으로 backtest start/poll/result를 command workflow에서 확인할 수 있다. +- Completion mode: check-on-pass + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다. + +각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [API-1] GetBacktestRun Rail | [ ] | +| [API-2] Worker Runtime Wiring | [ ] | +| [API-3] Execution Evidence Tests | [ ] | +| [API-4] Backtest YAML Flow | [ ] | +| [API-5] Verification | [ ] | + +## 구현 체크리스트 + +- [ ] [API-1] Add API and worker `GetBacktestRun` forwarding/handler support for polling. +- [ ] [API-2] Wire worker `alt-worker` with `BacktestStarter`, `RegisterRunBacktestHandler`, `StorageBarSource`, result store, and a built-in strategy resolver. +- [ ] [API-3] Add/update tests for built-in strategy resolver, worker execution wiring, and typed run polling. +- [ ] [API-4] Update backtest YAML scenarios to import daily bars before start/poll/result. 검증: start/poll/result scenario가 run id, terminal status, result summary key를 출력한다. +- [ ] [API-5] Run API/worker/CLI verification and `git diff --check`. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. +> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다. + +- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. +- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다. +- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_cloud_G08_N.log`로 아카이브한다. +- [ ] active `PLAN-*-G??.md`를 `plan_cloud_G08_M.log`로 아카이브한다. +- [ ] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하여 plan/review/archive 산출물이 추적 가능한지 확인한다. +- [ ] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다. +- [ ] PASS이면 active task 디렉터리 `agent-task/m-command-first-operator-workflow/04+02_backtest_runtime_flow/`를 `agent-task/archive/YYYY/MM/m-command-first-operator-workflow/04+02_backtest_runtime_flow/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다. +- [ ] PASS이고 task group이 `m-`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다. +- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/m-command-first-operator-workflow/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다. +- [ ] WARN/FAIL이고 user-review gate가 트리거되지 않았으면 다음 active `PLAN-cloud-G08.md`와 `CODE_REVIEW-cloud-G08.md`를 작성하고 `complete.log`를 작성하지 않는다. +- [ ] USER_REVIEW이면 `agent-ops/skills/common/code-review/templates/user-review-template.md` 기준으로 `USER_REVIEW.md`를 작성하고 active `PLAN-*.md`, `CODE_REVIEW-*.md`, `complete.log`를 남기지 않는다. +- [ ] USER_REVIEW가 사용자 결정으로 완료/PASS 해소되면 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log`를 작성한 뒤 task directory를 archive로 이동한다. + +## 계획 대비 변경 사항 + +_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ + +## 주요 설계 결정 + +_구현 에이전트가 주요 설계 결정 사항을 기록한다._ + +## 사용자 리뷰 요청 + +_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._ + +- 상태: 없음 +- 사유 유형: 없음 +- 결정 필요: 없음 +- 차단 근거: 없음 +- 실행한 검증/명령: 없음 +- 자동 후속 불가 이유: 없음 +- 재개 조건: 없음 + +## 리뷰어를 위한 체크포인트 + +- `GetBacktestRunRequest` is registered and forwarded through API to worker. +- Worker process advertises backtest start only when `Starter` is actually wired. +- Backtest execution uses `StorageBarSource` and a bounded built-in strategy resolver, not API internals. +- YAML backtest scenarios import bars before start/poll/result. +- Result output includes run id, terminal status, and summary keys. + +## 검증 결과 + +_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._ + +필수 규칙: +- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다. +- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다. +- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다. +- 사용자 리뷰 요청으로 명령을 끝까지 실행하지 못했다면 `사용자 리뷰 요청`에 실행한 명령, 실제 출력, 미실행 명령의 사유를 기록한다. +- mobile/UI hang, timeout, 또는 2분 무진행은 blind retry를 중단하고 focused rerun 명령과 screenshot/window/UI-tree evidence path를 남기며, 불가능하면 정확한 사유를 남긴다. + +### API-1 중간 검증 +```bash +$ go test ./services/api/internal/workerclient ./services/api/internal/socket ./services/worker/internal/socket -run 'GetBacktestRun|BacktestHandlers|Capabilities' -count=1 +(output) +``` + +### API-2 중간 검증 +```bash +$ go test ./services/worker/internal/backtest ./services/worker/internal/jobs ./services/worker/internal/socket -count=1 +(output) +``` + +### API-3 중간 검증 +```bash +$ go test ./services/worker/... -run 'Backtest.*Flow|StorageBarSource|RunBacktest|BacktestStarter' -count=1 +(output) +``` + +### API-4 중간 검증 +```bash +$ go test ./apps/cli/internal/operator -run 'Backtest|Handoff' -count=1 +$ go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/backtest_run_polling.yaml +$ go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/backtest_result_summary.yaml +(output) +``` + +### API-5 중간 검증 +```bash +$ git diff --check +(output) +``` + +### 최종 검증 +```bash +$ go test ./services/api/... -count=1 +$ go test ./services/worker/... -count=1 +$ go test ./apps/cli/... -count=1 +$ go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/backtest_run_polling.yaml +$ go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/backtest_result_summary.yaml +$ git diff --check +(output) +``` + +--- + +> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?** +> If anything is blank, go back and fill it in before saving this file. +> Leave review-agent-only sections unchanged. diff --git a/agent-task/m-command-first-operator-workflow/04+02_backtest_runtime_flow/PLAN-cloud-G08.md b/agent-task/m-command-first-operator-workflow/04+02_backtest_runtime_flow/PLAN-cloud-G08.md new file mode 100644 index 0000000..925e2cc --- /dev/null +++ b/agent-task/m-command-first-operator-workflow/04+02_backtest_runtime_flow/PLAN-cloud-G08.md @@ -0,0 +1,330 @@ + + +# Plan - Backtest Runtime Flow + +## 이 파일을 읽는 구현 에이전트에게 + +이 plan은 구현 지시서이며, 구현 완료 전 active `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 내용과 검증 출력으로 채운다. 이 task는 `02+01_import_cli_scenario` 완료 뒤 구현한다. 최종 판정, archive 이동, `complete.log` 작성은 code-review-skill 전용이다. 사용자-only blocker가 있으면 review stub의 `사용자 리뷰 요청`을 채우고 멈춘다. + +## 배경 + +CLI에는 start/poll/result action이 있지만 real API/worker rail에는 poll이 호출하는 `GetBacktestRun` handler가 없고, worker entrypoint는 backtest starter/executor를 store-backed deps에 연결하지 않는다. 이 작업은 imported daily bars를 `StorageBarSource`로 읽는 worker runtime을 연결하고, backtest scenario들이 import 후 start/poll/result를 확인하게 만든다. PASS 시 `backtest-command-flow` 기능 Task를 완료 대상으로 삼는다. + +## 사용자 리뷰 요청 흐름 + +구현 중 사용자-only blocker는 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. code-review가 이를 검증하고 실제 `USER_REVIEW.md` 작성 여부를 결정한다. + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` +- Task ids: + - `backtest-command-flow`: imported daily bars를 입력으로 backtest start/poll/result를 command workflow에서 확인할 수 있다. +- 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` +- `agent-ops/rules/project/domain/api/rules.md` +- `agent-ops/rules/project/domain/worker/rules.md` +- `agent-ops/rules/project/domain/operations/rules.md` +- `agent-roadmap/current.md` +- `agent-roadmap/phase/operator-surface/PHASE.md` +- `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` +- `packages/contracts/proto/alt/v1/backtest.proto` +- `services/api/internal/socket/backtest.go` +- `services/api/internal/socket/backtest_test.go` +- `services/api/internal/socket/server_test.go` +- `services/api/internal/workerclient/client.go` +- `services/api/internal/workerclient/client_test.go` +- `services/worker/internal/socket/backtest.go` +- `services/worker/internal/socket/backtest_test.go` +- `services/worker/internal/socket/backtest_mapping.go` +- `services/worker/internal/socket/backtest_mapping_test.go` +- `services/worker/internal/socket/handlers.go` +- `services/worker/internal/socket/server_test.go` +- `services/worker/internal/jobs/backtest_starter.go` +- `services/worker/internal/jobs/backtest_jobs.go` +- `services/worker/internal/backtest/engine.go` +- `services/worker/internal/backtest/engine_test.go` +- `services/worker/internal/backtest/bar_source.go` +- `services/worker/internal/backtest/bar_source_test.go` +- `services/worker/internal/backtest/fixture_test.go` +- `services/worker/internal/storage/ports.go` +- `services/worker/cmd/alt-worker/main.go` +- `packages/domain/backtest/types.go` +- `apps/cli/internal/operator/runner.go` +- `apps/cli/internal/operator/output.go` +- `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/expected/backtest_run_request.jsonl` +- `apps/cli/testdata/operator/expected/backtest_run_polling.jsonl` +- `apps/cli/testdata/operator/expected/backtest_result_summary.jsonl` + +### 테스트 환경 규칙 + +- test_env: `local`. +- Matched profiles: `api-smoke`, `worker-smoke`, `operations-smoke`. +- Applied commands: `go test ./services/api/...`, `go test ./services/worker/...`, `go test ./apps/cli/...`, scenario validate commands, `git diff --check`. +- `bin/worker-storage-check` is not required unless implementation changes SQL/storage generated files. + +### 테스트 커버리지 공백 + +- `GetBacktestRunRequest` exists in protobuf but API/worker socket handlers are missing; add forwarding/handler tests. +- `jobs.BacktestStarter` and `RegisterRunBacktestHandler` have unit tests but `cmd/alt-worker` does not wire them into deps; add focused wiring coverage through helper extraction or capability tests. +- Backtest engine has fake strategy tests but no production strategy resolver. Add built-in `strategy-v1` or equivalent deterministic strategy port for command validation. +- Existing backtest YAML fixtures start runs without importing bars first. Update them to import first. + +### 심볼 참조 + +- Renamed/removed symbols: none. +- Additive call sites: workerclient interface fake implementations, API/worker handler registries, parser maps are already aware of `GetBacktestRunRequest/Response`. + +### 분할 판단 + +- Shared task group: `agent-task/m-command-first-operator-workflow/`. +- This subtask directory is `04+02_backtest_runtime_flow`; predecessor index `02` is `02+01_import_cli_scenario`. +- Predecessor completion status at plan creation: missing active/archive `complete.log`; implementation waits for predecessor completion. + +### 범위 결정 근거 + +- Excludes import CLI implementation; predecessor owns it. +- Excludes market status handoff finalization; `03` and `05` own it. +- Excludes trading order/paper trading/live trading APIs and production scheduling. +- Excludes Flutter UI. + +### 빌드 등급 + +- build=`cloud-G08`, review=`cloud-G08`: worker runtime wiring, async execution, API forwarding, storage-backed backtest input, and CLI command flow are cross-domain. + +## 의존 관계 및 구현 순서 + +- Wait for `02+01_import_cli_scenario` complete.log. +- Implement `GetBacktestRun` rail first, then worker runtime wiring, then backtest fixtures. + +## 구현 체크리스트 + +- [ ] [API-1] Add API and worker `GetBacktestRun` forwarding/handler support for polling. +- [ ] [API-2] Wire worker `alt-worker` with `BacktestStarter`, `RegisterRunBacktestHandler`, `StorageBarSource`, result store, and a built-in strategy resolver. +- [ ] [API-3] Add/update tests for built-in strategy resolver, worker execution wiring, and typed run polling. +- [ ] [API-4] Update backtest YAML scenarios to import daily bars before start/poll/result. 검증: start/poll/result scenario가 run id, terminal status, result summary key를 출력한다. +- [ ] [API-5] Run API/worker/CLI verification and `git diff --check`. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## [API-1] GetBacktestRun Rail + +### 문제 + +[packages/contracts/proto/alt/v1/backtest.proto](/config/workspace/alt/packages/contracts/proto/alt/v1/backtest.proto:44) defines `GetBacktestRunRequest`, and [apps/cli/internal/operator/runner.go](/config/workspace/alt/apps/cli/internal/operator/runner.go:317) polls it. But API and worker session handlers only register start/list/detail/result/compare: [services/worker/internal/socket/backtest.go](/config/workspace/alt/services/worker/internal/socket/backtest.go:52) and API tests do not include `GetBacktestRunRequest`. + +### 해결 방법 + +Add `GetBacktestRun` to `workerclient.WorkerClient`, implement a one-line socket client method, add API forwarding handler, and add worker handler that validates `run_id` and reads the run through store-backed analysis/run store. Prefer using `Analysis.GetRunDetail` to avoid growing `Deps` unless direct `BacktestRunStore` access is clearer. + +Before (`workerclient/client.go:31`): + +```go +StartBacktest(ctx context.Context, req *altv1.StartBacktestRequest) (*altv1.StartBacktestResponse, error) +ListBacktestRuns(ctx context.Context, req *altv1.ListBacktestRunsRequest) (*altv1.ListBacktestRunsResponse, error) +``` + +After: + +```go +StartBacktest(ctx context.Context, req *altv1.StartBacktestRequest) (*altv1.StartBacktestResponse, error) +GetBacktestRun(ctx context.Context, req *altv1.GetBacktestRunRequest) (*altv1.GetBacktestRunResponse, error) +ListBacktestRuns(ctx context.Context, req *altv1.ListBacktestRunsRequest) (*altv1.ListBacktestRunsResponse, error) +``` + +### 수정 파일 및 체크리스트 + +- [ ] `services/api/internal/workerclient/client.go`: interface and method. +- [ ] `services/api/internal/workerclient/client_test.go`: fake worker `GetBacktestRun` round-trip. +- [ ] `services/api/internal/socket/backtest.go`: forwarding handler. +- [ ] `services/api/internal/socket/backtest_test.go`: fake client method, validation, forwarding, socket test, handler registration. +- [ ] `services/api/internal/socket/server_test.go`: capability sync if needed. +- [ ] `services/worker/internal/socket/backtest.go`: handler registration and implementation. +- [ ] `services/worker/internal/socket/backtest_test.go`: success, validation, not found, unavailable, socket test, handler coverage. + +### 테스트 작성 + +Add `TestHandleGetBacktestRunForwards`, `TestHandleGetBacktestRunRequiresRunID`, worker success/not_found, and socket typed validation tests. + +### 중간 검증 + +```bash +go test ./services/api/internal/workerclient ./services/api/internal/socket ./services/worker/internal/socket -run 'GetBacktestRun|BacktestHandlers|Capabilities' -count=1 +``` + +Expected: API and worker poll rail tests pass. + +## [API-2] Worker Runtime Wiring + +### 문제 + +[services/worker/cmd/alt-worker/main.go](/config/workspace/alt/services/worker/cmd/alt-worker/main.go:42) sets Analysis/Results/Instruments/Bars but leaves [services/worker/cmd/alt-worker/main.go](/config/workspace/alt/services/worker/cmd/alt-worker/main.go:61) `backtest_start_surface` false. `RegisterRunBacktestHandler` and `NewBacktestStarter` exist but are not wired in production. + +### 해결 방법 + +Add a worker-internal built-in strategy resolver, e.g. `NewBuiltInStrategyPort()` with `strategy-v1` buy-and-hold or deterministic minimal strategy. In `main.go`, build: + +```go +barSource := workerbacktest.NewStorageBarSource(store, store) +strategyPort := workerbacktest.NewBuiltInStrategyPort() +engine := workerbacktest.NewEngine(barSource, strategyPort, store) +jobs.RegisterRunBacktestHandler(runner, store, engine, time.Now) +starter := jobs.NewBacktestStarter(runner, store) +deps.Starter = starter +``` + +Keep import aliases clear (`workerbacktest`) to avoid package name collisions. + +### 수정 파일 및 체크리스트 + +- [ ] `services/worker/internal/backtest/strategies.go`: built-in strategy resolver and strategy implementation. +- [ ] `services/worker/internal/backtest/strategies_test.go`: known strategy success and unknown strategy error. +- [ ] `services/worker/cmd/alt-worker/main.go`: wire bar source, strategy port, engine, job handler, starter. +- [ ] `services/worker/internal/socket/server_test.go`: capability now reflects Starter when deps include it. + +### 테스트 작성 + +Add strategy tests and, if feasible, extract a small helper for store-backed deps wiring so a unit test can assert `Starter != nil` without launching the process. If extraction adds too much scope, document in `계획 대비 변경 사항` and rely on strategy/job/socket tests. + +### 중간 검증 + +```bash +go test ./services/worker/internal/backtest ./services/worker/internal/jobs ./services/worker/internal/socket -count=1 +``` + +Expected: worker backtest engine/job/socket tests pass. + +## [API-3] Execution Evidence Tests + +### 문제 + +Existing job and engine tests are separate. They do not prove command start, poll, and result can use storage-backed bars together. + +### 해결 방법 + +Add or update a worker test using in-memory/fake stores to import/upsert bars, start a run synchronously via `BacktestStarter` with `WithStarterLaunch(func(fn func()) { fn() })`, poll/get run, and get result. Keep it unit-level; no Docker is required. + +### 수정 파일 및 체크리스트 + +- [ ] `services/worker/internal/jobs/backtest_starter_test.go` or new worker backtest flow test: synchronous launch flow. +- [ ] `services/worker/internal/backtest/fixture_test.go`: reuse or extend imported bars fixture if lower risk. +- [ ] `services/worker/internal/socket/backtest_test.go`: typed run status/result queries as needed. + +### 테스트 작성 + +Write a test whose assertions cover pending/running/succeeded transition enough for the command flow. At minimum assert terminal status `succeeded` and `GetResult` summary fields exist. + +### 중간 검증 + +```bash +go test ./services/worker/... -run 'Backtest.*Flow|StorageBarSource|RunBacktest|BacktestStarter' -count=1 +``` + +Expected: focused worker flow tests pass. + +## [API-4] Backtest YAML Flow + +### 문제 + +[apps/cli/testdata/operator/backtest_run_request.yaml](/config/workspace/alt/apps/cli/testdata/operator/backtest_run_request.yaml:1), [apps/cli/testdata/operator/backtest_run_polling.yaml](/config/workspace/alt/apps/cli/testdata/operator/backtest_run_polling.yaml:1), and [apps/cli/testdata/operator/backtest_result_summary.yaml](/config/workspace/alt/apps/cli/testdata/operator/backtest_result_summary.yaml:1) start runs without importing bars first. + +### 해결 방법 + +Add an `import_daily_bars` step to each backtest scenario before `start_backtest`, using the same symbol/date range as the import/status scenario. Keep `strategy_id: strategy-v1` if the built-in resolver uses that ID. Update expected JSONL fixtures to include import line and adjusted step counts. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/testdata/operator/backtest_run_request.yaml` +- [ ] `apps/cli/testdata/operator/backtest_run_polling.yaml` +- [ ] `apps/cli/testdata/operator/backtest_result_summary.yaml` +- [ ] matching expected JSONL fixtures. +- [ ] `apps/cli/internal/operator/runner_error_test.go` or runner tests if expectations change. + +### 테스트 작성 + +Update fake API tests so backtest scenarios include import line and still assert `run_id`, terminal `run_status`, and summary keys. + +### 중간 검증 + +```bash +go test ./apps/cli/internal/operator -run 'Backtest|Handoff' -count=1 +go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/backtest_run_polling.yaml +go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/backtest_result_summary.yaml +``` + +Expected: tests and scenario validation pass. + +## [API-5] Verification + +### 문제 + +This plan spans API, worker, and CLI; a package-only test can miss an interface compile failure in another module. + +### 해결 방법 + +Run the final commands exactly. + +### 수정 파일 및 체크리스트 + +- [ ] No extra files. + +### 테스트 작성 + +No additional tests. + +### 중간 검증 + +```bash +git diff --check +``` + +Expected: no warnings. + +## 수정 파일 요약 + +| 파일 | 항목 | +|------|------| +| `services/api/internal/workerclient/client.go` | API-1 | +| `services/api/internal/workerclient/client_test.go` | API-1 | +| `services/api/internal/socket/backtest.go` | API-1 | +| `services/api/internal/socket/backtest_test.go` | API-1 | +| `services/api/internal/socket/server_test.go` | API-1 | +| `services/worker/internal/socket/backtest.go` | API-1 | +| `services/worker/internal/socket/backtest_test.go` | API-1 | +| `services/worker/internal/backtest/strategies.go` | API-2 | +| `services/worker/internal/backtest/strategies_test.go` | API-2 | +| `services/worker/cmd/alt-worker/main.go` | API-2 | +| `services/worker/internal/socket/server_test.go` | API-2 | +| `services/worker/internal/jobs/backtest_starter_test.go` | API-3 | +| `services/worker/internal/backtest/fixture_test.go` | API-3 | +| `apps/cli/testdata/operator/backtest_run_request.yaml` | API-4 | +| `apps/cli/testdata/operator/backtest_run_polling.yaml` | API-4 | +| `apps/cli/testdata/operator/backtest_result_summary.yaml` | API-4 | +| `apps/cli/testdata/operator/expected/backtest_run_request.jsonl` | API-4 | +| `apps/cli/testdata/operator/expected/backtest_run_polling.jsonl` | API-4 | +| `apps/cli/testdata/operator/expected/backtest_result_summary.jsonl` | API-4 | +| `apps/cli/internal/operator/runner_error_test.go` | API-4 | + +## 최종 검증 + +```bash +go test ./services/api/... -count=1 +go test ./services/worker/... -count=1 +go test ./apps/cli/... -count=1 +go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/backtest_run_polling.yaml +go run ./apps/cli/cmd/alt operator scenario validate --file apps/cli/testdata/operator/backtest_result_summary.yaml +git diff --check +``` + +Expected: all commands exit 0. Fresh `go test -count=1` is required. + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/agent-task/m-command-first-operator-workflow/05+03,04_operator_handoff/CODE_REVIEW-local-G05.md b/agent-task/m-command-first-operator-workflow/05+03,04_operator_handoff/CODE_REVIEW-local-G05.md new file mode 100644 index 0000000..092ff8c --- /dev/null +++ b/agent-task/m-command-first-operator-workflow/05+03,04_operator_handoff/CODE_REVIEW-local-G05.md @@ -0,0 +1,134 @@ + + +# Code Review Reference - DOCS + +> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.** +> The task is NOT complete until every implementation-owned section below is filled in. +> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving. +> Fill implementation-owned sections, then stop with active files in place and report ready for review. +> If implementation is blocked by a user-only decision, user-owned external environment prerequisite, or scope conflict, fill `사용자 리뷰 요청` with evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`. Evidence gaps that a follow-up agent can close by rerunning commands or collecting artifacts are normal follow-up issues, not user-review blockers by themselves. +> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume. +> Follow the ownership table at the bottom of this file for which sections you own. + +## 개요 + +date=2026-06-03 +task=m-command-first-operator-workflow/05+03,04_operator_handoff, plan=0, tag=DOCS + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` +- Task ids: + - `operator-handoff`: command-first workflow가 UI MVP로 넘길 화면 후보와 아직 화면으로 올리지 않을 항목을 분리한다. +- Completion mode: check-on-pass + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다. + +각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [DOCS-1] Handoff Matrix | [ ] | +| [DOCS-2] Handoff Guard Tests | [ ] | +| [DOCS-3] Verification | [ ] | + +## 구현 체크리스트 + +- [ ] [DOCS-1] Update handoff matrix with command, expected output key, repeatability, UI candidate, and UI defer reason for import/status/backtest workflows. +- [ ] [DOCS-2] Add tests that guard required scenarios and handoff columns/keys. 검증: handoff 문서가 command, expected output key, 반복 운영 여부, UI defer 사유를 함께 기록하고, 충분히 표면화되지 않은 기능은 화면 후보에서 제외한다. +- [ ] [DOCS-3] Run docs/CLI verification and `git diff --check`. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. +> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다. + +- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. +- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다. +- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_local_G05_N.log`로 아카이브한다. +- [ ] active `PLAN-*-G??.md`를 `plan_local_G05_M.log`로 아카이브한다. +- [ ] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하여 plan/review/archive 산출물이 추적 가능한지 확인한다. +- [ ] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다. +- [ ] PASS이면 active task 디렉터리 `agent-task/m-command-first-operator-workflow/05+03,04_operator_handoff/`를 `agent-task/archive/YYYY/MM/m-command-first-operator-workflow/05+03,04_operator_handoff/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다. +- [ ] PASS이고 task group이 `m-`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다. +- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/m-command-first-operator-workflow/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다. +- [ ] WARN/FAIL이고 user-review gate가 트리거되지 않았으면 다음 active `PLAN-local-G05.md`와 `CODE_REVIEW-local-G05.md`를 작성하고 `complete.log`를 작성하지 않는다. +- [ ] USER_REVIEW이면 `agent-ops/skills/common/code-review/templates/user-review-template.md` 기준으로 `USER_REVIEW.md`를 작성하고 active `PLAN-*.md`, `CODE_REVIEW-*.md`, `complete.log`를 남기지 않는다. +- [ ] USER_REVIEW가 사용자 결정으로 완료/PASS 해소되면 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log`를 작성한 뒤 task directory를 archive로 이동한다. + +## 계획 대비 변경 사항 + +_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ + +## 주요 설계 결정 + +_구현 에이전트가 주요 설계 결정 사항을 기록한다._ + +## 사용자 리뷰 요청 + +_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._ + +- 상태: 없음 +- 사유 유형: 없음 +- 결정 필요: 없음 +- 차단 근거: 없음 +- 실행한 검증/명령: 없음 +- 자동 후속 불가 이유: 없음 +- 재개 조건: 없음 + +## 리뷰어를 위한 체크포인트 + +- Handoff doc separates UI candidates from deferred items. +- Commands, expected output keys, repeatability, and defer reasons are all documented. +- No UI implementation, wireframe commitment, or screen layout sneaks into this task. +- Tests guard required rows/fixtures/keys. + +## 검증 결과 + +_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._ + +필수 규칙: +- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다. +- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다. +- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다. +- 사용자 리뷰 요청으로 명령을 끝까지 실행하지 못했다면 `사용자 리뷰 요청`에 실행한 명령, 실제 출력, 미실행 명령의 사유를 기록한다. +- mobile/UI hang, timeout, 또는 2분 무진행은 blind retry를 중단하고 focused rerun 명령과 screenshot/window/UI-tree evidence path를 남기며, 불가능하면 정확한 사유를 남긴다. + +### DOCS-1 중간 검증 +```bash +$ rg --sort path -n 'UI defer reason|repeatable|expected output' apps/cli/testdata/operator/headless_validation.md +(output) +``` + +### DOCS-2 중간 검증 +```bash +$ go test ./apps/cli/internal/operator -run Handoff -count=1 +(output) +``` + +### DOCS-3 중간 검증 +```bash +$ git diff --check +(output) +``` + +### 최종 검증 +```bash +$ go test ./apps/cli/... -count=1 +$ rg --sort path -n 'UI defer reason|repeatable|expected output' apps/cli/testdata/operator/headless_validation.md +$ git diff --check +(output) +``` + +--- + +> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?** +> If anything is blank, go back and fill it in before saving this file. +> Leave review-agent-only sections unchanged. diff --git a/agent-task/m-command-first-operator-workflow/05+03,04_operator_handoff/PLAN-local-G05.md b/agent-task/m-command-first-operator-workflow/05+03,04_operator_handoff/PLAN-local-G05.md new file mode 100644 index 0000000..2c8094f --- /dev/null +++ b/agent-task/m-command-first-operator-workflow/05+03,04_operator_handoff/PLAN-local-G05.md @@ -0,0 +1,203 @@ + + +# Plan - Operator Handoff + +## 이 파일을 읽는 구현 에이전트에게 + +이 plan은 구현 지시서이며, 구현 완료 전 active `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 내용과 검증 출력으로 채운다. 이 task는 `03+02_market_status_scenario`와 `04+02_backtest_runtime_flow` 완료 뒤 구현한다. 최종 판정, archive 이동, `complete.log` 작성은 code-review-skill 전용이다. 사용자-only blocker가 있으면 review stub의 `사용자 리뷰 요청`을 채우고 멈춘다. + +## 배경 + +사용자는 화면 작업을 뒤로 미루고 기능이 표면화될 때까지 command-first 운영을 유지하려고 한다. 따라서 UI MVP로 넘길 후보는 command, expected output key, 반복 운영 여부, defer 사유가 충분히 정리된 뒤에만 올라가야 한다. 이 작업은 기존 headless validation handoff를 현재 마일스톤의 import/status/backtest 흐름 기준으로 갱신한다. + +## 사용자 리뷰 요청 흐름 + +구현 중 사용자-only blocker는 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. code-review가 이를 검증하고 실제 `USER_REVIEW.md` 작성 여부를 결정한다. + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` +- Task ids: + - `operator-handoff`: command-first workflow가 UI MVP로 넘길 화면 후보와 아직 화면으로 올리지 않을 항목을 분리한다. +- Completion mode: check-on-pass + +## 분석 결과 + +### 읽은 파일 + +- `agent-test/local/rules.md` +- `agent-test/local/operations-smoke.md` +- `agent-ops/rules/project/domain/operations/rules.md` +- `agent-roadmap/current.md` +- `agent-roadmap/phase/operator-surface/PHASE.md` +- `agent-roadmap/phase/operator-surface/milestones/command-first-operator-workflow.md` +- `apps/cli/testdata/operator/headless_validation.md` +- `apps/cli/internal/operator/handoff_test.go` +- `apps/cli/testdata/operator/expected/market_data_status_query.jsonl` +- `apps/cli/testdata/operator/expected/backtest_run_polling.jsonl` +- `apps/cli/testdata/operator/expected/backtest_result_summary.jsonl` +- `bin/dev` +- `docs/kis-live-secret-handoff.md` +- `docs/kis-live-secret-guide.md` + +### 테스트 환경 규칙 + +- test_env: `local`. +- Matched profile: `operations-smoke`. +- Applied commands: `go test ./apps/cli/...`, optional scenario validate commands if fixture paths are changed, and `git diff --check`. + +### 테스트 커버리지 공백 + +- Current handoff tests require scenario names and JSONL validity, but do not verify UI candidate/defer reason fields. +- Handoff doc currently has a `Remaining Flutter wireframe dependency` column, but not explicit `repeatable operation` or `UI candidate/defer reason` separation for newly surfaced workflows. + +### 심볼 참조 + +- Renamed/removed symbols: none. + +### 분할 판단 + +- Shared task group: `agent-task/m-command-first-operator-workflow/`. +- This subtask directory is `05+03,04_operator_handoff`. +- Predecessor index `03`: `03+02_market_status_scenario`; completion missing at plan creation. +- Predecessor index `04`: `04+02_backtest_runtime_flow`; completion missing at plan creation. +- Implementation waits for both predecessor complete logs. + +### 범위 결정 근거 + +- Excludes Flutter UI, wireframes, navigation, charts, and widgets. +- Excludes changing command behavior; predecessors own behavior. +- Excludes roadmap archive movement; code-review/runtime own completion handling. + +### 빌드 등급 + +- build=`local-G05`, review=`local-G05`: bounded docs/test update with explicit fixtures and no runtime code changes expected. + +## 의존 관계 및 구현 순서 + +- Wait for `03+02_market_status_scenario` and `04+02_backtest_runtime_flow` complete logs. +- Read their completed review/complete evidence if needed through active/archive complete.log dependency exception only. +- Update handoff doc and tests. + +## 구현 체크리스트 + +- [ ] [DOCS-1] Update handoff matrix with command, expected output key, repeatability, UI candidate, and UI defer reason for import/status/backtest workflows. +- [ ] [DOCS-2] Add tests that guard required scenarios and handoff columns/keys. 검증: handoff 문서가 command, expected output key, 반복 운영 여부, UI defer 사유를 함께 기록하고, 충분히 표면화되지 않은 기능은 화면 후보에서 제외한다. +- [ ] [DOCS-3] Run docs/CLI verification and `git diff --check`. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## [DOCS-1] Handoff Matrix + +### 문제 + +[apps/cli/testdata/operator/headless_validation.md](/config/workspace/alt/apps/cli/testdata/operator/headless_validation.md:24) is the existing UI handoff matrix, but it only has a broad remaining wireframe dependency column. The current milestone needs explicit separation between UI candidates and items still deferred. + +### 해결 방법 + +Keep the existing file instead of creating a new doc. Update the matrix columns to include: + +- command, +- input fixture, +- expected output fixture, +- expected output keys, +- repeatable operation (`yes/no/manual-only`), +- UI candidate, +- UI defer reason. + +Do not describe actual UI layout or build a screen. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/testdata/operator/headless_validation.md`: update matrix and notes. +- [ ] `bin/dev`: update short hint only if scenario names changed in predecessors. + +### 테스트 작성 + +No direct code test for prose, but DOCS-2 must assert required columns/key text to avoid silent drift. + +### 중간 검증 + +```bash +rg --sort path -n 'UI defer reason|repeatable|expected output' apps/cli/testdata/operator/headless_validation.md +``` + +Expected: updated column/section text is present. + +## [DOCS-2] Handoff Guard Tests + +### 문제 + +[apps/cli/internal/operator/handoff_test.go](/config/workspace/alt/apps/cli/internal/operator/handoff_test.go:12) guards scenario names and JSONL shape, but not the new handoff decisions. + +### 해결 방법 + +Extend tests to assert: + +- required scenarios include import/status/backtest scenarios produced by predecessors, +- each required scenario row references input and expected output fixtures, +- matrix contains the new handoff columns, +- expected JSONL fixtures contain the keys promised by each row where feasible (`provider`, `instrument_count`, `bar_count`, `count`, `run_id`, `run_status`, `starting_cash`, `ending_equity`, `total_return`, `trade_count`). + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/internal/operator/handoff_test.go`: add column/key coverage. +- [ ] `apps/cli/testdata/operator/expected/*.jsonl`: no content changes unless predecessor fixtures require final alignment. + +### 테스트 작성 + +Add `TestHandoffMatrixDocumentsCommandFirstColumns` and `TestExpectedFixturesContainPromisedKeys`. + +### 중간 검증 + +```bash +go test ./apps/cli/internal/operator -run Handoff -count=1 +``` + +Expected: handoff guard tests pass. + +## [DOCS-3] Verification + +### 문제 + +Docs-only changes can still break CLI fixture tests if paths or scenario names drift. + +### 해결 방법 + +Run CLI package tests and diff check. + +### 수정 파일 및 체크리스트 + +- [ ] No extra files. + +### 테스트 작성 + +No additional tests. + +### 중간 검증 + +```bash +git diff --check +``` + +Expected: no warnings. + +## 수정 파일 요약 + +| 파일 | 항목 | +|------|------| +| `apps/cli/testdata/operator/headless_validation.md` | DOCS-1 | +| `bin/dev` | DOCS-1 | +| `apps/cli/internal/operator/handoff_test.go` | DOCS-2 | +| `apps/cli/testdata/operator/expected/*.jsonl` | DOCS-2 | + +## 최종 검증 + +```bash +go test ./apps/cli/... -count=1 +rg --sort path -n 'UI defer reason|repeatable|expected output' apps/cli/testdata/operator/headless_validation.md +git diff --check +``` + +Expected: all commands exit 0. + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.