# BAT-049: 알람 시스템 — 알람 envelope wire 계약 + trex.alerts exchange + core CRITICAL emitter + baseline 정합 (dcy-033) - Status: release-candidate - Profile: standard - Source Discovery: dcy-033 - Included REQ: REQ-098 (Interface), REQ-099 (Integration), REQ-100 (Integration), REQ-101 (Documentation) - Excluded REQ: 없음 ## Summary - dcy-033(제품군 알람 전달 체계) confirmed Discovery에서 확정된 알람 시스템 1단계 구현. - REQ-098: 알람 envelope 표준 JSON 스키마 wire 계약을 `docs/interface-contract.md`에 문서화. - REQ-099: `trex.alerts` (topic, durable=True) AMQP exchange를 `declare_topology()`에 멱등 선언 추가. - REQ-100: application 레이어 `AlarmEmitter` + CRITICAL code 8종 발생 지점 배선. - REQ-101: `docs/runtime-flows.md`에 알람 발신 흐름 섹션 추가 + baseline 문서 정합. ## Scope - In Scope: - `docs/interface-contract.md` — `Interface: trex.alerts (알람 채널, dcy-033)` 신규 섹션 추가(기존 섹션 불변) - `trex_core/adapters/messaging/topology.py` — `ALERTS_EXCHANGE` 상수 추가 - `trex_core/adapters/messaging/rabbitmq.py` — `declare_topology()`에 `trex.alerts` 선언, `publish_alarm_event()` 메서드 추가 - `trex_core/adapters/messaging/in_memory.py` — `publish_alarm_event()` stub 추가 - `trex_core/application/messaging.py` — `MessagingTransport` 프로토콜에 `publish_alarm_event()` 추가 - `trex_core/application/alarm_emitter.py` — `AlarmEmitter` 신규 구현 - `trex_core/application/execution.py` — `fill_price_unresolvable`, `sell_skipped_no_balance` 배선 - `trex_core/application/reconciliation.py` — `core_holding_broker_flat` 배선 - `trex_core/application/ledger_outbox.py` — `ledger_delivery_failed` 배선 - `trex_core/application/killswitch.py` — `kill_switch_fired` 배선 - `trex_core/adapters/broker/rabbitmq.py` — `publish_unavailable_after_reconnect` / `dlq_publish_failed` 배선 (콜백 패턴) - `trex_core/application/portfolio.py` / `trex_core/application/snapshot_scheduler.py` — `portfolio_hub_unavailable` 배선 - `trex_core/runtime/reset.py` — `schema_verification_failed` / `migration_failed` 배선 (transport None 안전) - `trex_core/runtime/daemon.py` — `AlarmEmitter` 생성·주입 - `tests/application/test_alarm_emitter.py` — AlarmEmitter 단위 테스트 신규 - `tests/adapters/messaging/test_topology.py` 또는 `test_in_memory_transport.py` — declare_topology trex.alerts assertion 추가 - `docs/runtime-flows.md` — 알람 발신 흐름 섹션 추가 - Out of Scope: - trex.events / trex.intent.req / trex.slots.req / trex.control.req 변경 — 가산·격리 불변(REQ-099 AC-2) - 텔레그램 봇 토큰·chat_id 등 외부 알람 시크릿 — trex-notifier 담당 - INFO·WARN code 배선 — CRITICAL 우선(dcy-033 범위 경계) - 통합/e2e(실 RabbitMQ) 테스트 — 팀장이 실인프라로 수행 ## Documents - Planning: [planning.md](./planning.md) - Design: [design.md](./design.md) - Implementation: [implementation.md](./implementation.md) - Verification: [verification.md](./verification.md) ## Notes - 이 batch는 신규 AMQP exchange(`trex.alerts`) 추가이지만 기존 wire 계약(exchange/큐/라우팅)을 변경하지 않는 가산·격리 추가이므로 wire 계약 변경 에스컬레이션 대상이 아님. - `publish_unavailable_after_reconnect` / `dlq_publish_failed`는 rabbitmq.py 어댑터에서 발생 → 콜백 패턴으로 상위에 전파. 설계 결정 details는 design.md 참조. - `reset.py`는 transport 미연결 가능 → `AlarmEmitter`가 `None` transport를 안전하게 처리. - R-1(Low): trex.alerts exchange 선언 후 notifier 미연결 시 알람 발행은 `mandatory=False`로 silent drop — 운영상 무해. - R-2(Low): rabbitmq.py 어댑터 콜백 주입 시 생성 시점 의존성 순환 가능성 → daemon.py에서 생성 순서 주의.