Files
trex-core/docs/batches/bat-011_20260607_safety-sell-triggers/verification.md
T
genichinandClaude Sonnet 4.6 0082d3b5da fix(kis): REQ-038 현재가 tr_id 정정 + REL-003 확정 + dcy-008 kill-switch Discovery
## REQ-038 CHG-04/05: KIS 시세 tr_id 정정 (FHKST01010100)
- kis.py _tr_price(): TTTC8397R/VTTC8397R → FHKST01010100 (실전/모의 공용)
  배포 전 실 KIS LIVE 진단에서 구 tr_id가 rt_cd=1 "없는 서비스 코드"로 거부됨을
  확인 — stop-loss/take-profit이 LIVE에서 조용히 미발동하는 결함이었음.
  FHKST01010100으로 정정 후 get_current_price('005930')=329000(rt_cd=0) 확인.
- test_kis_price.py: AC-7 테스트 정정 (FHKST01010100 공용 검증)
- REQ-038: CHG-04/05 Change Log 추가, Requirement/AC-7/Notes 정정
- BAT-011 implementation.md: LIVE 검증 및 tr_id 정정 이력 추가
- BAT-011 verification.md: AC-7 evidence를 CHG-04 정정 버전으로 갱신
- docs/srs/index.md: CHG-04/05 Change Log 항목 추가

## REL-003: core 자율 안전 매도 release 문서 생성
- docs/releases/rel-003_20260607_core-autonomous-safety-sell.md 신규 생성
  (BAT-010 + BAT-011, app-service profile, Status: confirmed)
- docs/releases/index.md: REL-003 행 추가

## dcy-008: 비상 정지/강제 청산(kill-switch) Discovery 초안
- docs/discovery/dcy-008_20260607_emergency-stop-kill-switch.md 신규 생성
  GitHub #3 기반; SlotService.sell() 재사용, 당일 전략 제외 day-scoped
  FR 6개, NFR 3개, OQ 4개 (트리거 표면/영속 방식/수동 해제 결정 필요)
- docs/discovery/index.md: dcy-008 행 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 10:17:36 +09:00

5.4 KiB
Raw Blame History

BAT-011 Verification

  • Status: verified
  • Batch: BAT-011

Acceptance Mapping

REQ-037 (forced_close_at 만기 자동 매도 루프)

AC Evidence
AC-1: 만기+워치독 만료 → sell() test_safety_sell_worker.py::TestForcedClose::test_expired_past_due_sells
AC-2: 미만기(now+1h) → 미호출 test_future_not_due_no_sell
AC-3: 워치독 활성 → 미호출(보호) test_watchdog_active_protected
AC-4: forced_close_at None → 제외 test_no_forced_close_excluded
AC-5: pending_sell 중복 미호출 test_idempotent_on_pending_sell (transition_log PENDING_SELL 1건)
AC-6: interval 주기 TestRunOnce::test_base_tick_is_finest_interval + safety_sell.base_tick_sec/run_once _due 캐던스(코드)
grace 보호 test_grace_period_defers

REQ-038 (stop-loss·take-profit KIS polling + 트리거)

AC Evidence
AC-1: stck_prpr ≤ stop_loss → 손절 TestPriceTriggers::test_stop_loss_triggers
AC-2: stck_prpr ≥ take_profit → 익절 test_take_profit_triggers
AC-3: 두 조건 미충족 → 미호출 test_neither_condition_no_sell
AC-4: 워치독 활성 → KIS 호출 0 test_watchdog_active_no_kis_call (broker.calls == [])
AC-5: 임계값 None → 제외 test_no_thresholds_excluded
AC-6: pending_sell 중복 미호출 test_idempotent_on_pending_sell
AC-7 (CHG-04): 시세 tr FHKST01010100(실전/모의 공용) + stck_prpr test_kis_price.py::test_tr_price_is_quotations_tr + test_get_current_price_parses_stck_prpr; 실 KIS LIVE 검증: get_current_price('005930')=Decimal('329000')(rt_cd=0). 구 TTTC8397R 는 LIVE rt_cd=1 "없는 서비스 코드" 로 폐기
AC-8: 시간당 호출 ≤ N×(3600/interval) test_quota_estimate(N=3,interval=30→360) + test_only_eligible_slots_polled(워치독 만료+임계 슬롯만 poll)
가격 미수신 → skip test_price_unavailable_skips

REQ-039 (장 마감 강제 청산)

AC Evidence
AC-1: 시각 도래 → 전체 holding sell() TestMarketClose::test_time_reached_liquidates_all
AC-2: 워치독 활성 포함 청산 test_watchdog_active_included
AC-3: 미설정 → 미동작 test_not_configured_no_sell
AC-4: 거래일 1회 발동 가드 test_once_per_day_guard
AC-5: pending_sell 중복 미호출 REQ-036 idempotency(SlotService.sell) — test_service_sell.py::test_sell_idempotent_on_pending_sell 승계, 청산 경로 동일 sell() 사용
AC-6: grace period 무관 청산 test_grace_period_does_not_block
발동 시각 이전 → 미동작 test_before_time_no_sell

REQ-040 (update_thresholds intent RPC)

AC Evidence
AC-1: stop_loss_price 갱신 test_update_thresholds_handler.py::test_updates_stop_loss
AC-2: take_profit + forced_close 갱신 test_updates_take_profit_and_forced_close
AC-3: last_seen_at 리셋 test_resets_watchdog_last_seen
AC-4: 부분 갱신(미포함 유지) test_partial_update_keeps_other_fields
AC-5: null → 해제 test_explicit_null_clears
AC-6: non-holding → ignored/not_holding test_non_holding_ignored
AC-7: reply_to → updated 응답 test_reply_updated_status
미존재 슬롯 → ignored/slot_not_found test_unknown_slot_ignored

REQ-042 (baseline 문서 정합)

AC Evidence
AC-1: interface-contract update_thresholds 계약 docs/interface-contract.md trex.intent.req update_thresholds 액션 블록 + Patterns 행
AC-2: interface-contract price 선택 필드 buy payload 에 stop_loss_price/take_profit_price 추가
AC-3: runtime-flows 4종 흐름 docs/runtime-flows.md 워치독 갱신/forced_close/가격 체크/장 마감 흐름 4종 추가
AC-4: runtime-flows A-5 주석 갱신 broker degrade 흐름의 "A-5 미구현" → dcy-007 REQ-037~041 해소로 갱신
AC-5: project-structure trex-safety-sell 스레드 docs/project-structure.md 7 스레드 목록 + safety_sell.py/watchdog.py 모듈 + 변경 로그

Evidence

  • Test:
    • 신규 테스트 38종 green (test_kis_price 7 + test_safety_sell_worker 23 + test_update_thresholds_handler 8).
    • 단위 전체 회귀: 236 passed / 23 skipped(::test_sandbox_token_and_submit deselect — .env=LIVE 산물).
    • 인프라 게이트(PG trex_core_test + RabbitMQ): 259 passed(마이그레이션 001~004 적용 + PG repo round-trip 포함).
    • ruff check trex_core tests → All checks passed.
  • Manual:
    • 없음(트리거 로직은 결정적 단위 테스트로 커버; 실 KIS 라이브 트리거는 운영 실증 이월).
  • Logs:
    • 236 passed, 23 skipped, 1 deselected in ~0.8s / 259 passed ... in ~11s.

Carried-Over Items

  • BAT-010 R-2 (실 PostgreSQL 004_add_price_thresholds.sql round-trip): 해소 — 인프라 게이트 259 passed(마이그레이션 적용 + PG repo 테스트 green)로 확인.
  • 운영 실증 이월(차기 거래일): stop-loss·take-profit·forced_close·장 마감의 실 KIS 라이브 트리거 1건 관찰. 휴장/운영 제약으로 본 batch 는 mock·정적 검증까지. release feedback 으로 추적.

Result

  • Ready for Release: true
  • Blocking Issues:
    • 없음. 잔여(실 KIS 라이브 트리거 운영 실증)는 blocker 아님 — paper/mock 결정적 검증 + KIS 어댑터 tr_id/파싱 단위 검증으로 release gate 충족. 차기 거래일 운영 관찰로 보강(REL feedback).