Files
trex-core/docs/srs/Interface/req-045_kill-switch-execution.md
T

6.7 KiB
Raw Blame History

req-045: kill-switch 실행 — 범위별 holding 즉시 청산 + 이력 로깅

  • Status: Implemented
  • Type: Interface
  • Priority: High
  • Owner: project maintainers

Intent

운영자가 trex.control.req 에 action: "kill_switch" 를 발행하면 대상 범위(portfolio 단위 또는 전역)의 모든 holding 슬롯을 즉시 청산한다. 기존 SlotService.sell()(REQ-036)을 재사용해 순차 매도를 제출하고, 같은 발동에서 대상 범위를 당일 제외(REQ-044/046)로 표시한다. 자율 안전 매도(dcy-007)와 독립적으로 동작하며, 발동 이력을 로깅한다(dcy-008 FR-1/4/5/6, NFR-1/2).

Requirement

  • action: "kill_switch" payload: {action, scope: "portfolio"|"global", portfolio_id?(scope=portfolio 시 필수), actor?}.
  • 발동 시 대상 범위의 모든 holding 슬롯에 SlotService.sell(actor="kill-switch", reason="emergency_stop") 을 순차 호출한다.
    • scope=portfolio: 해당 portfolio_id 의 holding 슬롯만.
    • scope=global: 당일 전체 holding 슬롯.
  • 이미 pending_sell 인 슬롯은 중복 sell 하지 않는다(REQ-036 idempotency).
  • 발동과 동시에 대상 범위를 당일 제외로 표시한다(REQ-044 store 의 exclude(...) 호출). masking 동작 자체는 REQ-046.
  • 발동 이력(actor, 발동 시각, scope, portfolio_id, 처리 슬롯 수)을 데몬 로그에 1건 기록한다.
  • 응답: {status: "ok", scope, portfolio_id?, liquidated: <처리 슬롯 수>}. scope=portfolio 인데 portfolio_id 누락 시 {status: "error", reason: "portfolio_id_required"}.
  • kill-switch 실행은 자율 안전 매도 루프(dcy-007)와 상태/스레드를 공유하지 않으며 서로 영향을 주지 않는다.

Acceptance Criteria

  1. Given holding 슬롯 N개(전역), When {action:"kill_switch", scope:"global"} 처리, Then N개 모두 holding→pending_sell(actor=kill-switch, reason=emergency_stop) 전이되고 응답 liquidated=N.
  2. Given portfolio pf-A 에 holding 2개 + pf-B 에 holding 1개, When {action:"kill_switch", scope:"portfolio", portfolio_id:"pf-A"}, Then pf-A 2개만 청산되고 pf-B 는 holding 유지.
  3. Given 대상 중 이미 pending_sell 인 슬롯, When kill_switch 처리, Then 그 슬롯에 중복 sell 호출이 없다(REQ-036 idempotency, transition_log 중복 없음).
  4. Given scope=portfolio 인데 portfolio_id 누락, When 처리, Then {status:"error", reason:"portfolio_id_required"}.
  5. Given kill_switch 발동, When 처리 완료, Then 대상 범위가 REQ-044 store 에 당일 제외로 기록된다(list_excluded(today) 에 포함).
  6. Given kill_switch 발동, When 로그를 확인, Then actor/발동 시각/scope/portfolio_id/처리 슬롯 수를 담은 이력 1건이 기록된다.
  7. Given 자율 안전 매도 루프(dcy-007)가 동작 중, When kill_switch 가 발동, Then 두 경로가 독립적으로 동작하며(REQ-036 idempotency 로 충돌 없음) safety-sell 루프가 중단/오류 없이 유지된다.
  8. Given holding N개, When kill_switch 처리, Then 전체 sell() 제출 완료까지 지연이 N×100ms + 5s 이내이다(순차, outbox 전송 제외; A-4 N<10 가정).

Impacted Area

  • Docs:
    • docs/runtime-flows.md — kill-switch 발동 흐름(트리거→순차 sell()→당일 제외 표시) (REQ-047 처리)
    • docs/interface-contract.md — kill_switch payload/응답 계약 (REQ-047 처리)
  • Modules:
    • trex_core/application/messaging_handlers.py — kill_switch handler(REQ-043 dispatch 하위)
    • trex_core/domain/slot/service.py 또는 신규 application 서비스 — 범위별 holding 조회 + 순차 sell() 진입점
    • REQ-044 store 연동(당일 제외 표시)
  • Tests:
    • kill_switch handler 단위 테스트(전역/portfolio/idempotency/portfolio_id 누락/이력 로깅/독립성)

Notes

  • NFR-1(지연)·NFR-2(dcy-007 독립)는 본 REQ AC-8/AC-7 로 흡수(별도 REQ 미승격 — 독립 backlog 가치 낮음, dcy-008 정합).
  • pending_buy 슬롯 처리는 dcy-008 OQ-3 Deferred → 기본 구현은 HOLDING 만 대상. pending_buy 롤백은 후속(REQ 추가 또는 change-req).
  • R-1(큐 부하): sell()은 PENDING_SELL 전이(DB write 1회)로 빠름. execution worker 순차 처리 유지.
  • R-3(브로커 오류): sell()→PENDING_SELL 성공 시 기존 outbox retry 가 eventual consistency 보장.

Change Log

CHG-20260607-01

  • Date: 2026-06-07
  • Author: Justin Ko

Change Summary

  • dcy-008(confirmed) → REQ-045 초안 생성.

Intent

  • kill-switch 즉시 청산(FR-1/4/5/6)과 NFR-1/2 흡수를 Interface REQ 로 정규화.

Acceptance Criteria Delta

  • Added: AC-1~8 전체

Impacted Area Delta

  • Docs: runtime-flows.md, interface-contract.md (REQ-047)
  • Modules: messaging_handlers.py, service.py(또는 신규 서비스), REQ-044 store 연동
  • Tests: kill_switch handler 단위

Delivery Trace Delta

  • Batches: none (미할당)
  • Releases: none

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: keep-current
  • Follow-up Action: confirm-req 로 승인.

CHG-20260607-02

  • Date: 2026-06-07
  • Author: Justin Ko

Change Summary

  • Proposed → Approved (confirm-req).

Intent

  • 승인 게이트 통과: 필수 필드·구체 AC(1~8)·Impacted Area·Change Log 완비. dcy-008(confirmed) 범위와 모순 없음. NFR-1/2 흡수, OQ-3(pending_buy) REQ Deferred 는 비핵심 후속으로 승인 blocker 아님(기본 구현 HOLDING 한정).

Acceptance Criteria Delta

  • (변경 없음)

Impacted Area Delta

  • (변경 없음)

Delivery Trace Delta

  • Batches: none (미할당)
  • Releases: none

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: keep-current
  • Follow-up Action: suggest-batch-reqs / draft-batch 로 delivery 편성.

CHG-20260607-03

  • Date: 2026-06-07
  • Author: Justin Ko

Change Summary

  • Status Approved → Implemented (confirm-req-implemented, 근거 batch BAT-012 release-candidate).

Intent

  • BAT-012 verification 의 AC↔evidence(실행 6 단위: 전역/portfolio 범위/idempotency/당일 제외 표시/resume 비가역/no-holding + e2e kill_switch global liquidated=2 → closed, emergency_stop reason)로 AC-1~8 충족. NFR-1/2 흡수 확인.

Acceptance Criteria Delta

  • (변경 없음)

Impacted Area Delta

  • (변경 없음)

Delivery Trace Delta

  • Batches: BAT-012 (release-candidate)
  • Releases: none

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: keep-current (Implemented)
  • Follow-up Action: draft-release 로 BAT-012 배포 편성. 실 KIS 라이브 발동은 운영 실증 이월.