# req-104: 전략 차단 게이트 — pause ∨ reconcile-warning 중 하나라도 걸리면 차단 - Status: Implemented - Type: Interface - Priority: High - Owner: trex-core-dev ## Intent - 현재 전략 차단은 pause(수동 durable) 채널에만 의존한다. reconcile-warning(자동 durable) 채널을 추가해, **pause ∨ reconcile-warning 중 하나라도 존재하면 해당 슬롯/포트폴리오의 전략 수행(intent 수용 + slots read 차단 표면)을 차단**한다. - dcy-034 FR-2 대응: 두 채널이 독립적으로 작동하며 OR 논리로 게이트를 확장한다. - slots RPC wire 계약(`trex.slots.req` 응답 스키마)에서 `reconcile_warned` 플래그를 additive 필드로 노출해 운영자가 차단 원인을 식별할 수 있게 한다(NFR-4 최소 침습). - **차단 범위(OQ-B 확정)**: reconcile-warning 차단은 **외부 전략 intent/read 전용**이다. **내부 안전망(safety-sell · watchdog · kill-switch)은 차단 예외**다. 근거: 집행 수량 정본은 브로커 잔고(execution.py)이므로 안전망은 수량 오류에 안전하며, 차단 시 포지션이 무보호로 방치된다. ## Requirement - 시스템은 `IntentService._admit_buy` 및 `_admit_sell` 수행 시 대상 슬롯의 `pause_store` 또는 `ReconcileWarningStore` 중 하나라도 차단 기록이 있으면 intent를 `rejected`(reason: `reconcile_warned` 또는 `paused`)로 반환해야 한다. - **내부 안전망 경로(safety-sell / kill-switch / watchdog)는 reconcile-warning 차단을 우회해야 한다.** 이 경로들은 `IntentService._admit_*` 게이트를 거치지 않는 별도 내부 경로를 사용하며, reconcile-warning이 걸린 슬롯에 대해서도 안전망 매도를 실행할 수 있어야 한다(OQ-B 확정, 차단 대상은 외부 전략 intent만). - 시스템은 slots RPC 핸들러(`make_slots_rpc_handler`)에서 각 슬롯 행에 `reconcile_warned: bool` 필드를 추가해 reconcile-warning 차단 여부를 노출해야 한다. - `slot_to_dict` 함수는 `ReconcileWarningStore`를 선택적으로 주입받고, `reconcile_warned` 필드를 산출해야 한다(pause_store의 `paused` 필드 처리 방식과 동형). - 기존 `paused` 필드 및 `warned` 필드는 변경 없이 유지해야 한다(additive only, NFR-4). - reconcile-warning 차단으로 rejected된 buy intent는 `reason="reconcile_warned"` 를 반환해야 한다. ## Acceptance Criteria 1. Given 슬롯의 portfolio_id가 ReconcileWarningStore에 warned 상태일 때, When buy intent가 제출되면, Then status=`rejected`, reason=`reconcile_warned`가 반환된다(전략 진입 차단). 2. Given 슬롯의 portfolio_id가 ReconcileWarningStore에 warned 상태일 때, When sell intent가 제출되면(외부 전략 경로), Then status=`rejected`, reason=`reconcile_warned`가 반환된다(전략 매도 차단). **단, safety-sell / kill-switch / watchdog의 내부 안전망 매도 경로는 이 차단을 받지 않으며 정상 실행되어야 한다(OQ-B 확정, 차단 예외).** 3. Given pause도 reconcile-warning도 없는 정상 슬롯에서, When buy/sell intent가 제출되면, Then 기존 admission 로직이 그대로 동작한다(오발동 없음). 4. Given pause만 있는 슬롯에서, When slots RPC가 호출되면, Then `paused=True`, `reconcile_warned=False` 필드가 반환된다(기존 paused 동작 불변). 5. Given reconcile-warning만 있는 슬롯에서, When slots RPC가 호출되면, Then `paused=False`, `reconcile_warned=True` 필드가 반환된다. 6. Given pause와 reconcile-warning이 모두 있는 슬롯에서, When slots RPC가 호출되면, Then `paused=True`, `reconcile_warned=True`가 모두 반환된다. 7. Given ReconcileWarningStore가 주입되지 않은 구성에서, When slots RPC가 호출되면, Then `reconcile_warned=False`(또는 필드 부재 시 기본값)로 반환되어 기존 클라이언트가 깨지지 않는다(하위 호환). 8. Given 기존 `warned` 필드(슬롯 qty ≠ hub asset_quantity 로컬 계산), When 신규 필드가 추가돼도, Then `warned` 필드 정의와 동작이 변경되지 않는다. ## Impacted Area - Docs: `docs/interface-contract.md` (slots RPC 응답 스키마 `reconcile_warned` 필드 추가 명시) - Modules: - `trex_core/application/portfolio.py` (`slot_to_dict` — `reconcile_warned` 필드 추가) - `trex_core/application/intents.py` (`IntentService._admit_buy`, `_admit_sell` — reconcile-warning 게이트 추가) - `trex_core/application/messaging_handlers.py` (`make_slots_rpc_handler` — ReconcileWarningStore 주입 파라미터 추가) - `trex_core/runtime/daemon.py` (ReconcileWarningStore 주입 배선) - Tests: - `tests/application/test_intents.py` (reconcile_warned 차단 시나리오, 정상 슬롯 오발동 없음) - `tests/application/test_messaging_handlers.py` (slots RPC reconcile_warned 필드 노출) - `tests/application/test_portfolio.py` (`slot_to_dict` reconcile_warned 필드 검증) ## Notes - **safety-sell / kill-switch / watchdog 차단 예외(OQ-B 확정)**: 내부 안전망(safety-sell REQ-037~039, kill-switch REQ-045, watchdog REQ-034) 경로는 reconcile-warning 차단 예외다. 집행 수량 정본은 브로커 잔고(`execution.py`)이므로 안전망은 수량 오류에 안전하며, 차단하면 포지션이 무보호로 방치된다. 이 경로들은 `IntentService._admit_*` 게이트를 거치지 않는 별도 내부 호출 경로를 사용하므로 구조적으로 차단을 우회한다. batch design에서 경로 분리 구조를 명시적으로 확인한다. - `reconcile_warned` 필드는 `slot_to_dict` 단에서 `ReconcileWarningStore.is_warned(slot_id)` 또는 `slot_id in list_warned()` 조회로 산출한다. batch design에서 성능(N+1) 고려해 bulk 조회 방식 선택. - AMQP wire 계약 변경 사항: `trex.slots.req` 응답 행에 `reconcile_warned: bool` 필드 additive 추가. trex-orb-v1·trex-tsl-v1이 이 필드를 무시해도 하위 호환이 유지되는지 batch design에서 확인 필요. - dcy-034 FR-2, NFR-4 대응. ## Change Log ### CHG-20260626-01 - Date: 2026-06-26 - Author: trex-core-dev - Status: Approved → Implemented - Summary: BAT-050(PR #31, ced7eda) origin/main 머지 완료. QC(opus) PASS + 팀장 confirm-batch-verification. pause∨reconcile-warning OR 게이트, 안전망 우회(OQ-B), slots RPC reconcile_warned 필드, 전 AC 검증 완료. #### Acceptance Criteria Delta - 없음 #### Impacted Area Delta - 없음 #### Delivery Trace Delta - Batches: BAT-050 (core-A) - Releases: M3 (배포 대기) #### Revalidation Impact - Reverification Needed: no - Existing Implementation Invalidated: no - Status Recommendation: Implemented - Follow-up Action: 없음. #### Validation Plan - BAT-050 verification.md AC 매핑 전항목 PASS 확인됨. ### CHG-20260625-02 - Date: 2026-06-25 - Author: trex-core-dev #### Change Summary - REQ-104 **Proposed → Approved** (confirm-req, 팀장 2026-06-25). - OQ-B 결정 반영: reconcile-warning 차단 범위 = 외부 전략 intent/read 전용. 내부 안전망(safety-sell/watchdog/kill-switch)은 차단 예외로 확정. AC-2에 예외 명시. - Intent, Requirement, Notes에 OQ-B 결정 근거(집행 수량 정본=브로커, 차단 시 포지션 무보호) 추가. #### Intent - 팀장 confirm-req 결정(OQ-B 차단 예외 확정)을 REQ에 반영. #### Acceptance Criteria Delta - Added: 없음. - Updated: AC-2(safety-sell/kill-switch/watchdog 차단 예외 명시). - Removed: 없음. #### Impacted Area Delta - Notes: 안전망 경로 차단 예외 설계 원칙 구체화. - Modules: `intents.py` — 차단 게이트가 외부 전략 intent 경로에만 적용됨을 구현 시 명시. - Tests: safety-sell/kill-switch가 reconcile-warning 슬롯에서도 실행됨을 확인하는 테스트 추가 필요. #### Delivery Trace Delta - Batches: 미정 (suggest-batch-reqs 이후) - Releases: 미정 #### Revalidation Impact - Reverification Needed: no - Existing Implementation Invalidated: no - Status Recommendation: Approved - Follow-up Action: batch design에서 안전망 경로 분리 구조 명시 확인. #### Validation Plan - 외부 intent reconcile_warned 차단 테스트 pass / safety-sell 차단 우회 테스트 pass / slots RPC reconcile_warned 필드 반환 테스트 pass / 기존 paused/warned 동작 회귀 pass. ### CHG-20260625-01 - Date: 2026-06-25 - Author: trex-core-dev #### Change Summary - REQ-104 신규 생성 (Proposed) — dcy-034 FR-2 대응, draft-req 단계. #### Intent - pause 단독 게이트를 pause ∨ reconcile-warning OR 게이트로 확장해 자동 차단 채널을 활성화. #### Acceptance Criteria Delta - Added: AC-1~8 전부 신규. - Updated: 없음. - Removed: 없음. #### Impacted Area Delta - Docs: interface-contract.md 갱신 예정. - Modules: portfolio.py, intents.py, messaging_handlers.py. - Tests: 신규 게이트 테스트. #### Delivery Trace Delta - Batches: 미정 - Releases: 미정 #### Revalidation Impact - Reverification Needed: no (신규 REQ) - Existing Implementation Invalidated: no - Status Recommendation: keep-current - Follow-up Action: confirm-req 후 wire 계약 영향 확인 포함 batch design. #### Validation Plan - reconcile_warned 차단 및 정상 슬롯 오발동 없음 테스트 pass / slots RPC reconcile_warned 필드 반환 테스트 pass / 기존 paused/warned 동작 회귀 pass.