자동매매봇 구현 인계
다른 Claude Code 세션에서 이어받기 위한 상태 기록.
한 줄 요약
19티켓 중 18건이 main 머지 완료. BE-34·BE-16 은 커밋·검증까지 끝나고 codex 리뷰 대기, BE-33·BE-17 은 미착수다.
이어받는 법
# 1. 현재 run 확인 — 티켓 노드 상태가 여기 있다
~/.harness/bin/harness run status
# 2. 다음 티켓 실행 (한 번에 하나. 메모리 여유 없으면 더 줄인다)
cd ~/.harness && ./bin/harness run dispatch --max-parallel 1 --only "implement[BE-33]"- run id:
private-feature-20260830-140013 - 대상 레포:
/Users/biuea/stock-application(origin/main=239b19a) - 워크트리 루트:
/Users/biuea/stock-application-worktrees/ - 티켓 경로는 이 볼트를 직접 가리키게 재지정했다. 세션 scratchpad 의존은 없다.
티켓 상태
| 티켓 | 상태 | 비고 |
|---|---|---|
| DB-01·BE-01~09 | ✅ 머지 | PR #194~#203 |
| BE-27~32·DB-02 | ✅ 머지 | PR #204~#210 (wave 1) |
| BE-10·11·12 | ✅ 머지 | PR #211~#213 |
| BE-19·23·25·26 | ✅ 머지 | PR #214~#217 (wave 2) |
| BE-24 | ✅ 머지 | PR #218 |
| BE-13·14·15 | ✅ 머지 | PR #219~#221 (wave 4) |
| BE-34 | 커밋 2b3e772 | 이 과제 마지막 p0 (제안 이중 집행) 포함. 검증 통과, 리뷰 대기 |
| BE-16 | 커밋 ca7001c+ | Controller·스케줄러. 검증 통과, 리뷰 대기 |
| BE-33 | 미착수 | Rich Domain 관용구 + LiveTradeExecutor 의 order.domain 교차 참조 제거 |
| BE-17 | 미착수 | E2E 격리 시나리오 |
폐기: BE-18·20·21·22 는 후속 DAG 가 BE-30·28·32·29·DB-02·BE-25 로 흡수했다. 실행하지 않는다.
바로 다음에 할 일 — wave 5 재작업 (리뷰 1차 완료, REQUEST_CHANGES)
codex 1차 리뷰를 이미 돌렸다. 전문: Tickets/_rework/review-prompts/wave5-codex-verdict.md
verdict: REQUEST_CHANGES — p0 3건 · p1 2건. 그중 p0-1 은 이 세션에서 고쳤다(커밋 1ebbd16). 남은 4건이 다음 세션 작업이다.
고침 (커밋 1ebbd16)
[BE-16] p0 중복→ 중복 블록 제거. 앞선 커밋에서 “크론 설정이 없다” 고 오판해 블록을 추가했는데 아래쪽에 이미 있었다. 테스트가 못 잡은 이유: ① 스케줄러 테스트가 중복 키를 허용하는 기본autotrading.schedulerYAML 키로 운영 기동 실패Yaml()로 직접 읽는다 ②src/test/resources/application.yml이 운영 파일을 가린다. 전체 테스트 통과와 실제 기동 실패가 공존했다.
남은 것 — BE-34 3건 · BE-16 1건
| 등급 | 티켓 | 내용 |
|---|---|---|
| p0 | BE-34 | 수동 승인 경로가 선점 커밋 전에 외부 주문을 제출한다. ApproveOrderProposalUseCase 의 단일 트랜잭션 안에서 선점 저장과 브로커 호출이 함께 돈다. 브로커 호출 후 롤백되면 선점도 사라져 재시도가 같은 실주문을 다시 낸다. 경합 테스트도 전체 승인 경로를 하나의 TransactionTemplate 로 감싸 “외부 호출 전 커밋” 을 검증하지 않는다 — 지금 1회인 건 DB 락 덕이지 durable claim 덕이 아니다 |
| p0 | BE-34 | 집행 실패 종목의 당일 재진입 차단 미구현. 실패 원장을 당일·모드·심볼로 조회하는 API 도, RiskRejectReason 의 제외 사유도 없다. ACCEPTANCE_UNCONFIRMED 기록 후 다음 사이클에 같은 종목이 다시 제안된다. 티켓의 당일 제외·익일 해제 요구가 통째로 빠졌다 |
| p1 | BE-34 | 실패한 제안이 AUTO_EXECUTED + fillId=null 로 남는다. OrderProposalStatus 에 티켓이 요구한 EXECUTION_FAILED 가 없어 완료와 재조정 필요가 구분되지 않는다 |
| p1 | BE-16 | 존재하지 않는 제안 승인이 404 가 아니라 400 을 반환한다. 테스트도 잘못된 400 을 고정하고 있다 |
리뷰가 확인해 준 것 (재작업 불필요)
후보별 TX1 → 트랜잭션 밖 브로커 호출 → TX2 분리 · recovery 포지션·체결 저장 · ExecutionFailure.record() · releaseProtection·보호 점검·단계 평가의 프로덕션 호출부 · 조작 토큰 거부 기본 · execution_claimed 의 expand 호환과 실행 가능한 롤백.
재리뷰 실행법
codex exec --skip-git-repo-check --ephemeral \
-o /tmp/wave5-review.json \
-C /private/tmp/wt-wave4 -s read-only -m gpt-5.6-sol \
-c 'model_reasoning_effort="high"' \
-- "$(cat '/Users/biuea/Desktop/dpdpdndn/프로젝트/주식앱/자동매매봇/Tickets/_rework/review-prompts/wave5-codex-prompt.txt')" < /dev/null통합 워크트리(/private/tmp/wt-wave4, 브랜치 integ/wave5)가 없으면 다시 만든다:
git fetch origin
git worktree add /private/tmp/wt-wave4 -b integ/wave5 origin/main # 이미 있으면 checkout -B
cd /private/tmp/wt-wave4 && git merge --no-edit feat/BE-34 && git merge --no-edit feat/BE-16리뷰가 BLOCKED — 리뷰 미실행 을 내면 메모리 부족이다 (도구 호스트가 못 뜬다). 아래 §6 정리를 먼저 하고 재실행한다.
BE-34·BE-16 남은 절차
BE-34·BE-16 은 커밋·검증이 끝났고 codex 리뷰만 남았다. 프롬프트를 그대로 보관해 뒀으니 이어서 실행하면 된다:
codex exec --skip-git-repo-check --ephemeral \
-o /tmp/wave5-review.json \
-C /private/tmp/wt-wave4 -s read-only -m gpt-5.6-sol \
-c 'model_reasoning_effort="high"' \
-- "$(cat '/Users/biuea/Desktop/dpdpdndn/프로젝트/주식앱/자동매매봇/Tickets/_rework/review-prompts/wave5-codex-prompt.txt')" < /dev/null통합 워크트리(/private/tmp/wt-wave4, 브랜치 integ/wave5)가 없으면 다시 만든다:
git fetch origin
git worktree add /private/tmp/wt-wave4 -b integ/wave5 origin/main # 이미 있으면 checkout -B
cd /private/tmp/wt-wave4 && git merge --no-edit feat/BE-34 && git merge --no-edit feat/BE-16리뷰가 BLOCKED — 리뷰 미실행 을 내면 메모리 부족이다 (도구 호스트가 못 뜬다). 아래 §6 정리를 먼저 하고 재실행한다.
APPROVED 면 PR 2건 생성 → 머지. PR 본문 형식은 이전 PR(#218~#221)을 참고한다.
BE-34·BE-16 남은 절차
통합 브랜치 integ/wave5(/private/tmp/wt-wave4)에서 검증은 끝났다:
order191 tests / 0 failures,autotrading763 tests / 0 failures, 둘 다 exit 0
남은 건 codex 리뷰 → PR 2건 → 머지다. 리뷰 프롬프트는 _rework/ 옆에 없으니 아래 규칙으로 새로 쓴다.
반드시 지킬 것 (이 과제에서 실제로 사고가 난 것들)
-
테스트는 두 패키지를 모두 돌린다.
*autotrading*만 쓰면order패키지가 통째로 빠진다. 실제로 그 함정에 걸려 구현과 테스트가 모순인 채 “통과” 로 보고된 적이 있다../gradlew test -Dkotest.filter.specs='com.biuea.stock.order.*' ./gradlew test -Dkotest.filter.specs='*autotrading*'BUILD SUCCESSFUL만 보지 말고 XML 의tests=건수를 확인한다 (0건 실행도 SUCCESSFUL 이다). -
통합 브랜치에서 검증한다. 개별 티켓만 통과하고 합치면 깨지는 사고가 4번 났다 — DB-02 의
NOT NULL, BE-28 의 낡은 기대값, BE-11 의 Fake 계약, BE-16 의@Scheduled플레이스홀더. -
리뷰는 codex 로 한다 (
review.code). Claude 단일 런타임 리뷰로 wave 를 닫지 않는다. 이 과제에서 codex 가 p0 30건 이상을 잡았고, 대부분 “테스트는 통과하는데 프로덕션이 부르지 않는” 종류였다. -
리뷰 지적을 정답지로 삼지 않는다. codex 도 두 번 틀렸다 (없는 파일 경로 인용, DTO 래퍼 오판). 외부 API 는 스펙 원문과 대조한다:
curl -s https://openapi.tossinvest.com/openapi-docs/latest/openapi.json -
거짓 완료를 확인한다. harness 가 이전
result.json을 재사용해 “완료” 로 표시한 적이 있다. 커밋 해시가 실제로 바뀌었는지 본다. -
메모리: 테스트 후 Gradle 워커와 Testcontainers 고아를 정리한다. 안 하면 누적돼 디스패치가 죽는다.
ps -eo pid,command | grep -E "[k]otest.filter|[g]radle.internal.worker|[G]radleDaemon" | awk '{print $1}' | xargs -r kill -9 docker ps --format '{{.Names}}\t{{.Image}}' | grep "mysql:8.0" | cut -f1 | xargs -r docker rm -f
BE-33·BE-17 착수 시
두 티켓 모두 ## 필수 배선 절이 있다 — 누락 시 반려다. BE-33 은 LiveTradeExecutor 의 order.domain 타입 7개 직접 참조 제거가 핵심이다 (autotrading 도메인에 남은 마지막 교차 참조).
Document History
| 날짜 | 변경 내용 |
|---|---|
| 2026-09-07 | 세션 인계용 최초 작성 |