Plan command-first operator workflow
This commit is contained in:
parent
ee01990117
commit
1314fe290b
13 changed files with 2267 additions and 4 deletions
|
|
@ -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`
|
||||
|
||||
|
|
|
|||
|
|
@ -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로 묶는다.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
- 확인 필요: 없음
|
||||
|
|
|
|||
|
|
@ -0,0 +1,155 @@
|
|||
<!-- task=m-command-first-operator-workflow/01_import_contract_worker_api plan=0 tag=API -->
|
||||
|
||||
# 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-<milestone-slug>`이면 완료 이벤트 메타데이터를 보고한다. 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-<milestone-slug>`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, 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.
|
||||
|
|
@ -0,0 +1,429 @@
|
|||
<!-- task=m-command-first-operator-workflow/01_import_contract_worker_api plan=0 tag=API -->
|
||||
|
||||
# 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`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
<!-- task=m-command-first-operator-workflow/02+01_import_cli_scenario plan=0 tag=CLI -->
|
||||
|
||||
# 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-<milestone-slug>`이면 완료 이벤트 메타데이터를 보고한다. 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-<milestone-slug>`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, 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.
|
||||
|
|
@ -0,0 +1,301 @@
|
|||
<!-- task=m-command-first-operator-workflow/02+01_import_cli_scenario plan=0 tag=CLI -->
|
||||
|
||||
# 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`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
<!-- task=m-command-first-operator-workflow/03+02_market_status_scenario plan=0 tag=CLI -->
|
||||
|
||||
# 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-<milestone-slug>`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, 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.
|
||||
|
|
@ -0,0 +1,250 @@
|
|||
<!-- task=m-command-first-operator-workflow/03+02_market_status_scenario plan=0 tag=CLI -->
|
||||
|
||||
# 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`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
<!-- task=m-command-first-operator-workflow/04+02_backtest_runtime_flow plan=0 tag=API -->
|
||||
|
||||
# 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-<milestone-slug>`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, 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.
|
||||
|
|
@ -0,0 +1,330 @@
|
|||
<!-- task=m-command-first-operator-workflow/04+02_backtest_runtime_flow plan=0 tag=API -->
|
||||
|
||||
# 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`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
<!-- task=m-command-first-operator-workflow/05+03,04_operator_handoff plan=0 tag=DOCS -->
|
||||
|
||||
# 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-<milestone-slug>`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, 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.
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
<!-- task=m-command-first-operator-workflow/05+03,04_operator_handoff plan=0 tag=DOCS -->
|
||||
|
||||
# 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`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
|
||||
Loading…
Reference in a new issue