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
63da87c9b3
fix(cli): BAT-022 slots 명령이 universe 대신 실제 슬롯 상태 표시 (dcy-016 후속)
...
`trex-core slots` 가 snapshot RPC 의 universe `assets`(portfolio)를 슬롯 상태로
오인 표시하던 갭 정정. snapshot envelope 이 슬롯 상태를 운반하지 않아 발생
(10개 슬롯인데 universe 1개·status 없음 — BAT-007 HTTP 슬롯 read 제거 후
슬롯 상태 read 표면 부재가 근인).
- REQ-028 (CHG-20260608-01): snapshot envelope 에 read-only per-slot `slots[]`
additive 추가(AC-4). strategy `assets[]`(universe, no-price) 불변.
- REQ-032 (CHG-20260608-03): `_cmd_slots` 가 envelope `slots[]`(실제 슬롯 상태)
표시 + `--status` 를 슬롯 status 기준 client-side 필터 + watchdog 결합.
`universe` 는 `assets[]` 유지. `universe --json` 도 universe 데이터로 scope.
- canonical `portfolio.slot_to_dict` 단일화 — BAT-007 stub / BAT-008 envelope
두 경로가 동일 슬롯 스키마(외부명 `entry_price` 유지, dcy-012 호환).
- interface-contract 에 `slots[]` 계약 + `assets[]` vs `slots[]` 구분 반영.
검증: 단위 338 passed + ruff clean + 신규 코드 데몬으로 실 PostgreSQL/RabbitMQ
운영 재현 PASS(slots=10·status·DB 일치·universe 분리·비침습). REQ-028/032
Implemented, BAT-022 release-candidate. pytest 인프라 게이트는 Human Approval
Memo 수용(운영 재현이 실 경로 커버).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-08 19:54:42 +09:00
genichin and Claude Opus 4.8
a570ac659e
fix(daemon): buy 심볼 resolver 결함 수정 + REL-004 draft (운영자 run 증거)
...
REL-004(미릴리즈 BAT-014~021 통합) draft-release 작성. confirm-release 전
운영자 프로그램 run-the-app 검증(실 데몬 + trex-core CLI e2e)을 수행했고,
369 passed 가 놓친 실 프로덕션 버그를 검출·수정했다.
- fix(REQ-007 CHG-20260608-03): Daemon._resolve_symbol 이 SnapshotAsset.symbol
(없는 속성)을 접근 → 데몬 buy admission 매 요청 AttributeError → intent RPC
타임아웃(실 데몬 매수 전면 불능). asset.item.symbol 로 수정. 단위 테스트가
stub resolver 를 주입해 실 배선을 한 번도 실행하지 않아 미검출이었음
- test: tests/runtime/test_daemon_resolve_symbol.py — 실 Daemon._resolve_symbol
× 실 SnapshotStore 회귀 가드(수정 전 실패하는 테스트)
- docs(release): rel-004 draft(app-service, BAT-014~021) + Pre-Release Run
Evidence(데몬 기동 + universe/slots/enter/exit e2e + ledger completed +
버그 검출·수정 + LIVE 미검증 한계) + releases/index REL-004 행
검증: 실 데몬 재기동 후 buy/sell e2e admitted→체결→closed + ledger completed,
단위 337 passed, ruff clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-08 17:38:34 +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
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
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
c912c08071
docs(req): dcy-008 kill-switch confirm-discovery + REQ-043~047 (Approved)
...
dcy-008(비상 정지/kill-switch) OQ-2(별도 테이블/store)·OQ-4(수동 해제
resume_kill_switch) 결정 → confirm-discovery(confirmed) → draft-req →
confirm-req(5개 Approved).
- REQ-043 (Interface): trex.pause.req → trex.control.req 제어 채널 + action dispatch (OQ-1)
- REQ-044 (Data): day-scoped killswitch_exclusion 테이블 + store + 005 마이그레이션 (OQ-2)
- REQ-045 (Interface): kill_switch 실행 — 범위별 holding 순차 sell() + idempotency + 이력 (NFR-1/2 흡수)
- REQ-046 (Interface): 당일 제외 masking + 다음 거래일 자동복귀 + resume_kill_switch (OQ-4, NFR-3 흡수)
- REQ-047 (Documentation): baseline 3문서 정합
OQ-3(pending_buy 롤백)은 REQ Deferred. srs index Next ID REQ-048, Register +5,
요약 갱신. dcy-008 생성된 REQ 참조 기록.
dcy-009(멀티 인스턴스 RabbitMQ, draft)는 별도 주제로 제외.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-07 11:29:31 +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 and Claude Opus 4.7
515af7a068
docs(srs): REQ-029 CHG-04 — orb-v1 snapshot consumption note
...
Record that the first strategy (orb-v1) queries view=buyable without a
strategy_key, so missing PortfolioItem strategy fields are harmless for the
single-strategy stage. Documentation-only; REQ-029 stays Implemented.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-06-06 10:34:40 +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 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
a44f9fddb7
Draft+approve REQ-005~009 from dcy-002 (slot-core daemon + API)
...
Decompose dcy-002 FR-1~FR-6 into five requirements and promote them to
Approved (gate passed; source dcy-002 confirmed):
- REQ-005 (Installation): slot-core daemon runtime + lifecycle/healthz
- REQ-006 (Data): PostgreSQL SlotRepository + schema + drift test
- REQ-007 (Interface): intent submission API + idempotency
- REQ-008 (Interface): read-only slot/capacity query API
- REQ-009 (Documentation): daemon/API/persistence baseline alignment
NFR-1/2/3 absorbed into REQ-006/007 acceptance. Update SRS index
(Next ID -> REQ-010, register, change log) and dcy-002 created-REQ refs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-04 11:12:34 +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