Files
trex-core/.proofline/lines/line-0011/req-0011.md
T

3.2 KiB

id, status, discovery, criteria
id status discovery criteria
req-0011 approved dcy-0011
create update retire satisfy
ac-0038
ac-0039

SELL 체결 이벤트 owner 보존과 unroutable 차단

Objective

SELL 주문 admission에서 확정된 전략 owner를 체결 event routing까지 보존하여 해당 전략 queue로만 전달한다. owner를 결정할 수 없는 SELL 체결은 정상 전략 event로 위장해 _ routing key로 발행하지 않고 명시적 전달 실패로 관측하되, 이미 성공한 broker 체결, slot 전이, ledger outbox 처리는 되돌리지 않는다.

Scope

  • HOLDING → PENDING_SELL admission에서 non-empty SellIntent.sell_strategy_id, slot에 보존된 non-empty sell_strategy_id, non-empty strategy_id 순서로 SELL event owner를 확정하고 기존 durable sell_strategy_id에 저장한다. Whitespace-only 값은 owner로 인정하지 않는다.
  • 확정된 owner는 기존 durable slot field를 통해 dispatch 전후와 daemon 재시작 후에도 보존하고, full fill 및 partial fill 후 external cancel의 slot_filled_sell routing hint로 사용한다.
  • zero-fill cancel 또는 reject는 fill event를 만들지 않고 기존 rollback 계약을 유지하며 확정 owner를 HOLDING에 보존한다. 이후 명시적 새 owner가 없는 SELL admission은 이 owner를 다시 사용하고, 명시적 새 owner가 있으면 그것으로 교체한다.
  • owner 미확정 SELL 체결은 trex.events 정상 전략 topic 또는 DLQ에 synthetic owner message를 publish하지 않는다. stable reason code sell_event_owner_missing, tick-level counter, ERROR log, best-effort alarm으로 구분해 관측한다.
  • 정상 owner가 있는 event의 publish 실패도 금융 처리를 rollback하지 않는다. 기존 payload의 slot_id, event_type, sequence_at을 변경하지 않으며, 재시작·반복 polling에서 같은 terminal execution의 event 재발행을 새로 보장하지 않는다.
  • docs/interface-contract.md와 docs/runtime-flows.md의 RabbitMQ event routing 및 slot event 발행 구간에 owner 선택, pre-publish skip, 전달 실패 의미를 구현과 함께 동기화한다.

Constraints

  • sell_strategy_id와 strategy_id의 의미를 합치거나 legacy mapping을 추가하지 않는다.
  • 새 persistence column이나 strategy-event outbox를 추가하지 않는다. restart 보장은 terminal 처리 전에 durable PENDING_SELL row를 다시 읽는 범위이며, terminal commit 뒤 실패한 event의 재생 저장소를 이번 Line에서 도입하지 않는다.
  • publisher confirm과 1회 reconnect/retry, RabbitMQ mandatory publish 및 기존 transport DLQ 계약은 유지한다.
  • alarm payload와 log는 secret, credential, connection string 또는 raw exception text를 포함하지 않는다.
  • production broker 주문, production lifecycle, production daemon 재기동은 검증에서 실행하지 않는다.

Non-Goals

  • 이미 발생한 과거 DLQ message의 복구 또는 재발행
  • 전략 consumer 구현 변경 및 전역 exactly-once 보장
  • RabbitMQ topology, queue TTL/max-length, exchange 이름 변경
  • BUY event owner 계약 변경
  • durable strategy-event outbox 또는 운영 replay command 추가