feat(config): expose paper broker tuning via env (REQ-010 AC-5, BAT-009)
Wire the existing PaperBroker scenario knobs (fill_after_polls / qty_per_poll / reject_symbols) to daemon env so REQ-011 AC-2 e2e scenarios (delayed / partial / reject) can be reproduced by a daemon restart. Unset == prior PaperBroker() behaviour, byte-for-byte (no regression). - config.py: PaperBrokerConfig + from_env parsing (TREX_PAPER_*) - daemon.py: _build_broker injects config.paper into PaperBroker - .env.example: document the 3 paper tuning keys (paper-only, e2e) - tests: paper broker defaults + env tuning parsing SDLC: REQ-010 CHG-20260606-01 (AC-5 added) / -02 (Implemented); BAT-009 batch-lite release-candidate; REL-001 feedback handoff records pre-deployment e2e observations incl. event-publisher idle-drop and paper correlation_id collision (GitHub #4, #5). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
# BAT-009 Implementation
|
||||
|
||||
- Status: completed
|
||||
- Batch: BAT-009
|
||||
|
||||
## Plan Summary
|
||||
- REQ-010 CHG-20260606-01 / AC-5: paper broker 튜닝 knob(REQ-011 AC-2 지연/부분/거부)을 데몬 env 로 노출. 미설정=기존 `PaperBroker()` 동작 byte-for-byte(회귀 없음).
|
||||
|
||||
## Changed Files
|
||||
- trex_core/runtime/config.py: `PaperBrokerConfig` frozen dataclass(`fill_after_polls:int=0`, `qty_per_poll:Optional[int]=None`, `reject_symbols:frozenset[str]=frozenset()`). `DaemonConfig.paper` 필드(broker=='paper' 일 때만 참조). `from_env()` 에서 `TREX_PAPER_FILL_AFTER_POLLS`(int, 기본 0), `TREX_PAPER_QTY_PER_POLL`(빈 문자열→None), `TREX_PAPER_REJECT_SYMBOLS`(콤마 분리, 공백/빈 토큰 제거→frozenset) 파싱.
|
||||
- trex_core/runtime/daemon.py: `_build_broker` paper 분기를 `PaperBroker(fill_after_polls=config.paper.fill_after_polls, qty_per_poll=config.paper.qty_per_poll, reject_symbols=set(config.paper.reject_symbols))` 로 교체.
|
||||
- .env.example: `TREX_BROKER=paper` 아래 paper 튜닝 키 3개 주석 문서화(미설정=즉시 전량 체결·거부 없음).
|
||||
- tests/runtime/test_config_dotenv.py: `_KEYS` 에 3개 키 추가, `test_paper_broker_defaults`(미설정=0/None/frozenset()), `test_paper_broker_env_tuning`(FILL_AFTER_POLLS=2, QTY_PER_POLL=4, REJECT_SYMBOLS="005930, 000660 ," → 2/4/{005930,000660}).
|
||||
|
||||
## Execution Log
|
||||
1. `PaperBrokerConfig` dataclass + `DaemonConfig.paper` 필드 추가(기본값 = 기존 `PaperBroker()` 동작).
|
||||
2. `from_env()` env 파싱(빈 문자열/공백 토큰 정규화).
|
||||
3. `_build_broker` paper 분기 주입 + `.env.example` 문서화.
|
||||
4. 단위테스트 2개 추가, 좁은 테스트 → 전체 회귀 → ruff 순서로 검증.
|
||||
|
||||
## Validation
|
||||
- `pytest tests/runtime/test_config_dotenv.py`: **6 passed**(기존 4 + 신규 2).
|
||||
- 전체 `pytest --deselect ...::test_sandbox_token_and_submit`(네트워크 의존 KIS sandbox 제외): **167 passed, 23 skipped**.
|
||||
- `ruff check trex_core tests`: All checks passed.
|
||||
- e2e(별도, verification.md 에 상세): 데몬 env 재기동으로 거부 롤백 `idle→pending_buy→idle`, 지연 체결 `+3.7s`, 부분 체결 qty 6 누적 `+2.5s` 재현.
|
||||
|
||||
## Remaining Risks
|
||||
- 없음(저위험). broker=='paper' 일 때만 참조(kis 경로 무시), 미설정=기존 동작. 빈/공백 토큰 edge 는 단위테스트로 고정.
|
||||
@@ -0,0 +1,32 @@
|
||||
# BAT-009: paper broker 튜닝 env 노출 (minor-change)
|
||||
|
||||
- Status: release-candidate
|
||||
- Profile: batch-lite
|
||||
- Source Discovery: dcy-002 (REQ-010 데몬 설정 편의) — 동기는 dcy-003/REQ-011 e2e 시나리오 재현(Notes 참조)
|
||||
- Included REQ: REQ-010 (CHG-20260606-01, AC-5)
|
||||
- Excluded REQ: 없음
|
||||
|
||||
## Summary
|
||||
- REQ-010 CHG-20260606-01 로 추가된 AC-5(paper broker 튜닝 env 노출)를 delivery 하는 minor-change batch-lite. REQ-011 AC-2 가 이미 요구하는 paper 더블의 결정적 시나리오(지연/부분/거부)를 데몬 재기동만으로 재현할 수 있도록, 기존 `PaperBroker` 생성자 knob 을 `.env`/OS env(`TREX_PAPER_FILL_AFTER_POLLS`/`TREX_PAPER_QTY_PER_POLL`/`TREX_PAPER_REJECT_SYMBOLS`)로 노출한다. 미설정이면 기존 `PaperBroker()` 동작과 byte-for-byte 동일(회귀 없음).
|
||||
|
||||
## Scope
|
||||
- In Scope:
|
||||
- `runtime/config.py`: `PaperBrokerConfig` frozen dataclass + `DaemonConfig.from_env()` 파싱(빈 문자열 → None/frozenset 정규화).
|
||||
- `runtime/daemon.py`: `_build_broker` paper 분기에서 `config.paper` 주입.
|
||||
- `.env.example`: paper 튜닝 키 3개 문서화(미설정=production-like 기본).
|
||||
- `tests/runtime/test_config_dotenv.py`: 기본값(test_paper_broker_defaults) + env 파싱(test_paper_broker_env_tuning).
|
||||
- Out of Scope:
|
||||
- PaperBroker 내부 체결 로직 변경(REQ-011 에서 이미 구현·검증).
|
||||
- kis broker 경로(`broker=kis` 시 paper config 무시).
|
||||
- 부분 매도(수량 일부) 등 신규 능력(별도 Discovery/REQ).
|
||||
|
||||
## Documents
|
||||
- Planning: [planning.md](./planning.md)
|
||||
- Design: none (batch-lite with no architecture impact)
|
||||
- Implementation: [implementation.md](./implementation.md)
|
||||
- Verification: [verification.md](./verification.md)
|
||||
|
||||
## Notes
|
||||
- minor-change: 기존 PaperBroker 생성자 인자를 config 표면으로 노출하는 additive 변경. BrokerPort 계약·슬롯 런타임 흐름 불변, design 불요.
|
||||
- 동기 출처: REQ-011(dcy-003) e2e 시나리오 재현 필요. REQ-010(dcy-002) 의 설정 로딩 메커니즘 위에 키를 얹는 형태라 REQ-010 change-req 로 귀속.
|
||||
- 구현 코드는 본 batch 생성 시점에 이미 working tree 에 존재(미커밋). verification stage 에서 단위테스트(166 pass) + e2e evidence(거부 롤백/지연/부분)를 verification.md 에 정리한다.
|
||||
@@ -0,0 +1,32 @@
|
||||
# BAT-009 Planning
|
||||
|
||||
- Status: confirmed
|
||||
- Batch: BAT-009
|
||||
- Profile: batch-lite
|
||||
|
||||
## Included REQ
|
||||
- REQ-010 (Configuration): 데몬 설정 .env 로딩 — CHG-20260606-01 / AC-5 (paper 튜닝 env 노출)
|
||||
|
||||
## Delivery Plan
|
||||
1. `runtime/config.py`: `PaperBrokerConfig(fill_after_polls:int=0, qty_per_poll:Optional[int]=None, reject_symbols:frozenset[str]=frozenset())` 추가. `DaemonConfig` 에 `paper: PaperBrokerConfig` 필드(broker=='paper' 일 때만 참조). `from_env()` 에서 `TREX_PAPER_FILL_AFTER_POLLS`(int, 기본 0), `TREX_PAPER_QTY_PER_POLL`(빈 문자열→None), `TREX_PAPER_REJECT_SYMBOLS`(콤마 분리, 공백/빈 토큰 제거→frozenset) 파싱.
|
||||
2. `runtime/daemon.py`: `_build_broker` paper 분기를 `PaperBroker(fill_after_polls=..., qty_per_poll=..., reject_symbols=set(...))` 로 교체.
|
||||
3. `.env.example`: `TREX_BROKER=paper` 아래 paper 튜닝 키 3개 주석 문서화(미설정=즉시 전량 체결·거부 없음).
|
||||
4. `tests/runtime/test_config_dotenv.py`: `_KEYS` 에 3개 키 추가, `test_paper_broker_defaults`(미설정=0/None/frozenset()), `test_paper_broker_env_tuning`(FILL_AFTER_POLLS=2, QTY_PER_POLL=4, REJECT_SYMBOLS="005930, 000660 ," → 2/4/{005930,000660}).
|
||||
|
||||
## Dependencies
|
||||
- Internal: REQ-011 PaperBroker(생성자 knob 이미 존재), REQ-010 dotenv 로딩 메커니즘.
|
||||
- External: 없음.
|
||||
|
||||
## Design Gate
|
||||
- Design Required Before Implementation: no
|
||||
- Reason: 기존 PaperBroker 생성자 인자를 config/env 표면으로 노출하는 additive wiring. 외부 인터페이스(BrokerPort)·슬롯 런타임 흐름 변경 없음. 미설정 시 기존 동작과 byte-for-byte 동일. batch-lite + design 생략(minor-change).
|
||||
|
||||
## Milestones
|
||||
1. M1 — PaperBrokerConfig + from_env 파싱.
|
||||
2. M2 — _build_broker 주입 + .env.example 문서화.
|
||||
3. M3 — 단위테스트 green(기본/파싱) + ruff clean + 전체 회귀(166 pass).
|
||||
4. M4 — e2e 시나리오 evidence(거부 롤백 `idle→pending_buy→idle`, 지연 `+3.7s`, 부분 qty 누적 `+2.5s`).
|
||||
|
||||
## Risks
|
||||
- R-1 (Low): env 오설정이 production 데몬 동작을 바꿈. 대응: broker=='paper' 일 때만 참조(kis 경로 무시), 미설정=기본 동작, `.env.example` 에 "e2e 전용" 명시.
|
||||
- R-2 (Low): 빈 문자열/공백 토큰 파싱 edge. 대응: `qty_per_poll` 빈 문자열→None, `reject_symbols` 빈/공백 토큰 제거 — 단위테스트로 고정.
|
||||
@@ -0,0 +1,27 @@
|
||||
# BAT-009 Verification
|
||||
|
||||
- Status: confirmed
|
||||
- Batch: BAT-009
|
||||
|
||||
## Acceptance Mapping
|
||||
- REQ-010 (CHG-20260606-01):
|
||||
- AC1 `.env` 로드 → `test_loads_values_from_dotenv`. **PASS** (BAT-003 기존, 회귀 재확인)
|
||||
- AC2 OS env 우선 → `test_os_env_takes_precedence_over_dotenv`. **PASS** (BAT-003 기존)
|
||||
- AC3 `.env` 부재 회귀 → `test_no_dotenv_uses_os_env_only`. **PASS** (BAT-003 기존)
|
||||
- AC4 `.gitignore` → `.env` 무시 / `.env.example` 추적. **PASS** (BAT-003 기존)
|
||||
- **AC5 (본 batch)** paper 튜닝 env 파싱 + `_build_broker` 주입, 미설정=기본 동작 byte-for-byte:
|
||||
- 단위: `test_paper_broker_defaults`(미설정 → fill_after_polls=0, qty_per_poll=None, reject_symbols=frozenset()). **PASS**
|
||||
- 단위: `test_paper_broker_env_tuning`(FILL_AFTER_POLLS=2 / QTY_PER_POLL=4 / REJECT_SYMBOLS="005930, 000660 ," → 2 / 4 / {005930,000660}). **PASS**
|
||||
- e2e(데몬 env 재기동): 거부(`TREX_PAPER_REJECT_SYMBOLS=999999`) → `idle→pending_buy→idle` 롤백; 지연(`TREX_PAPER_FILL_AFTER_POLLS=3`) → `pending_buy→holding +3.7s`; 부분(`TREX_PAPER_QTY_PER_POLL=2`, qty 6) → holding qty 6 누적 `+2.5s`. **PASS**
|
||||
|
||||
## Evidence
|
||||
- Test: `pytest tests/runtime/test_config_dotenv.py` 6 passed(기존 4 + 신규 2). 전체 `pytest --deselect ...::test_sandbox_token_and_submit` **167 passed, 23 skipped**. `ruff check trex_core tests` All checks passed.
|
||||
- e2e: 실 PostgreSQL + RabbitMQ + portfolio-hub(dev) 대상 데몬 e2e. 슬롯 전이 trail(`slot_transition_log`)·timestamp gap 으로 시나리오별 결정성 확인. (REL-001 Feedback Handoff Observation Summary 와 동일 evidence)
|
||||
|
||||
## no architecture impact confirmed
|
||||
- batch-lite, planning Design Gate=no. 기존 `PaperBroker` 생성자 인자를 config/env 표면으로 노출하는 additive wiring 뿐 — BrokerPort 계약·슬롯 런타임 흐름 변경 없음. 미설정 시 기존 동작 byte-for-byte. baseline 문서(`docs/project-structure.md`/`docs/runtime-flows.md`) 영향 없음.
|
||||
|
||||
## Result
|
||||
- Ready for Release: true
|
||||
- Blocking Issues:
|
||||
- 없음. e2e 는 paper broker 한정(운영 KIS 경로 무영향). REL-001 배포 scope 와 분리된 후속 release 로 배포.
|
||||
@@ -16,3 +16,4 @@
|
||||
| BAT-006 | standard | release-candidate | REQ-017, REQ-018, REQ-019, REQ-020 | dcy-004 | [bat-006](./bat-006_20260604_portfolio-hub-ledger-integration/) |
|
||||
| BAT-007 | standard | release-candidate | REQ-021, REQ-022, REQ-023, REQ-024, REQ-025, REQ-026 | dcy-006 | [bat-007](./bat-007_20260605_strategy-module-rabbitmq-transport/) |
|
||||
| BAT-008 | standard | release-candidate | REQ-027, REQ-028, REQ-029, REQ-030, REQ-031, REQ-032, REQ-033 | dcy-005 | [bat-008](./bat-008_20260606_portfolio-hub-snapshot-read-layer/) |
|
||||
| BAT-009 | batch-lite | release-candidate | REQ-010 (CHG-20260606-01 / AC-5) | dcy-002 | [bat-009](./bat-009_20260606_paper-broker-env-tuning/) |
|
||||
|
||||
Reference in New Issue
Block a user