genichin and Claude Fable 5
ee3dc83a93
feat(broker): KIS venue parameterization — OrderRequest.venue + EXCG_ID_DVSN_CD (REQ-117/118, BAT-056)
...
- OrderRequest.venue: str = "KRX" additive 추가 (기존 위치 인수 순서 불변)
- BrokerPort.cancel_order: venue: str = "KRX" 파라미터 추가
- BrokerPort.get_current_price: market: str = "J" 파라미터 추가
- KISBroker.submit_order: EXCG_ID_DVSN_CD=req.venue 항상 명시 전송
- KISBroker.cancel_order: EXCG_ID_DVSN_CD=venue 항상 명시 전송
- KISBroker.get_current_price: FID_COND_MRKT_DIV_CODE=market 파라미터화
- PaperBroker: cancel_order/get_current_price 시그니처 정합 (venue/market 수신·무시)
- poll_fill TR 유지 (TTTC8001R) — NXT 체결 포함 여부 미확인 open item (코드 주석 기록)
- tests/adapters/broker/test_venue.py: REQ-117 AC-1~5 + REQ-118 AC-1~8 신규 17개
- docs: interface-contract.md OrderRequest/BrokerPort 섹션 + change log 추가
- docs: runtime-flows.md venue 전달 경로 명시 + change log 추가
결과: 794 passed, 47 skipped (기존 777+47 대비 신규 17개 추가 전부 통과)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
2026-07-06 23:24:51 +09:00
genichin
a96fd54799
docs/style(bat-052): QC 재검 비차단 minor 정리
...
- docs/operations.md: report 섹션을 WAC 실현PnL 정의로 갱신 (portfolio-hub WAC
기반, 매수 fee cost basis 편입, 멀티데이 정확; 미가용 시 실현섹션 에러·타섹션 정상;
당일 net 함수는 회귀 비교용 보존 명시)
- docs/runtime-flows.md: 운영 조회 리포트 흐름에 BAT-052 WAC 경로(get_realized_pnl
N콜) + degrade(폴백 없음) 단계 추가
- docs/batches/bat-052_*/: CHG-20260626-02 기준으로 buy_fee_only_assets·
buy_fee_by_asset 잔존 참조 제거 및 최종 구현 일치 갱신 (planning/design/
implementation/verification)
- tests/application/test_operator_report.py:82: 섹션 헤더 주석에서
buy_fee_by_asset 단어 제거 및 CHG-20260626-02 근거 추가 (주석만)
- trex_core/runtime/cli.py: __import__("datetime").timezone/timedelta inline
패턴을 정식 from datetime import timezone, timedelta로 교체 (동작 동일)
pytest: 717 passed, 47 skipped (로직 변경 없음, 회귀 0)
2026-06-26 20:35:17 +09:00
genichin and Claude 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
genichin and Claude Opus 4.8
f1b649cf2a
feat(execution): 체결가 0/None 시 지정가 백필 가드 + WARN 로깅 (dcy-032/BAT-048)
...
REQ-095(슬롯 평단·원장 price 지정가 백필, 0 오염 방지) + REQ-096(백필/미해결 WARN 로깅) 구현.
지정가 부재 시 skip+강WARN. application 단일화(_resolve_fill_price), wire/LedgerTrade 스키마 불변.
575 passed/0 fail, opus QC PASS. REQ-097 알람=스파이크 산출물만(impl 후속).
- _resolve_fill_price 헬퍼 추가: avg_price 검증, limit_price 백필, 미해결 WARN
- _on_filled/_on_partial_cancel 통합: 백필 적용, 슬롯/원장 일관성
- _record_ledger 시그니처: resolved_price 파라미터 (backward compat)
- test_execution_fill_price_backfill.py: 21 시나리오 (avg=None/0, limit=있음/없음 등)
- docs: dcy-032, req-095/096/097, bat-048 설계/검증
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
2026-06-21 13:34:31 +09:00
genichin and Claude Opus 4.8
d182464b7a
feat(messaging): OPS-005 이벤트 발행 연결 신뢰성 (BAT-047)
...
발행 전용 연결의 idle heartbeat 사망 후 첫 발행 유실 결함 제거.
- REQ-091 발행 재시도 + 강제 재연결(_force_reconnect, is_open 불신)
- REQ-092 idle keepalive(execution-loop 단일스레드 틱, process_data_events time_limit=0)
- REQ-093 DLQ 가시성 + emit 실패 ERROR 경보(구조화 로그, dcy-029 재사용)
- REQ-094 baseline 문서 정합(runtime-flows/operations/project-structure)
독립 opus QC PASS-WITH-NOTES → 시정 2건(ruff F401, AC-3 프로덕션 경로) 완료.
554 passed/47 skipped/회귀 0/ruff clean. NFR-1 wire 무회귀(interface-contract diff 0).
BAT-047 release-candidate, REQ-091~094 Implemented. dcy-031. M2 트랙B.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
2026-06-19 22:39:43 +09:00
genichin and Claude Opus 4.8
d8d9021260
feat(execution,obs): 호가단위 스냅(dcy-030/#28) + 운영 관측성(dcy-029/#29) + REL-007 환류
...
dcy-030 (issue #28 , P0 체결 복구):
- REQ-083 KRX 호가단위(tick) 순수 유틸 (domain/pricing.py)
- REQ-070 CHG: 슬리피지 실효가 호가단위 스냅 — 상한 준수(매수 floor/매도 ceil)
+ band<1tick 하한/상한 보장 + 부동소수 epsilon 가드. 147700→148400/54500→54700.
- BAT-044 release-candidate
dcy-029 (issue #29 , 운영 관측성):
- REQ-084 구조화 로깅 기반 (runtime/logging_setup.py): ISO8601 KST·레벨·Loki JSON
·correlation id(slot_id)
- REQ-085 주문 결과 로깅 (event=order_submit|fill|reject)
- REQ-087 거부 ERROR 가시성 (조용한 롤백 제거)
- REQ-086 청산 reason+actor 동반 노출 (안전망/전략 구분, 신규 필드 없음)
- REQ-088 운영 조회 CLI report (application/operator_report.py, 보유·오늘 체결
·실현 PnL net·대기, direct-DB)
- REQ-089 운영자 런북 docs/operations.md
- REQ-090 baseline 정합 (runtime-flows·project-structure·interface-contract)
- BAT-045(P0)·BAT-046(P1) release-candidate
REL-007: confirmed → feedback-captured (운영 인스턴스 라이브 검증 + #28/#29 환류
정규화). BAT-037~041 released.
검증: 537 passed, 47 skipped, 회귀 0, ruff clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-16 13:19:31 +09:00
genichin and Claude Opus 4.8
e0d4e71304
feat(slot,intent): slot strategy-state 저장소 (dcy-028) + sell retryable 플래그 (issue #27 )
...
BAT-042 (dcy-028 / issue #26 C-1/C-2/C-2b/C-3, REQ-079~082 + REQ-073/074 CHG):
- slot_strategy_state 별도 테이블 + StrategyStateStore(in-memory+PG) + occupancy_seq·version CAS + opaque UTF-8 data + 2단 size cap (REQ-079)
- trex.slots.strategy_state.set write RPC — reject reason 집합, 멱등 (REQ-080)
- Slot.occupancy_seq 필드 + inactive→pending_buy bump + →INACTIVE close 삭제 훅 → 점유 전환 ABA 구조적 차단 (REQ-081)
- slots.req 응답 행에 strategy_state 맵(batched 조립)·occupancy_seq additive (REQ-073 AC-7/REQ-074 AC-6)
- 마이그레이션 014(occupancy_seq)/015(slot_strategy_state), baseline 문서 정합 (REQ-082)
BAT-043 (issue #27 / REQ-007 CHG):
- rejected SellIntent 응답에 additive retryable: bool (core 소유 reason→retryable 매핑, 미인식 기본 true, bad_request* false) — 손절매 재시도 안전 경로 decoupling
검증: 487 passed, 47 skipped (신규 41: store CAS 6+ABA, occupancy bump/close 4경로, set RPC 9, slots read 5, retryable 8, PG 게이트), ruff clean.
REQ-079·080·081·082·073·074·007 → Implemented. issue #27 close. PG 경로 실 DB 검증은 release 위임.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-15 19:27:57 +09:00
genichin and Claude Sonnet 4.6
6786ffd05d
docs(discovery): dcy-027 모든 OQ Answered — 중장기 슬롯 운영 결정 완료
...
OQ-1: (a′) 기존 슬롯 도메인 유지 + 운영 프로파일/규칙 추가 (PositionBook 불필요)
OQ-2: safety_sell_enabled=false → 코어 손절매 루틴 없음, 전략 모듈 전적 책임
OQ-3: per-instance watchdog_timeout_sec 연장 (1800s 이상 권장), 알림은 후속 Discovery
OQ-4: 중장기 전략 폴링 주기 최소 1분·최대 10분
feat(bat-041): REQ-076/077/078 — watchdog timeout TOML + 중장기 운영 프로파일 + baseline
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-12 22:19:33 +09:00
genichin and Claude Opus 4.8
1cf13b060f
feat(broker): BAT-038 — 매도 증권거래세 누락 정정 + fee/tax 단일 정책 지점 (dcy-026/REQ-018, issue #24 )
...
dcy-026 confirm-discovery + REQ-018 change-req(CHG-20260612-01)→구현→
confirm-req-implemented(CHG-20260612-02) 전체 delivery.
- broker_port.py: calculate_tax(side, amount) 신규 + fee/tax 율 env 상수화
(TREX_KIS_FEE_BPS=1.5, TREX_KRX_TAX_SELL_BPS=20.0). 매도 0.2%/매수 0.
- paper.py / kis.py: tax=0.0 하드코딩 3곳 제거 → 정책 함수 호출.
KIS daily-ccld 응답에 fee/tax 필드 부재 → 정책 폴백(향후 정본 우선 훅).
- runtime-flows.md: 체결→ledger fee/tax 산출 흐름 갱신.
- tests: fee/tax 정책 단위 + issue #24 4건 회귀(fee+tax=1,376.9원).
429 passed (+6), ruff clean.
REQ-018 Approved→Implemented, BAT-038 release-candidate.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-12 17:57:15 +09:00
genichin and Claude Opus 4.8
f0ad37747b
feat(rel-007): dcy-025/024 + BAT-035/036 — slots.req 즉시 교체 + safety_sell_enabled
...
BAT-035 (dcy-025): trex.snapshot.req → trex.slots.req 즉시 교체
- topology: SNAPSHOT_REQ_QUEUE 제거, SLOTS_REQ_QUEUE = "trex.slots.req" 추가
- portfolio.py: View/build_snapshot_envelope/SnapshotEnvelope/_asset_to_dict 제거;
slot_to_dict 시그니처 확장(snapshot_store/watchdog_store/pause_store/watchdog_timeout_sec)
— asset_quantity(hub)/cash_balance/cash_estimated/warned/watchdog{}/paused 병합 (REQ-074)
- messaging_handlers.py: make_snapshot_rpc_handler 제거, make_slots_rpc_handler 추가
— filter(all/inactive/pending/holding/error) + spy(bool) 처리; strategy 필드 제외 (REQ-073/074)
- daemon.py: _snapshot_rpc_loop → _slots_rpc_loop, make_slots_rpc_handler 연결
- cli.py: universe/slots → slots_queue + spy=True + server-side filter; buyable→inactive 매핑 (REQ-063)
- rabbitmq.py: snapshot_queue → slots_queue
- docs: interface-contract.md + runtime-flows.md slots.req 계약으로 업데이트 (REQ-075)
- REQ-028: Implemented → Deprecated (코드 삭제 완료)
- 테스트: test_snapshot_handler/selection/rpc_watchdog/messaging_snapshot_consumer 삭제;
test_slots_handler.py(신규, 13 cases), test_killswitch_masking_resume 재작성,
test_ledger_option_d._apply_cash_estimate → slots handler 경유, test_topology/cli_operator 갱신
BAT-036 (dcy-024): per-instance safety_sell_enabled 플래그
- config.py: DaemonInstanceConfig + DaemonConfig 에 safety_sell_enabled: bool = True 추가;
from_toml 파싱, from_config 전파
- daemon.py: start() workers 조건부 — safety_sell_enabled=false 시 trex-safety-sell 미기동 + WARNING
- tests: test_instance_config.py 에 safety_sell_enabled 파싱 3개 케이스 추가
REQ: 073/074/075/021/034/063/048/005 Approved → Implemented
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-11 14:45:45 +09:00
genichin and Claude Sonnet 4.6
fb05a73130
feat(rel-006): dcy-022/023 + BAT-032~034 — 실행 정책·qty 검증·allocated_capital 제거 통합
...
BAT-032 (dcy-022): timeout_sec/slippage_pct 실행 정책, 미체결 자동 취소,
보호 지정가, `trex-core cancel` 백스톱. 마이그레이션 012.
BAT-033: `trex-core enter --qty` 필수 검증 — 미지정 시 RPC 전 즉시 오류.
BAT-034 (dcy-023): allocated_capital 죽은 필드 전 경로 제거 (domain·intent·
persistence·snapshot·CLI). 마이그레이션 013(비가역 DROP). 외부 발신자
unknown key 무시 수신 의미론 적용.
REL-006 confirmed: BAT-026~034 통합 릴리즈, pre-release smoke 증거 포함.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-11 07:42:03 +09:00
genichin and Claude Opus 4.8
e4be4d60c2
feat(slot): dcy-021 포지션 사이징 — 보유 슬롯 증액·부분 매도 (BAT-031)
...
자산 영구 슬롯(dcy-020)의 수량 가변 전제 위에 보유 포지션 수량 조정 구현.
명령형 계약(전략이 cash+quantity 로 qty+price 계산), core 는 실행 substrate,
수량 정본 = 브로커 잔고 재동기화로 "주문 수량 vs 보유 수량" 충돌 해소(별도 필드 없음).
- state.py: holding→pending_buy 전이 추가(증액) → 13 transitions (REQ-057)
- service.py: PENDING_SELL 진입 qty=caller as-is(None=전량 sentinel, 값=부분 주문) (REQ-062)
- intents.py: 증액 admission(holding 슬롯 매수=increase, M 캡 미적용), SellIntent.qty 부분 매도 (REQ-061)
- execution.py: _balance_map; 매도 dispatch=브로커잔고(전량)/min(주문,잔고)(부분);
매수 체결 avg_price 가중평균+브로커 정본 resync; 매도 체결 잔고>0→holding/0→inactive;
증액 롤백 holding 복귀 (REQ-066/062)
- messaging_handlers.py: sell payload qty 파싱(부분 매도)
- baseline 4문서(data-model/runtime-flows/interface-contract/project-structure) 정합 (REQ-067)
검증: 단위 378 / 통합(PG+RabbitMQ) 422 passed, ruff clean. run-the-app 사이징 e2e:
매수 10@1000 → 증액 +5@1200 → 15@1066.67 (가중평균) → 부분 매도 6 → 9@1066.67 (cost basis) → 전량→inactive.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 18:53:37 +09:00
genichin and Claude Opus 4.8
c04fd276b3
feat(reset): cutover 도구 폐기 → trex-core-reset(DB 재초기화) 대체 (REQ-064 CHG-20260610-03)
...
실 DB 점검 중 마이그레이션 009 부분 유니크 인덱스가 legacy 풀 데이터(같은
자산이 closed+재진입 holding 으로 portfolio_id 중복)에 적용 불가 → cutover·
데몬 부팅 모두 차단되는 결함 확인. 데이터 보존 cutover 를 폐기하고 DB wipe +
자산 중심 재초기화로 전환(사용자 결정). 빈 테이블에는 009 인덱스가 정상
생성되고 자산 중심에서 (instance_key, portfolio_id)는 설계상 유일.
- trex_core/runtime/reset.py 신규(trex-core-reset): slot-core 7테이블 wipe +
apply_migrations 재적용 → 자산 중심 스키마 착지 검증. dry-run 기본/--yes 적용,
파괴적·DB 전역. 보유 carry-over 없음(재초기화 후 reconcile_core_holdings 재편입).
- runtime/cutover.py + trex-core-cutover console script + test_cutover_rehearsal.py 삭제.
- pyproject: trex-core-reset 등록.
- tests/runtime/test_reset.py 신규 5건(PG-gated): wipe+착지·dry-run 무변경·멱등·
wipe 후 admission·테이블 커버리지.
- change-req REQ-064 CHG-20260610-03(cutover→재초기화 재정의) + srs index 갱신.
- baseline 4문서(data-model/runtime-flows/project-structure/interface-contract)
+ BAT-030 design/planning/index/implementation/verification 도구 서술 reset 으로 교체.
검증: ruff clean, 단위 367 passed, PG+RabbitMQ 통합 411 passed/1 skip(KIS sandbox).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 16:08:05 +09:00
genichin and Claude Opus 4.8
7d727824dc
feat(slot): BAT-030 — 자산 중심 cutover 완성 (dcy-020 BAT-δ, REQ-056·057·062·064·065)
...
M1 literal inactive 전면화: SlotState 5-state(idle/closed 별칭 제거),
마이그레이션 010(CHECK 교체+행 rewrite), ops_checks 를 transition_log 기반 재작성.
M2 집행 매도 수량 브로커 정본(D3): dispatch 매도 qty=broker hldg_qty,
미러 fallback 없음, 브로커 0 → skip+WARN, 리스트 기반 dispatch(head-block 방지).
M3 컬럼 drop + legacy pool 제거: 마이그레이션 011(trading_date·entry_count DROP),
repo 계약 instance 스코프 개편(집행 큐 포함), preallocation 폐기(데몬 7스레드),
admission 자산 중심 단일 경로(slot_id 정본), capacity 재정의(available=M−active),
daily_symbol_entries 코드 경로 제거.
M4 cutover 도구(D1·D4): trex-core-cutover(전체 rebuild, preflight/브로커 carry-over/
--allow-unmapped/--promote-unique/dry-run) + PG 리허설 테스트 8건.
M5 baseline 마감: data-model/runtime-flows/project-structure/interface-contract
자산 중심 최종 갱신 + run-trex-core-daemon 스킬 정합.
검증: 단위 367 passed + ruff clean; PG-gated 29 passed(010/011 round-trip·드리프트
가드·cutover 리허설); RabbitMQ 21 passed; run-the-app e2e(test DB+실 MQ, M=1):
reconcile 슬롯 생성→slot_id 매수→dedup→capacity_full→fill→already_active→
매도→inactive(자산 바인딩 보존)→영구 슬롯 재활성 전 구간 green.
실 cutover 는 운영자 실행(REL 단계, D4).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 15:16:15 +09:00
genichin and Claude Opus 4.8
6e8e79660c
feat(slot): slot entry_count + closed-slot reallocation (dcy-019, BAT-025) + REL-005
...
dcy-019/issue #18 : slot 자원을 진입 횟수 기준으로 고르게 재사용하고 idle 소진 시
closed 슬롯을 직접 재할당한다. 거버넌스는 전부 change-req(신규 REQ 없음).
- 도메인(REQ-002): Slot.entry_count(기본 0) + EXPECTED_SLOT_FIELDS, 상태 머신
closed→pending_buy 신규 전이(base 8→9, ALLOWED_TRANSITIONS 14→15),
_apply_transition_fields closed→pending_buy clean-slate + →pending_buy 시 +1
- 영속화(REQ-006): 멱등 마이그레이션 008(entry_count), flat 매핑,
find_allocatable_slot(idle∪closed, entry_count→updated_at→slot_id) + in-memory 동등
- admission(REQ-007): _admit_buy find_idle_slot→find_allocatable_slot + from_state=slot.status
- 테스트(REQ-003): 전이 카운트/계약 가드 정합 + test_slot_entry_count.py / test_buy_admission_reallocation.py
- 문서(REQ-009): data-model.md / runtime-flows.md 정합
- 기존 daily_symbol_entries(symbol-scoped) 분리·미변경
BAT-025(release-candidate) delivery + change-req REQ-002/003/006/007/009(CHG-20260609-01).
REL-005(confirmed, app-service): BAT-024+BAT-025 묶음. operator-facing run-the-app
스모크로 enter --forced-close-at(BAT-024)·closed 재할당(BAT-025) 실 데몬 검증
(실 PG 마이그레이션 008 round-trip 포함).
검증: 단위 366 passed / 35 skipped(KIS sandbox 1건 deselect — live .env 환경 의존), ruff clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-09 14:49:22 +09:00
genichin and Claude Opus 4.8
2bfecd59a8
feat(ledger): dcy-018 option D cash/position write-back + 추정 현금 (BAT-023)
...
ledger write 응답의 portfolio-hub 권위 cash/quantity 를 스냅샷에 write-back 해
매수/매도 직후 "수량 live·현금 stale" 비대칭 제거(option D 활성화). portfolio-hub#8
(*_after 응답) 동작 중 확인으로 그간 deferred 됐던 REQ-030 을 닫음.
거버넌스: 전부 change-req (신규 REQ 없음, dcy-018 OQ-3 a).
- REQ-017: record_trade → LedgerWriteOutcome{result, cash_balance_after,
asset_quantity_after}. 어댑터가 응답 root flat *_after 파싱(new+duplicate, 누락 None)
- REQ-019: LedgerWriter 에 SnapshotStore 주입 → new+duplicate write-back
(best-effort, *_after 절대값이라 멱등). LedgerOutbox.pending_cash_delta()
- REQ-029: 추정 현금 오버레이(_apply_cash_estimate, cash_estimated 라벨, OQ-4 i)
+ 슬롯 오버레이 유지(OQ-1 B). 미정산 outbox delta 기반, write-back 수렴
- REQ-030: option D 활성화 → Approved→Implemented
best-effort 격리(NFR-1): write-back/추정 실패가 ledger 멱등·청산 무차단.
배치 번호: 동시 커밋된 BAT-022(slot-state, dcy-016)와 충돌해 BAT-023 으로 배정.
검증: 단위 350 passed/35 skipped, 인프라 게이트(PG+RabbitMQ) 385 passed, ruff clean.
신규 test_ledger_option_d + adapter/PG 테스트. BAT-023 release-candidate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-08 21:50:56 +09:00
genichin and Claude Opus 4.8
6d7bca1460
feat(safety-sell): dcy-017 워치독 소유권 가시화 — snapshot 상태 + 발동 로깅 (BAT-021)
...
전략 이탈로 슬롯이 내부 청산 루틴(워치독) 소유로 넘어간 상태가 무성이라
운영자가 인지할 수 없던 문제(issue #12 )를 가시화한다.
거버넌스: 전부 change-req (신규 REQ 없음, dcy-017 OQ-3; Redis 미채택).
- REQ-034/021: WatchdogStore.last_seen + snapshot RPC 응답에 holding 슬롯
워치독 상태(expired/last_seen) read-only 동봉(best-effort)
- REQ-032: trex-core slots 가 expired 슬롯을 WATCHDOG-OWNED(전략 이탈) 표시
- REQ-037/038/039: safety-sell 워치독 소유 진입(WARN)/이탈(INFO) + 발동
(forced_close·stop_loss=WARN, take_profit·market_close=INFO) 로그 +
in-process 카운터(SafetySellService.counters), 구조화 필드(slot_id/
portfolio_id/reason/phase/instance_key). per-tick 스킵은 카운터만
- REQ-042: runtime-flows/interface-contract 정합
best-effort 격리(NFR-1): 모든 가시화는 예외 격리 — 워치독 판정·청산 불변.
dcy-016 억제 읽기로 관측이 워치독을 리셋하지 않음(비침습).
검증: 단위 335 passed/34 skipped, 인프라 게이트(PG+RabbitMQ) 369 passed, ruff clean.
신규 test_safety_sell_visibility(6) + snapshot watchdog(1) + CLI(1). BAT-021 rc.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-08 17:10:26 +09:00
genichin and Claude Opus 4.8
d09b93195f
feat(cli): dcy-016 운영자 CLI 확장 (universe/slots/enter/exit) + 워치독 억제 (BAT-020)
...
운영자가 조회·매수·매도를 CLI 로 수행하되 데몬 RabbitMQ RPC 로 통일해 단일
writer admission·불변식을 보존(DB 직접 쓰기 없음)하고, 운영자 조회가 전략
생존 신호로 오인되지 않게 워치독을 억제한다.
거버넌스: 전부 change-req (신규 REQ 없음, dcy-016 OQ-3).
- REQ-032: CLI universe/slots(snapshot RPC) + enter(buy)/exit(sell) intent RPC
+ 인스턴스 라우팅(--config/--instance/default) + enter/exit 안전장치
(확인 프롬프트 기본 ON / --yes(paper) / --yes --live(이중 ack) / --dry-run)
+ 전 명령 --json. pause/resume 는 direct-DB 유지
- REQ-022: CLI request-reply RPC 클라이언트(call_rpc) 재사용
- REQ-021/034: snapshot 요청 워치독 억제 플래그(touch_watchdog/actor=operator)
→ 핸들러가 last_seen_at 갱신 스킵. 기본값 현행 유지(하위호환). 운영자
조회가 죽은 전략의 safety-sell 을 무력화하던 결함(R-4) 제거
- REQ-026: interface-contract/runtime-flows 정합
CLI 는 rpc/confirm 주입 가능(테스트 broker/DB-free). snapshot envelope 은
asset-centric 이라 exit 은 운영자 제공 slot_id 사용(slot_id 노출은 본 주기 밖).
검증: 단위 327 passed/34 skipped, 인프라 게이트(PG+RabbitMQ) 361 passed, ruff clean.
신규 test_cli_operator(14) + snapshot 워치독 억제(2). BAT-020 release-candidate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-08 16:48:26 +09:00
genichin and Claude Opus 4.8
b851b927ee
fix(ledger): dcy-015 outbox 영속 오류 분류 + 백오프/dead-letter (BAT-019)
...
portfolio-hub 404(미등록 포트폴리오)가 retryable 로 분류되어 백오프·상한 없이
초당 영구 재시도되던 버그(issue #13 , 실측 930회) 정정.
거버넌스: 전부 change-req (신규 REQ 없음, dcy-015 OQ-3; 백오프 env 는 REQ-019 흡수).
- REQ-017: 404/400/422 → LedgerPermanentError 분류 (409 conflict / 408·429·5xx·
network retryable 불변). LedgerPort 에 permanent 타입 추가
- REQ-019: 영속 → 터미널 delivery_failed 즉시(재시도 0). retryable 지수 백오프
+jitter+next_retry_at, max_attempts 초과 시 dead-letter delivery_failed.
list_pending 이 백오프 행 스킵(head-of-line 보호). 마이그레이션 007(status enum
+next_retry_at). 백오프 env(base/cap/max-attempts)
- REQ-018: 터미널/dead-letter WARN + WriterStats.delivery_failed 카운터 가시화
- REQ-020: runtime-flows/data-model/interface-contract 정합
단일 터미널 delivery_failed(permanent/dead-letter, last_outcome 로 사유 구분) —
conflict_blocked 패턴과 동형. dead-letter 는 운영자 재처리 가능 상태.
검증: 단위 311 passed/34 skipped, 인프라 게이트(PG+RabbitMQ) 345 passed, ruff clean.
신규 test_ledger_outbox_backoff + adapter/PG 테스트, 기존 retryable 백오프 정합.
BAT-019 release-candidate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-08 16:12:17 +09:00
genichin and Claude Opus 4.8
0b7db66463
feat(runtime): dcy-014 trading_date KST 타임존 분리 + 일일 슬롯 preallocation (BAT-018)
...
데몬이 시스템 UTC 날짜로 슬롯을 1회만 preallocate 해 trading_date 가 KST 캘린더와
어긋나고 재시작 없이는 다음날 슬롯이 안 생기던 문제(issue #14 ) 정정.
거버넌스: 전부 change-req (신규 REQ 없음, dcy-014 OQ-3; 스케줄러는 REQ-030 패턴 준용).
- REQ-005: trading_date 를 설정 타임존(기본 Asia/Seoul) 기준 계산(timestamp 는 UTC
유지). DailyPreallocationScheduler 신규 — TZ 일자당 1회 멱등 fire, 재시작 없이
다음날 슬롯 자동 생성. setup() 배선 + trex-preallocation 스레드
- REQ-048: TOML trading_timezone/daily_preallocation_time 키 + from_config 전파
- REQ-009: runtime-flows/data-model 정합 + instance.example.toml
OQ-1 기본 00:00(TZ 자정, TOML 설정 가능) / OQ-2 매 캘린더일 생성(거래일 캘린더 후속).
멱등 preallocate 로 중복 tick·다중 인스턴스 중복 생성 0.
검증: 단위 302 passed/32 skipped, 인프라 게이트(PG+RabbitMQ) 334 passed, ruff clean.
신규 test_preallocation_scheduler(고정 clock) + test_instance_config 확장.
BAT-018 release-candidate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-08 15:39:04 +09:00
genichin and Claude Opus 4.8
4746f74aae
fix(broker): dcy-013 KIS 외부 취소 감지 + 부분 체결 회계 + stale 워치독 (BAT-017)
...
KIS 계좌에서 직접 매도 주문을 취소하면 poll_fill 이 cncl_yn 을 파싱하지 않아
슬롯이 pending_sell 에 영구히 갇히고 죽은 주문을 무한 폴링하던 버그(issue #9 )
정정.
거버넌스: 전부 change-req (신규 REQ 없음, dcy-013 OQ-3).
- REQ-012: KIS poll_fill cncl_yn 파싱 → 외부 취소 감지. FillStatus.cancelled
/is_partial_cancel 추가. 체결 0 취소→cancelled, 부분 체결 후 취소→partial+cancelled
- REQ-013: 집행 _on_partial_cancel — 체결분 원장 1회 + qty 차감(매도 잔여/매수 체결분)
+ holding 복귀 (OQ-1 A안). 전량 취소는 기존 롤백 경로 재사용
- REQ-018: 부분 체결분 원장 1회 기록 (_record_ledger 재사용)
- REQ-031: 잔여 포지션 정합 연계 (slot.qty ↔ 실 잔고, 과매도 방지)
- REQ-014: pending stale 워치독 Alert-only (TREX_PENDING_STALE_THRESHOLD,
WARN+카운터, 상태 미변경) — 취소 감지 누락 backstop
- REQ-015: interface-contract/runtime-flows 정합
전량 취소는 holding 자동 복구(limit_price clear→재매도 시장가, dcy-012 연계).
KIS cncl_yn 실 규약은 운영 검증(미지 값 보수 처리 + 워치독 backstop).
검증: 단위 294 passed/32 skipped, 인프라 게이트(PG+RabbitMQ) 326 passed, ruff clean.
신규 test_kis_cancel(httpx stub) + test_execution_cancel(programmable broker).
BAT-017 release-candidate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-08 14:11:49 +09:00
genichin and Claude Opus 4.8
cc28e1fba5
fix(execution): dcy-012 매도 가격 버그 정정 — slot entry_price→limit_price rename (BAT-016)
...
매도(sell) 주문이 현재가가 아닌 매수가(entry_price) 지정가로 나가던 버그(issue #10 )
정정. 슬롯의 매수 전용 entry_price 를 side 무관 "현재 pending 주문 지정가"
limit_price 로 내부 rename 하고, pending 이탈(→holding/→closed) 시 clear 해
매수 지정가가 매도로 누수되는 경로를 구조적으로 제거.
거버넌스: 전부 change-req (신규 REQ 없음, dcy-012 OQ-3).
- REQ-002: Slot entry_price→limit_price rename + clear-on-exit 생애주기
- REQ-006: daily_slot 컬럼 rename 마이그레이션 006 (idempotent) + persistence 매핑
- REQ-013: _dispatch 가 slot.limit_price 단일 필드로 가격/주문유형 결정
- REQ-007: SellIntent/sell payload optional limit_price + _admit_sell 운반
- REQ-036: SlotService.sell optional 가격 → 자율 매도(safety-sell/kill-switch) 시장가
- REQ-003: 컬럼 계약/드리프트 가드 limit_price 반영
- REQ-015: runtime-flows/interface-contract/data-model 정합
매도 정책(OQ-1 하이브리드): 가격 지정→지정가("00"), 미지정→시장가("01").
자율 매도는 가격 미전달 → 항상 시장가 (손절 미체결 pending_sell 갇힘 방지, issue #9 연계).
검증: 단위 286 passed/32 skipped, 인프라 게이트(PG+RabbitMQ) 318 passed, ruff clean.
신규 test_sell_pricing(recording broker)로 지정가 매수 슬롯의 매도가 매수가
재사용 안 함을 직접 검증. BAT-016 release-candidate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-08 13:41:46 +09:00
genichin and Claude Opus 4.8
aee3512383
feat(intents): dcy-011 buy intent portfolio_id 필수 계약 + ledger skip 가시화 (BAT-015)
...
dcy-011 전 주기 delivery. issue #6(buy 식별자 정정) + issue #11(ledger silent skip) 흡수.
거버넌스: 기존 Implemented REQ는 change-req, 신규 기능만 신규 REQ(OQ-3).
- REQ-007 (change-req): buy admission portfolio_id 필수화 + SnapshotStore symbol
resolve + unknown_portfolio 거부 (hard cutover, OQ-1/OQ-2)
- REQ-021 (change-req): buy 메시지 payload symbol 제거
- REQ-018 (change-req): _record_ledger skip 가시화 (WARN + ledger_skipped 카운터)
- REQ-055 (신규): closed↔ledger_outbox anti-join 운영 점검 find_ledger_gap_slots
코드: intents.py(BuyIntent portfolio_id 필수 + resolve_symbol 주입 + _admit_buy
reject 분기), messaging_handlers.py, runtime/daemon.py(_resolve_symbol 배선),
execution.py(skip WARN 로그), adapters/persistence/ops_checks.py(신규 anti-join).
검증: 단위 282 passed/32 skipped, 인프라 게이트(PG+RabbitMQ) 314 passed, ruff clean.
BAT-015(standard) release-candidate. srs/index Next ID → REQ-056.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-08 12:57:51 +09:00
genichin and Claude Opus 4.8
565af6792c
feat(safety-sell): dcy-010 BAT-014 — 영속 거부 재시도 쿨다운 (REQ-052~054)
...
dcy-010(safety-sell 영속 거부 재시도 백오프) 전체 SDLC: draft-req → confirm-req →
draft-batch(BAT-014 batch-lite) → run-batch-delivery → confirm-req-implemented.
2026-06-07 실 KIS LIVE SL/TP e2e에서 발견한 KIS 주문 spam 위험(영속 거부 시
매도 무한 재제출) 차단.
- REQ-052 (Integration): SafetySellService per-slot 인메모리 쿨다운
(_in_cooldown/_attempt_sell/_prune_cooldown) — forced_close·stop-loss·take-profit
트리거에 min_retry_interval_sec(600s) 이내 재시도 skip(가격 poll 포함) +
max_retry_warn_count(3) 도달 시 WARNING + holding 이탈 정리. market_close 제외.
- REQ-053 (Configuration): SafetySellConfig min_retry_interval_sec/max_retry_warn_count
+ TREX_SAFETY_SELL_MIN_RETRY_INTERVAL/MAX_RETRY_WARN_COUNT env (additive)
- REQ-054 (Documentation): runtime-flows 쿨다운 flow + 가격체크 tr_id(FHKST01010100) 정정
인메모리 only(DB/스레드/인터페이스 변경 없음), default 미설정 시 기존 동작 불변.
검증: 신규 8 단위(쿨다운 6 + config 2), 전체 278 passed, ruff clean.
REQ-052~054 Implemented, BAT-014 release-candidate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-08 00:35:11 +09:00
genichin and Claude Opus 4.8
9f83c64a40
feat(multi-instance): dcy-009 BAT-013 — RabbitMQ 다중 인스턴스 토폴로지 (REQ-048~051)
...
dcy-009(다중 인스턴스 RabbitMQ 토폴로지) 전체 SDLC: draft-req → confirm-req →
draft-batch(BAT-013) → run-batch-delivery → confirm-req-implemented.
- REQ-048 (Configuration): DaemonInstanceConfig.from_toml + DaemonConfig.from_config
(env 병합, portfolio_hub_token 주입) + 데몬 --config 필수 argparse + .gitignore 인스턴스
TOML + config/instance.example.toml
- REQ-049 (Interface): topology 동적 큐명 빌더 intent/snapshot/control_queue(instance_key)
— default=리터럴 큐명(하위호환), named=`{base}.{instance_key}` + daemon per-instance 구독
- REQ-050 (Integration): trex.direct(topic)/trex.broadcast(fanout) exchange +
declare_topology(instance_key) per-instance binding + control dual binding + direct_routing_key
- REQ-051 (Documentation): interface-contract/runtime-flows/project-structure 정합
하위호환: instance_key="default" → 기존 리터럴 큐명·RPC 경로 무회귀(FR-5).
split-brain 방지(NFR-3): 인스턴스 전용 큐. 민감값(NFR-4): TOML + gitignore.
검증: 신규 9 단위 + RabbitMQ 라우팅 2, 단위 271 passed,
인프라 게이트 301 passed(directed 격리 S-2 + broadcast dual S-3 + default 무회귀 S-4),
ruff clean. REQ-048~051 Implemented, BAT-013 release-candidate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-07 15:10:36 +09:00
genichin
7e23648489
feat: add kill-switch control flow
2026-06-07 14:00:20 +09:00
genichin and Claude Opus 4.8
a30efa8f3b
feat(safety-sell): dcy-007 core 자율 안전 매도 — BAT-010 기반 + BAT-011 트리거
...
dcy-007(core 자율 안전 매도) 전체 delivery. BAT-010 기반 인프라가 미커밋
상태였고 BAT-011 트리거 레이어와 공유 파일에서 섞여 있어 한 커밋으로 묶음.
BAT-010 (REQ-034/035/036/041, release-candidate):
- WatchdogStore(application/watchdog.py) + snapshot RPC 워치독 갱신
- Slot stop_loss_price/take_profit_price 필드 + 004_add_price_thresholds.sql
- SlotService.sell() 자율 매도 내부 경로 + idempotency
- SafetySellConfig env 5종 파싱
BAT-011 (REQ-037/038/039/040/042, release-candidate):
- SafetySellService(application/safety_sell.py): forced_close 만기 / stop-loss·
take-profit KIS polling / 장 마감 강제 청산 + trex-safety-sell 7번째 스레드
- BrokerPort.get_current_price + KIS inquire-price(TTTC8397R/VTTC8397R, stck_prpr)
+ paper stub
- SlotService.update_thresholds() + intent RPC update_thresholds 액션
(부분 갱신/null 해제, 워치독 last_seen_at 리셋)
- baseline 3문서 정합(interface-contract/runtime-flows/project-structure)
거버넌스: REQ-034~042 Implemented 동기화, BAT-010/011 release-candidate,
dcy-007 discovery 포함.
검증: 신규 38 테스트 green, 단위 236 passed/23 skipped,
인프라 게이트(PG+RabbitMQ) 259 passed(마이그레이션 001~004 round-trip 포함),
ruff clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-07 08:32:30 +09:00
genichin
ca757009f5
feat: add portfolio snapshot read layer
2026-06-06 09:33:00 +09:00
genichin
6c7a1cf6f6
feat: add messaging transport rollout
2026-06-06 00:02:52 +09:00
genichin
aed54911d4
chore: commit current workspace changes
2026-06-04 23:38:42 +09:00
genichin and Claude Opus 4.8
97d58318db
Deliver BAT-004: broker execution + KIS adapter + durable handoff
...
Implement REQ-011~015 (dcy-003): the order-execution layer on top of the
BAT-002 slot-core daemon, connecting intents to real orders.
- application: BrokerPort (submit/poll_fill/cancel) + ExecutionService
(claim -> submit -> poll -> transition -> rollback -> reconcile)
- adapters/broker: PaperBroker (deterministic async double) and KISBroker
(KIS Open API: token, order-cash, inquire-daily-ccld, cancel; VTS sandbox
tr_ids; live account gated behind allow_live)
- persistence: option-A execution queue (find_pending_for_dispatch FOR
UPDATE SKIP LOCKED, mark_dispatched idempotency guard, clear_dispatch)
- runtime: background execution loop in the daemon lifespan + startup
reconcile; config selects paper|kis
Verification (real KIS VTS 모의투자 + PostgreSQL): 92 passed, ruff clean,
domain import sweep shows zero broker/web/db deps, buy->holding /
sell->closed / reject->idle, idempotent dispatch (exactly one order),
reconcile after crash creates no duplicate order, KIS sandbox token+submit
round-trip, and a daemon E2E through the background loop. Align the four
baseline docs. BAT-004 -> release-candidate; REQ-011~015 -> Implemented.
KIS live-account go-live, partial-fill accrual, option-B outbox, connection
pooling, and the safety floor remain deferred to follow-up Discoveries.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-04 17:46:17 +09:00
genichin and Claude Opus 4.8
a4e263c8e7
Deliver BAT-002: slot-core daemon + HTTP intent API + PostgreSQL
...
Implement REQ-005~009 (dcy-002 slice 1) as an onion stack on top of the
BAT-001 pure domain:
- application: IntentService (admission + single-writer transition +
intent_id idempotency via durable intent_log)
- adapters/persistence: PostgreSQLSlotRepository + PostgreSQLIntentStore +
trex-core-owned migrations (daily_slot per Appendix A, daily_symbol_entries,
slot_transition_log, intent_log) + in-memory intent store
- adapters/api: FastAPI /v1 (healthz, intents/buy|sell|{id}, slots, capacity)
- runtime: trex-core-daemon entrypoint with lifespan migrate+preallocate
Verification (against local PostgreSQL 18): 74 passed, ruff clean, domain
import sweep shows zero web/db deps (NFR-1), 20-thread concurrency admits
exactly the idle count (NFR-2), idempotent resubmit causes no double
transition (NFR-3), EXPECTED_SLOT_FIELDS<->information_schema drift test
(realizes dcy-001 OQ-2's deferred DB-side check), and a daemon E2E smoke.
Align all four baseline docs to the new daemon/API/persistence layers.
BAT-002 -> release-candidate; REQ-005~009 -> Implemented. Full async outbox,
broker execution, safety floor, and strategy daemons remain deferred to a
follow-up Discovery.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-04 13:46:08 +09:00
genichin and Claude Opus 4.8
20498aa4ce
Deliver BAT-001: bootstrap trex-core + port slot pure domain
...
Implement REQ-001~004 (dcy-001): scaffold the trex-core package
(pyproject, trex_core/, tests/), port the slot pure domain into
trex_core.domain.slot with import rewrites, add the EXPECTED_SLOT_FIELDS
contract guard (test_contract), and port the state/service unit tests.
Verification: 56 passed, ruff clean, import sweep shows zero external
deps, public __all__ exposes no infra symbols, contract negative case
reproduced. Align project-structure/runtime-flows baselines to the real
tree. Sync SDLC tracking: REQ-001~004 → Implemented, BAT-001 →
release-candidate.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-04 00:16:07 +09:00
genichin and Claude Opus 4.8
b40e569537
Bootstrap StagePilot baseline for slot domain migration
...
Initialize baseline seed, four baseline docs (project-structure,
runtime-flows, interface-contract, data-model), and the active
discovery/srs/batches/releases indexes. Content derived from the
trex-orbit slot pure-domain migration plan (trex-core as a new base,
pure domain only).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-03 09:47:14 +00:00