Files
trex-core/docs/srs/Integration/req-100_core-alarm-emitter.md
T
genichinandClaude Opus 4.8 d4c5fcbba1 feat(alarm): trex-core 알람 emitter + trex.alerts exchange (dcy-033 BAT-049, Implemented)
AlarmEmitter(application, best-effort 비차단)+trex.alerts topic exchange 가산·격리+8 CRITICAL code 배선. 608 passed, opus QC PASS, 팀장 e2e(텔레그램 HTTP200) 통과. REQ-098~101 Implemented.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
2026-06-21 19:25:55 +09:00

9.3 KiB

req-100: trex-core 알람 emitter — CRITICAL code 발신 배선

  • Status: Implemented
  • Type: Integration
  • Priority: High
  • Owner: trex-core-dev

Intent

  • ALARM-INVENTORY.md §A trex-core 행의 CRITICAL alarm code 8종을 trex-core 소스 내 발생 지점에서 REQ-098 envelope 형식으로 trex.alerts exchange(REQ-099)에 발행하도록 배선한다.
  • 알람 발행은 best-effort 비차단: 발행 실패(transport 단절·예외)가 core 본업(슬롯 전이·매매 집행·원장 기록)을 막지 않아야 한다.
  • trex-core는 텔레그램 토큰 등 외부 시크릿을 보유하지 않는다. core는 trex.alerts exchange에 발행만 하고, 텔레그램 전달은 trex-notifier 책임이다.

Requirement

  • trex-core는 아래 8개 CRITICAL code의 발생 지점에서 REQ-098 envelope을 trex.alerts exchange로 발행해야 한다.

    code 발생 위치 (ALARM-INVENTORY §A 기준) 조건
    fill_price_unresolvable execution.py:261 체결가 미해결 → 슬롯 PENDING 고착
    sell_skipped_no_balance execution.py:128 매도 dispatch skip (브로커 잔고 0) → PENDING_SELL 고착
    core_holding_broker_flat reconciliation.py:47 슬롯 보유인데 브로커 잔고 0 (정산 불일치)
    ledger_delivery_failed ledger_outbox.py:218-245 원장 영구 실패/데드레터/409 충돌
    kill_switch_fired killswitch.py:72 긴급 청산 발동
    publish_unavailable_after_reconnect / dlq_publish_failed rabbitmq.py:262,293 재연결 후에도 발행 불가 / DLQ 발행 실패
    portfolio_hub_unavailable portfolio.py:156 / snapshot_scheduler.py:90,98 포트폴리오/현금 정보 부실화
    schema_verification_failed / migration_failed reset.py:152 리셋·마이그레이션 무결성 실패
  • 알람 emitter는 application 레이어에 AlarmEmitter (또는 동등한 이름의 thin class/함수)로 구현하며, MessagingTransport 포트를 통해 발행한다(직접 pika 호출 금지 — 의존성 역전 유지).

  • 발행 실패(TransportUnavailableError 또는 기타 예외) 시 ERROR 로그를 남기고 예외를 삼킨다(re-raise 금지). 슬롯 전이·주문 집행·원장 기록 경로는 알람 발행 실패에 영향받지 않는다.

  • envelope source = "trex-core", severity = "critical", schema_version = "1". occurred_at은 발행 시점 KST ISO-8601.

  • fields는 code별 최소 컨텍스트를 포함한다(예: fill_price_unresolvable이면 {"slot_id": "...", "symbol": "..."}). 빈 dict도 허용.

  • trex-core 코드 어디에도 텔레그램 봇 토큰, chat_id 등 외부 알람 시크릿을 import·로드·참조하지 않는다.

Acceptance Criteria

  1. Given trex-core가 기동돼 MessagingTransport가 연결된 상태에서, When 위 8개 code 각각의 조건이 발생하면, Then 해당 code를 담은 REQ-098 envelope(source="trex-core", severity="critical", schema_version="1")이 routing key alarm.critical.trex-core로 trex.alerts exchange에 발행되어야 한다.
  2. Given 알람 emitter가 publish_alarm()을 호출할 때, When MessagingTransport가 disconnected 또는 reconnecting 상태(TransportUnavailableError 발생)이면, Then 예외가 caller로 전파되지 않고 ERROR 로그만 남겨야 한다.
  3. Given 알람 emitter가 publish_alarm()을 호출할 때, When 발행 중 임의 예외가 발생하면, Then 예외가 caller로 전파되지 않고 ERROR 로그만 남겨야 한다.
  4. Given kill_switch_fired·ledger_delivery_failed·fill_price_unresolvable 등 알람 발행 지점이 슬롯 전이·매매 집행·원장 기록 경로 중간에 위치할 때, When 알람 발행이 예외로 실패해도, Then 해당 경로(슬롯 전이·집행·원장 기록)는 정상 완료되거나 기존 에러 처리 흐름을 따라야 한다(알람 발행 실패가 core 본업 실패를 유발하지 않음).
  5. Given trex-core 코드베이스 전체를 탐색할 때, When 텔레그램 봇 토큰·chat_id·TELEGRAM_* 환경변수를 참조하는 코드를 찾으면, Then 해당 참조가 0건이어야 한다.
  6. Given 알람 emitter 구현이 완료됐을 때, When AlarmEmitter(또는 동등 컴포넌트)의 단위 테스트를 실행하면, Then 8개 code 각각에 대해 (a) 정상 발행 시 올바른 envelope 필드 검증, (b) transport 예외 발생 시 re-raise 없음 + 로그 기록 두 케이스가 모두 통과해야 한다.
  7. Given AlarmEmitter가 MessagingTransport 포트를 통해 구현됐을 때, When application 레이어 코드를 확인하면, Then pika 라이브러리를 직접 import하는 코드가 없어야 한다(의존성 역전 준수).
  8. Given domain 레이어(trex_core/domain/) 코드를 확인할 때, When AlarmEmitter 또는 messaging import를 탐색하면, Then domain 레이어에 messaging/transport/infra 관련 import가 없어야 한다(domain 순수성 불변식).

Impacted Area

  • Docs: docs/interface-contract.md — 알람 채널 섹션에 core emitter source/routing key 명시(REQ-098 섹션 내용)
  • Modules:
    • trex_core/application/ — AlarmEmitter (또는 동등 thin class/함수) 신규 추가
    • 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/adapters/portfolio/ 또는 trex_core/application/snapshot_scheduler.py — portfolio_hub_unavailable 발행 배선
    • trex_core/runtime/reset.py — schema_verification_failed / migration_failed 발행 배선
    • trex_core/runtime/daemon.py — AlarmEmitter 인스턴스 생성·주입
  • Tests:
    • tests/application/ — AlarmEmitter 단위 테스트 (8 code × 2 케이스 최소 16 테스트)
    • 기존 execution/reconciliation/killswitch/ledger_outbox 테스트 회귀 확인

Notes

  • AlarmEmitter는 application 레이어에 두고 MessagingTransport 포트만 주입받는다. 테스트에서는 InMemoryTransport 또는 mock transport를 주입해 결정적 단위 테스트를 작성한다.
  • publish_unavailable_after_reconnect / dlq_publish_failed는 rabbitmq.py 어댑터에서 발생하지만, 알람 emitter를 어댑터 내부에 두면 의존성이 역전되므로 처리 방식을 batch design에서 결정한다(예: 어댑터가 콜백을 호출하거나, 이벤트를 상위 레이어로 전달하는 방식).
  • portfolio_hub_unavailable는 portfolio.py:156과 snapshot_scheduler.py:90,98 두 곳에서 발생 가능 — 중복 발행 억제는 notifier의 rate-limit 책임이므로 core는 각 발생 지점에서 독립 발행한다.
  • reset.py는 daemon이 아닌 CLI 진입점(trex-core-reset)에서 실행된다. MessagingTransport 미연결 가능성 있음 — transport가 None이면 발행 skip + 로그(batch design에서 확정).
  • dcy-033 성공기준 S-1(CRITICAL 조건 발생 시 텔레그램 도달) 전제 조건: core emitter가 올바른 envelope을 trex.alerts에 발행.
  • dcy-033 NFR-3(core에 외부 시크릿 유입 없음) 대응 — AC-5가 직접 검증 기준.
  • INFO·WARN code 배선은 이 REQ 범위 밖. CRITICAL 우선(dcy-033 범위 경계).

Change Log

CHG-20260621-02

  • Date: 2026-06-21
  • Author: trex-core-dev

Change Summary

  • Status: Approved → Implemented. BAT-049 confirm-batch-verification 팀장 승인(QC PASS-WITH-NOTES blocker 0 + 팀장 실인프라 e2e 통과). AlarmEmitter 29 단위 테스트 통과(8 code × 정상+예외 케이스). 텔레그램 sendMessage HTTP 200 e2e 확인. 잔여: reset.py 2 code 간접 검증(non-blocker, 정직 공개).

Delivery Trace Delta

  • Batches: BAT-049 (release-candidate)
  • Releases: 미정

Revalidation Impact

  • Reverification Needed: no

CHG-20260621-01

  • Date: 2026-06-21
  • Author: trex-core-dev

Change Summary

  • REQ-100 신규 생성(Proposed). dcy-033 FR-2(core 부분) 대응: ALARM-INVENTORY §A core CRITICAL 8종 emitter 배선.

Intent

  • trex-core가 소유한 CRITICAL alarm code 발생 지점에서 표준 envelope을 trex.alerts exchange로 발행하는 알람 emitter를 구현한다.

Acceptance Criteria Delta

  • Added: AC-1~8 (신규 생성)
  • Updated: (없음)
  • Removed: (없음)

Impacted Area Delta

  • Docs:
    • docs/interface-contract.md 알람 섹션 core emitter 내용 추가
  • Modules:
    • application 레이어 AlarmEmitter 신규 + 8개 발생 지점 배선
  • Tests:
    • AlarmEmitter 단위 테스트 신규 추가

Delivery Trace Delta

  • Batches: (미정, M2 이후 큐잉)
  • Releases: (미정)

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: keep-current
  • Follow-up Action: REQ-098/099/101과 단일 batch 편성 예정

Validation Plan

  • AlarmEmitter 단위 테스트 8 code × 2 케이스 통과
  • 기존 execution/reconciliation/killswitch 테스트 회귀 통과
  • domain 레이어 messaging import 0건 확인(grep)
  • TELEGRAM_* 환경변수 참조 0건 확인(grep)