Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
5.4 KiB
5.4 KiB
id, status, discovery, criteria
| id | status | discovery | criteria | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| req-0008 | approved | dcy-0008 |
|
Reconcile-warned strategy intent rejection alerts
Objective
trex-core가 활성 reconciliation warning 때문에 외부 strategy의 신규 buy 또는 sell intent를 reconcile_warned로 최종 거부하면, 해당 intent_id의 최초 처리에서만 원인을 식별할 수 있는 sanitized warning event를 trex.alerts에 한 건 발행하게 한다. 기존 durable intent idempotency와 warning 차단 권한을 유지하고, duplicate intent 및 무관한 decision의 알림을 억제하며, 알림 실패가 intent decision·저장·응답 또는 broker 동작에 영향을 주지 않도록 한다.
Scope
IntentService가 새intent_id를 처리하여 buy 또는 sell decision을status="rejected",reason="reconcile_warned"로 결정하고IntentStore.finalize()가 성공한 뒤에만 warning event를 발행한다.- 동일
intent_id의 duplicate/retry는 기존IntentStore.try_insert()와 저장된 final decision을 canonical dedup authority로 사용한다. Duplicate path, 처리 중인 intent 및 process-local cache는 새 event를 만들지 않는다. - 서로 다른
intent_id가 같은 warned slot을 대상으로 각각 거부되면 각 intent는 독립적인 최초 거부 event 한 건을 만든다. - Event는 기존
AlarmEmitter와trex.alertsenvelope·routing contract를 재사용하고severity="warn",code="strategy_intent_rejected"를 사용한다. - Event fields의 필수 allowlist는
instance_key,intent_id,intent_type,reason="reconcile_warned",broker_submitted=false다. Canonical slot 또는 intent에서 안전하게 확인된 값이 있을 때만slot_id,portfolio_id,symbol,strategy_id를 추가하며, unavailable optional field는 추정하거나 raw payload에서 복사하지 않고 생략한다. - Buy의
strategy_id와 sell의sell_strategy_id는 event의 공통strategy_idfield로 정규화한다. Buy의 canonicalslot_id또는 legacyportfolio_id입력과 sell의slot_id입력 모두에서 같은 allowlist 계약을 적용한다. - Optional context 조회 실패, publisher 부재 및 alarm transport failure는 원래 final decision과 RPC response를 변경하거나 intent 처리를 실패시키지 않는다. 알림을 위해 slot, warning, intent, broker, ledger 또는 portfolio-hub 상태를 mutation하지 않는다.
- Production daemon은 이미 생성하는 동일
AlarmEmitter를IntentService에 연결한다. 직접 application construction과 non-daemon entry point는 optional publisher 경계에서 기존 동작과 호환된다. - Buy·sell 최초 거부, duplicate 억제, 서로 다른 intent의 독립 발행, 다른 decision의 무발행, publish failure, optional context, payload 보안과 production wiring을 repository-local automated tests로 검증한다.
Constraints
- AC-0023이 소유하는 B/C warning 판정, strategy RPC 제외, buy/sell
reconcile_warned차단, warn-store fail-closed 및 authoritative clear semantics를 완화·대체·확장하지 않는다. - AC-0024의 mismatch detected/changed/resolved lifecycle, fingerprint,
reconcile_notification_state와 operatorsync/verifyrecovery authority를 변경하거나 재사용하지 않는다. - Alarm은
IntentStore.finalize()보다 먼저 발행해서는 안 된다. Finalize가 실패하거나 final decision이 확정되지 않은 경우 알림을 성공한 거부로 보고해서는 안 된다. - Publisher return value나 failure는 저장된 rejection을 rollback하거나 RPC status/reason을 바꾸지 않는다. 별도 durable outbox, notification-state persistence 또는 retry loop를 추가하지 않는다.
- Event title, fields와 이 경로가 남기는 rendered log에는 account number/hash, credential, token, password, DSN, raw strategy
extra, raw request, raw KIS/broker/portfolio-hub payload 또는 raw exception body가 없어야 한다. broker_submitted=false는 거부가 broker submission 전에 확정됐음을 나타내며, 이 기능이 broker submit/cancel 호출을 새로 만들거나 기존 호출 순서를 바꾸어서는 안 된다.- Safety-sell, kill-switch, watchdog처럼
IntentService를 우회하는 내부 안전 경로는 계속 reconciliation warning gate와 이 strategy rejection alarm의 대상이 아니다. - 기존 intent RPC response schema, intent idempotency, slot transition과 alarm wire compatibility를 유지하며 RabbitMQ topology 또는 notifier rendering 변경을 요구하지 않는다.
- Normative Design Documents: 없음. 이 REQ와 AC-0025가 normative specification을 소유한다.
Non-Goals
- 다른 rejection reason의 범용 strategy intent alarm, reason별 severity 정책, rate limit·aggregation·escalation
- Strategy retry·backoff·pause·circuit-breaker 정책과 strategy/TVR wire schema 변경
- B/C mismatch 탐지·해소 알림과 strategy intent 거부 알림의 lifecycle 또는 persistence 통합
- Alarm의 exactly-once delivery, process crash 복구, durable outbox, publish retry와 재시작 후 재발행
- Warning 자동 해제, quantity 자동 보정, broker order submit/cancel, ledger write 또는 portfolio-hub write
- Safety-sell·kill-switch·watchdog 내부 경로의 신규 알림
trex-notifiermessage formatting·delivery channel, RabbitMQ topology, production deployment, release 또는 issue closure