# req-046: kill-switch 당일 제외 masking + 자동 해제 + 수동 resume - Status: Implemented - Type: Interface - Priority: High - Owner: project maintainers ## Intent kill-switch 발동(REQ-045)으로 표시된 당일 제외 상태를 snapshot RPC 응답에 반영해 대상 자산을 당일 전략 실행에서 제외한다(추가 매수 차단). 제외는 day-scoped 라 다음 거래일 자동 복귀하며(REQ-044 `trading_date` 키), 운영자는 같은 거래일 내 `action: "resume_kill_switch"` 로 수동 해제할 수 있다(dcy-008 FR-2/3, NFR-3, OQ-4 Answered). ## Requirement - snapshot RPC 응답 산출 시 masking 소스에 "kill-switch 당일 제외"(REQ-044 `list_excluded(today)`)를 추가한다: `mask = pending | warning | pause | killswitch_today`. - scope=portfolio 제외는 해당 `portfolio_id` 자산만, 전역 제외는 당일 전체 자산을 마스킹한다. - 마스킹된 자산은 buyable/held 뷰에 노출되지 않아 당일 추가 매수 의도가 거부된다. - 당일 제외는 `trading_date` 기준 day-scoped 다. 다음 거래일 첫 조회/부팅 시 `list_excluded(다음 날)` 에 포함되지 않아 자동 복귀한다(별도 해제 동작 불필요). - 영속성: 데몬 재시작 후에도 같은 거래일이면 masking 이 유지된다(REQ-044 영속, NFR-3). - 수동 해제: `action: "resume_kill_switch"` payload `{action, scope, portfolio_id?, actor?}` 처리 시 대상 범위의 당일 제외를 해제(REQ-044 `clear(...)`)해 다음 조회부터 정상 매매 대상으로 복귀시킨다. - resume 은 **당일 제외(매매 차단)만 해제**하며 이미 청산(매도)된 슬롯을 되돌리지 않는다(매도 비가역). - 응답: `{status: "ok", scope, portfolio_id?}`. scope=portfolio 인데 `portfolio_id` 누락 시 `{status:"error", reason:"portfolio_id_required"}`. ## Acceptance Criteria 1. Given `pf-A` 가 당일 제외(REQ-044)로 표시됨, When snapshot RPC(view=buyable/all) 처리, Then `pf-A` 자산이 응답 assets 에서 마스킹되어 노출되지 않는다. 2. Given 전역 당일 제외 표시, When snapshot RPC 처리, Then 당일 전체 자산이 마스킹된다. 3. Given 당일 제외 표시 후, When 당일 추가 매수 intent 가 해당 자산에 들어오면, Then buyable 마스킹으로 거부/비노출된다. 4. Given `pf-A` 당일(D) 제외, When 거래일 D+1 로 snapshot RPC 처리, Then `pf-A` 가 다시 노출된다(자동 복귀, 별도 resume 불필요). 5. Given `pf-A` 제외 후 데몬 재시작(같은 거래일 D), When snapshot RPC 처리, Then 여전히 마스킹된다(영속, NFR-3). 6. Given `pf-A` 당일 제외 상태, When `{action:"resume_kill_switch", scope:"portfolio", portfolio_id:"pf-A"}` 처리, Then 다음 snapshot RPC 부터 `pf-A` 가 정상 노출되고 응답 `{status:"ok"}`. 7. Given resume_kill_switch scope=portfolio 인데 `portfolio_id` 누락, When 처리, Then `{status:"error", reason:"portfolio_id_required"}`. 8. Given resume_kill_switch 처리, When 이미 청산된 슬롯을 확인, Then 슬롯 상태(pending_sell/closed)는 되돌려지지 않는다(매도 비가역). ## Impacted Area - Docs: - `docs/interface-contract.md` — masking 소스에 kill-switch 당일 제외 + resume_kill_switch 계약 (REQ-047 처리) - `docs/runtime-flows.md` — 당일 제외 masking / 자동 복귀 / 수동 resume 흐름 (REQ-047 처리) - Modules: - `trex_core/application/portfolio.py`(또는 snapshot envelope builder) — masking 소스에 `list_excluded(today)` 추가 - `trex_core/application/messaging_handlers.py` — `resume_kill_switch` handler(REQ-043 dispatch 하위) + snapshot 핸들러에 killswitch store 주입 - REQ-044 store 연동(`list_excluded`/`clear`) - Tests: - masking 단위 테스트(portfolio/전역/추가매수 거부) + day-scoped 자동 복귀(날짜 mock) + 재시작 영속 + resume 단위 ## Notes - dcy-008 OQ-4 Answered: 수동 해제 지원(`resume_kill_switch`). 자동 복귀(day-scoped)와 병행. - NFR-3(영속 후 재시작 masking 유지)는 본 REQ AC-5 로 흡수. - 전역 제외 sentinel 해석은 REQ-044 store 계약을 따른다. - masking 합성은 기존 pause masking 패턴(`portfolio.py`)을 재사용(A-2). ## Change Log ### CHG-20260607-01 - Date: 2026-06-07 - Author: Justin Ko #### Change Summary - dcy-008(confirmed) → REQ-046 초안 생성. #### Intent - 당일 제외 masking/자동 복귀/수동 resume(FR-2/3, OQ-4, NFR-3 흡수)을 Interface REQ 로 정규화. #### Acceptance Criteria Delta - Added: AC-1~8 전체 #### Impacted Area Delta - Docs: interface-contract.md, runtime-flows.md (REQ-047) - Modules: portfolio.py, messaging_handlers.py, REQ-044 store 연동 - Tests: masking + day-scoped + 영속 + resume 단위 #### 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) OQ-4 결정(resume_kill_switch) 반영, NFR-3 흡수. 범위·결정과 모순 없음. #### 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(masking·resume 7 단위: portfolio/전역 masking + buyable 차단 + day-scoped 자동복귀(날짜) + 영속 + resume 재포함 + 청산 비가역 + backward-compat; e2e resume_kill_switch → exclusion 0)로 AC-1~8 충족. NFR-3 흡수. #### 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 배포 편성.