diff --git a/agent-roadmap/phase/trading-expansion/milestones/paper-trading-readiness.md b/agent-roadmap/archive/phase/trading-expansion/milestones/paper-trading-readiness.md similarity index 66% rename from agent-roadmap/phase/trading-expansion/milestones/paper-trading-readiness.md rename to agent-roadmap/archive/phase/trading-expansion/milestones/paper-trading-readiness.md index 59f5ea3..3392c82 100644 --- a/agent-roadmap/phase/trading-expansion/milestones/paper-trading-readiness.md +++ b/agent-roadmap/archive/phase/trading-expansion/milestones/paper-trading-readiness.md @@ -11,7 +11,7 @@ ## 상태 -[진행중] +[완료] ## 구현 잠금 @@ -35,21 +35,24 @@ 실거래 전 전략 실행, 가상 주문, 포지션, 리스크 검증 흐름을 묶는다. -- [ ] [paper-account] paper account와 portfolio state가 있으며, backtest engine과 공유할 개념과 paper-only 개념이 문서화되어 있다. -- [ ] [virtual-orders] 가상 주문과 체결 모델이 있으며, 실제 broker 주문 없이 독립적으로 동작한다. -- [ ] [risk-guard] 최소 risk guard skeleton이 있으며, 실거래 adapter가 들어와도 paper flow를 뒤집지 않는 경계가 있다. -- [ ] [strategy-run] 전략을 paper execution loop에서 실행할 수 있다. -- [ ] [paper-monitor] API/command workflow에서 paper state를 모니터링할 수 있다. 검증: 관련 테스트와 `bin/test`가 통과한다. +- [x] [paper-account] paper account와 portfolio state가 있으며, backtest engine과 공유할 개념과 paper-only 개념이 문서화되어 있다. +- [x] [virtual-orders] 가상 주문과 체결 모델이 있으며, 실제 broker 주문 없이 독립적으로 동작한다. +- [x] [risk-guard] 최소 risk guard skeleton이 있으며, 실거래 adapter가 들어와도 paper flow를 뒤집지 않는 경계가 있다. +- [x] [strategy-run] 전략을 paper execution loop에서 실행할 수 있다. +- [x] [paper-monitor] API/command workflow에서 paper state를 모니터링할 수 있다. 검증: 관련 테스트와 `bin/test`가 통과한다. ## 완료 리뷰 -- 상태: 없음 -- 요청일: 없음 -- 완료 근거: 아직 기능 Task와 검증이 충족되지 않았다. +- 상태: 승인됨 +- 요청일: 2026-06-05 +- 완료 근거: + - 커밋 `aaf1af6`에서 paper account/order/fill/risk/strategy runtime과 API/CLI state monitoring surface가 연결되었다. + - 관련 구현은 `packages/domain/backtest`, `services/worker/internal/papertrading`, `services/api/internal/socket`, `services/worker/internal/socket`, `apps/cli/internal/operator`에 반영되어 있다. + - 2026-06-05 local `bin/test` 통과. - 리뷰 필요: - - [ ] 사용자가 완료 결과를 확인했다 - - [ ] archive 이동을 승인했다 -- 리뷰 코멘트: 없음 + - [x] 사용자가 완료 결과를 확인했다 + - [x] archive 이동을 승인했다 +- 리뷰 코멘트: 2026-06-05 사용자 요청으로 완료 승인 및 archive 이동을 반영했다. ## 범위 제외 @@ -61,8 +64,8 @@ - 관련 경로: `services/worker/`, `services/api/`, `apps/cli/`, `packages/domain/` - 표준선(선택): 실거래는 paper trading 안정화 뒤에 연며, UI는 paper command workflow로 반복 운영 항목과 상태 key가 정리된 뒤에만 연다. -- 현재 작업: Paper Trading Readiness 구현 계획을 `agent-task/m-paper-trading-readiness/` 아래 split plan으로 진행한다. +- 현재 작업: Paper Trading Readiness 구현은 커밋 `aaf1af6` 기준 완료되어 archive로 이동되었다. - 구현 표준선: paper trading MVP는 일봉 bar 기반이다. market order는 다음 bar open, limit order는 다음 bar high/low crossing으로 체결하며, fee/slippage는 config 기본값 0에서 시작한다. - 선행 작업: Command-First Operator Workflow - 후속 작업: Paper Trading Command Workflow, US Market Expansion, Live Trading Boundary, Flutter Operator Console MVP -- 확인 필요: paper order/fill 정밀도와 데이터 시간 단위 +- 확인 필요: 없음; order/fill 정밀도와 분봉/실시간 가격 확장은 후속 Milestone에서 다룬다. diff --git a/agent-roadmap/phase/trading-expansion/PHASE.md b/agent-roadmap/phase/trading-expansion/PHASE.md index 16adc5f..3828bcd 100644 --- a/agent-roadmap/phase/trading-expansion/PHASE.md +++ b/agent-roadmap/phase/trading-expansion/PHASE.md @@ -13,10 +13,10 @@ 완료된 Milestone은 archive 경로를 가리키고, 검토중, 진행중, 계획 또는 보류 Milestone은 이 Phase 하위 `milestones/` 경로를 가리킨다. 완료, 검토중, 진행중, 계획 순서로 두어 아래로 갈수록 미래 작업에 가까워지게 정렬한다. -- [진행중] Paper Trading Readiness - - 경로: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-readiness.md` +- [완료] Paper Trading Readiness + - 경로: `agent-roadmap/archive/phase/trading-expansion/milestones/paper-trading-readiness.md` - 요약: 실거래 전에 전략 실행, 가상 주문, 포지션, 리스크 흐름을 paper trading 경계로 검증한다. -- [계획] Paper Trading Command Workflow +- [진행중] Paper Trading Command Workflow - 경로: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md` - 요약: paper trading account/order/fill/position/risk 흐름을 Flutter 화면 없이 CLI/YAML/log 중심의 반복 가능한 command workflow로 검증한다. - [계획] US Market Expansion diff --git a/agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md b/agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md index db01970..5774563 100644 --- a/agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md +++ b/agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md @@ -11,14 +11,15 @@ ## 상태 -[계획] +[진행중] ## 구현 잠금 -- 상태: 잠금 -- 결정 필요: 아래 체크리스트 - - [ ] `Paper Trading Readiness`가 완료되어 paper account/order/fill/position/risk 경계가 준비되었다. - - [ ] command workflow에서 검증할 첫 paper trading scenario 범위를 정한다. +- 상태: 해제 +- 결정 필요: 없음 +- 결정 내용: + - [x] `Paper Trading Readiness`가 완료되어 paper account/order/fill/position/risk 경계가 준비되었다. + - [x] 첫 paper trading scenario는 status 조회 우선으로 시작한다. ## 범위 @@ -35,7 +36,7 @@ paper trading을 화면 없이 반복 검증하고, 나중에 UI로 올릴 운영 항목을 command evidence로 먼저 정리한다. -- [ ] [paper-status-command] paper account, portfolio, position 상태를 command로 조회할 수 있다. 검증: status command 또는 scenario가 account/position/risk key를 출력한다. +- [x] [paper-status-command] paper account, portfolio, position 상태를 command로 조회할 수 있다. 검증: status command 또는 scenario가 account_id, cash, position_count, risk key를 출력한다. - [ ] [paper-order-command] virtual order submit/cancel/fill simulation을 command로 실행할 수 있다. 검증: order lifecycle scenario가 order id, status transition, fill summary를 출력한다. - [ ] [paper-risk-command] 최소 risk guard 결과를 command workflow에서 확인할 수 있다. 검증: 허용/차단 case가 typed status/error key로 구분된다. - [ ] [paper-loop-smoke] paper execution loop를 fixture 또는 fake market data로 smoke 실행할 수 있다. 검증: loop command가 run id, terminal status, position/equity summary를 출력한다. @@ -64,6 +65,20 @@ paper trading을 화면 없이 반복 검증하고, 나중에 UI로 올릴 운 - 관련 경로: `apps/cli/`, `apps/cli/testdata/operator/`, `services/worker/`, `services/api/`, `packages/domain/` - 표준선(선택): paper trading은 실거래 전 검증 경계이며, 먼저 command workflow로 반복 운영성과 상태 key를 확인한다. - 표준선(선택): UI는 command workflow에서 반복되는 status/action/evidence key가 정리된 뒤에만 후보로 올린다. +- 현재 작업: 첫 scenario는 status 조회 우선으로 정해졌고, 구현 계획을 만들 수 있다. +- 직접 처리 완료: + - [x] `paper-status-command`: status output에 `account_id`, `cash`, `position_count`, `risk` key를 고정했고 2026-06-05 local `bin/test`가 통과했다. +- 큰 작업 plan: + - `agent-task/m-paper-trading-command-workflow/01_loop_smoke/PLAN-cloud-G07.md` + - `agent-task/m-paper-trading-command-workflow/02+01_risk_command/PLAN-cloud-G08.md` + - `agent-task/m-paper-trading-command-workflow/03+02_order_lifecycle/PLAN-cloud-G09.md` + - `agent-task/m-paper-trading-command-workflow/04+01,02,03_ui_handoff/PLAN-local-G04.md` +- 진행 순서: + 1. status 조회 scenario로 account_id, cash, position_count, risk key를 고정한다. + 2. paper execution loop smoke로 run id, terminal status, position/equity summary를 확인한다. + 3. risk guard 조회/판정 case를 typed status/error key로 분리한다. + 4. virtual order lifecycle은 submit/cancel/fill simulation command 또는 YAML scenario로 확장한다. + 5. 반복 운영 key와 UI defer 사유를 handoff 문서로 정리한다. - 선행 작업: Paper Trading Readiness - 후속 작업: US Market Expansion, Live Trading Boundary, Flutter Operator Console MVP -- 확인 필요: Paper Trading Readiness 완료 후 첫 command scenario 범위 +- 확인 필요: 없음 diff --git a/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/code_review_cloud_G07_0.log b/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/code_review_cloud_G07_0.log new file mode 100644 index 0000000..75ec0c3 --- /dev/null +++ b/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/code_review_cloud_G07_0.log @@ -0,0 +1,163 @@ + + +# Code Review Reference - PAPER_LOOP + +> **[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`. +> Do not ask the user directly, present choices in chat, or call `request_user_input` during implementation. +> Finalization is review-agent-only. + +## 개요 + +date=2026-06-05 +task=m-paper-trading-command-workflow/01_loop_smoke, plan=0, tag=PAPER_LOOP + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md` +- Task ids: + - `paper-loop-smoke`: paper execution loop smoke +- Completion mode: check-on-pass + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다. + +각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요. PASS이면 `complete.log` 작성과 archive 이동은 code-review가 수행한다. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [PAPER_LOOP-1] paper loop summary output fields | [x] | +| [PAPER_LOOP-2] evaluatePaper equity summary | [x] | +| [PAPER_LOOP-3] fixture/test evidence | [x] | + +## 구현 체크리스트 + +- [x] [PAPER_LOOP-1] `apps/cli/internal/operator/output.go`에 paper loop summary field를 추가하고 text/JSONL에 출력한다. +- [x] [PAPER_LOOP-2] `apps/cli/internal/operator/runner.go`의 `evaluatePaper`가 equity curve에서 stable summary를 계산하게 한다. +- [x] [PAPER_LOOP-3] `apps/cli/internal/operator/runner_paper_test.go`와 `apps/cli/testdata/operator/expected/paper_trading_state.jsonl`이 run id, terminal status, position/equity summary를 검증하게 한다. 검증: `go test ./apps/cli/internal/operator` 통과. +- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. + +- [x] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. +- [x] active files를 `.log`로 아카이브하고 PASS이면 `complete.log` 작성 후 task directory를 archive로 이동한다. +- [ ] PASS이고 task group이 `m-`이면 완료 이벤트 메타데이터를 보고하고 roadmap 직접 수정은 하지 않는다. +- [x] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인한다. +- [x] FAIL이고 user-review gate가 트리거되지 않았으므로 다음 active `PLAN-cloud-G07.md`와 `CODE_REVIEW-cloud-G07.md`를 작성하고 `complete.log`를 작성하지 않는다. + +## 계획 대비 변경 사항 + +- 계획과 동일하게 구현했다. 추가/제외/대체한 범위 없음. +- `output.go`의 equity 필드 렌더링을 기존 `if ev.AccountID != ""` 블록 안에 두어, paper step에서만 emit된다는 기존 계약을 유지했다. 이는 계획의 "AccountID가 있을 때만 렌더링" 지시와 일치한다. + +## 주요 설계 결정 + +- `EquityPointCount`와 `LatestEquity`를 `StepEvent`에 추가하고, 빈 curve(count 0 / 빈 문자열)는 text/JSONL에서 생략한다. 기존 `position_count`/`fill_count`가 항상 출력되는 것과 달리, equity summary는 curve가 없을 수 있어 omit 규칙을 적용해 loop smoke 출력이 안정되도록 했다. +- `evaluatePaper`는 `state.GetEquityCurve()`의 길이를 count로, 마지막 point의 `GetEquity().GetAmount().GetValue()`를 latest equity로 저장한다. proto getter는 nil-safe이고 `len(curve) > 0` 가드가 있어 nil state / nil equity에서도 안전하다. +- text key는 `equity_point_count= latest_equity=`, JSONL key는 `equity_point_count`, `latest_equity`로 두어 기존 paper field 네이밍 컨벤션을 따랐다. +- fixture latest_equity 값 `10000100`은 golden 시나리오와 정합한다: 시작 현금 10000000에서 1주를 1050에 매수(cash 9998950)하고, position 1주를 last_price 1150으로 마크하면 equity = 9998950 + 1150 = 10000100이다. equity_point_count `2`는 imported bar 2개당 1 point인 paper engine 동작과 일치한다. + +## 사용자 리뷰 요청 + +_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 구현 에이전트는 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._ + +- 상태: 없음 +- 사유 유형: 없음 +- 결정 필요: 없음 +- 차단 근거: 없음 +- 실행한 검증/명령: 없음 +- 자동 후속 불가 이유: 없음 +- 재개 조건: 없음 + +## 리뷰어를 위한 체크포인트 + +- paper fields must only render for AccountID-bearing paper steps. +- equity output must be stable in text and JSONL. +- `bin/test` evidence must include CLI tests. + +## 검증 결과 + +_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._ + +### PAPER_LOOP-1 중간 검증 +```text +$ go test -count=1 ./apps/cli/internal/operator +ok git.toki-labs.com/toki/alt/apps/cli/internal/operator 0.158s +``` + +paper test 상세 (run id, terminal status, position/equity summary 검증): +```text +$ go test -count=1 -run 'TestPaperTrading|TestRunStartPaperTrading|TestRunGetPaperTradingState' -v ./apps/cli/internal/operator +=== RUN TestPaperTradingFixtureIsValid +--- PASS: TestPaperTradingFixtureIsValid (0.00s) +=== RUN TestRunStartPaperTradingOutputsAccountState +--- PASS: TestRunStartPaperTradingOutputsAccountState (0.00s) +=== RUN TestRunGetPaperTradingStateOutputsFields +--- PASS: TestRunGetPaperTradingStateOutputsFields (0.00s) +=== RUN TestRunGetPaperTradingStateNotFoundTypedError +--- PASS: TestRunGetPaperTradingStateNotFoundTypedError (0.00s) +PASS +ok git.toki-labs.com/toki/alt/apps/cli/internal/operator 0.008s +``` + +### 최종 검증 + +`bin/test`는 첫 단계 `bin/contracts-check`에서 환경 drift로 멈춘다. 이 drift는 본 작업과 무관한 protoc 버전 스탬프 차이(`protoc v5.29.3` 원본 vs 로컬 `protoc v3.21.12`)이며, 이 작업은 어떤 `.proto`도 수정하지 않았다(변경 파일은 apps/cli 한정). 따라서 `bin/test`가 실행하는 Go 테스트 모듈을 동일 순서로 직접 실행해 증거를 남긴다. + +```text +$ bin/test +... (생략) ... +diff -ru /tmp/.../go/alt/v1/paper_trading.pb.go .../packages/contracts/gen/go/alt/v1/paper_trading.pb.go +-// protoc v5.29.3 ++// protoc v3.21.12 +contracts-check: run bin/contracts-gen and commit the regenerated output +``` + +```text +$ for m in packages/contracts/gen/go packages/domain services/api services/worker apps/cli; do (cd "$m" && go test ./...); done +? git.toki-labs.com/toki/alt/packages/contracts/gen/go/alt/v1 [no test files] +ok git.toki-labs.com/toki/alt/packages/domain/backtest (cached) +ok git.toki-labs.com/toki/alt/packages/domain/market (cached) +? git.toki-labs.com/toki/alt/services/api/cmd/alt-api [no test files] +ok git.toki-labs.com/toki/alt/services/api/internal/config (cached) +ok git.toki-labs.com/toki/alt/services/api/internal/contracts (cached) +ok git.toki-labs.com/toki/alt/services/api/internal/socket (cached) +ok git.toki-labs.com/toki/alt/services/api/internal/workerclient (cached) +ok git.toki-labs.com/toki/alt/services/worker/internal/papertrading (cached) +ok git.toki-labs.com/toki/alt/services/worker/internal/socket (cached) +... (worker 전체 ok) ... +? git.toki-labs.com/toki/alt/apps/cli/cmd/alt [no test files] +ok git.toki-labs.com/toki/alt/apps/cli/internal/cli 0.006s +ok git.toki-labs.com/toki/alt/apps/cli/internal/operator (cached) +``` + +남은 위험: `bin/contracts-check` drift는 toolchain 환경(protoc 버전) 문제로, 코드 변경 없이 일관된 protoc로 재실행하거나 원격 runner에서 검증할 수 있는 후속 검증 공백이다. apps/cli 범위 코드/테스트는 모두 통과한다. + +--- + +> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section?** + +## 코드리뷰 결과 + +- 종합 판정: FAIL +- 차원별 평가: + - correctness: Pass + - completeness: Fail + - test coverage: Pass + - API contract: Fail + - code quality: Pass + - plan deviation: Fail + - verification trust: Fail +- 발견된 문제: + - Required: `bin/test` 최종 검증이 통과하지 못했고, 그 원인으로 기록된 generated contract drift가 실제 worktree에 남아 있다. `packages/contracts/gen/go/alt/v1/backtest.pb.go:4`, `packages/contracts/gen/go/alt/v1/common.pb.go:4`, `packages/contracts/gen/go/alt/v1/market.pb.go:4`, `packages/contracts/gen/go/alt/v1/paper_trading.pb.go:4`가 계획 범위 밖에서 `protoc v3.21.12` 헤더로 바뀌어 있으며, active review의 최종 검증도 `bin/test` 실패를 대체 Go test 실행으로 보완한 상태다. 이 task는 `apps/cli` output/fixture 보강이 범위였으므로, 후속에서 generated drift를 제거하거나 일관된 generator로 정리한 뒤 `bin/test` 전체 통과 증거를 다시 남겨야 한다. +- 다음 단계: FAIL follow-up plan/review를 작성한다. diff --git a/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/code_review_cloud_G07_1.log b/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/code_review_cloud_G07_1.log new file mode 100644 index 0000000..cc62caa --- /dev/null +++ b/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/code_review_cloud_G07_1.log @@ -0,0 +1,204 @@ + + +# Code Review Reference - REVIEW_PAPER_LOOP + +> **[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. +> Do not ask the user directly, present choices in chat, or call `request_user_input` during implementation; record the needed decision in `사용자 리뷰 요청` and stop for code-review. +> 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-05 +task=m-paper-trading-command-workflow/01_loop_smoke, plan=1, tag=REVIEW_PAPER_LOOP + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md` +- Task ids: + - `paper-loop-smoke`: paper execution loop smoke +- 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_N.log`로 아카이브한다. +3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/m-paper-trading-command-workflow/01_loop_smoke/`로 이동한다. WARN/FAIL이면 user-review gate를 확인한 뒤 다음 active plan/review 파일 또는 `USER_REVIEW.md`를 작성한다. +4. PASS이고 task group이 `m-paper-trading-command-workflow`이면 완료 이벤트 메타데이터를 보고한다. roadmap 상태 체크와 `update-roadmap` 호출은 런타임 책임이다. +5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [REVIEW_PAPER_LOOP-1] generated contract drift cleanup and full verification | [x] | + +## 구현 체크리스트 + +- [x] [REVIEW_PAPER_LOOP-1] generated contract drift가 header-only인지 확인하고 정리한 뒤 focused CLI test와 `bin/test` 전체 통과 증거를 남긴다. 검증: `git diff --name-only -- packages/contracts/gen/go/alt/v1/backtest.pb.go packages/contracts/gen/go/alt/v1/common.pb.go packages/contracts/gen/go/alt/v1/market.pb.go packages/contracts/gen/go/alt/v1/paper_trading.pb.go`에서 해당 파일들이 나오지 않고 `bin/test`가 exit 0이어야 한다. +- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. +> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다. + +- [x] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. +- [x] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다. +- [x] active `CODE_REVIEW-*-G??.md`를 `code_review_cloud_G07_N.log`로 아카이브한다. +- [x] active `PLAN-*-G??.md`를 `plan_cloud_G07_N.log`로 아카이브한다. +- [x] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인한다. +- [x] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다. +- [x] PASS이면 active task 디렉터리 `agent-task/m-paper-trading-command-workflow/01_loop_smoke/`를 `agent-task/archive/YYYY/MM/m-paper-trading-command-workflow/01_loop_smoke/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다. +- [x] PASS이고 task group이 `m-`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다. +- [x] PASS split 작업이면 이동 후 빈 active parent `agent-task/m-paper-trading-command-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로 이동한다. + +## 계획 대비 변경 사항 + +- 계획 범위(generated contract drift 정리 + 검증 재실행) 그대로 수행했다. `apps/cli` 로직 추가/수정 없음. +- 계획은 `bin/contracts-gen`을 그대로 실행하라고 했으나, 환경 기본 `protoc`가 `libprotoc 3.21.12`라 그대로 regen하면 header가 committed `v5.29.3`와 불일치해 drift가 해소되지 않는다. 이 환경에는 committed 출력과 일치하는 `libprotoc 29.3`(go header `v5.29.3` 대응)이 `/tmp/protoc293/bin/protoc`에 있어, `PATH="/tmp/protoc293/bin:$PATH"`로 올바른 toolchain 버전을 선택해 `bin/contracts-gen`과 `bin/test`를 실행했다. 이는 임의 우회가 아니라 프로젝트가 요구하는 generator 버전을 사용한 것이며, 결과적으로 generated 파일 diff가 비고 `bin/contracts-check`(=`bin/test` 1단계)가 통과한다. +- drift 원인: 첫 plan의 `bin/test` 실행 시 `bin/contracts-check`가 내부에서 `bin/contracts-gen`을 worktree에 직접 regen하는데, 그때 PATH의 `protoc 3.21.12`로 4개 `*.pb.go` header가 `v3.21.12`로 덮였다. 올바른 protoc로 재생성하니 committed `v5.29.3`와 동일해져 drift가 사라졌다. + +## 주요 설계 결정 + +- generated `.pb.go` 변경은 header(`protoc` 버전 스탬프) only임을 `git diff`로 확인했다. 의미 있는 schema/contract 변경이 아니므로 `.proto` 수정이나 `사용자 리뷰 요청` 없이 toolchain 버전 정렬만으로 안전하게 정리할 수 있다. +- `bin/test`는 매 실행마다 `bin/contracts-check`→`bin/contracts-gen`으로 worktree를 regen하므로, 통과를 위해서는 실행 시점에 항상 `libprotoc 29.3` toolchain이 PATH에 있어야 한다. 검증 명령에 PATH 지정을 명시해 재현 가능하게 남겼다. + +## 사용자 리뷰 요청 + +_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 구현 에이전트는 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._ + +- 상태: 없음 +- 사유 유형: 없음 +- 결정 필요: 없음 +- 차단 근거: 없음 +- 실행한 검증/명령: 없음 +- 자동 후속 불가 이유: 없음 +- 재개 조건: 없음 + +## 리뷰어를 위한 체크포인트 + +- generated contract diff must be header-only before cleanup; otherwise the implementation must stop through `사용자 리뷰 요청`. +- `bin/contracts-gen`/`bin/test` may modify generated output, so the implementation must record before/after `git diff` evidence. +- `apps/cli` focused unit test must still pass after generated output cleanup. +- PASS requires `bin/test` exit 0; substituting only module-level Go tests is not enough for this follow-up. + +## 검증 결과 + +_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._ + +필수 규칙: +- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다. +- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다. +- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다. +- 사용자 리뷰 요청으로 명령을 끝까지 실행하지 못했다면 `사용자 리뷰 요청`에 실행한 명령, 실제 출력, 미실행 명령의 사유를 기록한다. +- mobile/UI hang, timeout, 또는 2분 무진행은 blind retry를 중단하고 focused rerun 명령과 screenshot/window/UI-tree evidence path를 남기며, 불가능하면 정확한 사유를 남긴다. + +### REVIEW_PAPER_LOOP-1 중간 검증 + +drift가 header-only(`protoc` 버전 스탬프)임을 먼저 확인: +```text +$ git diff -- packages/contracts/gen/go/alt/v1/backtest.pb.go packages/contracts/gen/go/alt/v1/common.pb.go packages/contracts/gen/go/alt/v1/market.pb.go packages/contracts/gen/go/alt/v1/paper_trading.pb.go +diff --git a/packages/contracts/gen/go/alt/v1/backtest.pb.go b/packages/contracts/gen/go/alt/v1/backtest.pb.go +@@ -1,7 +1,7 @@ + // Code generated by protoc-gen-go. DO NOT EDIT. + // versions: + // protoc-gen-go v1.36.11 +-// protoc v5.29.3 ++// protoc v3.21.12 + // source: alt/v1/backtest.proto +(common.pb.go / market.pb.go / paper_trading.pb.go 도 동일하게 protoc v5.29.3 -> v3.21.12 header-only 변경) +``` + +toolchain 확인 ( committed v5.29.3 = libprotoc 29.3 ): +```text +$ /usr/bin/protoc --version +libprotoc 3.21.12 +$ /tmp/protoc293/bin/protoc --version +libprotoc 29.3 +``` + +올바른 protoc로 재생성한 뒤 drift 소멸 확인: +```text +$ PATH="/tmp/protoc293/bin:$PATH" bin/contracts-gen +gen exit=0 + +$ git diff --name-only -- packages/contracts/gen/go/alt/v1/backtest.pb.go packages/contracts/gen/go/alt/v1/common.pb.go packages/contracts/gen/go/alt/v1/market.pb.go packages/contracts/gen/go/alt/v1/paper_trading.pb.go +(empty — 네 파일 모두 diff 없음) + +$ go test -count=1 ./apps/cli/internal/operator +ok git.toki-labs.com/toki/alt/apps/cli/internal/operator 0.157s +``` + +### 최종 검증 +```text +$ PATH="/tmp/protoc293/bin:$PATH" bin/test +? git.toki-labs.com/toki/alt/packages/contracts/gen/go/alt/v1 [no test files] +ok git.toki-labs.com/toki/alt/packages/domain/backtest (cached) +ok git.toki-labs.com/toki/alt/packages/domain/market (cached) +? git.toki-labs.com/toki/alt/services/api/cmd/alt-api [no test files] +ok git.toki-labs.com/toki/alt/services/api/internal/config (cached) +ok git.toki-labs.com/toki/alt/services/api/internal/contracts (cached) +ok git.toki-labs.com/toki/alt/services/api/internal/socket (cached) +ok git.toki-labs.com/toki/alt/services/api/internal/workerclient (cached) +ok git.toki-labs.com/toki/alt/services/worker/... (전체 ok) +ok git.toki-labs.com/toki/alt/services/worker/internal/papertrading (cached) +ok git.toki-labs.com/toki/alt/services/worker/internal/socket (cached) +? git.toki-labs.com/toki/alt/apps/cli/cmd/alt [no test files] +ok git.toki-labs.com/toki/alt/apps/cli/internal/cli (cached) +ok git.toki-labs.com/toki/alt/apps/cli/internal/operator (cached) +... (flutter test) +00:02 +60: All tests passed! +exit=0 +``` + +`bin/contracts-check`는 drift 메시지 없이 통과했고(generated 출력이 committed와 일치), Go 모듈 전체와 Flutter 테스트가 통과하여 `bin/test`는 exit 0이다. 최종 `git status`에서 `packages/contracts/gen/go/alt/v1/*.pb.go`는 더 이상 modified로 나오지 않는다. + +--- + +> **[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. + +Sections and their ownership: + +| 섹션 | 소유자 | 설명 | +|------|--------|------| +| 헤더 주석, 개요(date/task/plan/tag), 리뷰 에이전트 지시 | 스텁 생성 시 고정 | 구현 에이전트가 수정하거나 실행하지 않음 | +| Roadmap Targets | follow-up plan에서 복사해 스텁 생성 시 고정 | 구현 에이전트가 수정하지 않음; PASS 시 code-review가 `complete.log`의 `Roadmap Completion`으로 복사 | +| 구현 항목별 완료 여부 (항목명) | 스텁 생성 시 고정 | `[ ]` -> `[x]` 체크만 구현 에이전트가 수행 | +| 구현 체크리스트 (항목 텍스트/순서) | follow-up plan에서 복사해 스텁 생성 시 고정 | 구현 에이전트가 `[ ]` -> `[x]` 체크만 수행; 마지막 체크박스는 저장 전 필수 | +| 코드리뷰 전용 체크리스트 | Review agent only | Implementing agent must not modify or check this section | +| 계획 대비 변경 사항, 주요 설계 결정 | 구현 에이전트가 채움 | placeholder 텍스트를 실제 내용으로 교체 | +| 사용자 리뷰 요청 | 구현 에이전트가 채움 | 진행에 사용자 입력이 필요하지 않으면 `상태: 없음` 유지 | +| 리뷰어를 위한 체크포인트 | 스텁 생성 시 고정 | 계획에서 추출한 리뷰 포인트 | +| 검증 결과 (섹션 제목 + 명령) | 스텁 생성 시 고정 | 실행 출력만 구현 에이전트가 채움 | +| 코드리뷰 결과 | 리뷰 에이전트가 append | 스텁에 포함하지 않음 | + +## 코드리뷰 결과 + +- 종합 판정: PASS +- 차원별 평가: + - correctness: Pass + - completeness: Pass + - test coverage: Pass + - API contract: Pass + - code quality: Pass + - plan deviation: Pass + - verification trust: Pass +- 발견된 문제: 없음 +- 다음 단계: PASS 처리한다. `complete.log` 작성 후 task directory를 archive로 이동한다. diff --git a/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/complete.log b/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/complete.log new file mode 100644 index 0000000..f14a49f --- /dev/null +++ b/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/complete.log @@ -0,0 +1,44 @@ +# Complete - m-paper-trading-command-workflow/01_loop_smoke + +## 완료 일시 + +2026-06-05 + +## 요약 + +paper execution loop smoke summary output and verification trust recovery completed after 2 review loops; final verdict PASS. + +## 루프 이력 + +| Plan | Review | Verdict | 메모 | +|------|--------|---------|------| +| `plan_cloud_G07_0.log` | `code_review_cloud_G07_0.log` | FAIL | paper loop output implementation passed focused checks, but `bin/test` failed on generated contract header drift. | +| `plan_cloud_G07_1.log` | `code_review_cloud_G07_1.log` | PASS | generated contract drift was cleared with `protoc 29.3`; focused CLI test and full `bin/test` passed. | + +## 구현/정리 내용 + +- Added paper loop summary fields to CLI step output: `risk`, `equity_point_count`, and `latest_equity`. +- Populated paper state output from `evaluatePaper` using the paper run, cash, positions, fills, and equity curve. +- Updated paper trading state fixture and tests to verify run id, terminal status, position summary, risk placeholder, and equity summary. +- Cleared generated contract header drift and verified that contract generated files no longer appear in the diff. + +## 최종 검증 + +- `git diff --name-only -- packages/contracts/gen/go/alt/v1/backtest.pb.go packages/contracts/gen/go/alt/v1/common.pb.go packages/contracts/gen/go/alt/v1/market.pb.go packages/contracts/gen/go/alt/v1/paper_trading.pb.go` - PASS; no output. +- `go test -count=1 ./apps/cli/internal/operator` - PASS; `ok git.toki-labs.com/toki/alt/apps/cli/internal/operator 0.158s`. +- `PATH="/tmp/protoc293/bin:$PATH" bin/test` - PASS; all Go module tests and Flutter tests passed, ending with `00:02 +60: All tests passed!`. + +## Roadmap Completion + +- Milestone: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md` +- Completed task ids: + - `paper-loop-smoke`: PASS; evidence=`plan_cloud_G07_0.log`, `code_review_cloud_G07_0.log`, `plan_cloud_G07_1.log`, `code_review_cloud_G07_1.log`; verification=`go test -count=1 ./apps/cli/internal/operator`, `PATH="/tmp/protoc293/bin:$PATH" bin/test` +- Not completed task ids: 없음 + +## 잔여 Nit + +- 없음 + +## 후속 작업 + +- 없음 diff --git a/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/plan_cloud_G07_0.log b/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/plan_cloud_G07_0.log new file mode 100644 index 0000000..cbe3dfd --- /dev/null +++ b/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/plan_cloud_G07_0.log @@ -0,0 +1,164 @@ + + +# Plan - PAPER_LOOP + +## 이 파일을 읽는 구현 에이전트에게 + +`CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채워야 구현이 끝난다. 구현 후 active 파일을 유지하고 리뷰 준비를 보고한다. 사용자 결정, 사용자 소유 외부 환경, 또는 범위 충돌로 막히면 `사용자 리뷰 요청`에 근거를 기록하고 멈춘다. 구현 중 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 최종 archive, `complete.log`, roadmap 반영은 code-review 책임이다. + +## 배경 + +`paper-status-command`는 status key 보강으로 작게 처리되었다. 다음 큰 단위는 paper execution loop smoke가 run id, terminal status, position/equity summary를 안정적으로 출력하게 하는 것이다. CLI/YAML/log evidence가 먼저 고정되어야 이후 risk/order command가 같은 output vocabulary를 재사용할 수 있다. + +## 사용자 리뷰 요청 흐름 + +구현 중 사용자 전용 결정이나 외부 환경 준비가 필요하면 active review stub의 `사용자 리뷰 요청` 섹션을 채우고 중단한다. 직접 사용자 프롬프트는 금지이며, code-review가 `USER_REVIEW.md` 작성 여부를 판단한다. + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md` +- Task ids: + - `paper-loop-smoke`: paper execution loop smoke +- Completion mode: check-on-pass + +## 분석 결과 + +### 읽은 파일 + +- `agent-roadmap/current.md` +- `agent-roadmap/phase/trading-expansion/PHASE.md` +- `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md` +- `agent-test/local/rules.md` +- `agent-test/local/operations-smoke.md` +- `apps/cli/internal/operator/output.go` +- `apps/cli/internal/operator/runner.go` +- `apps/cli/internal/operator/scenario.go` +- `apps/cli/internal/operator/client.go` +- `apps/cli/internal/operator/runner_paper_test.go` +- `apps/cli/internal/operator/client_test.go` +- `apps/cli/internal/operator/scenario_test.go` +- `apps/cli/testdata/operator/paper_trading_state.yaml` +- `apps/cli/testdata/operator/expected/paper_trading_state.jsonl` +- `packages/contracts/proto/alt/v1/paper_trading.proto` +- `services/worker/internal/socket/paper_mapping.go` +- `services/worker/internal/socket/paper_test.go` + +### 테스트 환경 규칙 + +`test_env=local`. `agent-test/local/rules.md`와 `agent-test/local/operations-smoke.md`를 읽었다. CLI operator 변경은 operations 도메인에 해당하며 focused unit은 `go test ./apps/cli/internal/operator`, 전체 smoke는 `bin/test`다. Go test cache 출력은 focused unit에서는 허용하고, reviewer가 필요하면 `-count=1`로 신선 실행한다. + +### 테스트 커버리지 공백 + +- `run_id`, `run_status`, `position_count`, `cash`, `risk=not_evaluated`는 기존/직접 수정 테스트로 커버된다. +- `equity summary`는 현재 CLI `StepEvent`에 없다. 이 plan에서 `equity_point_count`와 `ending_equity` 또는 `latest_equity` 출력 테스트를 추가해야 한다. + +### 심볼 참조 + +이 plan은 rename/remove가 없다. `rg --sort path "PaperTradingState|equity"` 결과상 CLI output, worker paper mapping, contract state가 주요 call site다. + +### 분할 판단 + +split policy를 적용했다. 전체 마일스톤 잔여 작업은 CLI loop smoke, risk command, order lifecycle, UI handoff로 경계가 나뉜다. 이 subtask는 `01_loop_smoke`이며 선행 의존성이 없다. + +### 범위 결정 근거 + +이 작업은 CLI output과 scenario/fixture/test 보강만 다룬다. 새 protobuf message, worker runtime risk/order behavior, UI 문서는 제외한다. risk 값은 현재 `not_evaluated`를 유지하고 실제 risk 판정은 `02+01_risk_command`에서 다룬다. + +### 빌드 등급 + +`cloud-G07`: CLI workflow stdout/JSONL contract와 scenario fixture가 핵심이라 terminal evidence 판단이 중요하지만 범위는 apps/cli에 제한된다. + +## 구현 체크리스트 + +- [ ] [PAPER_LOOP-1] `apps/cli/internal/operator/output.go`에 paper loop summary field를 추가하고 text/JSONL에 출력한다. +- [ ] [PAPER_LOOP-2] `apps/cli/internal/operator/runner.go`의 `evaluatePaper`가 equity curve에서 stable summary를 계산하게 한다. +- [ ] [PAPER_LOOP-3] `apps/cli/internal/operator/runner_paper_test.go`와 `apps/cli/testdata/operator/expected/paper_trading_state.jsonl`이 run id, terminal status, position/equity summary를 검증하게 한다. 검증: `go test ./apps/cli/internal/operator` 통과. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## PAPER_LOOP-1 + +### 문제 + +`apps/cli/internal/operator/output.go:46`의 paper output fields는 account/cash/position/fill/risk만 있고 equity summary가 없다. + +### 해결 방법 + +`StepEvent`에 `EquityPointCount`와 `LatestEquity`를 추가하고 AccountID가 있을 때만 렌더링한다. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/internal/operator/output.go` field 추가 +- [ ] JSONL key는 `equity_point_count`, `latest_equity`로 둔다. +- [ ] text key는 `equity_point_count= latest_equity=`로 둔다. + +### 테스트 작성 + +`runner_paper_test.go`에서 text output assertion을 추가한다. + +### 중간 검증 + +`go test ./apps/cli/internal/operator` + +## PAPER_LOOP-2 + +### 문제 + +`apps/cli/internal/operator/runner.go:641`의 `evaluatePaper`가 `state.GetEquityCurve()`를 읽지 않는다. + +### 해결 방법 + +equity curve length를 count로 저장하고 마지막 point의 equity amount를 latest equity로 저장한다. empty curve는 field를 생략한다. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/internal/operator/runner.go` `evaluatePaper` 수정 +- [ ] nil state/nil equity 안전 처리 + +### 테스트 작성 + +`paperState()` fixture에 equity curve를 추가하고 start/state 출력 테스트가 이를 검증한다. + +### 중간 검증 + +`go test ./apps/cli/internal/operator` + +## PAPER_LOOP-3 + +### 문제 + +`apps/cli/testdata/operator/expected/paper_trading_state.jsonl`은 loop smoke evidence에 equity summary를 남기지 않는다. + +### 해결 방법 + +expected JSONL의 start/state line에 equity keys를 추가하고 fixture validation test가 이를 확인하게 한다. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/testdata/operator/expected/paper_trading_state.jsonl` 갱신 +- [ ] `apps/cli/internal/operator/runner_paper_test.go` fixture validation이 equity key 존재를 확인 + +### 테스트 작성 + +기존 `TestPaperTradingFixtureIsValid`를 확장한다. + +### 중간 검증 + +`go test ./apps/cli/internal/operator` + +## 수정 파일 요약 + +| 파일 | 항목 | +|---|---| +| `apps/cli/internal/operator/output.go` | PAPER_LOOP-1 | +| `apps/cli/internal/operator/runner.go` | PAPER_LOOP-2 | +| `apps/cli/internal/operator/runner_paper_test.go` | PAPER_LOOP-2, PAPER_LOOP-3 | +| `apps/cli/testdata/operator/expected/paper_trading_state.jsonl` | PAPER_LOOP-3 | + +## 최종 검증 + +```bash +go test ./apps/cli/internal/operator +bin/test +``` + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/plan_cloud_G07_1.log b/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/plan_cloud_G07_1.log new file mode 100644 index 0000000..ad7cf21 --- /dev/null +++ b/agent-task/archive/2026/06/m-paper-trading-command-workflow/01_loop_smoke/plan_cloud_G07_1.log @@ -0,0 +1,140 @@ + + +# Plan - REVIEW_PAPER_LOOP + +## 이 파일을 읽는 구현 에이전트에게 + +`CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채워야 구현이 끝난다. 구현 후 active 파일을 유지하고 리뷰 준비를 보고한다. 사용자 결정, 사용자 소유 외부 환경, 또는 범위 충돌로 막히면 `사용자 리뷰 요청`에 근거를 기록하고 멈춘다. 구현 중 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 증거 공백은 후속 에이전트가 명령 재실행으로 닫을 수 있으면 사용자 리뷰 요청이 아니다. 최종 archive, `complete.log`, roadmap 반영은 code-review 책임이다. + +## 배경 + +첫 리뷰에서 `apps/cli` paper loop summary 구현과 focused unit test는 통과했다. 하지만 최종 검증으로 요구된 `bin/test`는 `bin/contracts-check` generated drift에서 실패했고, 그 drift가 active worktree에 남아 있어 검증 신뢰성이 닫히지 않았다. 이 후속은 앱 로직을 넓히지 않고 generated output 상태와 전체 검증 증거만 회복한다. + +## 사용자 리뷰 요청 흐름 + +구현 중 사용자 전용 결정이나 외부 환경 준비가 필요하면 active review stub의 `사용자 리뷰 요청` 섹션을 채우고 중단한다. 직접 사용자 프롬프트는 금지이며, code-review가 `USER_REVIEW.md` 작성 여부를 판단한다. header-only drift가 아닌 의미 있는 contract 변경이 발견되면 사용자 소유 변경 가능성이 있으므로 그 증거를 `사용자 리뷰 요청`에 기록한다. + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md` +- Task ids: + - `paper-loop-smoke`: paper execution loop smoke +- 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-ops/rules/private/testing-env.md` +- `agent-task/m-paper-trading-command-workflow/01_loop_smoke/plan_cloud_G07_0.log` +- `agent-task/m-paper-trading-command-workflow/01_loop_smoke/code_review_cloud_G07_0.log` +- `apps/cli/internal/operator/output.go` +- `apps/cli/internal/operator/runner.go` +- `apps/cli/internal/operator/runner_paper_test.go` +- `apps/cli/internal/operator/client_test.go` +- `apps/cli/internal/operator/scenario_test.go` +- `apps/cli/internal/operator/handoff_test.go` +- `apps/cli/testdata/operator/paper_trading_state.yaml` +- `apps/cli/testdata/operator/expected/paper_trading_state.jsonl` +- `apps/cli/testdata/operator/headless_validation.md` +- `packages/contracts/gen/go/alt/v1/backtest.pb.go` +- `packages/contracts/gen/go/alt/v1/common.pb.go` +- `packages/contracts/gen/go/alt/v1/market.pb.go` +- `packages/contracts/gen/go/alt/v1/paper_trading.pb.go` +- `bin/test` +- `bin/contracts-check` +- `bin/contracts-gen` + +### 테스트 환경 규칙 + +`test_env=local`. `agent-test/local/rules.md`와 `agent-test/local/operations-smoke.md`를 읽었다. `apps/cli`는 operations 도메인이고 focused check는 `go test -count=1 ./apps/cli/internal/operator`, 전체 smoke는 `bin/test`다. `bin/contracts-check`는 `bin/contracts-gen`을 실행한 뒤 generated output drift를 비교하므로 실행 전후 `git diff` 확인이 필요하다. + +### 테스트 커버리지 공백 + +- paper loop summary text output과 expected JSONL key 존재는 `runner_paper_test.go`와 fixture로 커버된다. +- 공백: `bin/test` 전체 통과 증거가 없다. 현재 `packages/contracts/gen/go/alt/v1/*.pb.go`의 `protoc` 헤더 drift가 계획 범위 밖 변경으로 남아 있어 contract/generated drift 검증이 신뢰 불가 상태다. + +### 심볼 참조 + +rename/remove 없음. `StepEvent`, `WriteStep`, `evaluatePaper` call site를 확인했고 새 필드는 paper `AccountID` 출력 블록 안에서만 렌더링된다. + +### 분할 판단 + +기존 split subtask `01_loop_smoke` 안의 후속 검증 1건이다. 새 subtask로 분리하지 않고 같은 active task directory에서 plan 1로 이어간다. + +### 범위 결정 근거 + +허용 범위는 generated contract drift 확인/정리와 검증 재실행뿐이다. `.proto` schema, worker/API behavior, Flutter UI, roadmap 문서는 수정하지 않는다. `apps/cli` 로직은 검증 재실행 중 실패가 재현될 때만 해당 실패를 최소 수정한다. + +### 빌드 등급 + +`cloud-G07`: unit test 통과 뒤 real `bin/test`/generated-output drift가 남은 terminal verification trust 회복 작업이다. + +## 구현 체크리스트 + +- [ ] [REVIEW_PAPER_LOOP-1] generated contract drift가 header-only인지 확인하고 정리한 뒤 focused CLI test와 `bin/test` 전체 통과 증거를 남긴다. 검증: `git diff --name-only -- packages/contracts/gen/go/alt/v1/backtest.pb.go packages/contracts/gen/go/alt/v1/common.pb.go packages/contracts/gen/go/alt/v1/market.pb.go packages/contracts/gen/go/alt/v1/paper_trading.pb.go`에서 해당 파일들이 나오지 않고 `bin/test`가 exit 0이어야 한다. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +### REVIEW_PAPER_LOOP-1 + +#### 문제 + +`code_review_cloud_G07_0.log:113`는 `bin/test`가 `bin/contracts-check`에서 멈췄다고 기록한다. 실제 worktree도 `packages/contracts/gen/go/alt/v1/backtest.pb.go:4`, `packages/contracts/gen/go/alt/v1/common.pb.go:4`, `packages/contracts/gen/go/alt/v1/market.pb.go:4`, `packages/contracts/gen/go/alt/v1/paper_trading.pb.go:4`에 계획 범위 밖 `protoc v3.21.12` header drift가 남아 있다. + +#### 해결 방법 + +먼저 아래 diff가 네 파일의 `protoc` header-only 변경인지 확인한다. + +```bash +git diff -- packages/contracts/gen/go/alt/v1/backtest.pb.go packages/contracts/gen/go/alt/v1/common.pb.go packages/contracts/gen/go/alt/v1/market.pb.go packages/contracts/gen/go/alt/v1/paper_trading.pb.go +``` + +header-only drift가 맞으면 현재 checkout의 generator로 정리한다. + +```bash +bin/contracts-gen +``` + +그 다음 generated contract 파일이 더 이상 diff에 나오지 않는지 확인한다. 만약 diff가 header-only가 아니거나 `.proto` 의미 변경으로 보이면 임의로 정리하지 말고 `사용자 리뷰 요청`에 차단 근거를 기록한다. + +#### 수정 파일 및 체크리스트 + +- [ ] `packages/contracts/gen/go/alt/v1/backtest.pb.go` header drift 정리 +- [ ] `packages/contracts/gen/go/alt/v1/common.pb.go` header drift 정리 +- [ ] `packages/contracts/gen/go/alt/v1/market.pb.go` header drift 정리 +- [ ] `packages/contracts/gen/go/alt/v1/paper_trading.pb.go` header drift 정리 +- [ ] `CODE_REVIEW-cloud-G07.md`에 `git diff`, `go test -count=1 ./apps/cli/internal/operator`, `bin/test`의 실제 stdout/stderr 기록 + +#### 테스트 작성 + +새 테스트는 작성하지 않는다. 이 후속은 검증 신뢰 회복이며 기존 focused CLI test와 `bin/test`가 충분한 회귀 경계다. + +#### 중간 검증 + +```bash +git diff --name-only -- packages/contracts/gen/go/alt/v1/backtest.pb.go packages/contracts/gen/go/alt/v1/common.pb.go packages/contracts/gen/go/alt/v1/market.pb.go packages/contracts/gen/go/alt/v1/paper_trading.pb.go +go test -count=1 ./apps/cli/internal/operator +``` + +## 수정 파일 요약 + +| 파일 | 항목 | +|---|---| +| `packages/contracts/gen/go/alt/v1/backtest.pb.go` | REVIEW_PAPER_LOOP-1 | +| `packages/contracts/gen/go/alt/v1/common.pb.go` | REVIEW_PAPER_LOOP-1 | +| `packages/contracts/gen/go/alt/v1/market.pb.go` | REVIEW_PAPER_LOOP-1 | +| `packages/contracts/gen/go/alt/v1/paper_trading.pb.go` | REVIEW_PAPER_LOOP-1 | +| `agent-task/m-paper-trading-command-workflow/01_loop_smoke/CODE_REVIEW-cloud-G07.md` | REVIEW_PAPER_LOOP-1 | + +## 최종 검증 + +```bash +git diff --name-only -- packages/contracts/gen/go/alt/v1/backtest.pb.go packages/contracts/gen/go/alt/v1/common.pb.go packages/contracts/gen/go/alt/v1/market.pb.go packages/contracts/gen/go/alt/v1/paper_trading.pb.go +go test -count=1 ./apps/cli/internal/operator +bin/test +``` + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/agent-task/m-paper-trading-command-workflow/02+01_risk_command/CODE_REVIEW-cloud-G08.md b/agent-task/m-paper-trading-command-workflow/02+01_risk_command/CODE_REVIEW-cloud-G08.md new file mode 100644 index 0000000..f132fcf --- /dev/null +++ b/agent-task/m-paper-trading-command-workflow/02+01_risk_command/CODE_REVIEW-cloud-G08.md @@ -0,0 +1,92 @@ + + +# Code Review Reference - PAPER_RISK + +> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.** +> Complete implementation-owned sections, paste actual verification output, and stop with active files in place for review. +> If user-only input is required, fill `사용자 리뷰 요청` and do not ask the user directly. + +## 개요 + +date=2026-06-05 +task=m-paper-trading-command-workflow/02+01_risk_command, plan=0, tag=PAPER_RISK + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md` +- Task ids: + - `paper-risk-command`: risk guard command workflow +- Completion mode: check-on-pass + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[REVIEW AGENT ONLY]** PASS/WARN/FAIL 판정, log archive, `complete.log`, task archive는 리뷰 에이전트 전용이다. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [PAPER_RISK-1] risk state contract and worker mapping | [ ] | +| [PAPER_RISK-2] CLI risk output keys | [ ] | +| [PAPER_RISK-3] risk fixture/tests | [ ] | + +## 구현 체크리스트 + +- [ ] [PAPER_RISK-1] `Snapshot.Rejected`를 service state와 protobuf state로 additive하게 노출한다. +- [ ] [PAPER_RISK-2] worker/API/CLI mapping이 risk summary를 stable key로 출력하게 한다. +- [ ] [PAPER_RISK-3] risk allow/block fixture 또는 fake API test가 typed status/error key를 검증하게 한다. 검증: `bin/contracts-check`, `go test ./services/worker/...`, `go test ./services/api/...`, `go test ./apps/cli/internal/operator` 통과. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. + +- [ ] PASS/WARN/FAIL 판정을 append한다. +- [ ] active files를 `.log`로 아카이브하고 PASS이면 `complete.log` 작성 후 task directory를 archive로 이동한다. +- [ ] PASS이면 roadmap completion metadata를 보고한다. + +## 계획 대비 변경 사항 + +_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ + +## 주요 설계 결정 + +_구현 에이전트가 주요 설계 결정 사항을 기록한다._ + +## 사용자 리뷰 요청 + +_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 구현 에이전트는 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._ + +- 상태: 없음 +- 사유 유형: 없음 +- 결정 필요: 없음 +- 차단 근거: 없음 +- 실행한 검증/명령: 없음 +- 자동 후속 불가 이유: 없음 +- 재개 조건: 없음 + +## 리뷰어를 위한 체크포인트 + +- protobuf changes must be additive and generated outputs must match. +- risk summary must distinguish clear vs blocked without faking broker behavior. +- API must stay thin and worker-owned runtime must remain worker-owned. + +## 검증 결과 + +### PAPER_RISK-1 중간 검증 +```text +$ bin/contracts-check +(output) +``` + +### 최종 검증 +```text +$ bin/test +(output) +``` + +--- + +> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section?** diff --git a/agent-task/m-paper-trading-command-workflow/02+01_risk_command/PLAN-cloud-G08.md b/agent-task/m-paper-trading-command-workflow/02+01_risk_command/PLAN-cloud-G08.md new file mode 100644 index 0000000..88aaaf0 --- /dev/null +++ b/agent-task/m-paper-trading-command-workflow/02+01_risk_command/PLAN-cloud-G08.md @@ -0,0 +1,181 @@ + + +# Plan - PAPER_RISK + +## 이 파일을 읽는 구현 에이전트에게 + +`CODE_REVIEW-cloud-G08.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 선행 `01_loop_smoke`의 `complete.log`가 없으면 구현을 시작하지 말고 리뷰 준비가 아닌 blocked 상태로 보고한다. 사용자 입력이 필요하면 review stub의 `사용자 리뷰 요청`에 기록하고 직접 질문하지 않는다. + +## 배경 + +현재 status output은 `risk=not_evaluated`로만 안정화되어 있다. 마일스톤은 risk guard 결과를 command workflow에서 typed status/error key로 구분해야 한다. 기존 engine은 rejected orders를 `Snapshot.Rejected`로 보유하지만 service state와 protobuf state에는 노출하지 않는다. + +## 사용자 리뷰 요청 흐름 + +구현 중 범위 충돌이나 사용자 결정이 필요하면 active review stub `사용자 리뷰 요청`에 근거를 기록하고 중단한다. code-review가 사용자 리뷰 전환을 판단한다. + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md` +- Task ids: + - `paper-risk-command`: risk guard command workflow +- Completion mode: check-on-pass + +## 분석 결과 + +### 읽은 파일 + +- `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.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` +- `packages/contracts/proto/alt/v1/paper_trading.proto` +- `packages/domain/backtest/types.go` +- `packages/domain/backtest/types_test.go` +- `services/worker/internal/papertrading/engine.go` +- `services/worker/internal/papertrading/service.go` +- `services/worker/internal/socket/paper.go` +- `services/worker/internal/socket/paper_mapping.go` +- `services/worker/internal/socket/paper_test.go` +- `services/api/internal/socket/paper.go` +- `services/api/internal/socket/paper_test.go` +- `apps/cli/internal/operator/runner.go` +- `apps/cli/internal/operator/output.go` +- `apps/cli/internal/operator/runner_paper_test.go` + +### 테스트 환경 규칙 + +`test_env=local`. contracts/API/worker/operations smoke 문서를 읽었다. Proto schema가 바뀌면 `bin/contracts-gen`, `bin/contracts-check`, `go test ./packages/contracts/gen/go/...`가 필요하다. API는 `go test ./services/api/...`, worker는 `go test ./services/worker/...`, CLI는 `go test ./apps/cli/internal/operator`, 전체는 `bin/test`. + +### 테스트 커버리지 공백 + +- Domain `CheckRisk` unit은 있다. +- Engine rejected orders test가 있지만 service/proto/API/CLI로 rejected/risk summary가 노출되지 않는다. +- risk command/status key 검증 fixture가 없다. + +### 심볼 참조 + +rename/remove 없음. `rg --sort path "RejectedOrder|RiskDecision|PaperTradingState"` 결과상 worker engine/service/socket, contracts, API/CLI parser and runner가 영향권이다. + +### 분할 판단 + +이 subtask는 `02+01_risk_command`이고 `01_loop_smoke` 완료가 선행이다. 선행 `complete.log`는 아직 없다. 구현 시작 전 `agent-task/m-paper-trading-command-workflow/01_loop_smoke/complete.log` 또는 archive 후보를 확인해야 한다. + +### 범위 결정 근거 + +이 작업은 risk summary/read surface까지만 다룬다. explicit order submit/cancel/fill lifecycle은 `03+02_order_lifecycle`에서 다룬다. 고급 risk engine과 실거래 주문 제출은 범위 밖이다. + +### 빌드 등급 + +`cloud-G08`: protobuf additive schema, worker state mapping, API/CLI output이 함께 바뀌며 terminal evidence와 protocol compatibility가 중요하다. + +## 구현 체크리스트 + +- [ ] [PAPER_RISK-1] `Snapshot.Rejected`를 service state와 protobuf state로 additive하게 노출한다. +- [ ] [PAPER_RISK-2] worker/API/CLI mapping이 risk summary를 stable key로 출력하게 한다. +- [ ] [PAPER_RISK-3] risk allow/block fixture 또는 fake API test가 typed status/error key를 검증하게 한다. 검증: `bin/contracts-check`, `go test ./services/worker/...`, `go test ./services/api/...`, `go test ./apps/cli/internal/operator` 통과. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## PAPER_RISK-1 + +### 문제 + +`services/worker/internal/papertrading/engine.go:55`의 `Snapshot.Rejected`가 `service.go:30` State로 복사되지 않고 `paper_trading.proto:36` state에도 risk/rejected field가 없다. + +### 해결 방법 + +`PaperTradingState`에 additive repeated risk/rejected summary field를 추가한다. worker state에 rejected slice를 보존하고 mapping을 추가한다. + +### 수정 파일 및 체크리스트 + +- [ ] `packages/contracts/proto/alt/v1/paper_trading.proto` +- [ ] generated Go/Dart contract outputs via `bin/contracts-gen` +- [ ] `services/worker/internal/papertrading/service.go` +- [ ] `services/worker/internal/socket/paper_mapping.go` + +### 테스트 작성 + +worker paper mapping/service tests에 rejected summary assertion 추가. + +### 중간 검증 + +`bin/contracts-check` + +## PAPER_RISK-2 + +### 문제 + +`apps/cli/internal/operator/runner.go:641`은 risk를 `not_evaluated`로 고정한다. + +### 해결 방법 + +proto risk/rejected summary를 읽어 `risk=clear|blocked`, `risk_rejected_count`, `risk_reason` 등 stable key로 출력한다. key 이름은 fixture와 tests에 고정한다. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/internal/operator/output.go` +- [ ] `apps/cli/internal/operator/runner.go` +- [ ] `apps/cli/internal/operator/runner_paper_test.go` + +### 테스트 작성 + +fake API response에 blocked risk case를 추가해 text/JSONL output을 검증한다. + +### 중간 검증 + +`go test ./apps/cli/internal/operator` + +## PAPER_RISK-3 + +### 문제 + +마일스톤 검증은 허용/차단 case가 typed status/error key로 구분되어야 한다. + +### 해결 방법 + +paper scenario fixture 또는 focused fake API test에 clear and blocked cases를 둔다. blocked는 typed error가 아니라 paper state risk summary로 표현하고, 실제 invalid request는 기존 typed error 경로를 유지한다. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/testdata/operator/*` +- [ ] `apps/cli/internal/operator/runner_paper_test.go` + +### 테스트 작성 + +`TestRunGetPaperTradingStateOutputsRiskFields` 추가. + +### 중간 검증 + +`go test ./services/worker/... && go test ./services/api/... && go test ./apps/cli/internal/operator` + +## 의존 관계 및 구현 순서 + +이 subtask directory는 `02+01_risk_command`이므로 `01_loop_smoke`의 `complete.log`가 필요하다. directory name 외의 추가 dependency는 없다. + +## 수정 파일 요약 + +| 파일 | 항목 | +|---|---| +| `packages/contracts/proto/alt/v1/paper_trading.proto` | PAPER_RISK-1 | +| `packages/contracts/gen/go/alt/v1/paper_trading.pb.go` | PAPER_RISK-1 | +| `apps/client/lib/src/generated/alt/v1/paper_trading*.dart` | PAPER_RISK-1 | +| `services/worker/internal/papertrading/service.go` | PAPER_RISK-1 | +| `services/worker/internal/socket/paper_mapping.go` | PAPER_RISK-1 | +| `services/worker/internal/socket/paper_test.go` | PAPER_RISK-1 | +| `apps/cli/internal/operator/output.go` | PAPER_RISK-2 | +| `apps/cli/internal/operator/runner.go` | PAPER_RISK-2 | +| `apps/cli/internal/operator/runner_paper_test.go` | PAPER_RISK-2, PAPER_RISK-3 | + +## 최종 검증 + +```bash +bin/contracts-check +go test ./services/worker/... +go test ./services/api/... +go test ./apps/cli/internal/operator +bin/test +``` + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/agent-task/m-paper-trading-command-workflow/03+02_order_lifecycle/CODE_REVIEW-cloud-G09.md b/agent-task/m-paper-trading-command-workflow/03+02_order_lifecycle/CODE_REVIEW-cloud-G09.md new file mode 100644 index 0000000..8ca3ee3 --- /dev/null +++ b/agent-task/m-paper-trading-command-workflow/03+02_order_lifecycle/CODE_REVIEW-cloud-G09.md @@ -0,0 +1,92 @@ + + +# Code Review Reference - PAPER_ORDER + +> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.** +> Complete implementation-owned sections, paste actual verification output, and stop with active files in place for review. +> Do not ask the user directly; use `사용자 리뷰 요청` for user-only blockers. + +## 개요 + +date=2026-06-05 +task=m-paper-trading-command-workflow/03+02_order_lifecycle, plan=0, tag=PAPER_ORDER + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md` +- Task ids: + - `paper-order-command`: virtual order lifecycle command +- Completion mode: check-on-pass + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[REVIEW AGENT ONLY]** PASS/WARN/FAIL 판정과 archive는 리뷰 에이전트 전용이다. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [PAPER_ORDER-1] paper order contract | [ ] | +| [PAPER_ORDER-2] worker order lifecycle state | [ ] | +| [PAPER_ORDER-3] API/CLI lifecycle scenario | [ ] | + +## 구현 체크리스트 + +- [ ] [PAPER_ORDER-1] protobuf contract에 paper order command/query messages를 additive하게 추가하고 parser maps/client methods를 갱신한다. +- [ ] [PAPER_ORDER-2] worker paper service가 virtual order submit/cancel/fill simulation state를 in-memory로 관리하고 typed status를 반환한다. +- [ ] [PAPER_ORDER-3] API pass-through와 CLI scenario action이 order id, status transition, fill summary를 출력한다. 검증: `bin/contracts-check`, `go test ./services/worker/...`, `go test ./services/api/...`, `go test ./apps/cli/internal/operator`, `bin/test` 통과. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. + +- [ ] PASS/WARN/FAIL 판정을 append한다. +- [ ] active files를 `.log`로 아카이브하고 PASS이면 `complete.log` 작성 후 task directory를 archive로 이동한다. +- [ ] PASS이면 roadmap completion metadata를 보고한다. + +## 계획 대비 변경 사항 + +_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ + +## 주요 설계 결정 + +_구현 에이전트가 주요 설계 결정 사항을 기록한다._ + +## 사용자 리뷰 요청 + +_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 구현 에이전트는 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._ + +- 상태: 없음 +- 사유 유형: 없음 +- 결정 필요: 없음 +- 차단 근거: 없음 +- 실행한 검증/명령: 없음 +- 자동 후속 불가 이유: 없음 +- 재개 조건: 없음 + +## 리뷰어를 위한 체크포인트 + +- No real broker behavior is introduced. +- Order state transitions are deterministic and tested. +- API remains pass-through; worker owns runtime state. + +## 검증 결과 + +### PAPER_ORDER-1 중간 검증 +```text +$ bin/contracts-check +(output) +``` + +### 최종 검증 +```text +$ bin/test +(output) +``` + +--- + +> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section?** diff --git a/agent-task/m-paper-trading-command-workflow/03+02_order_lifecycle/PLAN-cloud-G09.md b/agent-task/m-paper-trading-command-workflow/03+02_order_lifecycle/PLAN-cloud-G09.md new file mode 100644 index 0000000..3e0a1e0 --- /dev/null +++ b/agent-task/m-paper-trading-command-workflow/03+02_order_lifecycle/PLAN-cloud-G09.md @@ -0,0 +1,194 @@ + + +# Plan - PAPER_ORDER + +## 이 파일을 읽는 구현 에이전트에게 + +`CODE_REVIEW-cloud-G09.md`를 실제 구현과 검증 출력으로 채운다. `02+01_risk_command`의 `complete.log`가 없으면 구현하지 않는다. 사용자에게 직접 질문하지 말고 필요한 결정은 review stub `사용자 리뷰 요청`에 남긴다. + +## 배경 + +현재 paper trading은 strategy run에서 생성된 pending order를 daily bar로 체결한다. 마일스톤의 order lifecycle command는 operator가 virtual order submit/cancel/fill simulation을 command/YAML로 검증할 수 있게 만드는 큰 작업이다. 이는 새 contract/API/worker/CLI surface를 포함한다. + +## 사용자 리뷰 요청 흐름 + +구현 중 범위가 submit/cancel/fill 중 하나로 줄어야 하거나 사용자 결정이 필요하면 review stub에 근거를 기록하고 중단한다. code-review가 사용자 리뷰 전환을 판단한다. + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md` +- Task ids: + - `paper-order-command`: virtual order lifecycle command +- Completion mode: check-on-pass + +## 분석 결과 + +### 읽은 파일 + +- `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.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` +- `packages/contracts/proto/alt/v1/paper_trading.proto` +- `packages/domain/backtest/types.go` +- `services/worker/internal/papertrading/engine.go` +- `services/worker/internal/papertrading/service.go` +- `services/worker/internal/socket/paper.go` +- `services/worker/internal/socket/paper_mapping.go` +- `services/api/internal/socket/paper.go` +- `services/api/internal/workerclient/client.go` +- `apps/cli/internal/operator/client.go` +- `apps/cli/internal/operator/runner.go` +- `apps/cli/internal/operator/scenario.go` +- `apps/cli/internal/operator/runner_paper_test.go` +- `apps/cli/go.mod` +- `services/api/go.mod` +- `services/worker/go.mod` +- `packages/domain/go.mod` + +### 테스트 환경 규칙 + +`test_env=local`. contracts/API/worker/operations smoke 적용. New protobuf messages require `bin/contracts-gen`, `bin/contracts-check`, generated Go tests, API/worker parser registration tests, CLI parser tests, focused module tests, and final `bin/test`. + +### 테스트 커버리지 공백 + +- `OrderIntent`, fill, and risk domain unit tests exist. +- No operator-facing order id/status lifecycle contract exists. +- No worker service state stores submitted/canceled virtual orders outside strategy-generated pending orders. +- No CLI action for submit/cancel/order status exists. + +### 심볼 참조 + +rename/remove 없음. `rg --sort path "OrderIntent|StartPaperTrading|GetPaperTradingState"` shows domain order types are internal and paper runtime surface currently only start/state. + +### 분할 판단 + +This is `03+02_order_lifecycle`; predecessor `02+01_risk_command` must complete first. Missing predecessor `complete.log` is expected at planning time and must be checked before implementation. + +### 범위 결정 근거 + +Implement paper-only virtual order lifecycle. Exclude real broker submission, broker balance sync, high-frequency execution, and production auto execution. Persistence may stay in-memory unless tests prove a durable store is needed; do not add database migrations without explicit review note. + +### 빌드 등급 + +`cloud-G09`: broad additive contract/API/worker/CLI lifecycle surface with ordering/status semantics and high blast radius. + +## 구현 체크리스트 + +- [ ] [PAPER_ORDER-1] protobuf contract에 paper order command/query messages를 additive하게 추가하고 parser maps/client methods를 갱신한다. +- [ ] [PAPER_ORDER-2] worker paper service가 virtual order submit/cancel/fill simulation state를 in-memory로 관리하고 typed status를 반환한다. +- [ ] [PAPER_ORDER-3] API pass-through와 CLI scenario action이 order id, status transition, fill summary를 출력한다. 검증: `bin/contracts-check`, `go test ./services/worker/...`, `go test ./services/api/...`, `go test ./apps/cli/internal/operator`, `bin/test` 통과. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## PAPER_ORDER-1 + +### 문제 + +`paper_trading.proto:16` only has start/state requests. No submit/cancel/order status messages exist. + +### 해결 방법 + +Add paper order messages with order id, account id, instrument, side, quantity, type, optional limit price, status, fill summary. Update generated contracts and parser maps in CLI/API/worker/client. + +### 수정 파일 및 체크리스트 + +- [ ] `packages/contracts/proto/alt/v1/paper_trading.proto` +- [ ] generated Go/Dart outputs via `bin/contracts-gen` +- [ ] `apps/cli/internal/operator/parser_map.go` +- [ ] `services/api/internal/contracts/parser_map.go` +- [ ] `services/worker/internal/contracts/parser_map.go` + +### 테스트 작성 + +Parser map tests must include new messages. + +### 중간 검증 + +`bin/contracts-check` + +## PAPER_ORDER-2 + +### 문제 + +`services/worker/internal/papertrading/service.go:47` stores terminal state only, not operator-submitted orders. + +### 해결 방법 + +Add in-memory paper order registry keyed by account/order id. Submit creates order status, cancel transitions pending order, fill simulation applies existing fill/risk helpers against account state and records fill summary. + +### 수정 파일 및 체크리스트 + +- [ ] `services/worker/internal/papertrading/service.go` +- [ ] `services/worker/internal/socket/paper.go` +- [ ] `services/worker/internal/socket/paper_mapping.go` +- [ ] `services/worker/internal/socket/paper_test.go` +- [ ] `services/worker/internal/papertrading/service_test.go` + +### 테스트 작성 + +Service tests for submit, cancel, fill, invalid account/order id, insufficient cash/position. + +### 중간 검증 + +`go test ./services/worker/...` + +## PAPER_ORDER-3 + +### 문제 + +`apps/cli/internal/operator/scenario.go:44` only supports start/get state paper actions. + +### 해결 방법 + +Add scenario actions for submit/cancel/fill simulation or a single order lifecycle action if simpler. CLI output must include `order_id`, `order_status`, `fill_count` or `fill_summary`. + +### 수정 파일 및 체크리스트 + +- [ ] `services/api/internal/workerclient/client.go` +- [ ] `services/api/internal/socket/paper.go` +- [ ] `services/api/internal/socket/paper_test.go` +- [ ] `apps/cli/internal/operator/client.go` +- [ ] `apps/cli/internal/operator/scenario.go` +- [ ] `apps/cli/internal/operator/runner.go` +- [ ] `apps/cli/internal/operator/output.go` +- [ ] `apps/cli/internal/operator/runner_paper_test.go` +- [ ] `apps/cli/testdata/operator/*` + +### 테스트 작성 + +Fake API CLI lifecycle test and YAML fixture validation. + +### 중간 검증 + +`go test ./services/api/... && go test ./apps/cli/internal/operator` + +## 의존 관계 및 구현 순서 + +This directory is `03+02_order_lifecycle`; only predecessor `02+01_risk_command` is encoded in the path. Do not start until the predecessor has `complete.log`. + +## 수정 파일 요약 + +| 파일 | 항목 | +|---|---| +| `packages/contracts/proto/alt/v1/paper_trading.proto` | PAPER_ORDER-1 | +| parser maps and generated outputs | PAPER_ORDER-1 | +| `services/worker/internal/papertrading/service.go` | PAPER_ORDER-2 | +| `services/worker/internal/socket/paper*.go` | PAPER_ORDER-2 | +| `services/api/internal/workerclient/client.go` | PAPER_ORDER-3 | +| `services/api/internal/socket/paper.go` | PAPER_ORDER-3 | +| `apps/cli/internal/operator/*` | PAPER_ORDER-3 | +| `apps/cli/testdata/operator/*` | PAPER_ORDER-3 | + +## 최종 검증 + +```bash +bin/contracts-check +go test ./services/worker/... +go test ./services/api/... +go test ./apps/cli/internal/operator +bin/test +``` + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/agent-task/m-paper-trading-command-workflow/04+01,02,03_ui_handoff/CODE_REVIEW-local-G04.md b/agent-task/m-paper-trading-command-workflow/04+01,02,03_ui_handoff/CODE_REVIEW-local-G04.md new file mode 100644 index 0000000..dec4745 --- /dev/null +++ b/agent-task/m-paper-trading-command-workflow/04+01,02,03_ui_handoff/CODE_REVIEW-local-G04.md @@ -0,0 +1,91 @@ + + +# Code Review Reference - PAPER_HANDOFF + +> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.** +> Fill implementation-owned sections and verification output. Do not ask the user directly. + +## 개요 + +date=2026-06-05 +task=m-paper-trading-command-workflow/04+01,02,03_ui_handoff, plan=0, tag=PAPER_HANDOFF + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md` +- Task ids: + - `paper-ui-handoff`: paper UI handoff +- Completion mode: check-on-pass + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[REVIEW AGENT ONLY]** PASS/WARN/FAIL 판정과 archive는 리뷰 에이전트 전용이다. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [PAPER_HANDOFF-1] handoff doc paper keys | [ ] | +| [PAPER_HANDOFF-2] handoff tests | [ ] | +| [PAPER_HANDOFF-3] UI candidate/defer split | [ ] | + +## 구현 체크리스트 + +- [ ] [PAPER_HANDOFF-1] paper command workflow keys를 `apps/cli/testdata/operator/headless_validation.md` 또는 existing handoff doc surface에 추가한다. +- [ ] [PAPER_HANDOFF-2] `apps/cli/internal/operator/handoff_test.go`가 paper command, expected output key, 반복 운영 여부, UI defer 사유를 검증하게 한다. +- [ ] [PAPER_HANDOFF-3] Flutter 실화면 구현 없이 UI candidate/defer 항목만 분리한다. 검증: `go test ./apps/cli/internal/operator` 통과. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. + +- [ ] PASS/WARN/FAIL 판정을 append한다. +- [ ] active files를 `.log`로 아카이브하고 PASS이면 `complete.log` 작성 후 task directory를 archive로 이동한다. +- [ ] PASS이면 roadmap completion metadata를 보고한다. + +## 계획 대비 변경 사항 + +_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ + +## 주요 설계 결정 + +_구현 에이전트가 주요 설계 결정 사항을 기록한다._ + +## 사용자 리뷰 요청 + +_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 구현 에이전트는 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._ + +- 상태: 없음 +- 사유 유형: 없음 +- 결정 필요: 없음 +- 차단 근거: 없음 +- 실행한 검증/명령: 없음 +- 자동 후속 불가 이유: 없음 +- 재개 조건: 없음 + +## 리뷰어를 위한 체크포인트 + +- No Flutter screen implementation. +- Handoff doc keys match actual command fixtures. +- UI defer reasons are explicit. + +## 검증 결과 + +### PAPER_HANDOFF-1 중간 검증 +```text +$ go test ./apps/cli/internal/operator +(output) +``` + +### 최종 검증 +```text +$ bin/test +(output) +``` + +--- + +> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section?** diff --git a/agent-task/m-paper-trading-command-workflow/04+01,02,03_ui_handoff/PLAN-local-G04.md b/agent-task/m-paper-trading-command-workflow/04+01,02,03_ui_handoff/PLAN-local-G04.md new file mode 100644 index 0000000..88de703 --- /dev/null +++ b/agent-task/m-paper-trading-command-workflow/04+01,02,03_ui_handoff/PLAN-local-G04.md @@ -0,0 +1,153 @@ + + +# Plan - PAPER_HANDOFF + +## 이 파일을 읽는 구현 에이전트에게 + +`CODE_REVIEW-local-G04.md`를 실제 문서 변경과 검증 출력으로 채운다. predecessors `01`, `02`, `03`의 `complete.log`가 없으면 구현을 시작하지 않는다. 사용자에게 직접 질문하지 않는다. + +## 배경 + +ALT 운영 UI는 headless evidence가 정리된 뒤에만 연다. paper trading command workflow가 반복 상태/action/evidence key를 만든 뒤 UI 후보와 defer 항목을 문서화해야 한다. + +## 사용자 리뷰 요청 흐름 + +문서에 사용자 선택이 필요한 UI 우선순위가 드러나면 review stub `사용자 리뷰 요청`에 기록하고 중단한다. + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md` +- Task ids: + - `paper-ui-handoff`: paper UI handoff +- Completion mode: check-on-pass + +## 분석 결과 + +### 읽은 파일 + +- `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md` +- `agent-ops/rules/project/rules.md` +- `agent-ops/rules/project/domain/operations/rules.md` +- `agent-test/local/rules.md` +- `agent-test/local/operations-smoke.md` +- `apps/cli/testdata/operator/headless_validation.md` +- `apps/cli/internal/operator/handoff_test.go` +- `apps/cli/testdata/operator/paper_trading_state.yaml` +- `apps/cli/testdata/operator/expected/paper_trading_state.jsonl` + +### 테스트 환경 규칙 + +`test_env=local`, operations smoke. Handoff doc/test changes should run `go test ./apps/cli/internal/operator`; final smoke may use `bin/test`. + +### 테스트 커버리지 공백 + +Existing `handoff_test.go` covers headless validation docs for prior scenarios, but paper trading UI handoff coverage needs new command/output key assertions after predecessors complete. + +### 심볼 참조 + +rename/remove 없음. Handoff task is docs/tests only unless predecessor output keys reveal missing docs parser assumptions. + +### 분할 판단 + +This is `04+01,02,03_ui_handoff`. It depends on loop smoke, risk command, and order lifecycle because it must document actual final keys. + +### 범위 결정 근거 + +Do not implement Flutter screens. Do not invent UI layout. Only document command, expected output key, repeated operation status, UI candidate, and defer reason. + +### 빌드 등급 + +`local-G04`: docs/test handoff with low code risk after predecessor evidence exists. + +## 구현 체크리스트 + +- [ ] [PAPER_HANDOFF-1] paper command workflow keys를 `apps/cli/testdata/operator/headless_validation.md` 또는 existing handoff doc surface에 추가한다. +- [ ] [PAPER_HANDOFF-2] `apps/cli/internal/operator/handoff_test.go`가 paper command, expected output key, 반복 운영 여부, UI defer 사유를 검증하게 한다. +- [ ] [PAPER_HANDOFF-3] Flutter 실화면 구현 없이 UI candidate/defer 항목만 분리한다. 검증: `go test ./apps/cli/internal/operator` 통과. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## PAPER_HANDOFF-1 + +### 문제 + +`apps/cli/testdata/operator/headless_validation.md`에는 paper command workflow의 final key set이 아직 정리되지 않았다. + +### 해결 방법 + +predecessor outputs를 기준으로 status, loop, risk, order lifecycle command와 expected output key를 문서화한다. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/testdata/operator/headless_validation.md` + +### 테스트 작성 + +handoff test fixture expectations를 갱신한다. + +### 중간 검증 + +`go test ./apps/cli/internal/operator` + +## PAPER_HANDOFF-2 + +### 문제 + +Handoff 문서 drift를 막을 테스트가 paper keys를 아직 강제하지 않는다. + +### 해결 방법 + +`handoff_test.go`에 paper scenarios and key requirements를 추가한다. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/internal/operator/handoff_test.go` + +### 테스트 작성 + +paper entries missing key/defer reason이면 fail하도록 assertion 추가. + +### 중간 검증 + +`go test ./apps/cli/internal/operator` + +## PAPER_HANDOFF-3 + +### 문제 + +운영 UI gate상 paper trading 화면 후보와 command-only defer 항목을 분리해야 한다. + +### 해결 방법 + +문서에 UI candidate/defer reason column or section을 명시한다. Flutter 파일은 변경하지 않는다. + +### 수정 파일 및 체크리스트 + +- [ ] `apps/cli/testdata/operator/headless_validation.md` + +### 테스트 작성 + +Handoff test가 UI defer reason을 확인한다. + +### 중간 검증 + +`go test ./apps/cli/internal/operator` + +## 의존 관계 및 구현 순서 + +Directory `04+01,02,03_ui_handoff` requires `01_loop_smoke`, `02+01_risk_command`, and `03+02_order_lifecycle` complete logs. No additional dependency is encoded. + +## 수정 파일 요약 + +| 파일 | 항목 | +|---|---| +| `apps/cli/testdata/operator/headless_validation.md` | PAPER_HANDOFF-1, PAPER_HANDOFF-3 | +| `apps/cli/internal/operator/handoff_test.go` | PAPER_HANDOFF-2 | + +## 최종 검증 + +```bash +go test ./apps/cli/internal/operator +bin/test +``` + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/apps/cli/internal/operator/output.go b/apps/cli/internal/operator/output.go index ec2adfc..46117e1 100644 --- a/apps/cli/internal/operator/output.go +++ b/apps/cli/internal/operator/output.go @@ -49,6 +49,13 @@ type StepEvent struct { Cash string PositionCount int FillCount int + Risk string + + // Paper loop equity summary. EquityPointCount is the length of the paper + // equity curve and LatestEquity is the equity amount of its last point. + // They are omitted for an empty curve so loop smoke evidence stays stable. + EquityPointCount int + LatestEquity string } // RunSummary is the final record describing a whole scenario run. @@ -128,6 +135,15 @@ func (o *Writer) WriteStep(ev StepEvent) { } fields["position_count"] = ev.PositionCount fields["fill_count"] = ev.FillCount + if ev.Risk != "" { + fields["risk"] = ev.Risk + } + if ev.EquityPointCount > 0 { + fields["equity_point_count"] = ev.EquityPointCount + } + if ev.LatestEquity != "" { + fields["latest_equity"] = ev.LatestEquity + } } o.writeJSON(fields) return @@ -176,6 +192,15 @@ func (o *Writer) WriteStep(ev StepEvent) { line += fmt.Sprintf(" cash=%s", ev.Cash) } line += fmt.Sprintf(" position_count=%d fill_count=%d", ev.PositionCount, ev.FillCount) + if ev.Risk != "" { + line += fmt.Sprintf(" risk=%s", ev.Risk) + } + if ev.EquityPointCount > 0 { + line += fmt.Sprintf(" equity_point_count=%d", ev.EquityPointCount) + } + if ev.LatestEquity != "" { + line += fmt.Sprintf(" latest_equity=%s", ev.LatestEquity) + } } fmt.Fprintln(o.w, line) } diff --git a/apps/cli/internal/operator/runner.go b/apps/cli/internal/operator/runner.go index ddfb347..0bfc858 100644 --- a/apps/cli/internal/operator/runner.go +++ b/apps/cli/internal/operator/runner.go @@ -643,10 +643,18 @@ func evaluatePaper(ev StepEvent, step Step, errInfo *altv1.ErrorInfo, state *alt ev.Cash = state.GetCash().GetAmount().GetValue() ev.PositionCount = len(state.GetPositions()) ev.FillCount = len(state.GetFills()) + ev.Risk = "not_evaluated" if run := state.GetRun(); run != nil { ev.RunID = run.GetId() ev.RunStatus = strings.ToLower(strings.TrimPrefix(run.GetStatus().String(), "BACKTEST_RUN_STATUS_")) } + // Summarise the equity curve so loop smoke output carries a stable + // point count and the latest equity value. An empty curve leaves both + // fields zero/empty so they are omitted from text and JSONL. + if curve := state.GetEquityCurve(); len(curve) > 0 { + ev.EquityPointCount = len(curve) + ev.LatestEquity = curve[len(curve)-1].GetEquity().GetAmount().GetValue() + } } if step.Expect.RunStatus != "" && state.GetRun() != nil { diff --git a/apps/cli/internal/operator/runner_paper_test.go b/apps/cli/internal/operator/runner_paper_test.go index 6dd6e46..3e85bad 100644 --- a/apps/cli/internal/operator/runner_paper_test.go +++ b/apps/cli/internal/operator/runner_paper_test.go @@ -31,6 +31,7 @@ func TestPaperTradingFixtureIsValid(t *testing.T) { scanner := bufio.NewScanner(f) sawAccount := false sawSummary := false + sawEquity := false for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if line == "" { @@ -45,6 +46,11 @@ func TestPaperTradingFixtureIsValid(t *testing.T) { } if rec["account_id"] == "paper-1" { sawAccount = true + if _, ok := rec["equity_point_count"]; ok { + if _, ok := rec["latest_equity"]; ok { + sawEquity = true + } + } } if rec["type"] == "summary" { sawSummary = true @@ -59,6 +65,9 @@ func TestPaperTradingFixtureIsValid(t *testing.T) { if !sawSummary { t.Error("expected fixture missing a summary line") } + if !sawEquity { + t.Error("expected fixture missing equity_point_count/latest_equity on a paper line") + } } func paperState(accountID string) *altv1.PaperTradingState { @@ -75,6 +84,10 @@ func paperState(accountID string) *altv1.PaperTradingState { Fills: []*altv1.BacktestTrade{ {InstrumentId: "KRX:005930", Side: "buy", Price: &altv1.Price{Amount: &altv1.Decimal{Value: "1050"}}}, }, + EquityCurve: []*altv1.BacktestEquityPoint{ + {TimestampUnixMs: 1746057600000, Equity: &altv1.Price{Amount: &altv1.Decimal{Value: "10000000"}}}, + {TimestampUnixMs: 1747267200000, Equity: &altv1.Price{Amount: &altv1.Decimal{Value: "10000100"}}}, + }, } } @@ -111,6 +124,9 @@ func TestRunStartPaperTradingOutputsAccountState(t *testing.T) { "cash=9998950", "position_count=1", "fill_count=1", + "risk=not_evaluated", + "equity_point_count=2", + "latest_equity=10000100", } { if !strings.Contains(out, want) { t.Errorf("output %q missing %q", out, want) @@ -151,9 +167,12 @@ func TestRunGetPaperTradingStateOutputsFields(t *testing.T) { if code != codeOK { t.Fatalf("exit code = %d, want 0 (out=%q)", code, out) } - if !strings.Contains(out, "account_id=paper-1") || !strings.Contains(out, "position_count=1") { + if !strings.Contains(out, "account_id=paper-1") || !strings.Contains(out, "position_count=1") || !strings.Contains(out, "risk=not_evaluated") { t.Errorf("output %q missing paper state fields", out) } + if !strings.Contains(out, "equity_point_count=2") || !strings.Contains(out, "latest_equity=10000100") { + t.Errorf("output %q missing equity summary fields", out) + } got := api.lastGetPaperStateReq() if got == nil { diff --git a/apps/cli/testdata/operator/expected/paper_trading_state.jsonl b/apps/cli/testdata/operator/expected/paper_trading_state.jsonl index d0bacb1..dd36922 100644 --- a/apps/cli/testdata/operator/expected/paper_trading_state.jsonl +++ b/apps/cli/testdata/operator/expected/paper_trading_state.jsonl @@ -1,4 +1,4 @@ {"action":"import_daily_bars","bar_count":2,"instrument_count":1,"provider":"kis","scenario":"paper_trading_state","status":"ok","step":"import_kr_daily_bars","type":"step"} -{"account_id":"paper-1","action":"start_paper_trading","cash":"9998950","fill_count":1,"position_count":1,"run_id":"paper-paper-1-1","run_status":"succeeded","scenario":"paper_trading_state","status":"ok","step":"start","type":"step"} -{"account_id":"paper-1","action":"get_paper_trading_state","cash":"9998950","fill_count":1,"position_count":1,"run_id":"paper-paper-1-1","run_status":"succeeded","scenario":"paper_trading_state","status":"ok","step":"state","type":"step"} +{"account_id":"paper-1","action":"start_paper_trading","cash":"9998950","equity_point_count":2,"fill_count":1,"latest_equity":"10000100","position_count":1,"risk":"not_evaluated","run_id":"paper-paper-1-1","run_status":"succeeded","scenario":"paper_trading_state","status":"ok","step":"start","type":"step"} +{"account_id":"paper-1","action":"get_paper_trading_state","cash":"9998950","equity_point_count":2,"fill_count":1,"latest_equity":"10000100","position_count":1,"risk":"not_evaluated","run_id":"paper-paper-1-1","run_status":"succeeded","scenario":"paper_trading_state","status":"ok","step":"state","type":"step"} {"exit_code":0,"passed":3,"scenario":"paper_trading_state","status":"ok","steps":3,"type":"summary"}