chore(governance): remove legacy StagePilot artifacts
This commit is contained in:
@@ -1,371 +0,0 @@
|
||||
# req-002: slot 순수 도메인 이식 및 공개 API 확정
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- 검증된 slot 상태머신/서비스 계약을 인프라에 오염되지 않은 storage-agnostic 코어로 trex-core 에 이식해, trex-core 의 표준 도메인 작성 패턴(순수 도메인 + Protocol 저장소 경계)을 확립한다.
|
||||
|
||||
## Requirement
|
||||
- trex-orbit 의 순수 6개 모듈(`state`/`models`/`errors`/`repository`/`service`/`in_memory_repository`)과 `__init__.py` 를 `trex_core.domain.slot` 네임스페이스로 이식하고, 모듈 간 import 경로를 `trex_core.domain.slot.*` 로 통일하며, 공개 API 를 인프라 심볼 없이 노출한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given 이식 완료, When `from trex_core.domain.slot import SlotState, Slot, SlotCapacity, SlotTransitionRecord, SlotRepository, SlotService, SlotDomainError, SlotNotFoundError, SlotStateMismatchError, SlotTransitionError, is_allowed_transition, SLOT_ADVISORY_LOCK_ID, ALLOWED_TRANSITIONS` 를 실행, Then 모두 import 에 성공한다.
|
||||
2. Given 이식된 도메인 코드, When 정적 import 스윕, Then stdlib 와 `trex_core.domain.slot` 내부 참조 외 외부 의존(psycopg/네트워크/CLI/config) import 가 0이다. (NFR-1)
|
||||
3. Given 공개 API, When `__init__.py` 의 `__all__` 을 확인, Then `PostgreSQLSlotRepository`·`check_slot_domain_schema_drift` 등 인프라 심볼이 노출되지 않는다.
|
||||
4. Given `SlotService`, When 6 상태/9 base 전이(`closed→pending_buy` 포함, dcy-019)/advisory-lock 직렬화/`closed→idle` 재진입 +1/`→pending_buy` 시 slot `entry_count` +1(dcy-019)/`closed→pending_buy` clean-slate 점유 초기화/lock 보유 중 외부 I/O 금지 동작을 확인, Then 보존된다. (NFR-2 — 검증은 REQ-003)
|
||||
5. (CHG-20260610-02, dcy-023/issue #22) Given allocated_capital 제거 후, Then `Slot` 모델과 `EXPECTED_SLOT_FIELDS` 에 `allocated_capital` 필드가 없고, `SlotService` 의 설정/전이 경로(buy 진입·전이 시 set/clear)에서 해당 파라미터가 제거된다.
|
||||
6. (CHG-20260612-01, issue #25) Given `SlotRepository.list_slots(instance_key, status_filter=None)`, When `status_filter` 가 status 값 집합(예: `{"inactive"}`, `{"pending_buy","pending_sell"}`)이면, Then 해당 status 슬롯만 반환하고 `None`(미지정)이면 기존대로 전체를 반환한다(in-memory 구현 포함). 기존 무인자 호출자는 동작이 불변이다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/interface-contract.md, docs/data-model.md (계약 기준 — 큰 변경 없을 수 있음)
|
||||
- Modules: trex_core/domain/slot/{__init__,state,models,errors,repository,service,in_memory_repository}.py, (CHG-20260610-02) models.py `Slot`/`EXPECTED_SLOT_FIELDS` + service.py allocated_capital 제거, (CHG-20260612-01) repository.py `SlotRepository.list_slots` 시그니처 `status_filter` 옵션 + in_memory_repository.py 구현
|
||||
- Tests: REQ-003 에서 이식 단위테스트 + 계약 테스트로 검증
|
||||
|
||||
## Notes
|
||||
- NFR-1(순수 경계)·NFR-2(불변식 보존)를 본 REQ 의 acceptance 로 흡수. NFR-3(컬럼 계약)은 REQ-003 계약 테스트가 강제한다.
|
||||
- 이식 시 유일한 코드 수정은 `__init__.py` docstring 정리 수준이며 로직 변경은 없다(dcy-001 A-2).
|
||||
- 네임스페이스 `trex_core.domain.slot` 은 dcy-001 OQ-1 결정. REQ-001(부트스트랩) 선행.
|
||||
- 출처: dcy-001 FR-2.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260603-01
|
||||
- Date: 2026-06-03
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-001 FR-2 로부터 최초 생성(Proposed). NFR-1·NFR-2 를 acceptance 로 흡수.
|
||||
|
||||
#### Intent
|
||||
- slot 순수 도메인 이식 + 공개 API 확정 요구사항을 backlog 로 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- 공개 API import, 외부 의존 0, 인프라 심볼 비노출, 도메인 불변식 보존 4개 기준
|
||||
- Updated:
|
||||
- 없음
|
||||
- Removed:
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- docs/interface-contract.md, docs/data-model.md
|
||||
- Modules:
|
||||
- trex_core/domain/slot/* (6 모듈 + __init__)
|
||||
- Tests:
|
||||
- REQ-003 에 위임
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- none
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 후 batch 편성(REQ-001 과 동일 batch 가능)
|
||||
|
||||
#### Validation Plan
|
||||
- 공개 API import 성공 + import 스윕(외부 의존 0) + REQ-003 테스트 통과로 검증.
|
||||
|
||||
### CHG-20260603-02
|
||||
- Date: 2026-06-03
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status Proposed → Approved (confirm-req).
|
||||
|
||||
#### Intent
|
||||
- 승인 게이트(필수 필드·구체 AC·blocker 없음) 충족, source dcy-001(confirmed, handoff 승인)과 모순 없음 확인.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- 없음
|
||||
- Updated:
|
||||
- 없음
|
||||
- Removed:
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- docs/srs/index.md (Register 상태 Approved)
|
||||
- Modules:
|
||||
- 없음
|
||||
- Tests:
|
||||
- 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- none (batch 편성 전)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs / draft-batch 로 delivery batch 편성
|
||||
|
||||
#### Validation Plan
|
||||
- 승인 후 batch planning 에서 본 REQ 의 Acceptance Criteria 를 검증 기준으로 사용.
|
||||
|
||||
### CHG-20260603-03
|
||||
- Date: 2026-06-03
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status Approved → Implemented (confirm-req-implemented, 근거 batch BAT-001 release-candidate).
|
||||
|
||||
#### Intent
|
||||
- BAT-001 verification.md 의 evidence(공개 API import / import 스윕 외부 의존 0 / `__all__` 인프라 심볼 0 / 도메인 불변식 테스트)로 AC1~AC4 충족 → 구현 완료 동기화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- 없음
|
||||
- Updated:
|
||||
- 없음
|
||||
- Removed:
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- docs/srs/index.md (Register Implemented)
|
||||
- Modules:
|
||||
- 없음
|
||||
- Tests:
|
||||
- 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- BAT-001 (release-candidate)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: draft-release 로 release 편성
|
||||
|
||||
#### Validation Plan
|
||||
- BAT-001 verification evidence 재참조로 충분.
|
||||
|
||||
### CHG-20260608-01
|
||||
|
||||
- Date: 2026-06-08
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-012/issue #10) 슬롯 도메인 필드 `entry_price` → `limit_price`(side 무관 "현재 pending 주문 지정가") 내부 rename + 생애주기 정의: pending 진입 시 set, pending 이탈(→HOLDING/→CLOSED) 시 None clear. `transit_slot`/`_apply_transition_fields` 파라미터·`EXPECTED_SLOT_FIELDS` 반영. BAT-016 재구현·재검증 완료 → Implemented 유지.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 매수 지정가가 매도 주문에 누수되는 구조적 원인을 도메인 모델에서 제거(clear-on-exit). 가격 필드 의미를 side 무관으로 통일.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Updated:
|
||||
- Slot.`entry_price` → `limit_price`; →HOLDING/→CLOSED 전이 시 limit_price clear, →PENDING_* 전이 시 set.
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/domain/slot/models.py`(Slot/EXPECTED_SLOT_FIELDS), `trex_core/domain/slot/service.py`(transit_slot/_apply_transition_fields clear-on-exit)
|
||||
- Tests: tests/domain/slot/test_service.py(holding clear), tests/domain/slot/test_contract.py(필드셋)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-016
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (BAT-016 에서 완료)
|
||||
- Existing Implementation Invalidated: yes (entry_price 필드명/유지 의미)
|
||||
- Status Recommendation: Implemented (change-req → BAT-016 재검증)
|
||||
- Follow-up Action: confirm-req-implemented(BAT-016).
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- BAT-016: 전이별 set/clear 단위 + 컬럼 계약 가드(REQ-003) 정합.
|
||||
|
||||
### CHG-20260609-01
|
||||
|
||||
- Date: 2026-06-09
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-019/issue #18) 슬롯 도메인에 (1) slot-scoped `Slot.entry_count`(기본 0) 필드 + `EXPECTED_SLOT_FIELDS` 추가, (2) 상태 머신 허용 전이에 `closed→pending_buy`(closed 슬롯 직접 재할당) 추가(8→9 base 전이), (3) `_apply_transition_fields` 에 closed→pending_buy clean-slate 점유 초기화 + 모든 `→pending_buy`(idle→/closed→) 시 `entry_count` +1 로직 반영. 기존 `daily_symbol_entries`(symbol-scoped, AC-3)는 무관·미변경. BAT-025 재구현·재검증 완료 → Implemented 유지.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 슬롯 자원을 고르게 재사용(최저 진입 우선)하고 idle 소진 시 closed 재할당을 허용하기 위해, 슬롯 단위 누적 진입 횟수를 도메인 정본에 영속하고 closed→pending_buy 직접 전이를 도메인 계약에 추가.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Updated:
|
||||
- AC-4: "6 상태/8 전이" → "6 상태/9 base 전이(`closed→pending_buy` 포함)". 불변식 보존 대상에 `→pending_buy 시 entry_count +1`, `closed→pending_buy clean-slate 점유 초기화` 추가.
|
||||
- Added:
|
||||
- `Slot.entry_count`(int, 기본 0) 필드가 `EXPECTED_SLOT_FIELDS` 계약에 포함된다.
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/domain/slot/models.py`(Slot.entry_count/EXPECTED_SLOT_FIELDS), `trex_core/domain/slot/state.py`(closed→pending_buy 전이), `trex_core/domain/slot/service.py`(clean-slate + entry_count +1)
|
||||
- Tests: tests/domain/slot/test_state.py(전이 카운트 14→15), test_contract.py(필드셋), test_slot_entry_count.py(신규)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-025
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (BAT-025 에서 완료)
|
||||
- Existing Implementation Invalidated: no (additive — 기존 idle-only 동작은 closed 후보 부재 시 보존, 회귀 green)
|
||||
- Status Recommendation: Implemented (change-req → BAT-025 재검증)
|
||||
- Follow-up Action: confirm-req-implemented(BAT-025).
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- BAT-025: 전이 카운트/계약 가드 + entry_count 증분·보존 + closed→pending_buy clean-slate 단위 테스트 green; `daily_symbol_entries`(AC-3) 회귀 green.
|
||||
|
||||
### CHG-20260610-01
|
||||
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-020 자산 중심 슬롯 모델) 본 REQ 의 슬롯 도메인(6상태·`closed→idle` 복구·entry_count·익명 슬롯)이 dcy-020 으로 **재정의/폐기 예정**. 신규 REQ-057(상태머신 inactive↔pending_buy↔holding↔pending_sell·holding 로컬·인스턴스 스코프 lock)·REQ-056(영구 슬롯 필드·entry_count 제거)·REQ-062(qty hub 정본+미러)가 대체. **현재 코드는 불변이므로 Implemented 유지(keep-current)**, 실제 폐기/재정의는 dcy-020 delivery 배치(상태머신/스키마 BAT)에서 확정한다.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 자산 1:1 영구 슬롯 모델 전환의 추적성을 본 REQ 에 forward-link.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Updated: 없음(본 주기 변경 없음 — dcy-020 delivery 배치에서 AC 재정의 예정)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs: dcy-020, REQ-056/057/062
|
||||
- Modules: (예정) domain/slot/state.py·models.py·service.py
|
||||
- Tests: (예정) REQ-057 테스트로 대체
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: (예정) dcy-020 상태머신/스키마 배치
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no (현 시점)
|
||||
- Existing Implementation Invalidated: no (코드 불변 — dcy-020 delivery 시 무효화·재정의)
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: dcy-020 delivery 배치에서 Deprecated/재정의 + 그때 status 전환.
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- dcy-020 상태머신 배치의 verification 으로 대체.
|
||||
|
||||
### CHG-20260610-02
|
||||
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-023/issue #22) 죽은 필드 `allocated_capital` 을 슬롯 도메인에서 제거 — `Slot` 모델·`EXPECTED_SLOT_FIELDS` 계약·`SlotService` 의 설정/전이(set/clear) 경로에서 삭제. 소비처(의사결정/회계/사이징) 0건 확인(dcy-023 §3). AC-5 추가, Implemented→Approved(재구현 대기).
|
||||
|
||||
#### Intent
|
||||
|
||||
- 실제 소비되는 필드만 슬롯 계약에 남겨 유지 비용과 "capital 이 사이징한다"는 오해를 제거. dcy-021 사이징 계약(전략이 qty 계산, core 미관여) 확정의 귀결.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- AC-5: Slot 모델·EXPECTED_SLOT_FIELDS·SlotService 경로에서 allocated_capital 부재.
|
||||
- Updated:
|
||||
- 없음
|
||||
- Removed:
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: trex_core/domain/slot/models.py(Slot/EXPECTED_SLOT_FIELDS), trex_core/domain/slot/service.py(설정/전이 경로 파라미터 제거)
|
||||
- Tests: tests/domain/slot/ 계약 테스트(필드셋) + allocated_capital 참조 테스트 정리
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: (예정) dcy-023 batch
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (dcy-023 batch 에서 수행)
|
||||
- Existing Implementation Invalidated: yes (필드 제거 — 기존 필드셋 계약 evidence 무효)
|
||||
- Status Recommendation: Approved (Implemented→Approved 되돌림)
|
||||
- Follow-up Action: dcy-023 batch 구현·검증 후 confirm-req-implemented.
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- dcy-023 batch: 필드셋 계약 테스트(allocated_capital 부재) + 전체 suite 회귀 green.
|
||||
|
||||
### CHG-20260610-IMPL
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-034(release-candidate) verification — allocated_capital 전 경로 제거(도메인/intent/영속/snapshot/CLI), 마이그레이션 013 테스트 DSN 멱등 round-trip + 컬럼 부재 확인, 전체 428 passed + PG 게이트 21 passed + ruff clean, grep 전수 0건. Blocking Issues 없음.
|
||||
|
||||
### CHG-20260612-01
|
||||
|
||||
- Date: 2026-06-12
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, issue #25) `SlotRepository.list_slots` 에 optional `status_filter` 파라미터를 추가해 status 필터링을 저장소 경계로 내린다. 시그니처 `list_slots(instance_key, status_filter: Optional[set[str]] = None)` — `None` 은 기존(전체), 값 집합이면 해당 status 만 반환. in-memory 구현도 동일 의미로 갱신. slots RPC 핸들러(REQ-073)의 per-request full scan + Python 필터를 제거하기 위한 포트 확장. 신규 AC-6 추가 구현·검증 필요 → **Implemented → Approved 되돌림**.
|
||||
|
||||
#### Intent
|
||||
|
||||
- `trex.slots.req` 가 매 요청마다 전 슬롯을 fetch 한 뒤 Python 에서 거르던 구조(issue #25)를 DB 레벨 필터로 바꾸기 위해, 도메인 포트(`list_slots`)와 in-memory 더블을 먼저 확장한다. 기존 무인자 호출자(reconcile/safety-sell 등)는 default `None` 으로 동작 불변.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- AC-6: `list_slots(instance_key, status_filter)` — status 값 집합 필터 + `None` 전체, in-memory 포함, 기존 호출자 불변.
|
||||
- Updated/Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs: 없음
|
||||
- Modules: `trex_core/domain/slot/repository.py`(Protocol 시그니처), `trex_core/domain/slot/in_memory_repository.py`(구현)
|
||||
- Tests: in-memory `list_slots(status_filter)` 단위 — status 집합 필터 + None 전체 + 기존 무인자 회귀
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-040 (예정, issue #25)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (BAT-040 에서 AC-6 + 기존 AC 회귀)
|
||||
- Existing Implementation Invalidated: no (추가 파라미터는 default None 으로 기존 동작 보존). 단 신규 AC-6 미구현으로 Implemented 유지 불가 → Approved.
|
||||
- Status Recommendation: Implemented → **Approved**
|
||||
- Follow-up Action: confirm-req → BAT-040 구현·검증 → confirm-req-implemented
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- BAT-040: in-memory `list_slots` status 집합 필터 + None 전체 단위 테스트, 기존 무인자 호출 회귀, 전체 suite + ruff clean.
|
||||
|
||||
### CHG-20260612-IMPL
|
||||
- Date: 2026-06-12
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-040(release-candidate) verification — AC-6 `list_slots(status_filter)` in-memory 5종(None 전체/단일 status/pending 그룹/무매치/instance 스코프) PASSED, 무인자 호출자 default None 동작 보존(전체 439 passed), ruff clean. Blocking Issues 없음.
|
||||
@@ -1,443 +0,0 @@
|
||||
# req-007: intent 제출 HTTP API + 멱등
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- 매수·매도 전략 데몬이 HTTP 로 intent 를 제출하면 코어가 단독으로 admission/검증 후 슬롯을 전이하도록 한다(전략은 제안, 코어가 집행). intent_id 멱등으로 재전송 안전을 보장한다.
|
||||
|
||||
## Requirement
|
||||
- `POST /v1/intents/buy` 와 `POST /v1/intents/sell` 를 제공한다. 코어는 admission/검증 후 슬롯 전이(idle→pending_buy / holding→pending_sell)를 advisory lock 하 단일 writer 로 수행하고, 동기로 admit/reject 를 응답한다. 수락된 intent 는 같은 트랜잭션에서 `intent_log`(intent_id, payload, decision, ts) 에 durable 기록하며 `intent_id` 로 dedup 한다. `GET /v1/intents/{intent_id}` 로 결정을 재조회한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given 할당 가능 슬롯(idle ∪ closed, dcy-019), When `POST /v1/intents/buy`, Then `find_allocatable_slot`(entry_count→updated_at→slot_id 정렬)로 최저 진입 후보를 잡아 `slot.status→pending_buy`(idle→ 또는 closed→ 직접 재할당) 전이하고 `{admitted:true, slot_id}` 를 동기 응답한다. idle·closed 모두 소진 시 `no_idle_slot` 거부.
|
||||
2. Given holding 슬롯, When `POST /v1/intents/sell`, Then 검증 통과 시 holding→pending_sell 로 전이하고 admit 결과를 동기 응답한다(거부 시 사유 포함).
|
||||
3. Given 이미 처리된 `intent_id`, When 동일 intent 재전송, Then 슬롯이 중복 전이되지 않고 최초 결정과 동일한 응답을 돌려준다(멱등). (NFR-3)
|
||||
4. Given 동일 슬롯에 대한 동시 intent, When 병렬 처리, Then advisory lock 으로 직렬화되어 단일 writer 불변식이 유지된다(매수·매도 전략은 슬롯을 직접 쓰지 않음). (NFR-2)
|
||||
5. Given 수락된 intent, When `GET /v1/intents/{intent_id}`, Then 기록된 decision 을 반환한다.
|
||||
6. (CHG-20260610-02, dcy-023/issue #22) Given buy intent payload, Then `allocated_capital` 은 계약 필드가 아니다 — `BuyIntent` 에 필드가 없고 admission 경로에서 전달되지 않으며, 외부 발신자가 payload 에 키를 포함해도 unknown key 로 무시된다(즉시 제거, dcy-023 OQ-1).
|
||||
7. (CHG-20260615-01, issue #27) Given **rejected** sell intent 응답(`intent_type:"sell"`, `status:"rejected"`), Then additive `retryable: bool` 필드가 포함된다 — core 가 소유한 reason→retryable 매핑으로 채워지고 `reason` 은 유지된다. 매핑: `slot_state_changed`/`slot_not_holding:pending_buy`/`duplicate_in_flight` → `true`; `slot_not_found`/`slot_not_holding:inactive`/`slot_not_holding:pending_sell`/`slot_not_holding:error`/`bad_request:*` → `false`; 미인식 reason → `true`(안전 기본 — 멈춘 손절매가 hammering 보다 위험). admitted/processing/buy 응답·기존 필드는 불변(완전 additive·하위호환).
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/interface-contract.md(HTTP API 계약), docs/runtime-flows.md(요청 흐름) — REQ-009 에서 정합
|
||||
- Modules: trex_core/ 하위 API 어댑터(FastAPI 라우터/스키마) + 애플리케이션 서비스; 도메인 패키지는 무의존 유지(NFR-1); (CHG-20260610-02) intents.py BuyIntent·admission + messaging_handlers.py payload 파싱 allocated_capital 제거
|
||||
- Tests: API 통합테스트(정상/거부/멱등 재전송/동시성)
|
||||
|
||||
## Notes
|
||||
- 동기 커밋 + intent_id 멱등 + intent_log(dcy-002 OQ-1). 완전 비동기 outbox 는 브로커 Discovery 로 Deferred.
|
||||
- `intent_log` 테이블은 REQ-006 에서 생성. REQ-005(런타임)·REQ-006(영속화) 선행.
|
||||
- NFR-2(단일 writer)·NFR-3(멱등) 흡수.
|
||||
- 출처: dcy-002 FR-2, FR-4.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260603-01
|
||||
- Date: 2026-06-03
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-002 FR-2·FR-4 로부터 최초 생성(Proposed). NFR-2·NFR-3 흡수.
|
||||
|
||||
#### Intent
|
||||
- intent 제출 API + 멱등 요구사항을 backlog 로 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- buy/sell 전이, 멱등 재전송, 동시성 단일 writer, intent 재조회 5개 기준
|
||||
- Updated:
|
||||
- 없음
|
||||
- Removed:
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- docs/interface-contract.md, docs/runtime-flows.md
|
||||
- Modules:
|
||||
- API 어댑터(FastAPI) + 애플리케이션 서비스
|
||||
- Tests:
|
||||
- API 통합테스트(정상/거부/멱등/동시성)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- none
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 후 batch 편성
|
||||
|
||||
#### Validation Plan
|
||||
- API 통합테스트(멱등 재전송 + 동시성 직렬화 포함)로 검증.
|
||||
|
||||
### CHG-20260603-02
|
||||
- Date: 2026-06-03
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status Proposed → Approved (confirm-req).
|
||||
|
||||
#### Intent
|
||||
- 승인 게이트(필수 필드·구체 AC·blocker 없음) 충족, source dcy-002(confirmed, handoff 승인)와 모순 없음 확인.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- 없음
|
||||
- Updated:
|
||||
- 없음
|
||||
- Removed:
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- docs/srs/index.md (Register 상태 Approved)
|
||||
- Modules:
|
||||
- 없음
|
||||
- Tests:
|
||||
- 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- none (batch 편성 전)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs / draft-batch 로 delivery batch 편성
|
||||
|
||||
#### Validation Plan
|
||||
- 승인 후 batch planning 에서 본 REQ 의 Acceptance Criteria 를 검증 기준으로 사용.
|
||||
|
||||
### CHG-20260603-03
|
||||
- Date: 2026-06-03
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status Approved → Implemented (confirm-req-implemented, 근거 batch BAT-002 release-candidate).
|
||||
|
||||
#### Intent
|
||||
- BAT-002 verification.md 의 acceptance mapping + evidence(pytest 74 pass / PG 통합 / 데몬 E2E)로 모든 AC 충족 → 구현 완료 동기화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- 없음
|
||||
- Updated:
|
||||
- 없음
|
||||
- Removed:
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- docs/srs/index.md (Register Implemented)
|
||||
- Modules:
|
||||
- 없음
|
||||
- Tests:
|
||||
- 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- BAT-002 (release-candidate)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: draft-release 로 release 편성
|
||||
|
||||
#### Validation Plan
|
||||
- BAT-002 verification evidence 재참조로 충분.
|
||||
|
||||
### CHG-20260608-01
|
||||
|
||||
- Date: 2026-06-08
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-011) buy intent admission 계약 변경: `portfolio_id` 필수화 + admission 시 universe(`SnapshotStore`) 에서 `symbol` resolve + universe 부재 시 `unknown_portfolio` 거부. 기존 symbol-필수/portfolio_id-optional 폐기(hard cutover, 하위호환 없음). BAT-015 에서 재구현·재검증 완료 → Implemented 유지.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 정식 식별자(asset_id=portfolio_id) 기반 원장 귀속·safety 보호 범위 정합(issue #6). `_admit_buy` 에 portfolio_id_required/unknown_portfolio reject + symbol resolve(`resolve_symbol` 주입) 추가.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- buy 는 portfolio_id 필수(누락 시 `portfolio_id_required`), symbol 은 서버 resolve(`SnapshotStore`), universe 부재 시 `unknown_portfolio` 거부.
|
||||
- Updated:
|
||||
- 기존 admission AC 의 symbol 입력 전제 → portfolio_id 기반으로 정정.
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/application/intents.py`(BuyIntent portfolio_id 필수+symbol resolve, IntentService.resolve_symbol), `messaging_handlers.py`(buy payload), `runtime/daemon.py`(resolver 배선)
|
||||
- Docs: `docs/interface-contract.md`, `docs/runtime-flows.md`
|
||||
- Tests: intent/messaging buy 테스트 portfolio_id 기반 전환
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-015
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (BAT-015 에서 완료)
|
||||
- Existing Implementation Invalidated: yes (symbol-필수 admission 경로)
|
||||
- Status Recommendation: Implemented (change-req → BAT-015 재구현·재검증)
|
||||
- Follow-up Action: confirm-req-implemented(BAT-015) 로 Implemented 동기화.
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- BAT-015 verification: portfolio_id_required/unknown_portfolio/symbol resolve 단위 + 전체 회귀(314 passed).
|
||||
|
||||
### CHG-20260608-02
|
||||
|
||||
- Date: 2026-06-08
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-012) sell intent 계약에 optional 매도 가격 필드 추가: `SellIntent.limit_price`(+ sell payload `limit_price`) → `_admit_sell` 이 슬롯 `limit_price` 로 운반. 지정 시 지정가 매도, 미지정 시 시장가(자율 매도 기본 경로). buy 의 `entry_price` 는 동일 슬롯 `limit_price` 로 매핑(동작 동일). BAT-016 재구현·재검증 완료 → Implemented 유지.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 매도 가격 하이브리드 정책(가격 유무 분기, dcy-012 OQ-1/OQ-2)을 intent 제출 계약에 반영. 기존 재량 매도 호출(가격 미지정)은 시장가로 안전 동작(NFR-3).
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- sell intent/payload optional `limit_price`(미지정 → 시장가, 지정 → 지정가). admission 이 슬롯 limit_price 로 운반.
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/application/intents.py`(SellIntent/_admit_sell, _admit_buy limit_price 매핑), `trex_core/application/messaging_handlers.py`(sell payload limit_price)
|
||||
- Docs: docs/interface-contract.md
|
||||
- Tests: tests/application/test_sell_pricing.py
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-016
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (BAT-016 에서 완료)
|
||||
- Existing Implementation Invalidated: no (optional 추가, 기존 sell 호출 시장가로 호환)
|
||||
- Status Recommendation: Implemented (change-req → BAT-016 재검증)
|
||||
- Follow-up Action: confirm-req-implemented(BAT-016).
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- BAT-016: 가격 전달 매도 → 지정가 / 미전달 → 시장가 단위 + 핸들러 payload.
|
||||
|
||||
### CHG-20260608-03
|
||||
|
||||
- Date: 2026-06-08
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, REL-004 사전 run 검증에서 발견된 결함 수정) 데몬 buy 심볼 resolver 버그 정정: `Daemon._resolve_symbol` 이 `SnapshotStore.get()` 반환값(`SnapshotAsset`)에서 `asset.symbol` 을 접근했으나 symbol 은 `asset.item.symbol` 에 있어 `AttributeError` → 데몬 buy admission 이 매번 크래시(intent RPC 타임아웃). `asset.item.symbol` 로 수정. 단위 테스트가 stub resolver 를 주입해 실 데몬 배선을 한 번도 실행하지 않아 369 passed 에도 누락됐다 — 실 데몬 기동 + CLI e2e(REL-004 smoke)에서 검출. Implemented 유지.
|
||||
|
||||
#### Intent
|
||||
|
||||
- dcy-011/REQ-007 의 buy 심볼 서버 resolve 가 실 런타임(daemon + SnapshotStore)에서 동작하도록 배선 결함 수정 + 회귀 가드 추가.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- (변경 없음 — AC 동일; 배선 결함 수정. 실 데몬 resolver 가 SnapshotAsset.item.symbol 을 읽음)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/runtime/daemon.py`(`_resolve_symbol` → `asset.item.symbol`)
|
||||
- Tests: tests/runtime/test_daemon_resolve_symbol.py(실 Daemon._resolve_symbol × 실 SnapshotStore 회귀)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-015
|
||||
- Releases: REL-004 (사전 run 검증에서 검출·수정)
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (REL-004 live smoke + 회귀 테스트로 완료)
|
||||
- Existing Implementation Invalidated: yes (데몬 buy admission 경로 — 실 런타임에서 전면 실패였음)
|
||||
- Status Recommendation: Implemented (배선 수정 + 회귀 가드)
|
||||
- Follow-up Action: REL-004 confirm-release 전 live smoke 증거에 반영.
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- 실 데몬 기동(paper + test PG/RabbitMQ) + `trex-core enter pf-005930 --yes` → admitted/체결/ledger completed e2e + test_daemon_resolve_symbol 회귀.
|
||||
|
||||
### CHG-20260609-01
|
||||
|
||||
- Date: 2026-06-09
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-019/issue #18) buy admission(`_admit_buy`) 의 슬롯 선택을 `find_idle_slot` → `find_allocatable_slot`(idle ∪ closed, entry_count→updated_at→slot_id 정렬)로 일반화하고, 후보 status 를 따르도록 transit from_state 를 하드코딩 `IDLE` → `slot.status` 로 변경(closed 후보면 `closed→pending_buy` 직접 재할당). 마지막 슬롯 경합 재시도 루프·멱등(intent_log dedup)·단일 writer 불변식 보존. BAT-025 검증 완료 → Implemented 유지.
|
||||
|
||||
#### Intent
|
||||
|
||||
- idle 소진 시에도 closed 슬롯을 재할당해 슬롯 자원을 효율적으로 회전시키고, 슬롯 사용을 진입 횟수 기준으로 고르게 분산.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Updated:
|
||||
- AC-1: 후보 = idle ∪ closed, `find_allocatable_slot` 선택 + `slot.status→pending_buy` 전이(closed 직접 재할당 포함), 양쪽 소진 시 `no_idle_slot` 거부로 일반화.
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/application/intents.py`(`_admit_buy`: find_allocatable_slot + from_state=slot.status)
|
||||
- Tests: tests/application/test_buy_admission_reallocation.py(신규: closed 재할당 admit/idle 우선/양쪽 소진 reject), tests/application/test_intent_concurrency.py(경합 회귀 보존)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-025
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (BAT-025 에서 완료)
|
||||
- Existing Implementation Invalidated: no (closed 후보 부재 시 기존 idle-only 동작과 동일 — 회귀 green)
|
||||
- Status Recommendation: Implemented (change-req → BAT-025 재검증)
|
||||
- Follow-up Action: confirm-req-implemented(BAT-025).
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- BAT-025: closed 재할당 admit / idle 우선 / 양쪽 소진 reject 단위 + 동시성 경합 회귀 green.
|
||||
|
||||
### CHG-20260610-01
|
||||
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-020) buy/sell admission 이 자산 중심으로 **재정의 예정** — REQ-059(FCFS·M캡·무치환·over-cap)·REQ-061(intent 자산 키 통일, `sell-by-slot_id` 폐기, already_active/not_holding)가 대체. `find_allocatable_slot`/idle·closed 배정 폐기. 외부 전략 계약 변경(NFR-4) 동반. 현재 코드 불변이라 Implemented 유지(keep-current), dcy-020 admission/intent 배치에서 확정(외부 계약 cutover 게이트).
|
||||
|
||||
#### Intent
|
||||
|
||||
- 신호 기반 자산 admission 전환 추적성 forward-link.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Updated: 없음(dcy-020 delivery 배치에서 admission/intent AC 재정의)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs: dcy-020, REQ-059/061
|
||||
- Modules: (예정) application/intents.py·메시지 핸들러/스키마
|
||||
- Tests: (예정) intent/admission 테스트 재작성
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: (예정) dcy-020 admission/intent 배치(외부 계약 cutover)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no (현 시점)
|
||||
- Existing Implementation Invalidated: no (코드 불변)
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: dcy-020 admission/intent 배치에서 재정의 + status 전환. 외부 전략 모듈 동시 전환(NFR-4).
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- dcy-020 admission/intent 배치 verification 으로 대체.
|
||||
|
||||
### CHG-20260610-02
|
||||
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-023/issue #22) buy intent payload 계약에서 `allocated_capital` 즉시 제거 — `BuyIntent` 데이터클래스 필드·admission 전달(`_admit_buy`→SlotService)·messaging handler payload 파싱(`body.get("allocated_capital")`) 삭제. 외부 발신자(trex-orb-v1)가 키를 계속 송신해도 unknown key 로 무시되어 무해(dcy-023 OQ-1 운영자 결정: 즉시 제거, 유예 없음). AC-6 추가, Implemented→Approved(재구현 대기).
|
||||
|
||||
#### Intent
|
||||
|
||||
- 사이징·회계 소비자가 없는 운반 전용 필드를 intent 계약에서 제거. dcy-021 명령형 qty 사이징 계약과 정합.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- AC-6: BuyIntent 에 allocated_capital 부재 + 수신 payload 의 해당 키 무시.
|
||||
- Updated:
|
||||
- 없음
|
||||
- Removed:
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: trex_core/application/intents.py(BuyIntent/admission), trex_core/application/messaging_handlers.py(payload 파싱)
|
||||
- Tests: intent admission·handler 파싱 테스트에서 allocated_capital 참조 정리 + 키 포함 payload 무시 테스트
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: (예정) dcy-023 batch
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (dcy-023 batch 에서 수행)
|
||||
- Existing Implementation Invalidated: yes (BuyIntent 필드·파싱 제거)
|
||||
- Status Recommendation: Approved (Implemented→Approved 되돌림)
|
||||
- Follow-up Action: dcy-023 batch 구현·검증 후 confirm-req-implemented.
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- dcy-023 batch: allocated_capital 포함 payload 가 정상 admit 되며 슬롯·로그에 미반영(무시) + 전체 suite green.
|
||||
|
||||
### CHG-20260610-IMPL
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-034(release-candidate) verification — allocated_capital 전 경로 제거(도메인/intent/영속/snapshot/CLI), 마이그레이션 013 테스트 DSN 멱등 round-trip + 컬럼 부재 확인, 전체 428 passed + PG 게이트 21 passed + ruff clean, grep 전수 0건. Blocking Issues 없음.
|
||||
|
||||
### CHG-20260615-01
|
||||
- Date: 2026-06-15
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- (change-req, issue #27) rejected SellIntent 응답에 additive `retryable: bool` 추가. core 소유 reason→retryable 매핑으로 채우고 `reason` 유지. #26 sell-idempotency 논의(거부 sticky)의 후속 — 데몬이 reason 문자열 하드코딩 없이 권위 플래그로 retry/stop 판단(손절매 안전 경로 decoupling).
|
||||
|
||||
#### Intent
|
||||
- 거부 retryability를 core 도메인 지식으로 캡슐화해, 새 reason 추가 시 데몬 분류가 조용히 drift하는 안전 실패 모드 제거(issue #27).
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: AC-7 (rejected sell 응답 additive `retryable` + core 소유 매핑 + 미인식 기본 true + 완전 additive)
|
||||
- Updated: 없음
|
||||
- Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/interface-contract.md(rejected sell 응답 `retryable` 필드)
|
||||
- Modules: trex_core/application/messaging_handlers.py(intent 응답 빌더 — sell+rejected 시 retryable; core 소유 `_SELL_REJECT_RETRYABLE` 매핑)
|
||||
- Tests: tests/application/(retryable 플래그 매핑 케이스 + additive 하위호환)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: BAT-043(편성 예정)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: yes (신규 AC-7만)
|
||||
- Existing Implementation Invalidated: no (완전 additive — 기존 응답 필드/admit/buy 불변)
|
||||
- Status Recommendation: revert-to-approved (Implemented → Approved — 신규 additive AC 구현·검증 대기)
|
||||
- Follow-up Action: BAT-043 batch-lite 구현·검증 후 confirm-req-implemented
|
||||
|
||||
#### Validation Plan
|
||||
- messaging_handlers 테스트: 각 reject reason → 기대 retryable 매핑, 미인식 reason → true, admitted/processing/buy 응답에 retryable 부재, 기존 reason 필드 유지.
|
||||
|
||||
### CHG-20260615-IMPL
|
||||
- Date: 2026-06-15
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-043(release-candidate) verification — rejected sell 응답 additive `retryable`(core 소유 `_SELL_REJECT_RETRYABLE` 매핑 + `_sell_reject_retryable` helper, 미인식 true/`bad_request*` false). AC-7 evidence: `tests/application/test_sell_retryable_flag.py`(매핑 7 reason+미인식+None+bad_request, 응답 inactive/unknown_slot/bad_request→false, admitted/buy 부재). 487 passed, ruff clean. 기존 AC-1~6 불변. Blocking Issues 없음.
|
||||
@@ -1,152 +0,0 @@
|
||||
# req-008: 슬롯 read-only 조회 HTTP API
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- 매도 전략이 보유 슬롯을 평가하고 운영자가 가용성을 모니터링할 수 있도록, 코어가 슬롯 스냅샷과 capacity 를 read-only 로 제공한다.
|
||||
|
||||
## Requirement
|
||||
- `GET /v1/slots?status=holding`(status/trading_date 필터)로 슬롯 스냅샷을 read-only 로 반환하고, `GET /v1/capacity` 로 idle/holding/pending 카운트 + scarcity_ratio 를 반환한다. 이 엔드포인트는 슬롯을 쓰지 않는다(read-only).
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given holding 슬롯이 있는 상태, When `GET /v1/slots?status=holding`, Then 해당 슬롯 스냅샷 목록을 반환한다(쓰기 부작용 없음).
|
||||
2. Given status/trading_date 필터, When 조회, Then 필터에 맞는 슬롯만 반환한다.
|
||||
3. Given 슬롯 분포, When `GET /v1/capacity`, Then idle/holding/pending 카운트와 scarcity_ratio 를 반환한다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/interface-contract.md(조회 API 계약) — REQ-009 에서 정합
|
||||
- Modules: trex_core/ 하위 API 어댑터(읽기 라우터); 도메인 `compute_slot_capacity`/repo 조회 재사용
|
||||
- Tests: 조회 API 통합테스트
|
||||
|
||||
## Notes
|
||||
- 엔드포인트 집합은 dcy-002 OQ-3 결정. REQ-005(런타임)·REQ-006(영속화) 선행.
|
||||
- read-only 라 단일 writer 불변식과 무관(쓰기 경로 아님).
|
||||
- 출처: dcy-002 FR-3.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260603-01
|
||||
- Date: 2026-06-03
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-002 FR-3 로부터 최초 생성(Proposed).
|
||||
|
||||
#### Intent
|
||||
- 슬롯 read-only 조회 API 요구사항을 backlog 로 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- holding 스냅샷, 필터, capacity 3개 기준
|
||||
- Updated:
|
||||
- 없음
|
||||
- Removed:
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- docs/interface-contract.md
|
||||
- Modules:
|
||||
- API 어댑터(읽기 라우터)
|
||||
- Tests:
|
||||
- 조회 API 통합테스트
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- none
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 후 batch 편성
|
||||
|
||||
#### Validation Plan
|
||||
- 조회 API 통합테스트(스냅샷/필터/capacity)로 검증.
|
||||
|
||||
### CHG-20260603-02
|
||||
- Date: 2026-06-03
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status Proposed → Approved (confirm-req).
|
||||
|
||||
#### Intent
|
||||
- 승인 게이트(필수 필드·구체 AC·blocker 없음) 충족, source dcy-002(confirmed, handoff 승인)와 모순 없음 확인.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- 없음
|
||||
- Updated:
|
||||
- 없음
|
||||
- Removed:
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- docs/srs/index.md (Register 상태 Approved)
|
||||
- Modules:
|
||||
- 없음
|
||||
- Tests:
|
||||
- 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- none (batch 편성 전)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs / draft-batch 로 delivery batch 편성
|
||||
|
||||
#### Validation Plan
|
||||
- 승인 후 batch planning 에서 본 REQ 의 Acceptance Criteria 를 검증 기준으로 사용.
|
||||
|
||||
### CHG-20260603-03
|
||||
- Date: 2026-06-03
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status Approved → Implemented (confirm-req-implemented, 근거 batch BAT-002 release-candidate).
|
||||
|
||||
#### Intent
|
||||
- BAT-002 verification.md 의 acceptance mapping + evidence(pytest 74 pass / PG 통합 / 데몬 E2E)로 모든 AC 충족 → 구현 완료 동기화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- 없음
|
||||
- Updated:
|
||||
- 없음
|
||||
- Removed:
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- docs/srs/index.md (Register Implemented)
|
||||
- Modules:
|
||||
- 없음
|
||||
- Tests:
|
||||
- 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- BAT-002 (release-candidate)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: draft-release 로 release 편성
|
||||
|
||||
#### Validation Plan
|
||||
- BAT-002 verification evidence 재참조로 충분.
|
||||
@@ -1,157 +0,0 @@
|
||||
# req-025: HTTP `/v1` API 완전 제거 (healthz 포함, HTTP 표면 0)
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- RabbitMQ 단일 transport 결정(dcy-006 OQ-1)에 따라 trex-core 의 HTTP `/v1` API 표면을 0 으로 만든다. 전략-facing 엔드포인트뿐 아니라 `GET /v1/healthz` 같은 앱 레벨 헬스 표면까지 제거하고(OQ-7), liveness 는 프로세스 감독(systemd/supervisor/docker restart)이 담당한다. 이중 transport 병행을 두지 않는다.
|
||||
|
||||
## Requirement
|
||||
- 아래 HTTP 엔드포인트와 그 어댑터를 trex-core 코드와 baseline 에서 제거한다.
|
||||
- `POST /v1/intents/buy`, `POST /v1/intents/sell`
|
||||
- `GET /v1/intents/{intent_id}`
|
||||
- `GET /v1/slots`, `GET /v1/capacity`
|
||||
- `GET /v1/healthz`
|
||||
- dcy-005 가 HTTP 로 가정한 스냅샷 read 엔드포인트(아직 미구현인 경우 가정 자체 갱신)
|
||||
- `trex_core/adapters/api/` HTTP 어댑터 패키지를 제거하고, FastAPI/uvicorn/Starlette 직접 의존을 코어 런타임에서 제거한다(테스트 전용 보조 import 도 마찬가지). `pyproject.toml` 의 `fastapi`/`uvicorn` 의존성을 정리한다.
|
||||
- `TREX_API_HOST` / `TREX_API_PORT` env 와 그 로딩 코드를 폐기한다(`DaemonConfig`/`.env.example` 정리).
|
||||
- 데몬 기동 후 HTTP 리스너가 어떤 포트에도 바인딩되어 있지 않아야 한다(HTTP 표면 0). 앱 레벨 헬스/관측성은 로그·메트릭으로 대체한다.
|
||||
- dcy-002 의 HTTP intent API 가정과 dcy-005 의 HTTP pull 가정(FR-1/A-3)을 cross-reference 로 갱신한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given 새 트리, When `find trex_core -path '*/adapters/api/*'` 또는 `grep -r "fastapi\|uvicorn" trex_core/`, Then 결과가 비어 있다(HTTP 어댑터 잔존 0).
|
||||
2. Given trex-core daemon, When 기동 후 포트 스캔, Then 어떤 TCP 포트에도 HTTP 리스너가 열려 있지 않다(HTTP 표면 0, dcy-006 S-6).
|
||||
3. Given `DaemonConfig.from_env()`, When 환경 변수 로딩, Then `TREX_API_HOST`/`TREX_API_PORT` 를 더 이상 참조하지 않고, 누락되어도 기동에 영향이 없다.
|
||||
4. Given `pyproject.toml`, When 의존성 목록을 점검, Then `fastapi`/`uvicorn`/`starlette` 가 코어 runtime 의존성에서 제거되어 있다.
|
||||
5. Given dcy-002·dcy-005 의 HTTP 가정 본문, When 본 변경 완료 시점에 cross-reference 갱신을 확인, Then 두 Discovery 의 HTTP 가정이 "transport 는 RabbitMQ(dcy-006)" 로 일관되게 안내된다.
|
||||
6. Given liveness 확인 시나리오, When 프로세스 감독(systemd/supervisor/docker restart)이 프로세스 죽음을 감지, Then 재시작이 broker 가용성과 무관하게 동작한다(broker 장애가 재시작 루프 유발 금지).
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/interface-contract.md(HTTP `/v1` 섹션 제거), docs/runtime-flows.md(HTTP 흐름 제거), docs/project-structure.md(adapters/api 제거), docs/discovery/dcy-002·dcy-005 cross-reference 갱신 — REQ-026 에서 정합.
|
||||
- Modules:
|
||||
- 제거 `trex_core/adapters/api/` 전체(`app.py`, `schemas.py`)
|
||||
- 변경 `trex_core/runtime/daemon.py`(uvicorn import/실행 제거; REQ-022 의 sync+thread 런타임으로 교체)
|
||||
- 변경 `trex_core/runtime/config.py`(`TREX_API_HOST`/`TREX_API_PORT` 폐기)
|
||||
- 변경 `pyproject.toml`(fastapi/uvicorn 제거; httpx 는 ledger 어댑터 사용처가 있으므로 유지)
|
||||
- 변경 `.env.example`(API_HOST/PORT 제거, `TREX_RABBITMQ_URL` 추가는 REQ-022 책임)
|
||||
- Tests:
|
||||
- 제거 `tests/adapters/api/` 전체(또는 messaging 등가 테스트로 이관)
|
||||
- 추가 daemon HTTP-표면-0 회귀 가드(포트 스캔 또는 import 가드)
|
||||
|
||||
## Notes
|
||||
- 출처: dcy-006 FR-5, OQ-1, OQ-7.
|
||||
- 본 REQ 의 검증은 transport 가 RabbitMQ 로 대체 가능한 상태(REQ-021/REQ-022/REQ-023 구현)에 의존한다. 동일 batch 또는 직후 batch 에서 함께 deliver 해야 통신 단절 위험(R-5)을 피할 수 있다.
|
||||
- httpx 는 본 REQ 가 제거 대상에서 제외한다(portfolio-hub ledger 어댑터가 사용).
|
||||
- 외부 운영 가시성(메트릭/로그) 표준화는 본 REQ 범위 밖이며 후속 운영 트랙으로 추적한다.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260605-01
|
||||
- Date: 2026-06-05
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-006 FR-5/OQ-1/OQ-7 로부터 최초 생성(Proposed). HTTP `/v1` API + healthz + adapters/api + API_HOST/PORT env + fastapi/uvicorn 의존 전부 제거 backlog 정규화.
|
||||
|
||||
#### Intent
|
||||
- 이중 transport 병행 없이 HTTP 표면 0 을 달성하고 dcy-002·dcy-005 의 HTTP 가정을 갱신.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- HTTP 어댑터 잔존 0, HTTP 리스너 0, env 폐기, 의존성 제거, cross-reference 갱신, 프로세스 감독 liveness (총 6개 기준)
|
||||
- Updated:
|
||||
- 없음
|
||||
- Removed:
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- docs/interface-contract.md, docs/runtime-flows.md, docs/project-structure.md, dcy-002/dcy-005 cross-reference
|
||||
- Modules:
|
||||
- adapters/api 제거, runtime/daemon.py, runtime/config.py, pyproject.toml, .env.example
|
||||
- Tests:
|
||||
- adapters/api 테스트 제거 또는 이관, daemon HTTP-표면-0 회귀 가드
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- none
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: yes (BAT-002 HTTP API 관련 구현 일부가 RabbitMQ 로 대체)
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 후 REQ-021~023 과 동일 batch 편성(통신 단절 R-5 회피).
|
||||
|
||||
#### Validation Plan
|
||||
- 코드 grep + 포트 스캔 + env 누락 기동 + pyproject 의존성 검사 + cross-reference 리뷰 + 프로세스 감독 시나리오로 검증.
|
||||
|
||||
### CHG-20260605-02
|
||||
- Date: 2026-06-05
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status 변경: Proposed -> Approved. confirm-req 승인 게이트 통과.
|
||||
|
||||
#### Intent
|
||||
- HTTP `/v1` API 완전 제거(healthz 포함, HTTP 표면 0)와 fastapi/uvicorn 의존 정리를 delivery input 으로 승인.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added/Updated/Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs/Modules/Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- none
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: yes (BAT-002 HTTP API 관련 구현 일부 RabbitMQ 로 대체)
|
||||
- Status Recommendation: Approved
|
||||
- Follow-up Action: REQ-021/022/023 과 반드시 동일 batch 로 deliver(big-bang 마이그레이션 R-5 회피)
|
||||
|
||||
#### Validation Plan
|
||||
- 기존 Acceptance Criteria 로 batch delivery 에서 검증.
|
||||
|
||||
### CHG-20260605-03
|
||||
- Date: 2026-06-05
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status 변경: Approved -> Implemented. BAT-007 release-candidate verification evidence 기반.
|
||||
|
||||
#### Intent
|
||||
- HTTP `/v1` API + healthz + adapters/api + fastapi/uvicorn 의존 + TREX_API_HOST/PORT 폐기를 구현 완료 상태로 동기화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added/Updated/Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs/Modules/Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- BAT-007 (release-candidate)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: yes (BAT-002 HTTP API 관련 구현/테스트 일부 RabbitMQ 로 대체됨; tests/adapters/api/ 제거)
|
||||
- Status Recommendation: Implemented
|
||||
- Follow-up Action: release 단계에서 전략 모듈 cut-over 순서 합의.
|
||||
|
||||
#### Validation Plan
|
||||
- AC-1: tests/runtime/test_daemon_no_http_surface.py::test_adapters_api_tree_does_not_exist + test_no_fastapi_or_uvicorn_in_trex_core_source.
|
||||
- AC-2: tests/runtime/test_daemon_no_http_surface.py::test_daemon_module_has_no_fastapi_or_uvicorn_import.
|
||||
- AC-3: tests/runtime/test_daemon_no_http_surface.py::test_config_env_no_longer_references_api_host_or_port.
|
||||
- AC-4: tests/runtime/test_daemon_no_http_surface.py::test_pyproject_dependencies_have_no_fastapi_or_uvicorn.
|
||||
- AC-5: docs/discovery/dcy-002_…md 헤더 supersede 메모 + dcy-005 cross-reference 보유.
|
||||
- AC-6: Daemon.run 의 signal handler + 포트 바인딩 0 코드 review.
|
||||
@@ -1,297 +0,0 @@
|
||||
# req-028: 종목 스냅샷 read 메시지 계약 + envelope + degraded 신호
|
||||
|
||||
- Status: Deprecated
|
||||
- Deprecated-By: REQ-073, REQ-074 (BAT-035, dcy-025, 2026-06-11)
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- 전략 모듈이 dcy-006 snapshot RPC 로 종목 스냅샷을 받는 요청/응답 계약(transport-무관 logical)을 정의한다. 빈 응답과 가용성 degrade 의 시맨틱을 모호하지 않게 한다.
|
||||
|
||||
## Requirement
|
||||
- 스냅샷 read 는 dcy-006 의 `trex.snapshot.req` request-reply RPC 위에서 동작한다. 요청 payload 는 선택적 `strategy_key`·`view` 를 가진다.
|
||||
- 응답은 **envelope** 다: `assets` 는 항상 배열(비면 `[]`, null 금지)이고, meta 로 `view`(에코), `available_slots`, `degraded`, `reason` 을 포함한다.
|
||||
- 각 자산 항목은 symbol, asset_id, cash_balance, asset_quantity, active_strategy_id, 전략파라미터(opaque)를 담고 가격은 제외한다.
|
||||
- (CHG-20260608-01) envelope 은 universe `assets[]` 와 **별도로** read-only `slots[]` 배열을 운반한다 — 데몬 슬롯 테이블의 per-slot 상태(`slot_id`·`status`(idle/holding/pending_buy/pending_sell)·`symbol`·`qty`·`limit_price`·`avg_price`·`portfolio_id`). 슬롯이 없어도 `[]`(null 금지). strategy 소비자는 무시 가능(additive). 운영자 CLI(`trex-core slots`)는 이 `slots[]` 를 표시한다.
|
||||
- portfolio-hub 가 불가해 권위 cash/position 을 유지할 수 없으면(write `*_after` 갱신 불가 또는 일일 fetch 실패) 응답에 `degraded=true` + machine-readable reason code(예: `portfolio_hub_unavailable`/`snapshot_fetch_failed`/`cash_position_stale`) + sanitize 된 message 를 실어 전략의 신규 매매 보류를 신호한다(빈 리스트/silent stale 금지).
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given 정상 상태, When 스냅샷을 요청, Then `assets`(배열) + meta(`view`·`available_slots`·`degraded`·`reason`) envelope 를 반환하고, 자산이 없어도 `assets` 는 `[]`(null 아님)다.
|
||||
2. Given portfolio-hub 불가(권위 cash/position 유지 불가), When 요청, Then `degraded=true` + reason code 가 포함되고 raw 예외/자격증명 등 민감정보는 노출되지 않는다.
|
||||
3. Given 응답 항목, Then 필드는 symbol/asset_id/cash_balance/asset_quantity/active_strategy_id/strategy_params(opaque) 이고 가격 필드는 없다.
|
||||
4. (CHG-20260608-01) Given 스냅샷 요청, Then envelope 에 read-only `slots[]` 배열을 포함한다 — 각 항목은 `slot_id`·`status`·`symbol`·`qty`·`limit_price`·`avg_price`·`portfolio_id` 를 담고, 슬롯이 없어도 `[]`(null 아님)다. `assets[]` 와 독립이며 strategy 소비자는 무시 가능(additive, 하위호환).
|
||||
5. (CHG-20260610-01, dcy-023/issue #22) Given 스냅샷 응답, Then `slots[]` 항목에 `allocated_capital` 키가 없다 — 구현이 계약 외로 노출하던 죽은 필드를 제거해 AC-4 의 문서화된 필드 집합과 구현을 정렬한다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/discovery/dcy-005_20260604_portfolio-hub-asset-snapshot-api.md, docs/discovery/dcy-016_20260608_operator-cli-rpc-commands.md, docs/interface-contract.md
|
||||
- Modules: trex_core/adapters/messaging (snapshot RPC 핸들러), trex_core/application/portfolio.py (`build_snapshot_envelope` — `slots[]`, (CHG-20260610-01) allocated_capital 노출 제거), 응답 스키마(transport-무관), trex_core/runtime/cli.py (REQ-032 companion)
|
||||
- Tests: envelope 스키마 검증(빈 응답 포함), degraded 주입 테스트, `slots[]` 스키마(빈 배열·status enum) + `trex-core slots` 실제 슬롯 상태 표시
|
||||
|
||||
## Notes
|
||||
- transport 는 dcy-006(REQ-021/022) 의 snapshot RPC 를 사용하며 본 REQ 는 logical 계약만 정의한다.
|
||||
- NFR-3(가용성 degrade, OQ-5) + OQ-6(빈 표현)을 본 REQ 로 흡수/반영한다.
|
||||
- 정확한 reason code enum/필드 스키마는 구현 단계에서 확정한다(dcy-005 OQ-5/OQ-6 결정 범위 내).
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260606-01
|
||||
- Date: 2026-06-06
|
||||
- Author: project maintainers
|
||||
|
||||
#### Change Summary
|
||||
- dcy-005 FR-1/FR-3 + OQ-5/OQ-6 분해로 최초 생성(Proposed). NFR-3 흡수.
|
||||
|
||||
#### Intent
|
||||
- 스냅샷 read 의 요청/응답 envelope 계약 + degrade 신호 정의.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- AC-1~3 신규
|
||||
- Updated:
|
||||
- none
|
||||
- Removed:
|
||||
- none
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- dcy-005, interface-contract
|
||||
- Modules:
|
||||
- adapters/messaging snapshot RPC 핸들러, 응답 스키마
|
||||
- Tests:
|
||||
- envelope 스키마, degraded 주입
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- none
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req
|
||||
|
||||
#### Validation Plan
|
||||
- envelope 스키마 검증 + portfolio-hub 불가 주입으로 degraded AC 검증.
|
||||
|
||||
### CHG-20260606-02
|
||||
- Date: 2026-06-06
|
||||
- Author: project maintainers
|
||||
|
||||
#### Change Summary
|
||||
- 승인 게이트 통과 → Proposed → Approved.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: none
|
||||
- Updated: none
|
||||
- Removed: none
|
||||
|
||||
#### Impacted Area Delta
|
||||
- 변경 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs / draft-batch
|
||||
|
||||
#### Validation Plan
|
||||
- 승인 기록. 구현 전 재검증 불필요.
|
||||
|
||||
### CHG-20260606-03
|
||||
- Date: 2026-06-06
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status 변경: Approved → Implemented. BAT-008 release-candidate verification evidence 기반.
|
||||
|
||||
#### Intent
|
||||
- snapshot RPC envelope 응답 + degraded 신호 + sanitization 구현 완료 상태로 동기화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added/Updated/Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs/Modules/Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- BAT-008 (release-candidate)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Implemented
|
||||
- Follow-up Action: release 단계는 별도 진행
|
||||
|
||||
#### Validation Plan
|
||||
- AC-1: tests/application/test_snapshot_handler.py::test_envelope_shape_returned + test_snapshot_selection.py::test_empty_envelope_assets_is_list_not_null.
|
||||
- AC-2: tests/application/test_snapshot_handler.py::test_degraded_signal_does_not_leak_credentials + 실 daemon 운영 검증.
|
||||
- AC-3: tests/application/test_snapshot_selection.py::test_envelope_shape_no_price_field.
|
||||
|
||||
### CHG-20260608-01
|
||||
- Date: 2026-06-08
|
||||
- Author: project maintainers
|
||||
|
||||
#### Change Summary
|
||||
- dcy-016 후속 정정. `trex-core slots`(REQ-032)가 universe `assets`(portfolio: asset_id/symbol/asset_quantity)를 **슬롯 상태로 오인 표시**하던 갭 — snapshot envelope 이 슬롯 상태 목록을 운반하지 않아 발생(운영자 관측: 10개 슬롯인데 universe portfolio 1개만, status 없음). envelope 에 **read-only per-slot 상태 목록 `slots[]` 를 additive 로 추가**한다(dcy-017 의 per-slot `watchdog` 동봉 선례와 동일 방식). BAT-007 에서 HTTP 슬롯 read(REQ-008/025) 제거 후 슬롯 상태 read 표면이 부재했던 점을 함께 해소.
|
||||
|
||||
#### Intent
|
||||
- 운영자가 데몬의 **실제 슬롯 상태(idle/holding/pending_buy/pending_sell)** 를 snapshot RPC 로 관측할 수 있게 한다. strategy-facing `assets[]`(universe) 계약은 그대로 유지하고, 슬롯 상태는 별도 `slots[]` 로 분리 노출한다.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- AC-4: Given 스냅샷 요청, Then envelope 에 read-only `slots[]` 배열을 포함한다 — 각 항목은 `slot_id`·`status`·`symbol`·`qty`·`limit_price`·`avg_price`·`portfolio_id` 를 담고, 슬롯이 없어도 `[]`(null 아님)다. `assets[]`(universe) 와 독립이며 strategy 소비자는 무시 가능(additive, 하위호환).
|
||||
- Updated:
|
||||
- none (AC-1~3 의 `assets[]`/degraded/no-price 계약 불변)
|
||||
- Removed:
|
||||
- none
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- docs/interface-contract.md(snapshot 응답에 `slots[]` 필드 추가), dcy-005/dcy-016
|
||||
- Modules:
|
||||
- trex_core/application/portfolio.py(`build_snapshot_envelope` 에 `slots[]`), trex_core/application/messaging_handlers.py(envelope), trex_core/runtime/cli.py(REQ-032 companion — `slots` 가 `slots[]` 를 읽도록, `universe` 는 `assets[]` 유지)
|
||||
- Tests:
|
||||
- envelope `slots[]` 스키마(빈 배열 포함), `trex-core slots` 가 universe 가 아닌 실제 슬롯 상태(status 포함)를 표시
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- BAT-008 (REQ-028 최초 구현), BAT-020 (dcy-016 — `slots` CLI 가 갭 노출). 정정 구현은 신규 BAT-022 (예정).
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: yes (신규 AC-4)
|
||||
- Existing Implementation Invalidated: no (AC-1~3 assets/degraded/no-price 근거 유지)
|
||||
- Status Recommendation: Implemented → Approved (신규 AC-4 미구현)
|
||||
- Follow-up Action: REQ-032 companion change-req + draft-batch(BAT-022) → 구현/검증
|
||||
|
||||
#### Validation Plan
|
||||
- AC-4: envelope `slots[]` 스키마 테스트(빈 배열·status enum 포함) + `trex-core slots` 통합 검증(universe 가 아닌 실제 슬롯 상태 N개를 status 와 함께 표시).
|
||||
|
||||
### CHG-20260608-02
|
||||
- Date: 2026-06-08
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status 변경: Approved → Implemented. BAT-022 release-candidate verification evidence 기반(AC-4 envelope `slots[]`).
|
||||
|
||||
#### Intent
|
||||
- envelope `slots[]`(operator-facing per-slot 상태) 구현 완료 상태로 동기화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added/Updated/Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs/Modules/Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- BAT-022 (release-candidate)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no (BAT-022 에서 완료)
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Implemented
|
||||
- Follow-up Action: release 단계 별도 진행
|
||||
|
||||
#### Validation Plan
|
||||
- AC-4: tests/application/test_snapshot_selection.py::test_envelope_shape_no_price_field + test_snapshot_handler.py::test_envelope_shape_returned(envelope `slots` list). 운영 재현: 신규 코드 데몬 + 실 PostgreSQL/RabbitMQ 에서 `trex-core slots` → slots=10·status 표시·DB `(2026-06-08,idle,10)` 일치(BAT-022 verification). pytest 인프라 게이트는 Human Approval Memo 수용 잔여.
|
||||
|
||||
### CHG-20260610-01
|
||||
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-023/issue #22) snapshot envelope `slots[]` 에서 `allocated_capital` 노출 제거 — `build_snapshot_envelope`(trex_core/application/portfolio.py) 가 계약(AC-4 필드 집합) 외로 노출하던 죽은 필드를 삭제해 문서화된 계약과 구현을 정렬. AC-5 추가, Implemented→Approved(재구현 대기).
|
||||
|
||||
#### Intent
|
||||
|
||||
- Slot 도메인에서 allocated_capital 이 제거(REQ-002 CHG-20260610-02)됨에 따라 read 표면에서도 동일 필드를 제거. strategy/operator 소비자가 죽은 필드를 참조할 여지 차단.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- AC-5: slots[] 항목에 allocated_capital 키 부재.
|
||||
- Updated:
|
||||
- 없음
|
||||
- Removed:
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: trex_core/application/portfolio.py(build_snapshot_envelope slots[] 매핑)
|
||||
- Tests: snapshot envelope slots[] 스키마 테스트에서 allocated_capital 부재 확인 + 기존 fixture 정리
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: (예정) dcy-023 batch
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (dcy-023 batch 에서 수행)
|
||||
- Existing Implementation Invalidated: yes (slots[] 노출 필드 변경)
|
||||
- Status Recommendation: Approved (Implemented→Approved 되돌림)
|
||||
- Follow-up Action: dcy-023 batch 구현·검증 후 confirm-req-implemented. CLI slots detail 표시 제거는 REQ-032 CHG-20260610-07 이 소유.
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- dcy-023 batch: envelope slots[] 스키마 테스트(allocated_capital 부재) + 전체 suite green.
|
||||
|
||||
### CHG-20260610-IMPL
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-034(release-candidate) verification — allocated_capital 전 경로 제거(도메인/intent/영속/snapshot/CLI), 마이그레이션 013 테스트 DSN 멱등 round-trip + 컬럼 부재 확인, 전체 428 passed + PG 게이트 21 passed + ruff clean, grep 전수 0건. Blocking Issues 없음.
|
||||
|
||||
### CHG-20260611-01
|
||||
|
||||
- Date: 2026-06-11
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-025) 본 REQ 가 소유한 snapshot read 계약(`trex.snapshot.req` 요청 view/strategy_key, 응답 envelope `assets[]`/`available_slots`/`watchdog[]`/degraded)이 **폐기 예정** — `trex.slots.req`(REQ-073) + 슬롯 단일 행 스키마(REQ-074)로 대체된다(즉시 교체, dcy-025 OQ-1). degraded/reason/message health 신호 의미는 REQ-073 으로 승계. 현재 코드는 불변이므로 Implemented 유지(keep-current, REQ-005 CHG-20260610-01 선례), dcy-025 delivery 배치에서 표면 제거와 함께 **Deprecated** 전환.
|
||||
|
||||
#### Intent
|
||||
|
||||
- snapshot→slots 표면 교체의 추적성 forward-link.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Updated: 없음(dcy-025 delivery 배치에서 본 REQ 의 envelope AC 폐기)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs: dcy-025, REQ-073/074/075
|
||||
- Modules: (예정) messaging_handlers.py snapshot 핸들러·portfolio.py envelope 빌더 제거/대체
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: (예정) dcy-025 delivery 배치
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no (현 시점 — 코드 불변)
|
||||
- Existing Implementation Invalidated: no (배치 구현 시점에 무효화·Deprecated 전환)
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: dcy-025 배치에서 표면 제거 + 본 REQ Deprecated 전환.
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- dcy-025 배치 verification 으로 대체(snapshot 표면 부재 + slots 표면 계약 검증).
|
||||
@@ -1,215 +0,0 @@
|
||||
# req-029: 자산 선별(slot overlay) + view 모드 + strategy_key 필터
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- 스냅샷 응답에 담을 자산 집합을 core 의 권위 슬롯 상태로 선별한다. 보유(holding)는 포함하되 일시·불안전 상태는 마스킹하고, 전략 타입별 view 와 전략별 필터를 제공한다.
|
||||
|
||||
## Requirement
|
||||
- 응답 base 집합은 요청 `view`(`all` 기본 | `buyable` | `held`)로 선택한다: `all` = universe 전체(portfolio-hub 보유 + holding 슬롯), `buyable` = universe − 슬롯 점유, `held` = holding 슬롯 자산만.
|
||||
- 마스킹(pending·warning·pause)은 전 모드에 균일 적용한다. pending 은 모든 모드에서 마스킹되므로 `held` 는 holding 만 포함한다. 포함/마스킹 판정은 core 권위 슬롯 상태 + 정합 결과 + pause 상태를 portfolio-hub 보유 여부보다 우선한다(slot overlay, 불변식 A).
|
||||
- 선택적 `strategy_key`(요청 시) 는 자산의 단일 `active_strategy_id` 와 대소문자 구분 정확 일치로 직교 필터링한다. `strategy_key` 는 사람이 읽는 안정 유일 slug(예: `target-value-v1`)다.
|
||||
- 최종 합성: `assets = base(view) − mask(pending·warning·pause) − (strategy_key 필터, 주어진 경우)`. `buyable` 은 `available_slots=0` 이면 `[]` 다.
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given 같은 종목이 holding 슬롯·pending 슬롯에 각각 있을 때, When `view=all`, Then holding 자산은 포함되고 pending 자산은 마스킹된다.
|
||||
2. Given `available_slots=0`, When `view=buyable`, Then `[]` 를 반환한다.
|
||||
3. Given `view=held`, Then holding 슬롯 자산만 반환하고 pending 은 제외한다.
|
||||
4. Given `strategy_key` 제공, Then `active_strategy_id` 가 일치하는 자산만 반환하고, 생략 시 (마스킹 후) 전체 자산을 반환한다.
|
||||
5. Given warning 또는 pause 자산, When 임의 `view`, Then 해당 자산은 마스킹된다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/discovery/dcy-005_20260604_portfolio-hub-asset-snapshot-api.md
|
||||
- Modules: trex_core/application 스냅샷 선별/slot overlay 로직(slot repository 재사용), strategy_key 필터
|
||||
- Tests: view 모드별·마스킹·strategy_key 필터 합성 테스트
|
||||
|
||||
## Notes
|
||||
- core 권위 슬롯 상태(불변식 A)가 portfolio-hub 보유 여부보다 우선한다.
|
||||
- OQ-4(in-flight 합성)·OQ-9(strategy_key)·OQ-11/OQ-12(view 모드) 반영.
|
||||
- holding 자산의 보유 수량 표기를 core 슬롯 vs 스냅샷 중 무엇 기준으로 할지(holding→ledger flush 갭)는 설계 시 확정(dcy-005 OQ-4 잔여).
|
||||
- (orb-v1 소비 참고, CHG-04) 첫 전략 orb-v1 은 `strategy_key` 없이 `view=buyable` 로 조회한다. 즉 전략 설정과 무관하게 universe 전체를 대상으로 하고, slot 점유(holding·pending)·warning(정합 불일치)·pause(사용자) 만 제외하면 된다 — 이는 `view=buyable` + `strategy_key` 생략의 기존 동작과 정확히 일치한다. pending(in-flight) 제외는 중복 주문 방지, warning 제외는 틀린 baseline 매매 차단(REQ-031) 목적으로 orb-v1 의도에 부합한다(사용자 확인). 따라서 단일 전략 단계에서는 `/v1/portfolios` PortfolioItem 의 전략 필드(active_strategy_id/strategy_params) 부재가 orb-v1 동작에 무해하다. (2번째 전략부터는 strategy_key 라우팅이 필요해져 전략 필드 부재 해소가 재대두된다.)
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260606-01
|
||||
- Date: 2026-06-06
|
||||
- Author: project maintainers
|
||||
|
||||
#### Change Summary
|
||||
- dcy-005 FR-2/FR-8 + OQ-4/9/11/12 분해로 최초 생성(Proposed).
|
||||
|
||||
#### Intent
|
||||
- 응답 자산 선별(slot overlay·view·strategy_key) 규칙 정의.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- AC-1~5 신규
|
||||
- Updated:
|
||||
- none
|
||||
- Removed:
|
||||
- none
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- dcy-005
|
||||
- Modules:
|
||||
- 스냅샷 선별/slot overlay, strategy_key 필터
|
||||
- Tests:
|
||||
- view/마스킹/필터 테스트
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- none
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req
|
||||
|
||||
#### Validation Plan
|
||||
- 슬롯 상태 주입 후 view/마스킹/strategy_key 합성 테스트로 AC 검증.
|
||||
|
||||
### CHG-20260606-02
|
||||
- Date: 2026-06-06
|
||||
- Author: project maintainers
|
||||
|
||||
#### Change Summary
|
||||
- 승인 게이트 통과 → Proposed → Approved.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: none
|
||||
- Updated: none
|
||||
- Removed: none
|
||||
|
||||
#### Impacted Area Delta
|
||||
- 변경 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs / draft-batch
|
||||
|
||||
#### Validation Plan
|
||||
- 승인 기록. 구현 전 재검증 불필요.
|
||||
|
||||
### CHG-20260606-03
|
||||
- Date: 2026-06-06
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status 변경: Approved → Implemented. BAT-008 release-candidate verification evidence 기반.
|
||||
|
||||
#### Intent
|
||||
- `build_snapshot_envelope` 의 base(view) 산출 + masking OR 합성 + strategy_key 직교 필터 구현 완료 상태로 동기화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added/Updated/Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs/Modules/Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- BAT-008 (release-candidate)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Implemented
|
||||
- Follow-up Action: release 단계는 별도 진행
|
||||
|
||||
#### Validation Plan
|
||||
- AC-1: tests/application/test_snapshot_selection.py::test_view_all_includes_holding_excludes_pending_for_same_symbol.
|
||||
- AC-2: ::test_view_buyable_with_zero_available_slots_returns_empty.
|
||||
- AC-3: ::test_view_held_returns_only_holding_slot_assets.
|
||||
- AC-4: ::test_strategy_key_orthogonal_filter + ::test_strategy_key_missing_includes_everything_unmasked.
|
||||
- AC-5: ::test_warning_overlay_masks_asset_uniformly_across_views + ::test_pause_overlay_masks_asset.
|
||||
|
||||
### CHG-20260606-04
|
||||
- Date: 2026-06-06
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- 첫 전략 orb-v1 의 스냅샷 소비 패턴을 Notes 참고 사항으로 추가(본문 비변경). AC/요구사항/계약 변경 없음.
|
||||
|
||||
#### Intent
|
||||
- orb-v1 은 전략 설정(active_strategy_id/strategy_params)과 무관하게 모든 자산을 대상으로 하며 `strategy_key` 없이 `view=buyable` 로 조회한다는 소비 계약을 명시해, `/v1/portfolios` PortfolioItem 의 전략 필드 부재가 orb-v1 에 무해함을 기록한다.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: none
|
||||
- Updated: none
|
||||
- Removed: none
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- 본 REQ Notes 에 orb-v1 소비 참고 사항 1건 추가
|
||||
- Modules: 없음
|
||||
- Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- BAT-008 (release-candidate) — 영향 없음(기존 구현/검증 그대로 유효)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current (Implemented 유지)
|
||||
- Follow-up Action: orb-v1 Discovery 착수 시 본 참고 사항을 입력으로 사용. 2번째 전략 도입 시 strategy_key/strategy_params 필요 → PortfolioItem 전략 필드 부재 해소(detail strategy_set 보강 또는 별도 change-req) 재검토.
|
||||
|
||||
#### Validation Plan
|
||||
- 문서 전용 변경. 기존 AC-1~5 테스트 그대로 유효하며 재실행 불필요.
|
||||
|
||||
### CHG-20260608-01
|
||||
|
||||
- Date: 2026-06-08
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-018) 수량/현금 source 정합: 슬롯 오버레이(REQ-029)는 **유지**(lifecycle 중 슬롯 = 코어 권위 즉시값, 불변식 A). 스냅샷 응답에 미정산 ledger 가 있는 자산은 `cash_balance += pending delta` + `cash_estimated:true` 라벨로 **추정 현금 오버레이**(OQ-4 (i))를 노출하고, option D write-back 도착 시 권위값 수렴. BAT-023 재구현·재검증 완료 → Implemented 유지.
|
||||
|
||||
#### Intent
|
||||
|
||||
- "수량 live·현금 stale" 비대칭 제거 — 수량은 슬롯 오버레이(정확), 현금은 추정 오버레이(라벨)로 즉시성 확보 후 권위값 수렴.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- 스냅샷 자산에 추정 현금 오버레이(`cash_estimated` 플래그) — 미정산 outbox delta 기반. 슬롯 오버레이는 그대로 유지(변경 없음).
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/application/messaging_handlers.py`(`_apply_cash_estimate`)
|
||||
- Docs: `docs/interface-contract.md`(envelope `cash_estimated`)
|
||||
- Tests: tests/application/test_ledger_option_d.py(estimate overlay)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-023
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (BAT-023 에서 완료)
|
||||
- Existing Implementation Invalidated: no (오버레이 유지 + 추정 additive)
|
||||
- Status Recommendation: Implemented (change-req → BAT-023 재검증)
|
||||
- Follow-up Action: confirm-req-implemented(BAT-023).
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- BAT-023: 미정산 자산 cash_estimated + 추정 cash 단위, write-back 후 수렴.
|
||||
@@ -1,464 +0,0 @@
|
||||
# req-032: 런타임 pause/resume 제어
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: Medium
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- 운영자가 특정 자산을 런타임에 매매에서 제외(pause)하거나 다시 포함(resume)할 수 있게 한다. 프로그램 이상·이벤트 시 안전 통제를 위한 수동 overlay 다.
|
||||
|
||||
## Requirement
|
||||
- pause/resume 단위는 `portfolio_id`(= asset_id)다.
|
||||
- 제어는 **CLI** 와 **dcy-006 RPC 제어 메시지** 둘 다로 가능하며, 둘은 동일한 pause 상태를 변경한다. config 리로드 방식은 채택하지 않는다.
|
||||
- pause 상태는 **Postgres 에 영속**(portfolio_id 키)하며 daemon 재시작 후에도, 일일 스냅샷 refresh 후에도 유지된다(refresh 는 universe/포지션만 갱신, pause overlay 불변).
|
||||
- 적용 범위는 **전역** — pause 된 자산은 모든 view/전략 요청에서 마스킹된다.
|
||||
- pause 는 request-time mask 이므로 resume 시 다음 요청부터 즉시 응답에 복귀한다.
|
||||
- (CHG-20260609-01, issue #17) 운영자 CLI `enter` 는 시간 기반 자동청산을 위해 **`--forced-close-at <ISO8601>` (절대시간)** 옵션을 제공한다. CLI 는 이를 buy intent payload 의 기존 `forced_close_at` 필드에 매핑하며, 도메인·forced-close 루프(REQ-037)는 불변이다. 상대시간 옵션은 채택하지 않는다.
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given 운영자가 `portfolio_id` 를 pause, When 임의 `view`/`strategy_key` 로 스냅샷을 요청, Then 그 자산은 응답에서 마스킹된다.
|
||||
2. Given pause 상태에서 daemon 재시작 또는 일일 refresh 발생, When 이후 요청, Then pause 가 유지된다.
|
||||
3. Given 운영자가 resume, When 다음 요청, Then 그 자산이 응답에 다시 포함된다.
|
||||
4. Given CLI 로 pause 후 RPC 제어로 조회(또는 그 반대), Then 동일한 pause 상태가 보인다.
|
||||
5. (CHG-20260609-01) Given 운영자가 `trex-core enter <portfolio_id> ... --forced-close-at <ISO8601>`, When buy intent 가 제출·admit, Then payload 에 파싱된 `forced_close_at` 절대시각이 실리고 admitted 슬롯의 `forced_close_at` 이 그 값으로 설정된다.
|
||||
6. (CHG-20260609-01) Given `--forced-close-at` 미지정, Then payload 에 `forced_close_at` 을 포함하지 않고 기존 enter 동작이 불변이다. Given 잘못된 timestamp 형식, Then 제출 전 검증 오류로 거부된다.
|
||||
7. (CHG-20260610-06, issue #23) Given 운영자가 `trex-core enter <portfolio_id>` 에 `--qty` 를 지정하지 않으면, Then CLI 가 intent 제출 전에 즉시 오류를 반환하고 RPC 는 호출되지 않는다.
|
||||
8. (CHG-20260610-07, dcy-023/issue #22) Given 운영자 CLI, Then `enter` 는 `--capital` 옵션을 받지 않고(지정 시 argparse unknown argument 거부), buy intent payload 에 `allocated_capital` 을 싣지 않으며, `slots` detail 표시에서 `allocated_capital` 행이 제거된다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/discovery/dcy-005_20260604_portfolio-hub-asset-snapshot-api.md
|
||||
- Modules: pause 상태 store(Postgres), CLI 제어, dcy-006 RPC 제어 메시지 핸들러, 응답 산출 시 pause 마스킹, (CHG-20260609-01) `trex_core/runtime/cli.py` `_cmd_enter` `--forced-close-at` 옵션 → buy intent `forced_close_at` 매핑, (CHG-20260610-06) `trex_core/runtime/cli.py` `_cmd_enter` `--qty` 미지정 시 제출 전 오류 처리, (CHG-20260610-07) `trex_core/runtime/cli.py` `--capital` argparse 제거 + payload `allocated_capital` 제거 + `_print_slot_detail` 행 제거
|
||||
- Tests: pause→호출→resume→호출 시퀀스, 재시작/refresh 후 영속, (CHG-20260609-01) enter `--forced-close-at` payload 매핑·형식 검증, (CHG-20260610-06) enter `--qty` 누락 오류 + RPC 미호출, (CHG-20260610-07) `--capital` argparse 거부 + payload allocated_capital 부재
|
||||
|
||||
## Notes
|
||||
- pause(수동·영속) vs warning(자동·일시, REQ-031)은 독립 overlay 이며 OR 합성(둘 중 하나라도면 마스킹).
|
||||
- OQ-10 반영.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260606-01
|
||||
- Date: 2026-06-06
|
||||
- Author: project maintainers
|
||||
|
||||
#### Change Summary
|
||||
- dcy-005 FR-9 + OQ-10 분해로 최초 생성(Proposed).
|
||||
|
||||
#### Intent
|
||||
- 런타임 pause/resume 제어(단위·제어 표면·영속·범위) 정의.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- AC-1~4 신규
|
||||
- Updated:
|
||||
- none
|
||||
- Removed:
|
||||
- none
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- dcy-005
|
||||
- Modules:
|
||||
- pause store, CLI, RPC 제어, 마스킹
|
||||
- Tests:
|
||||
- pause/resume 시퀀스, 영속
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- none
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req
|
||||
|
||||
#### Validation Plan
|
||||
- pause→호출→resume→호출 + 재시작 영속 테스트로 AC 검증.
|
||||
|
||||
### CHG-20260606-02
|
||||
- Date: 2026-06-06
|
||||
- Author: project maintainers
|
||||
|
||||
#### Change Summary
|
||||
- 승인 게이트 통과 → Proposed → Approved.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: none
|
||||
- Updated: none
|
||||
- Removed: none
|
||||
|
||||
#### Impacted Area Delta
|
||||
- 변경 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs / draft-batch
|
||||
|
||||
#### Validation Plan
|
||||
- 승인 기록. 구현 전 재검증 불필요.
|
||||
|
||||
### CHG-20260606-03
|
||||
- Date: 2026-06-06
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status 변경: Approved → Implemented. BAT-008 release-candidate verification evidence 기반.
|
||||
|
||||
#### Intent
|
||||
- pause/resume CLI + RPC 제어 + Postgres 영속 구현 완료 상태로 동기화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added/Updated/Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs/Modules/Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- BAT-008 (release-candidate)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Implemented
|
||||
- Follow-up Action: release 단계는 별도 진행
|
||||
|
||||
#### Validation Plan
|
||||
- AC-1: tests/application/test_pause_handler.py::test_pause_then_list + test_snapshot_selection.py::test_pause_overlay_masks_asset.
|
||||
- AC-2: tests/adapters/portfolio/test_postgresql_pause_store.py::test_durability_simulated_via_fresh_store_instance.
|
||||
- AC-3: tests/application/test_pause_handler.py::test_resume_clears_pause.
|
||||
- AC-4: tests/application/test_pause_handler.py::test_cli_pause_visible_to_rpc_list_via_shared_store + 실 daemon RPC 운영 검증.
|
||||
|
||||
### CHG-20260608-01
|
||||
|
||||
- Date: 2026-06-08
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-016) 운영자 CLI 확장: `universe`/`slots`/`enter`/`exit` 서브커맨드 추가(전부 데몬 RabbitMQ RPC). 인스턴스 라우팅(`--config` canonical/`--instance` 단축/default), enter/exit 안전장치(확인 프롬프트 기본 ON + `--yes`(paper)/`--yes --live`(live 이중 ack)/`--dry-run`), 전 명령 `--json`. pause/resume/paused 는 기존 direct-DB 유지(OQ-3). BAT-020 재구현·재검증 완료 → Implemented 유지.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 운영자가 조회·매수(enter)·매도(exit)·일시정지를 CLI 로 수행하되, 매매는 데몬 admission(단일 writer)을 거쳐 불변식·portfolio_id 검증을 보존(DB 직접 쓰기 없음, NFR-1).
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- universe/slots(snapshot RPC)·enter(buy intent RPC)·exit(sell intent RPC) CLI + 인스턴스 라우팅 + enter/exit 안전장치 + `--json`.
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/runtime/cli.py`(서브커맨드/가드/라우팅/RPC 클라이언트)
|
||||
- Docs: `docs/interface-contract.md`, `docs/runtime-flows.md`
|
||||
- Tests: tests/runtime/test_cli_operator.py
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-020
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (BAT-020 에서 완료)
|
||||
- Existing Implementation Invalidated: no (pause/resume 불변, 명령 추가)
|
||||
- Status Recommendation: Implemented (change-req → BAT-020 재검증)
|
||||
- Follow-up Action: confirm-req-implemented(BAT-020).
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- BAT-020: CLI universe/slots/enter/exit RPC payload·안전장치·라우팅·--json 단위.
|
||||
|
||||
### CHG-20260608-02
|
||||
|
||||
- Date: 2026-06-08
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-017) `trex-core slots` 가 snapshot 응답의 `watchdog` 필드를 읽어 `expired=true` 슬롯을 **WATCHDOG-OWNED(전략 이탈)** 로 표시(+`watchdog_owned` 카운트). dcy-016 `slots` 확장. BAT-021 재구현·재검증 완료 → Implemented 유지.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 운영자가 CLI 로 워치독 소유(전략 이탈) 슬롯을 즉시 인지.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Updated:
|
||||
- `slots` 출력에 워치독 소유 표시(snapshot watchdog 필드 기반).
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/runtime/cli.py`(_cmd_slots watchdog 표시)
|
||||
- Tests: tests/runtime/test_cli_operator.py::test_slots_marks_watchdog_owned
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-021
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (BAT-021 에서 완료)
|
||||
- Existing Implementation Invalidated: no (표시 추가)
|
||||
- Status Recommendation: Implemented (change-req → BAT-021 재검증)
|
||||
- Follow-up Action: confirm-req-implemented(BAT-021).
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- BAT-021: slots watchdog-owned 표시 단위.
|
||||
|
||||
### CHG-20260608-03
|
||||
|
||||
- Date: 2026-06-08
|
||||
- Author: project maintainers
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-016 후속) `trex-core slots` 가 universe `assets[]`(portfolio: asset_id/symbol/asset_quantity)를 **슬롯 상태로 오인 표시**하던 갭 정정(운영 관측: 10개 슬롯인데 universe 1개·status 없음). snapshot envelope 의 신규 read-only `slots[]`(REQ-028 CHG-20260608-01, AC-4)를 읽어 **실제 슬롯 상태(`slot_id`·`status`(idle/holding/pending_buy/pending_sell)·`symbol`·`qty`·`limit_price`·`avg_price`)** 를 표시한다. `universe` 명령은 `assets[]`(universe) 유지로 둘을 명확히 분리. watchdog-owned 표시(CHG-20260608-02)는 `slots[]` 항목과 결합.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 운영자가 `trex-core slots` 로 데몬의 실제 슬롯 상태(idle/holding/pending_*)를 관측하게 한다. `universe`(거래 대상 portfolio)와 `slots`(데몬 슬롯 할당 상태)를 표면상 명확히 구분.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Updated:
|
||||
- `slots` 출력은 universe `assets[]` 가 아니라 envelope `slots[]`(슬롯 상태, `status` 포함)를 표시한다. `--status held/holding/...` 필터는 슬롯 상태 기준으로 적용된다.
|
||||
- Added: none
|
||||
- Removed: none
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/runtime/cli.py`(`_cmd_slots` → `resp["slots"]` 읽기). 전제: REQ-028 envelope `slots[]`(CHG-20260608-01).
|
||||
- Tests: `slots` 가 universe 가 아닌 실제 슬롯 상태(status 포함)를 표시, universe 와 구분.
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-020 (`slots` 최초 구현 — 갭 발생). 정정은 신규 BAT-022 (REQ-028 AC-4 와 함께).
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes
|
||||
- Existing Implementation Invalidated: yes (`slots` 가 universe assets 를 표시하던 부분이 슬롯 상태 의도와 불일치)
|
||||
- Status Recommendation: Implemented → Approved (REQ-028 `slots[]` 의존, BAT-022 재구현/재검증)
|
||||
- Follow-up Action: REQ-028 AC-4 구현 후 draft-batch(BAT-022) → 구현/검증
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- BAT-022: `trex-core slots` 가 envelope `slots[]` 의 실제 슬롯 상태(status enum 포함)를 표시하고 universe(`assets[]`)와 구분됨을 단위/통합 검증.
|
||||
|
||||
### CHG-20260608-04
|
||||
- Date: 2026-06-08
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status 변경: Approved → Implemented. BAT-022 release-candidate verification evidence 기반(`slots` 가 envelope `slots[]` 표시, CHG-20260608-03).
|
||||
|
||||
#### Intent
|
||||
- `trex-core slots` 가 실제 슬롯 상태(status)를 표시하는 정정 구현 완료 동기화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added/Updated/Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs/Modules/Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- BAT-022 (release-candidate)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no (BAT-022 에서 완료)
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Implemented
|
||||
- Follow-up Action: release 단계 별도 진행
|
||||
|
||||
#### Validation Plan
|
||||
- tests/runtime/test_cli_operator.py::test_slots_shows_real_slot_state_not_universe / ::test_slots_status_filters_by_slot_status / ::test_slots_marks_watchdog_owned. 운영 재현(BAT-022): 신규 코드 데몬 + 실 인프라 `trex-core slots` → slots=10 status·`--status holding`=0·universe(assets=1) 분리·비침습. pytest 인프라 게이트는 Human Approval Memo 수용 잔여.
|
||||
|
||||
### CHG-20260609-01
|
||||
|
||||
- Date: 2026-06-09
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, issue #17) `trex-core enter` 에 **`--forced-close-at <ISO8601>` (절대시간) 옵션** 추가. 운영자가 매수 진입 명령 하나로 시간 기반 자동청산(forced_close) 시각을 지정. CLI 는 이 값을 buy intent payload 의 **기존** `forced_close_at` 필드에 매핑한다(계약: REQ-007/021 buy intent body 가 이미 `forced_close_at` optional 수용, 도메인 `Slot.forced_close_at`(REQ-066), forced-close 만기 매도 루프 REQ-037 — 전부 구현·불변). 상대시간(`--hold-minutes`)은 **미채택**(사용자 결정: 절대시간만).
|
||||
|
||||
#### Intent
|
||||
|
||||
- 운영자가 진입 명령 하나로 시간 기반 매매 계획(자동청산 시각 포함)을 표현하게 한다. 현재는 `--stop-loss`/`--take-profit` 만 노출돼 시간 기반 청산은 별도 수동/스케줄 `exit` 가 필요했다(issue #17 갭). 도메인 능력은 이미 존재하고 CLI 노출만 보완.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- AC-5: `trex-core enter <portfolio_id> ... --forced-close-at <ISO8601 timestamp>` 가 주어지면 CLI 는 buy intent payload 에 `forced_close_at`(파싱된 절대시각)을 실어 제출하고, admitted 슬롯의 `forced_close_at` 이 그 값으로 설정된다.
|
||||
- AC-6: `--forced-close-at` 미지정 시 payload 에 `forced_close_at` 을 포함하지 않으며 기존 enter 동작은 불변(하위호환). 잘못된 timestamp 형식은 제출 **전** 검증 오류로 거부한다.
|
||||
- Updated: none
|
||||
- Removed: none
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/runtime/cli.py`(`_cmd_enter` payload 에 `forced_close_at` 추가 + `--forced-close-at` 인자/파싱·검증). buy intent 핸들러·도메인·forced-close 루프는 불변(이미 수용).
|
||||
- Docs: `docs/interface-contract.md`(enter 옵션 표 + buy intent payload `forced_close_at` 노출), 필요 시 `docs/runtime-flows.md`.
|
||||
- Tests: `tests/runtime/test_cli_operator.py`(enter `--forced-close-at` → payload `forced_close_at` 매핑 + 잘못된 형식 거부).
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: 신규 batch-lite(차기 BAT) — enter `--forced-close-at` 노출.
|
||||
- Releases: none (차기 release 또는 통합 편입).
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (신규 batch 에서 AC-5/6 검증)
|
||||
- Existing Implementation Invalidated: no (pause/resume/universe/slots/enter/exit 기존 AC 불변, 옵션 additive)
|
||||
- Status Recommendation: Implemented → Approved (신규 AC-5/6 미구현 — batch 재검증 후 Implemented 복귀; 기존 AC-1~4 및 CLI 명령은 구현 유지)
|
||||
- Follow-up Action: draft-batch(batch-lite) → run-batch-implementation → verification → confirm-req-implemented
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- 신규 BAT: `enter --forced-close-at <ts>` → buy intent payload 에 `forced_close_at` 정확 매핑 단위, 잘못된 형식(예 `--forced-close-at notatime`) 제출 전 거부 단위, 미지정 시 payload 미포함(회귀). (가능 시) 실 데몬 e2e: `enter --forced-close-at <근접시각>` → admitted 슬롯 `forced_close_at` 설정 → forced-close 루프(REQ-037) 만기 매도 확인.
|
||||
|
||||
### CHG-20260609-02
|
||||
|
||||
- Date: 2026-06-09
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- Status 변경: Approved → Implemented. BAT-024 release-candidate verification evidence 기반(CHG-20260609-01 AC-5/6).
|
||||
|
||||
#### Intent
|
||||
|
||||
- 운영자 `enter --forced-close-at`(절대시간) → buy intent `forced_close_at` 매핑 구현 완료 동기화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added/Updated/Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs/Modules/Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches:
|
||||
- BAT-024 (release-candidate)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no (BAT-024 에서 완료)
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Implemented
|
||||
- Follow-up Action: release 단계 별도 진행(차기 REL 또는 통합 편입)
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- tests/runtime/test_cli_operator.py::test_enter_with_forced_close_at_maps_to_payload (AC-5) / ::test_enter_without_forced_close_at_omits_field (AC-6 하위호환) / ::test_enter_rejects_malformed_forced_close_at_before_submit (AC-6 형식 거부). 전체 단위 353 passed, ruff clean.
|
||||
|
||||
### CHG-20260610-06
|
||||
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, issue #23) `trex-core enter`에 **`--qty` 미지정 시 제출 전 즉시 오류 반환** 추가. 현재 `--qty` 생략 → `qty=None` → admitted 응답 → 집행 루프 KIS 거절 → `pending_buy→inactive` 자동 롤백으로 "접수 성공처럼 보이지만 실제 매수 안 됨" 혼동 발생. CLI 단에서 admission 전에 차단.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 운영자가 수량 없이 `enter`를 실행하면 RPC 제출 이전에 즉시 오류를 보고 혼동 없이 재시도할 수 있도록 한다.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- AC-7: `trex-core enter <portfolio_id>` 에 `--qty` 를 지정하지 않으면 CLI 가 intent 제출 전에 즉시 오류를 반환하고 RPC 는 호출되지 않는다.
|
||||
- Updated: none
|
||||
- Removed: none
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/runtime/cli.py`(`_cmd_enter` 또는 argparse에 `--qty` 검증 추가)
|
||||
- Tests: `tests/runtime/test_cli_operator.py`(enter `--qty` 누락 오류 + RPC 미호출 검증)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: 신규 batch-lite(차기 BAT) — enter `--qty` 필수 검증
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (신규 batch-lite 에서 AC-7 검증)
|
||||
- Existing Implementation Invalidated: no (AC-1~6 기존 동작 불변, additive 검증 추가)
|
||||
- Status Recommendation: Implemented → Approved (AC-7 미구현; 기존 AC-1~6 구현은 유효)
|
||||
- Follow-up Action: draft-batch(batch-lite) → run-batch-implementation → verify → confirm-req-implemented
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- 신규 batch-lite: `enter` 에 `--qty` 없이 실행 → rc=1 + RPC calls=0 단위. `--qty 10`과 함께 실행 → 정상 submit 불변(회귀) 단위.
|
||||
|
||||
### CHG-20260610-07
|
||||
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-023/issue #22) 운영자 CLI 에서 `--capital` 옵션 제거 — `enter` argparse 인자 삭제(지정 시 unknown argument 거부), `_cmd_enter` summary·payload 의 `allocated_capital` 제거, `slots` detail(`_print_slot_detail`)의 `allocated_capital` 행 제거. AC-8 추가, Implemented→Approved(재구현 대기).
|
||||
|
||||
#### Intent
|
||||
|
||||
- `--capital` 이 사이징한다는 오해를 CLI 표면에서 원천 제거. 실제 수량은 `--qty`(AC-7 필수)만이 결정하며, capital 은 어떤 경로에서도 소비되지 않음(dcy-023 §3 전수 추적).
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- AC-8: `--capital` argparse 거부 + payload allocated_capital 부재 + slots detail 행 제거.
|
||||
- Updated:
|
||||
- 없음
|
||||
- Removed:
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: trex_core/runtime/cli.py(`--capital` 인자, `_cmd_enter` summary/payload, `_print_slot_detail`)
|
||||
- Tests: tests/runtime/test_cli_operator.py — 기존 enter 테스트의 `--capital` 인자 제거 + argparse 거부 테스트 추가
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: (예정) dcy-023 batch. BAT-033(AC-7, release-candidate)의 enter 테스트와 같은 파일을 수정하므로 dcy-023 batch 에서 정합 유지.
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (dcy-023 batch 에서 수행)
|
||||
- Existing Implementation Invalidated: yes (enter 인터페이스 변경 — 기존 --capital 사용 테스트/스크립트 무효)
|
||||
- Status Recommendation: Approved (Implemented→Approved 되돌림)
|
||||
- Follow-up Action: dcy-023 batch 구현·검증 후 confirm-req-implemented. AC-1~7 의 기존 evidence 는 유지되나 enter 표면 변경분 재검증 필요.
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- dcy-023 batch: `enter --capital` argparse 거부(단위) + enter payload allocated_capital 부재 + slots detail 표시 + 전체 suite green.
|
||||
|
||||
### CHG-20260610-IMPL
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-034(release-candidate) verification — allocated_capital 전 경로 제거(도메인/intent/영속/snapshot/CLI), 마이그레이션 013 테스트 DSN 멱등 round-trip + 컬럼 부재 확인, 전체 428 passed + PG 게이트 21 passed + ruff clean, grep 전수 0건. Blocking Issues 없음.
|
||||
@@ -1,236 +0,0 @@
|
||||
# req-034: per-slot 워치독 — snapshot RPC 기반 전략 모듈 활성 감지
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
|
||||
전략 모듈이 슬롯을 활성 관리 중인지 데몬이 감지하기 위해, snapshot RPC 응답 시 해당 슬롯들의 `last_seen_at` 타임스탬프를 in-memory 워치독 store에 기록한다. `TREX_WATCHDOG_TIMEOUT` 이상 갱신되지 않은 슬롯은 "전략 모듈 미감시" 상태로 판정해 자율 안전 매도 체크 대상이 된다(dcy-007 FR-5).
|
||||
|
||||
## Requirement
|
||||
|
||||
- 시스템은 `trex.snapshot.req` 요청을 처리할 때, 응답 envelope에 포함되는 `holding` 슬롯들의 `last_seen_at`을 in-memory 워치독 store(`dict[slot_id, datetime]`)에 현재 시각(UTC 또는 KST 일관 적용)으로 갱신해야 한다.
|
||||
- 시스템은 `now() − last_seen_at > TREX_WATCHDOG_TIMEOUT(초)` 조건이 성립하는 슬롯을 "워치독 만료(watchdog-expired)"로 판정해야 한다.
|
||||
- 데몬 기동 후 `TREX_WATCHDOG_GRACE_PERIOD(초)` 동안은 워치독 만료 판정을 유예해야 한다(grace period). grace period 중에는 어떤 슬롯도 만료로 판정하지 않는다.
|
||||
- 워치독 store는 Postgres에 영속하지 않으며 데몬 재시작 시 초기화된다.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Given `trex.snapshot.req` handler가 응답을 산출할 때, When 응답 슬롯 목록에 `slot_id = S`가 포함되면, Then `watchdog_store[S]`가 현재 시각으로 갱신된다.
|
||||
2. Given `TREX_WATCHDOG_TIMEOUT=120`이고 slot S의 `watchdog_store[S]`가 121초 전일 때, When 워치독 만료 여부를 평가하면, Then S는 만료로 판정된다.
|
||||
3. Given `TREX_WATCHDOG_TIMEOUT=120`이고 slot S의 `watchdog_store[S]`가 60초 전일 때, When 워치독 만료 여부를 평가하면, Then S는 만료로 판정되지 않는다.
|
||||
4. Given 데몬이 기동된 지 `TREX_WATCHDOG_GRACE_PERIOD=60` 초 이내일 때, When 워치독 만료 평가를 수행하면, Then 모든 슬롯의 만료 판정이 유예된다(store 비어 있는 슬롯 포함).
|
||||
5. Given 데몬 재시작이 발생하면, When 기동 직후 워치독 store를 조회하면, Then store는 비어 있다.
|
||||
6. Given 전략 모듈이 `TREX_WATCHDOG_TIMEOUT / 2` 미만 주기로 snapshot RPC를 보낼 때, When 정상 동작 중이면, Then 해당 슬롯의 워치독이 만료되지 않는다(NFR-4 관계식 검증).
|
||||
|
||||
## Impacted Area
|
||||
|
||||
- Docs:
|
||||
- `docs/runtime-flows.md` — 워치독 갱신 흐름 추가 (REQ-042 참조)
|
||||
- `docs/interface-contract.md` — snapshot RPC가 watchdog 갱신 신호임을 명시 (REQ-042 참조)
|
||||
- Modules:
|
||||
- `trex_core/application/messaging_handlers.py` — `make_snapshot_rpc_handler` 확장: 응답 슬롯의 `last_seen_at` 갱신
|
||||
- `trex_core/application/portfolio.py` 또는 신규 `trex_core/application/watchdog.py` — WatchdogStore (`dict[slot_id, datetime]`), grace period 시작 타임스탬프 관리
|
||||
- Tests:
|
||||
- `make_snapshot_rpc_handler` 단위 테스트 — `last_seen_at` 갱신 확인
|
||||
- 워치독 만료 판정 단위 테스트 — 만료/비만료/grace period 시나리오
|
||||
|
||||
## Notes
|
||||
|
||||
- 워치독 store 갱신은 snapshot RPC 응답 슬롯 기준이다. intent RPC(매수/매도)는 갱신 신호가 아니다(`update_thresholds` 액션은 제외 — REQ-040 참조).
|
||||
- NFR-4 권장 관계식: `snapshot RPC 호출 주기 < TREX_WATCHDOG_TIMEOUT / 2`. 기본값 기준 전략 모듈은 60초 이내 주기로 snapshot RPC를 호출해야 한다. 관계식 위반 시 정상 동작 슬롯에서도 워치독 오탐 발생.
|
||||
- 워치독 store 구현 위치(portfolio.py 확장 vs 신규 watchdog.py)는 batch planning에서 결정한다.
|
||||
- `TREX_WATCHDOG_TIMEOUT`, `TREX_WATCHDOG_GRACE_PERIOD` env var 파싱은 REQ-041 참조.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260607-01
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- dcy-007 confirmed → REQ-034 초안 생성
|
||||
|
||||
#### Intent
|
||||
|
||||
- per-slot 워치독 메커니즘(FR-5)을 독립 구현·검증 단위로 정규화
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added: AC-1~6 전체
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs: runtime-flows.md, interface-contract.md (REQ-042에서 처리)
|
||||
- Modules: messaging_handlers.py, watchdog store 신규/확장
|
||||
- Tests: snapshot handler + 워치독 판정 단위 테스트
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: none (미할당)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs 후 batch 배정
|
||||
|
||||
### CHG-20260607-02
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- Proposed → Approved (confirm-req)
|
||||
|
||||
#### Intent
|
||||
|
||||
- 승인 게이트 통과: 필수 필드·AC·Impacted Area·Change Log 완비 확인. dcy-007(confirmed) 범위 및 결정 사항과 모순 없음.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: none (미할당)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs 후 batch 배정
|
||||
|
||||
### CHG-20260608-01
|
||||
|
||||
- Date: 2026-06-08
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-016) 워치독 갱신 부수효과를 운영자 조회에서 억제: snapshot RPC 핸들러가 `touch_watchdog=false`/`actor="operator"` 요청에 대해 holding 슬롯 `last_seen_at` 갱신을 건너뛴다. 전략 폴링 기본 동작은 불변(REQ-034 핵심 의미 유지). BAT-020 재구현·재검증 완료 → Implemented 유지.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 운영자 CLI(`universe`/`slots`) 조회가 워치독 생존 신호로 작동해 죽은 전략의 safety-sell 을 억제하는 안전 결함(R-4)을 제거.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Updated:
|
||||
- 워치독 `last_seen_at` 갱신은 전략 폴링(기본)에만 적용; 운영자 억제 플래그 요청은 제외.
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/application/messaging_handlers.py`(snapshot 핸들러 워치독 분기)
|
||||
- Tests: tests/application/test_messaging_snapshot_consumer.py::test_operator_query_suppresses_watchdog_touch
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-020
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (BAT-020 에서 완료)
|
||||
- Existing Implementation Invalidated: no (기본 전략 폴링 동작 불변)
|
||||
- Status Recommendation: Implemented (change-req → BAT-020 재검증)
|
||||
- Follow-up Action: confirm-req-implemented(BAT-020).
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- BAT-020: operator 요청 시 watchdog.update 미호출, 기본 요청 시 호출 단위.
|
||||
|
||||
### CHG-20260608-02
|
||||
|
||||
- Date: 2026-06-08
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-017/issue #12) 워치독 상태 가시화: `WatchdogStore.last_seen(slot_id)` read-only getter 추가, snapshot RPC 응답에 holding 슬롯 워치독 상태(`expired`/`last_seen`) read-only 동봉(best-effort). 판정 로직·timeout 불변(관측만 추가). BAT-021 재구현·재검증 완료 → Implemented 유지.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 전략 이탈로 슬롯이 안전망(워치독) 소유로 넘어간 상태를 운영자가 인지 가능하게(무성 → 가시화).
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- snapshot 응답 워치독 상태 노출 + `last_seen` getter. 판정 동작 불변.
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/application/watchdog.py`(last_seen), `trex_core/application/messaging_handlers.py`(_attach_watchdog)
|
||||
- Tests: tests/application/test_messaging_snapshot_consumer.py::test_snapshot_exposes_watchdog_state_for_holding_slots
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-021
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (BAT-021 에서 완료)
|
||||
- Existing Implementation Invalidated: no (관측만 추가, 판정 불변)
|
||||
- Status Recommendation: Implemented (change-req → BAT-021 재검증)
|
||||
- Follow-up Action: confirm-req-implemented(BAT-021).
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- BAT-021: 워치독 만료 holding 슬롯의 expired/last_seen 노출 단위.
|
||||
|
||||
### CHG-20260611-01
|
||||
|
||||
- Date: 2026-06-11
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-025) 워치독 갱신 트리거 표면을 `trex.snapshot.req` → **`trex.slots.req`**(REQ-073)로 정합한다. 갱신 시맨틱: 기본 조회(holding 슬롯 포함)가 `last_seen_at` 을 터치하고, **`spy=true` 면 무터치**(기존 `actor="operator"`/`touch_watchdog=false` ad-hoc 플래그의 일반화·대체). 응답 노출은 top-level `watchdog[]` 배열이 아니라 슬롯 행의 `watchdog:{expired,last_seen}`(REQ-074). 만료 판정·grace period·in-memory store 는 불변.
|
||||
|
||||
#### Intent
|
||||
|
||||
- read 표면 교체 후에도 전략 폴링=생존 신호 / 비침습 조회 구분(R-4)을 보존.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Updated:
|
||||
- 워치독 갱신 트리거: `trex.snapshot.req` 처리 시 → `trex.slots.req` 기본 조회 시(holding 슬롯 last_seen 갱신).
|
||||
- 비침습 조회: `actor="operator"`/`touch_watchdog=false` → `spy=true`(무터치).
|
||||
- 노출: 응답 `watchdog[]` 배열 → 슬롯 행 `watchdog:{expired,last_seen}`.
|
||||
- Added/Removed: none
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: messaging_handlers.py(터치 분기), portfolio.py(slot_to_dict watchdog 흡수)
|
||||
- Docs: docs/interface-contract.md(REQ-075)
|
||||
- Tests: spy 무터치/기본 터치, 행 watchdog 필드
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: 신규 batch(REQ-073/074/075 와 동일 배치, dcy-025)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (신규 batch 에서 갱신 AC 검증)
|
||||
- Existing Implementation Invalidated: yes (snapshot 표면 기반 터치·watchdog[] 노출 evidence 가 표면 교체로 무효화)
|
||||
- Status Recommendation: Implemented → Approved (batch 재구현·재검증 후 복귀)
|
||||
- Follow-up Action: draft-batch → 구현/검증 → confirm-req-implemented
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- 신규 BAT: 기본 조회 터치/spy 무터치 단위(REQ-073 AC-4 와 공유), 행 watchdog 필드(REQ-074 AC-1), 만료·grace 회귀.
|
||||
@@ -1,151 +0,0 @@
|
||||
# req-036: 자동 매도 내부 경로 — SlotService.sell + idempotency
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
|
||||
자율 안전 매도 트리거가 RabbitMQ intent RPC를 거치지 않고 직접 슬롯 매도를 제출할 수 있도록 `SlotService.sell()` 내부 메서드를 추가한다. RabbitMQ 장애와 독립적으로 동작해야 하는 transport-independent 매도 경로다. 이미 `pending_sell` 상태인 슬롯에 대한 중복 트리거를 방지하는 idempotency도 함께 보장한다(dcy-007 FR-3, FR-4, A-1).
|
||||
|
||||
## Requirement
|
||||
|
||||
- `SlotService`는 `sell(slot_id, actor, reason)` 메서드를 제공해야 한다. 이 메서드는 `holding` 슬롯을 `pending_sell`로 전이시키고 기존 outbox 내구성·execution 루프 경로를 따른다.
|
||||
- `sell()`은 내부 함수 직접 호출이며 RabbitMQ intent RPC를 거치지 않는다.
|
||||
- 대상 슬롯이 이미 `pending_sell` 상태이면 `sell()`은 추가 전이 없이 조용히 반환하거나 멱등 응답을 반환해야 한다(중복 트리거 방지).
|
||||
- 대상 슬롯이 `holding` 이 아니고 `pending_sell`도 아닌 상태이면 적절한 예외 또는 오류 응답을 반환한다.
|
||||
- `sell()`을 통해 제출된 매도는 기존 `execution` worker의 `transit_slot(holding→pending_sell)` + broker dispatch + ledger 기록 경로를 재사용해야 한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Given `holding` 상태의 슬롯 S가 있을 때, When `SlotService.sell(S, actor="safety-sell", reason="stop_loss")` 를 호출하면, Then S의 상태가 `pending_sell`로 전이된다.
|
||||
2. Given `pending_sell` 상태의 슬롯 S가 있을 때, When `sell(S, ...)` 를 다시 호출하면, Then 슬롯 상태가 변경되지 않고 중복 매도 intent가 제출되지 않는다.
|
||||
3. Given `idle` 상태의 슬롯 S가 있을 때, When `sell(S, ...)` 를 호출하면, Then 오류(예외 또는 rejected 응답)가 반환되고 슬롯 상태는 변경되지 않는다.
|
||||
4. Given `sell()` 호출 성공 시, When execution worker가 이후 처리하면, Then 매도 주문이 broker에 제출되고 outbox 및 ledger 경로가 기존 intent RPC 경로와 동일하게 작동한다.
|
||||
5. Given RabbitMQ transport가 불가용 상태일 때, When `sell()` 을 호출하면, Then transport 상태와 무관하게 `holding→pending_sell` 전이가 성공한다.
|
||||
|
||||
## Impacted Area
|
||||
|
||||
- Docs: 없음 (런타임 흐름 변경은 REQ-037~039에서 발생, baseline 문서 갱신은 REQ-042 참조)
|
||||
- Modules:
|
||||
- `trex_core/domain/slot/service.py` — `SlotService.sell(slot_id, actor, reason)` 메서드 추가
|
||||
- Tests:
|
||||
- `SlotService.sell()` 단위 테스트 — `holding→pending_sell` 전이 확인
|
||||
- idempotency 테스트 — `pending_sell` 슬롯 중복 호출 시 무전이 확인
|
||||
- 잘못된 상태(`idle`) 슬롯 호출 시 오류 반환 확인
|
||||
|
||||
## Notes
|
||||
|
||||
- `sell()`은 `transit_slot(slot_id, from_state=HOLDING, to_state=PENDING_SELL, ...)` 패턴 위에 구현한다. 기존 advisory lock + Postgres commit 보장이 그대로 적용된다.
|
||||
- NFR-2(자동 매도 실패 시 outbox retry): broker 오류 발생 시 execution worker의 기존 retry 경로를 따른다. 별도 retry 로직 불필요.
|
||||
- `actor` 값은 트리거 구분을 위해 `"safety-sell"`, `"forced-close"`, `"market-close"` 등으로 구체화하는 것을 권장한다. 정확한 값은 batch 설계에서 결정한다.
|
||||
- 이 메서드는 dcy-007 FR-3의 "내부 자동 매도 trigger 경로"를 표준화한다. 이후 kill-switch Discovery(trex-core#3)에서도 재사용 가능하도록 격리한다.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260607-01
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- dcy-007 confirmed → REQ-036 초안 생성
|
||||
|
||||
#### Intent
|
||||
|
||||
- 자동 매도 내부 경로(FR-3, FR-4)를 독립 Interface REQ로 정규화
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added: AC-1~5 전체
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: service.py (`sell()` 메서드 추가)
|
||||
- Tests: 단위 테스트 3종
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: none (미할당)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs 후 batch 배정
|
||||
|
||||
### CHG-20260607-02
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- Proposed → Approved (confirm-req)
|
||||
|
||||
#### Intent
|
||||
|
||||
- 승인 게이트 통과: 필수 필드·AC·Impacted Area·Change Log 완비 확인. dcy-007(confirmed) 범위 및 결정 사항과 모순 없음.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: none (미할당)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs 후 batch 배정
|
||||
|
||||
### CHG-20260608-01
|
||||
|
||||
- Date: 2026-06-08
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-012) `SlotService.sell` 에 optional `limit_price` 파라미터(default None) 추가. 자율 매도(safety-sell/kill-switch)는 가격 미전달 → 시장가로 즉시 체결(미체결 pending_sell 갇힘 방지), 재량 경로만 지정가 전달 가능. BAT-016 재구현·재검증 완료 → Implemented 유지.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 자동 매도 내부 경로가 매수 지정가에 걸리지 않고 시장가로 체결되도록(issue #10/#9 연계), 가격 파라미터를 optional 로 추가하되 기본값 None 으로 자율 경로 체결성을 보장.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Updated:
|
||||
- `SlotService.sell(..., limit_price=None)` — 미전달 시 시장가(슬롯 limit_price None), 전달 시 지정가.
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: `trex_core/domain/slot/service.py`(`sell`)
|
||||
- Tests: tests/application/test_sell_pricing.py::test_safety_sell_dispatches_at_market
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-016
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (BAT-016 에서 완료)
|
||||
- Existing Implementation Invalidated: no (시그니처 확장, 기존 호출 default None 동일 동작)
|
||||
- Status Recommendation: Implemented (change-req → BAT-016 재검증)
|
||||
- Follow-up Action: confirm-req-implemented(BAT-016).
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- BAT-016: svc.sell 가격 미전달 → 시장가 + closed 전이 단위.
|
||||
@@ -1,151 +0,0 @@
|
||||
# req-040: update_thresholds intent RPC 액션
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
|
||||
전략 모듈이 매수 이후에도 손절·익절 임계값과 강제 만기 시각을 갱신할 수 있도록 `trex.intent.req` 채널에 `action: "update_thresholds"` 메시지 액션을 추가한다. 수신 시 해당 슬롯의 `stop_loss_price`·`take_profit_price`·`forced_close_at`를 DB에 갱신하고, 해당 슬롯의 워치독 `last_seen_at`을 현재 시각으로 리셋해 전략 모듈 활성 신호로 활용한다(dcy-007 FR-7).
|
||||
|
||||
## Requirement
|
||||
|
||||
- 시스템은 `trex.intent.req` 채널의 `action: "update_thresholds"` 메시지를 처리해야 한다.
|
||||
- 메시지 payload는 `{action: "update_thresholds", slot_id, stop_loss_price?, take_profit_price?, forced_close_at?}` 형식이며, 세 필드는 각각 독립적으로 포함하거나 생략할 수 있다. 생략된 필드는 현재 값을 유지한다.
|
||||
- 처리 성공 시 요청한 필드를 DB에 갱신하고 해당 슬롯의 워치독 `last_seen_at`을 현재 시각으로 리셋해야 한다.
|
||||
- 대상 슬롯이 `holding` 상태인 경우에만 갱신을 수행한다.
|
||||
- 대상 슬롯이 `holding`이 아닌 경우의 처리(무시 또는 에러 응답)는 구현 시 결정한다(OQ-6 Deferred — 선택 옵션: `{status: ignored, reason: "not_holding"}` 응답 또는 silent discard).
|
||||
- `reply_to`가 있으면 갱신 결과(`{status: updated|ignored, slot_id}`)를 응답으로 반환한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Given `holding` 상태의 슬롯 S가 있을 때, When `{action: "update_thresholds", slot_id: S, stop_loss_price: 50000}`을 `trex.intent.req`에 발행하면, Then S의 `stop_loss_price`가 `50000`으로 DB에 갱신된다.
|
||||
2. Given `holding` 상태의 슬롯 S가 있을 때, When `{action: "update_thresholds", slot_id: S, take_profit_price: 80000, forced_close_at: "2026-06-07T15:10:00+09:00"}`를 발행하면, Then S의 `take_profit_price`와 `forced_close_at`가 DB에 갱신된다.
|
||||
3. Given `holding` 상태의 슬롯 S가 있을 때, When `update_thresholds`를 수신하면, Then S의 워치독 `last_seen_at`이 현재 시각으로 리셋된다.
|
||||
4. Given `update_thresholds` 메시지에 `stop_loss_price`만 포함되고 `take_profit_price`와 `forced_close_at`는 생략될 때, When 처리되면, Then `stop_loss_price`만 갱신되고 나머지 두 필드는 기존 값을 유지한다.
|
||||
5. Given `null` 값으로 `stop_loss_price: null`을 명시할 때, When 처리되면, Then `stop_loss_price`가 `NULL`로 갱신된다(임계값 해제).
|
||||
6. Given 대상 슬롯이 `holding`이 아닌 상태일 때, When `update_thresholds`를 수신하면, Then 슬롯 필드가 변경되지 않는다. `reply_to`가 있으면 `{status: ignored, reason: "not_holding"}` 응답을 반환한다(OQ-6 구현 결정).
|
||||
7. Given `reply_to`가 있는 요청에서 갱신이 성공하면, When 처리가 완료되면, Then `{status: updated, slot_id}`가 `reply_to`로 반환된다.
|
||||
|
||||
## Impacted Area
|
||||
|
||||
- Docs:
|
||||
- `docs/interface-contract.md` — `update_thresholds` action 계약 추가 (REQ-042 참조)
|
||||
- Modules:
|
||||
- `trex_core/application/messaging_handlers.py` — `make_intent_rpc_handler` 확장: `update_thresholds` action 라우팅 + DB 갱신 + `last_seen_at` 리셋
|
||||
- `trex_core/domain/slot/service.py` — `SlotService.update_thresholds(slot_id, stop_loss_price, take_profit_price, forced_close_at)` 메서드 추가
|
||||
- Tests:
|
||||
- `update_thresholds` handler 단위 테스트 — holding 슬롯 갱신 확인, last_seen_at 리셋 확인
|
||||
- 필드 부분 갱신 테스트 (일부만 포함된 payload)
|
||||
- null 값 처리 테스트
|
||||
- non-holding 슬롯 무시 테스트
|
||||
|
||||
## Notes
|
||||
|
||||
- OQ-6(Deferred → REQ AC): `holding`이 아닌 슬롯 요청 처리 방식. 구현 시 `{status: ignored, reason: "not_holding"}` 응답 반환을 권장한다. silent discard도 허용되며 batch에서 결정한다.
|
||||
- `update_thresholds` 수신은 워치독 `last_seen_at` 리셋을 겸한다. 전략 모듈이 임계값을 갱신하면 활성 신호로 처리돼 그 시점부터 `TREX_WATCHDOG_TIMEOUT` 타이머가 재시작된다(REQ-034).
|
||||
- 기존 intent RPC dedup(`intent_log.try_insert`) 적용 여부는 batch 설계에서 결정한다. `update_thresholds`는 상태 read-modify가 아닌 idempotent SET이므로 dedup 생략이 적절할 수 있다.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260607-01
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- dcy-007 confirmed → REQ-040 초안 생성
|
||||
|
||||
#### Intent
|
||||
|
||||
- update_thresholds intent RPC 액션(FR-7)을 독립 Interface REQ로 정규화. OQ-6 Deferred 처리 방식을 AC-6에 명시.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added: AC-1~7 전체
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs: interface-contract.md (REQ-042에서 처리)
|
||||
- Modules: messaging_handlers.py (handler 확장), service.py (`update_thresholds()` 추가)
|
||||
- Tests: handler 단위 테스트 4종
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: none (미할당)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs 후 batch 배정
|
||||
|
||||
### CHG-20260607-02
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- Proposed → Approved (confirm-req)
|
||||
|
||||
#### Intent
|
||||
|
||||
- 승인 게이트 통과: 필수 필드·AC·Impacted Area·Change Log 완비 확인. dcy-007(confirmed) 범위 및 결정 사항과 모순 없음.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: none (미할당)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs 후 batch 배정
|
||||
|
||||
### CHG-20260607-03
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- Status Approved → Implemented (confirm-req-implemented, 근거 batch BAT-011 release-candidate).
|
||||
|
||||
#### Intent
|
||||
|
||||
- BAT-011 verification.md 의 AC↔evidence(`update_thresholds` 부분 갱신·null 해제·last_seen_at 리셋·non-holding ignored·미존재 slot_not_found·updated 응답)로 AC-1~7 충족 → 구현 완료 동기화. OQ-6 은 AC-6 의 `{ignored, not_holding}` 응답으로 확정 구현.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-011 (release-candidate)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current (Implemented)
|
||||
- Follow-up Action: draft-release 로 BAT-011 배포 편성.
|
||||
@@ -1,148 +0,0 @@
|
||||
# req-043: trex.control.req 제어 채널 + action dispatch
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
|
||||
기존 `trex.pause.req` 단일 목적 큐를 `trex.control.req` 제어 채널로 개념 확장하고, payload `action` 필드 기반 dispatch로 운영자 제어 명령을 단일 채널에서 처리한다. 기능마다 큐/consumer 스레드를 늘리지 않기 위한 단일 제어 채널 + action discriminator 패턴(dcy-008 OQ-1 Answered). 기존 pause/resume/list 동작을 보존하면서 kill-switch(REQ-045)와 resume_kill_switch(REQ-046) 라우팅 진입점을 추가한다.
|
||||
|
||||
## Requirement
|
||||
|
||||
- 데몬은 단일 제어 큐 `trex.control.req` 를 소비하고 메시지 payload 의 `action` 필드로 핸들러를 분기한다.
|
||||
- 기존 제어 action(`pause`/`resume`/`list`, REQ-032)의 동작·응답 계약을 그대로 유지한다.
|
||||
- 신규 action 라우팅을 추가한다: `kill_switch`(REQ-045), `resume_kill_switch`(REQ-046). 본 REQ는 라우팅·메시지 계약 골격만 정의하고 실제 청산/해제 동작은 각 REQ에서 정의한다.
|
||||
- 알 수 없는 `action` 은 `{status: "error", reason: "unknown_action:<action>"}` 으로 응답한다.
|
||||
- 기존 `trex.pause.req` consumer 스레드를 control consumer(`trex.control.req`)로 교체한다. 데몬 워커 스레드 총수는 불변(7개 유지).
|
||||
- 하위호환: `trex.pause.req` 를 사용하던 기존 클라이언트 호환 방식(별칭 큐 유지 vs `trex.control.req` 단일화)은 배포 영향이 있으므로 Notes 에 결정 필요로 남긴다.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Given `trex.control.req` 에 `{action: "pause", portfolio_id}` 발행, When 처리되면, Then 기존 REQ-032 pause 동작과 동일하게 `snapshot_pause` 에 반영되고 `{status: "ok", paused[], action}` 응답을 반환한다.
|
||||
2. Given `{action: "resume", portfolio_id}` / `{action: "list"}`, When 처리되면, Then 각각 기존 resume/list 동작과 동일한 응답을 반환한다.
|
||||
3. Given `{action: "kill_switch", ...}`, When 처리되면, Then kill-switch 핸들러(REQ-045)로 라우팅된다.
|
||||
4. Given `{action: "resume_kill_switch", ...}`, When 처리되면, Then resume 핸들러(REQ-046)로 라우팅된다.
|
||||
5. Given `{action: "bogus"}`, When 처리되면, Then `{status: "error", reason: "unknown_action:bogus"}` 를 반환한다.
|
||||
6. Given 데몬 기동, When 워커 스레드를 확인하면, Then pause consumer 가 control consumer 로 교체되어 총 워커 스레드 수가 7로 불변이다.
|
||||
|
||||
## Impacted Area
|
||||
|
||||
- Docs:
|
||||
- `docs/interface-contract.md` — 제어 채널 계약(`trex.control.req` + action 목록) (REQ-047 처리)
|
||||
- Modules:
|
||||
- `trex_core/adapters/messaging/topology.py` — `CONTROL_REQ_QUEUE = "trex.control.req"` 추가(또는 `PAUSE_REQ_QUEUE` 대체)
|
||||
- `trex_core/application/messaging_handlers.py` — `make_control_rpc_handler`(action dispatch) 신설 또는 `make_pause_rpc_handler` 확장
|
||||
- `trex_core/runtime/daemon.py` — pause consumer → control consumer 교체
|
||||
- Tests:
|
||||
- control dispatch 단위 테스트(pause/resume/list 회귀 + kill_switch/resume_kill_switch 라우팅 + unknown action)
|
||||
|
||||
## Notes
|
||||
|
||||
- dcy-008 OQ-1 Answered: 단일 제어 채널 + action discriminator. 새 큐 추가 없음.
|
||||
- 하위호환 결정 필요(배포): 기존 `trex.pause.req` 토픽 이름을 유지(별칭)할지, `trex.control.req` 로 단일화하고 전략/운영 클라이언트를 함께 갱신할지 — batch planning/release 단계에서 확정. 현재 CLI pause/resume 는 store 직접 호출이라 영향 없음(RPC 경로만 대상).
|
||||
- kill_switch/resume_kill_switch 의 payload 상세(scope/portfolio_id)는 REQ-045/046 에서 정의.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260607-01
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- dcy-008(confirmed) → REQ-043 초안 생성.
|
||||
|
||||
#### Intent
|
||||
|
||||
- kill-switch 트리거 표면(OQ-1 Answered)을 단일 제어 채널 Interface REQ 로 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added: AC-1~6 전체
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs: interface-contract.md (REQ-047)
|
||||
- Modules: topology.py, messaging_handlers.py, daemon.py
|
||||
- Tests: control dispatch 단위
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: none (미할당)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 로 승인.
|
||||
|
||||
### CHG-20260607-02
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- Proposed → Approved (confirm-req).
|
||||
|
||||
#### Intent
|
||||
|
||||
- 승인 게이트 통과: 필수 필드·구체 AC·Impacted Area·Change Log 완비. dcy-008(confirmed) 범위·결정(OQ-1/2/4 Answered, OQ-3 Deferred)과 모순 없음. 하위호환(큐 rename)은 batch/release 단계 비핵심 운영 결정으로 승인 blocker 아님.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: none (미할당)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs / draft-batch 로 delivery 편성.
|
||||
|
||||
### CHG-20260607-03
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- Status Approved → Implemented (confirm-req-implemented, 근거 batch BAT-012 release-candidate).
|
||||
|
||||
#### Intent
|
||||
|
||||
- BAT-012 verification 의 AC↔evidence(control dispatch 9 단위: pause/resume/list 회귀 + kill_switch/resume_kill_switch 라우팅 + unknown action + 워커 스레드 불변 + e2e control RPC)로 AC-1~6 충족.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-012 (release-candidate)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current (Implemented)
|
||||
- Follow-up Action: draft-release 로 BAT-012 배포 편성. 제어 큐 하위호환은 release rollout 결정.
|
||||
@@ -1,155 +0,0 @@
|
||||
# req-045: kill-switch 실행 — 범위별 holding 즉시 청산 + 이력 로깅
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
|
||||
운영자가 `trex.control.req` 에 `action: "kill_switch"` 를 발행하면 대상 범위(portfolio 단위 또는 전역)의 모든 `holding` 슬롯을 즉시 청산한다. 기존 `SlotService.sell()`(REQ-036)을 재사용해 순차 매도를 제출하고, 같은 발동에서 대상 범위를 당일 제외(REQ-044/046)로 표시한다. 자율 안전 매도(dcy-007)와 독립적으로 동작하며, 발동 이력을 로깅한다(dcy-008 FR-1/4/5/6, NFR-1/2).
|
||||
|
||||
## Requirement
|
||||
|
||||
- `action: "kill_switch"` payload: `{action, scope: "portfolio"|"global", portfolio_id?(scope=portfolio 시 필수), actor?}`.
|
||||
- 발동 시 대상 범위의 모든 `holding` 슬롯에 `SlotService.sell(actor="kill-switch", reason="emergency_stop")` 을 순차 호출한다.
|
||||
- scope=portfolio: 해당 `portfolio_id` 의 holding 슬롯만.
|
||||
- scope=global: 당일 전체 holding 슬롯.
|
||||
- 이미 `pending_sell` 인 슬롯은 중복 sell 하지 않는다(REQ-036 idempotency).
|
||||
- 발동과 동시에 대상 범위를 당일 제외로 표시한다(REQ-044 store 의 `exclude(...)` 호출). masking 동작 자체는 REQ-046.
|
||||
- 발동 이력(actor, 발동 시각, scope, portfolio_id, 처리 슬롯 수)을 데몬 로그에 1건 기록한다.
|
||||
- 응답: `{status: "ok", scope, portfolio_id?, liquidated: <처리 슬롯 수>}`. scope=portfolio 인데 `portfolio_id` 누락 시 `{status: "error", reason: "portfolio_id_required"}`.
|
||||
- kill-switch 실행은 자율 안전 매도 루프(dcy-007)와 상태/스레드를 공유하지 않으며 서로 영향을 주지 않는다.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Given holding 슬롯 N개(전역), When `{action:"kill_switch", scope:"global"}` 처리, Then N개 모두 `holding→pending_sell`(actor=kill-switch, reason=emergency_stop) 전이되고 응답 `liquidated=N`.
|
||||
2. Given portfolio `pf-A` 에 holding 2개 + `pf-B` 에 holding 1개, When `{action:"kill_switch", scope:"portfolio", portfolio_id:"pf-A"}`, Then `pf-A` 2개만 청산되고 `pf-B` 는 holding 유지.
|
||||
3. Given 대상 중 이미 `pending_sell` 인 슬롯, When kill_switch 처리, Then 그 슬롯에 중복 sell 호출이 없다(REQ-036 idempotency, transition_log 중복 없음).
|
||||
4. Given scope=portfolio 인데 `portfolio_id` 누락, When 처리, Then `{status:"error", reason:"portfolio_id_required"}`.
|
||||
5. Given kill_switch 발동, When 처리 완료, Then 대상 범위가 REQ-044 store 에 당일 제외로 기록된다(`list_excluded(today)` 에 포함).
|
||||
6. Given kill_switch 발동, When 로그를 확인, Then actor/발동 시각/scope/portfolio_id/처리 슬롯 수를 담은 이력 1건이 기록된다.
|
||||
7. Given 자율 안전 매도 루프(dcy-007)가 동작 중, When kill_switch 가 발동, Then 두 경로가 독립적으로 동작하며(REQ-036 idempotency 로 충돌 없음) safety-sell 루프가 중단/오류 없이 유지된다.
|
||||
8. Given holding N개, When kill_switch 처리, Then 전체 sell() 제출 완료까지 지연이 N×100ms + 5s 이내이다(순차, outbox 전송 제외; A-4 N<10 가정).
|
||||
|
||||
## Impacted Area
|
||||
|
||||
- Docs:
|
||||
- `docs/runtime-flows.md` — kill-switch 발동 흐름(트리거→순차 sell()→당일 제외 표시) (REQ-047 처리)
|
||||
- `docs/interface-contract.md` — kill_switch payload/응답 계약 (REQ-047 처리)
|
||||
- Modules:
|
||||
- `trex_core/application/messaging_handlers.py` — kill_switch handler(REQ-043 dispatch 하위)
|
||||
- `trex_core/domain/slot/service.py` 또는 신규 application 서비스 — 범위별 holding 조회 + 순차 sell() 진입점
|
||||
- REQ-044 store 연동(당일 제외 표시)
|
||||
- Tests:
|
||||
- kill_switch handler 단위 테스트(전역/portfolio/idempotency/portfolio_id 누락/이력 로깅/독립성)
|
||||
|
||||
## Notes
|
||||
|
||||
- NFR-1(지연)·NFR-2(dcy-007 독립)는 본 REQ AC-8/AC-7 로 흡수(별도 REQ 미승격 — 독립 backlog 가치 낮음, dcy-008 정합).
|
||||
- pending_buy 슬롯 처리는 dcy-008 OQ-3 Deferred → 기본 구현은 HOLDING 만 대상. pending_buy 롤백은 후속(REQ 추가 또는 change-req).
|
||||
- R-1(큐 부하): sell()은 PENDING_SELL 전이(DB write 1회)로 빠름. execution worker 순차 처리 유지.
|
||||
- R-3(브로커 오류): sell()→PENDING_SELL 성공 시 기존 outbox retry 가 eventual consistency 보장.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260607-01
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- dcy-008(confirmed) → REQ-045 초안 생성.
|
||||
|
||||
#### Intent
|
||||
|
||||
- kill-switch 즉시 청산(FR-1/4/5/6)과 NFR-1/2 흡수를 Interface REQ 로 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added: AC-1~8 전체
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs: runtime-flows.md, interface-contract.md (REQ-047)
|
||||
- Modules: messaging_handlers.py, service.py(또는 신규 서비스), REQ-044 store 연동
|
||||
- Tests: kill_switch handler 단위
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: none (미할당)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 로 승인.
|
||||
|
||||
### CHG-20260607-02
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- Proposed → Approved (confirm-req).
|
||||
|
||||
#### Intent
|
||||
|
||||
- 승인 게이트 통과: 필수 필드·구체 AC(1~8)·Impacted Area·Change Log 완비. dcy-008(confirmed) 범위와 모순 없음. NFR-1/2 흡수, OQ-3(pending_buy) REQ Deferred 는 비핵심 후속으로 승인 blocker 아님(기본 구현 HOLDING 한정).
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: none (미할당)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs / draft-batch 로 delivery 편성.
|
||||
|
||||
### CHG-20260607-03
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- Status Approved → Implemented (confirm-req-implemented, 근거 batch BAT-012 release-candidate).
|
||||
|
||||
#### Intent
|
||||
|
||||
- BAT-012 verification 의 AC↔evidence(실행 6 단위: 전역/portfolio 범위/idempotency/당일 제외 표시/resume 비가역/no-holding + e2e kill_switch global liquidated=2 → closed, emergency_stop reason)로 AC-1~8 충족. NFR-1/2 흡수 확인.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-012 (release-candidate)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current (Implemented)
|
||||
- Follow-up Action: draft-release 로 BAT-012 배포 편성. 실 KIS 라이브 발동은 운영 실증 이월.
|
||||
@@ -1,154 +0,0 @@
|
||||
# req-046: kill-switch 당일 제외 masking + 자동 해제 + 수동 resume
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
|
||||
kill-switch 발동(REQ-045)으로 표시된 당일 제외 상태를 snapshot RPC 응답에 반영해 대상 자산을 당일 전략 실행에서 제외한다(추가 매수 차단). 제외는 day-scoped 라 다음 거래일 자동 복귀하며(REQ-044 `trading_date` 키), 운영자는 같은 거래일 내 `action: "resume_kill_switch"` 로 수동 해제할 수 있다(dcy-008 FR-2/3, NFR-3, OQ-4 Answered).
|
||||
|
||||
## Requirement
|
||||
|
||||
- snapshot RPC 응답 산출 시 masking 소스에 "kill-switch 당일 제외"(REQ-044 `list_excluded(today)`)를 추가한다: `mask = pending | warning | pause | killswitch_today`.
|
||||
- scope=portfolio 제외는 해당 `portfolio_id` 자산만, 전역 제외는 당일 전체 자산을 마스킹한다.
|
||||
- 마스킹된 자산은 buyable/held 뷰에 노출되지 않아 당일 추가 매수 의도가 거부된다.
|
||||
- 당일 제외는 `trading_date` 기준 day-scoped 다. 다음 거래일 첫 조회/부팅 시 `list_excluded(다음 날)` 에 포함되지 않아 자동 복귀한다(별도 해제 동작 불필요).
|
||||
- 영속성: 데몬 재시작 후에도 같은 거래일이면 masking 이 유지된다(REQ-044 영속, NFR-3).
|
||||
- 수동 해제: `action: "resume_kill_switch"` payload `{action, scope, portfolio_id?, actor?}` 처리 시 대상 범위의 당일 제외를 해제(REQ-044 `clear(...)`)해 다음 조회부터 정상 매매 대상으로 복귀시킨다.
|
||||
- resume 은 **당일 제외(매매 차단)만 해제**하며 이미 청산(매도)된 슬롯을 되돌리지 않는다(매도 비가역).
|
||||
- 응답: `{status: "ok", scope, portfolio_id?}`. scope=portfolio 인데 `portfolio_id` 누락 시 `{status:"error", reason:"portfolio_id_required"}`.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Given `pf-A` 가 당일 제외(REQ-044)로 표시됨, When snapshot RPC(view=buyable/all) 처리, Then `pf-A` 자산이 응답 assets 에서 마스킹되어 노출되지 않는다.
|
||||
2. Given 전역 당일 제외 표시, When snapshot RPC 처리, Then 당일 전체 자산이 마스킹된다.
|
||||
3. Given 당일 제외 표시 후, When 당일 추가 매수 intent 가 해당 자산에 들어오면, Then buyable 마스킹으로 거부/비노출된다.
|
||||
4. Given `pf-A` 당일(D) 제외, When 거래일 D+1 로 snapshot RPC 처리, Then `pf-A` 가 다시 노출된다(자동 복귀, 별도 resume 불필요).
|
||||
5. Given `pf-A` 제외 후 데몬 재시작(같은 거래일 D), When snapshot RPC 처리, Then 여전히 마스킹된다(영속, NFR-3).
|
||||
6. Given `pf-A` 당일 제외 상태, When `{action:"resume_kill_switch", scope:"portfolio", portfolio_id:"pf-A"}` 처리, Then 다음 snapshot RPC 부터 `pf-A` 가 정상 노출되고 응답 `{status:"ok"}`.
|
||||
7. Given resume_kill_switch scope=portfolio 인데 `portfolio_id` 누락, When 처리, Then `{status:"error", reason:"portfolio_id_required"}`.
|
||||
8. Given resume_kill_switch 처리, When 이미 청산된 슬롯을 확인, Then 슬롯 상태(pending_sell/closed)는 되돌려지지 않는다(매도 비가역).
|
||||
|
||||
## Impacted Area
|
||||
|
||||
- Docs:
|
||||
- `docs/interface-contract.md` — masking 소스에 kill-switch 당일 제외 + resume_kill_switch 계약 (REQ-047 처리)
|
||||
- `docs/runtime-flows.md` — 당일 제외 masking / 자동 복귀 / 수동 resume 흐름 (REQ-047 처리)
|
||||
- Modules:
|
||||
- `trex_core/application/portfolio.py`(또는 snapshot envelope builder) — masking 소스에 `list_excluded(today)` 추가
|
||||
- `trex_core/application/messaging_handlers.py` — `resume_kill_switch` handler(REQ-043 dispatch 하위) + snapshot 핸들러에 killswitch store 주입
|
||||
- REQ-044 store 연동(`list_excluded`/`clear`)
|
||||
- Tests:
|
||||
- masking 단위 테스트(portfolio/전역/추가매수 거부) + day-scoped 자동 복귀(날짜 mock) + 재시작 영속 + resume 단위
|
||||
|
||||
## Notes
|
||||
|
||||
- dcy-008 OQ-4 Answered: 수동 해제 지원(`resume_kill_switch`). 자동 복귀(day-scoped)와 병행.
|
||||
- NFR-3(영속 후 재시작 masking 유지)는 본 REQ AC-5 로 흡수.
|
||||
- 전역 제외 sentinel 해석은 REQ-044 store 계약을 따른다.
|
||||
- masking 합성은 기존 pause masking 패턴(`portfolio.py`)을 재사용(A-2).
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260607-01
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- dcy-008(confirmed) → REQ-046 초안 생성.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 당일 제외 masking/자동 복귀/수동 resume(FR-2/3, OQ-4, NFR-3 흡수)을 Interface REQ 로 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added: AC-1~8 전체
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs: interface-contract.md, runtime-flows.md (REQ-047)
|
||||
- Modules: portfolio.py, messaging_handlers.py, REQ-044 store 연동
|
||||
- Tests: masking + day-scoped + 영속 + resume 단위
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: none (미할당)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 로 승인.
|
||||
|
||||
### CHG-20260607-02
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- Proposed → Approved (confirm-req).
|
||||
|
||||
#### Intent
|
||||
|
||||
- 승인 게이트 통과: 필수 필드·구체 AC(1~8)·Impacted Area·Change Log 완비. dcy-008(confirmed) OQ-4 결정(resume_kill_switch) 반영, NFR-3 흡수. 범위·결정과 모순 없음.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: none (미할당)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs / draft-batch 로 delivery 편성.
|
||||
|
||||
### CHG-20260607-03
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- Status Approved → Implemented (confirm-req-implemented, 근거 batch BAT-012 release-candidate).
|
||||
|
||||
#### Intent
|
||||
|
||||
- BAT-012 verification 의 AC↔evidence(masking·resume 7 단위: portfolio/전역 masking + buyable 차단 + day-scoped 자동복귀(날짜) + 영속 + resume 재포함 + 청산 비가역 + backward-compat; e2e resume_kill_switch → exclusion 0)로 AC-1~8 충족. NFR-3 흡수.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-012 (release-candidate)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current (Implemented)
|
||||
- Follow-up Action: draft-release 로 BAT-012 배포 편성.
|
||||
@@ -1,147 +0,0 @@
|
||||
# req-049: instance_key 기반 동적 큐명 + default 하위호환
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
|
||||
다중 인스턴스가 동일 RabbitMQ 에서 경쟁 소비(round-robin)로 split-brain 을 일으키지 않도록, 수신 큐명을 `instance_key` 기반으로 인스턴스별 분리한다. `topology.py` 의 고정 큐명 상수를 동적 함수로 교체하고, `declare_topology(instance_key)` + 각 consumer 가 인스턴스 전용 큐를 구독하게 한다. `instance_key="default"` 는 기존 리터럴 큐명을 그대로 사용해 하위호환을 보장한다(dcy-009 FR-2, FR-5, NFR-1/2/3).
|
||||
|
||||
## Requirement
|
||||
|
||||
- `topology.py` 의 고정 큐명 상수(`SNAPSHOT_REQ_QUEUE` 등)를 동적 빌더 함수로 교체/보강한다: `intent_queue(instance_key)`, `snapshot_queue(instance_key)`, `control_queue(instance_key)`.
|
||||
- **하위호환 규칙**: `instance_key in (None, "default")` 이면 기존 리터럴 큐명(`trex.intent.req` / `trex.snapshot.req` / `trex.control.req`)을 반환한다. 그 외에는 `{base}.{instance_key}` 를 반환한다(FR-5: default 무회귀).
|
||||
- `rabbitmq.py` `declare_topology(instance_key=...)` 가 인스턴스 전용 큐를 선언한다. `daemon.py` 의 intent/snapshot/control consumer 가 동일 `instance_key` 의 전용 큐를 `consume_rpc_forever` 로 구독한다.
|
||||
- `daemon.py` 는 설정(REQ-048 TOML)에서 읽은 `instance_key` 를 큐 선언/구독에 일관되게 전달한다.
|
||||
- 기존 pika `BlockingConnection` per-thread 패턴을 유지한다 — 큐 분리로 인해 추가 스레드/커넥션을 만들지 않는다(NFR-2). 워커 스레드 수 불변.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Given `instance_key="inst-1"`, When `intent_queue("inst-1")`/`snapshot_queue`/`control_queue`, Then 각각 `trex.intent.req.inst-1`/`trex.snapshot.req.inst-1`/`trex.control.req.inst-1` 를 반환한다.
|
||||
2. Given `instance_key="default"`(또는 None), When 동일 빌더, Then 기존 리터럴 `trex.intent.req`/`trex.snapshot.req`/`trex.control.req` 를 반환한다(하위호환).
|
||||
3. Given `declare_topology("inst-1")`, When 선언, Then `*.inst-1` 인스턴스 전용 큐가 선언된다(S-1 일부).
|
||||
4. Given `instance_key="default"` 데몬, When 전체 pytest 스위트 실행, Then 회귀 없음(FR-5/NFR-1, 기존 큐명 테스트 통과).
|
||||
5. Given 데몬 기동, When 워커 스레드 확인, Then per-thread connection 패턴 유지 + 스레드 수 불변(NFR-2).
|
||||
6. Given `instance_key="inst-1"` 와 `inst-2` 동시 운영(전용 큐 분리), When 각자 큐만 소비, Then 한 인스턴스의 snapshot/intent 소비가 다른 인스턴스 큐에 영향을 주지 않는다(NFR-3 split-brain 방지 기반).
|
||||
|
||||
## Impacted Area
|
||||
|
||||
- Docs:
|
||||
- `docs/runtime-flows.md`, `docs/project-structure.md` — 동적 큐명/토폴로지 (REQ-051 처리)
|
||||
- Modules:
|
||||
- `trex_core/adapters/messaging/topology.py` — 동적 큐명 빌더(default 하위호환)
|
||||
- `trex_core/adapters/messaging/rabbitmq.py` — `declare_topology(instance_key)`
|
||||
- `trex_core/runtime/daemon.py` — consumer 가 instance_key 전용 큐 구독
|
||||
- Tests:
|
||||
- `tests/adapters/messaging/` — 큐명 빌더(default vs named) + declare/consume 분리 + 기존 회귀
|
||||
|
||||
## Notes
|
||||
|
||||
- 하위호환 핵심: default = 리터럴 큐명(특수 처리)이라 기존 테스트/배포 무영향. FR-2 의 suffix 규칙은 named instance 에 적용.
|
||||
- NFR-3(split-brain 방지)는 인스턴스 전용 큐로 구조적으로 달성 — 다중 인스턴스 e2e 는 verification 에서 확인.
|
||||
- exchange/binding(트래픽 라우팅)은 REQ-050.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260607-01
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- dcy-009(confirmed) → REQ-049 초안 생성.
|
||||
|
||||
#### Intent
|
||||
|
||||
- instance_key 동적 큐명 + default 하위호환(FR-2/FR-5)을 Interface REQ 로 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added: AC-1~6 전체
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs: runtime-flows.md, project-structure.md (REQ-051)
|
||||
- Modules: topology.py, rabbitmq.py, daemon.py
|
||||
- Tests: tests/adapters/messaging
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: none (미할당)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 로 승인.
|
||||
|
||||
### CHG-20260607-02
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- Proposed → Approved (confirm-req).
|
||||
|
||||
#### Intent
|
||||
|
||||
- 승인 게이트 통과: 필수 필드·구체 AC·Impacted Area·Change Log 완비. dcy-009(confirmed) FR-2/FR-5 와 일치. default 하위호환 규칙 명확.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: none (미할당)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: suggest-batch-reqs / draft-batch 로 delivery 편성.
|
||||
|
||||
### CHG-20260607-03
|
||||
|
||||
- Date: 2026-06-07
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- Status Approved → Implemented (confirm-req-implemented, 근거 batch BAT-013 release-candidate).
|
||||
|
||||
#### Intent
|
||||
|
||||
- BAT-013 verification 의 AC↔evidence(빌더 단위 named suffix/default 리터럴 + declare_topology(instance_key) + 전체 301 passed 로 default 무회귀)로 AC-1~6 충족. NFR-1/2/3 흡수.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- (변경 없음)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-013 (release-candidate)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current (Implemented)
|
||||
- Follow-up Action: draft-release 로 BAT-013 배포 편성.
|
||||
@@ -1,135 +0,0 @@
|
||||
# req-057: 자산 영구 슬롯 상태머신 재정의 + 인스턴스 스코프 advisory lock
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- 영구 자산 슬롯에 맞춰 슬롯 상태머신을 재정의하고, holding 을 코어 로컬 정본으로 두며, 공유 DB 다중 인스턴스에서 단일 writer 불변식을 인스턴스 단위로 보존한다. (dcy-020 FR-6/FR-3/NFR-1)
|
||||
|
||||
## Requirement
|
||||
- 상태 집합을 `inactive → pending_buy → holding → pending_sell → inactive` (+ 모든 비-error → `error`, `error → {inactive, holding}` 운영자 resolve)로 재정의한다. 기존 `idle`·`closed` 는 영구 슬롯에서 단일 `inactive` 로 합치고 `closed→idle` 복구 전이를 제거한다. `holding`(포지션 열림)은 코어 슬롯의 로컬 정본으로 체결 시 동기 set, 매도 체결 시 동기 clear 한다(portfolio-hub `asset_quantity` 로 판단하지 않음). advisory lock 을 **인스턴스 스코프**(`pg_advisory_xact_lock(SLOT_LOCK_ID, hash(instance_key))`)로 두어 인스턴스 간 교차 직렬화를 제거한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given 상태머신, When 허용 전이 집합을 확인, Then `{inactive→pending_buy, pending_buy→holding, pending_buy→inactive, holding→pending_buy, holding→pending_sell, pending_sell→inactive, pending_sell→holding, *→error, error→inactive, error→holding}` 와 정확히 일치한다(dcy-021 CHG-20260610-03: `holding→pending_buy` 증액 전이 추가).
|
||||
2. Given 영구 슬롯, When 매도 체결로 종료, Then 슬롯은 `inactive` 로 돌아가고(별도 `closed`·`closed→idle` 없음) holding 로컬 플래그가 clear 된다.
|
||||
3. Given 서로 다른 instance_key 의 두 슬롯, When 동시에 전이, Then 인스턴스별 락으로 서로를 차단하지 않는다(교차 경합 없음).
|
||||
4. Given 같은 슬롯에 대한 동시 전이, When 병렬 처리, Then 인스턴스 스코프 락으로 직렬화되어 단일 writer 불변식이 유지된다.
|
||||
5. Given 보유(holding) 슬롯 증액, When `holding→pending_buy` 전이, Then 허용되고 체결 시 `pending_buy→holding` 으로 복귀한다(dcy-021 REQ-066). 부분 매도 잔량은 기존 `pending_sell→holding` 전이로 holding 을 유지한다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/runtime-flows.md(전이 흐름), docs/data-model.md(상태)
|
||||
- Modules: trex_core/domain/slot/state.py, trex_core/domain/slot/service.py, trex_core/domain/slot/models.py
|
||||
- Tests: tests/domain/slot/test_state.py, tests/domain/slot/test_service.py
|
||||
|
||||
## Notes
|
||||
- 기존 REQ-002(상태머신·서비스) 재정의 change-req 동반. dcy-001 의 6상태/closed→idle 모델 폐기.
|
||||
- holding 로컬 정본 근거(offline 안전·universe 누락 생존·hub 지연·capacity 원자성)는 dcy-020 FR-3.
|
||||
- 출처: dcy-020 FR-6, FR-3, NFR-1, OQ-7.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260610-01
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-020 FR-6/FR-3/NFR-1 로부터 최초 생성(Proposed). 상태머신 재정의(idle/closed→inactive, closed→idle 제거) + holding 로컬 정본 + 인스턴스 스코프 advisory lock.
|
||||
|
||||
#### Intent
|
||||
- 영구 자산 슬롯 상태머신·holding 로컬·인스턴스 단위 단일 writer 를 backlog 로 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- 전이 집합/inactive 종료/인스턴스별 락 비교차/동일 슬롯 직렬화 4개 기준
|
||||
- Updated: 없음
|
||||
- Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/runtime-flows.md, docs/data-model.md
|
||||
- Modules: domain/slot/state.py, service.py, models.py
|
||||
- Tests: test_state.py, test_service.py
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no (신규 정의; REQ-002 재정의 change-req 로 기존 폐기)
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req. REQ-002 change-req 동반.
|
||||
|
||||
#### Validation Plan
|
||||
- 전이 허용/거부 집합 + 인스턴스 락 단위테스트 green.
|
||||
|
||||
### CHG-20260610-02
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status Proposed → Approved (confirm-req). 필수 필드·구체 AC 충족, source dcy-020(confirmed, handoff 승인)과 모순 없음.
|
||||
|
||||
#### Intent
|
||||
- delivery input 으로 승격.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 없음 / Updated: 없음 / Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/srs/index.md (Register Approved) / Modules: 없음 / Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none / Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no / Existing Implementation Invalidated: no / Status Recommendation: keep-current / Follow-up Action: suggest-batch-reqs / draft-batch.
|
||||
|
||||
#### Validation Plan
|
||||
- 승인 후 batch planning 에서 본 REQ AC 를 검증 기준으로 사용.
|
||||
|
||||
### CHG-20260610-IMPL
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-027(토대)+BAT-030(literal inactive·별칭 제거) — 모든 AC 가 release-candidate 배치 verification 의 evidence 와 연결됨(단위 367/PG 29/MQ 21 passed + run-the-app 자산 중심 e2e). Blocking Issues 없음.
|
||||
|
||||
### CHG-20260610-03
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-021(포지션 사이징, issue #1) 반영: 상태 전이 집합에 **`holding→pending_buy`(보유 슬롯 증액)** 를 추가하고, `pending_sell→holding`(기존)을 부분 매도 잔량 holding 유지 경로로 명시. 전량 매도만 `pending_sell→inactive`.
|
||||
|
||||
#### Intent
|
||||
- 보유 자산 슬롯이 holding 을 유지한 채 수량 증액(추가 매수)·부분 감액을 표현하도록 상태머신을 additive 확장(dcy-020 이 고정한 "종료=전량 청산" 경계 해제).
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: AC-5(holding→pending_buy 증액 전이 허용·체결 시 holding 복귀, 부분 매도 잔량 pending_sell→holding)
|
||||
- Updated: AC-1 허용 전이 집합에 holding→pending_buy 포함
|
||||
- Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/runtime-flows.md, docs/data-model.md (REQ-067 정합)
|
||||
- Modules: trex_core/domain/slot/state.py(전이 추가), service.py(증액 qty/avg_price = REQ-066)
|
||||
- Tests: tests/domain/slot/test_state.py(전이 집합·size), test_service.py
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: dcy-021 신규 배치(예정)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: yes (전이 집합 변경 — test_state 갱신·증액 경로 검증)
|
||||
- Existing Implementation Invalidated: no (기존 전이 보존, additive) — 단 AC-1 "정확히 일치"가 신규 전이를 포함하도록 확장되어 재검증 필요
|
||||
- Status Recommendation: revert-to-approved (신규 전이 미구현 — dcy-021 배치에서 구현·검증 후 confirm-req-implemented)
|
||||
- Follow-up Action: dcy-021 배치 구현 + test_state 전이 집합 갱신 후 Implemented 복귀.
|
||||
|
||||
#### Validation Plan
|
||||
- ALLOWED_TRANSITIONS 에 holding→pending_buy 포함·size 갱신 단위 테스트 + 증액 end-to-end(REQ-066).
|
||||
|
||||
### CHG-20260610-IMPL
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-031(release-candidate) verification — 단위 378 / 통합 422 passed + run-the-app 사이징 e2e(증액 가중평균·부분 매도 잔량·전량 매도) green. Blocking Issues 없음.
|
||||
@@ -1,94 +0,0 @@
|
||||
# req-059: 활성 capacity 제어 + 신호 기반 admission (FCFS·M캡·무치환·over-cap)
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- 익명 슬롯 배정 대신 "동시 활성(holding) 최대 M개" 정책으로 capacity 를 제어하고, 매수/매도 신호를 해당 자산 슬롯의 활성화/비활성화로 처리한다. (dcy-020 FR-2/FR-3/OQ-1/OQ-8)
|
||||
|
||||
## Requirement
|
||||
- 매수 신호는 해당 자산 슬롯을 활성화(`inactive→pending_buy`)한다. 활성(holding+pending_buy) 수 < M 이면 즉시 활성화, == M 이면 **거부(`capacity_full`)** 한다. 코어는 자리를 만들려고 기존 holding 을 **자율 청산(치환)하지 않는다**(FCFS·무치환). 동시 후보 tie-break 은 `updated_at` asc → `portfolio_id`(alpha 비사용). M 을 현재 보유 수보다 작게 바꿔 over-cap 이 되면 **신규 활성화만 차단**하고 기존 보유는 자연 종료까지 유지한다(강제 청산 없음). 마지막 슬롯 경합은 인스턴스 스코프 advisory lock + 재시도로 직렬화한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given 활성 수 < M, When 자산 매수 신호, Then 그 자산 슬롯이 `pending_buy` 로 활성화된다.
|
||||
2. Given 활성 수 == M, When 새 자산 매수 신호, Then `capacity_full` 로 거부되고 기존 holding 은 청산되지 않는다.
|
||||
3. Given 이미 활성(pending_buy/holding/pending_sell)인 자산, When 또 매수 신호, Then 멱등 거부(`already_active`)된다.
|
||||
4. Given M 을 현재 보유 수보다 작게 변경(over-cap), When 신규 매수 신호, Then 활성 수가 M 이하로 내려갈 때까지 신규만 거부되고 기존 보유는 유지된다.
|
||||
5. Given 동시 매수 신호 경합, When 병렬 처리, Then 인스턴스 스코프 락으로 직렬화되어 M 초과 활성화가 발생하지 않는다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/runtime-flows.md(admission→활성화 흐름)
|
||||
- Modules: trex_core/application/intents.py, trex_core/application/portfolio.py(capacity 개념)
|
||||
- Tests: tests/application/test_intent_concurrency.py, tests/application/test_*admission*.py
|
||||
|
||||
## Notes
|
||||
- M 값 출처는 REQ-060(per-instance TOML). 기존 REQ-007(admission) 재정의 change-req 동반(find_allocatable_slot/idle 배정 폐기).
|
||||
- 출처: dcy-020 FR-2, FR-3, OQ-1, OQ-8.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260610-01
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-020 FR-2/FR-3/OQ-1/OQ-8 로부터 최초 생성(Proposed). FCFS + M 캡 + capacity_full 거부 + 무치환 + over-cap(신규만 차단) + already_active.
|
||||
|
||||
#### Intent
|
||||
- 신호 기반 활성화/비활성화와 동시 활성 M 제어를 backlog 로 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 활성화/거부/already_active/over-cap/경합 직렬화 5개 기준
|
||||
- Updated: 없음
|
||||
- Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/runtime-flows.md
|
||||
- Modules: application/intents.py, portfolio.py
|
||||
- Tests: test_intent_concurrency.py, admission 테스트
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req. REQ-007 재정의 change-req·REQ-060(M) 의존.
|
||||
|
||||
#### Validation Plan
|
||||
- FCFS/거부/over-cap/경합 단위·통합 테스트 green.
|
||||
|
||||
### CHG-20260610-02
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status Proposed → Approved (confirm-req). 필수 필드·구체 AC 충족, source dcy-020(confirmed, handoff 승인)과 모순 없음.
|
||||
|
||||
#### Intent
|
||||
- delivery input 으로 승격.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 없음 / Updated: 없음 / Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/srs/index.md (Register Approved) / Modules: 없음 / Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none / Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no / Existing Implementation Invalidated: no / Status Recommendation: keep-current / Follow-up Action: suggest-batch-reqs / draft-batch.
|
||||
|
||||
#### Validation Plan
|
||||
- 승인 후 batch planning 에서 본 REQ AC 를 검증 기준으로 사용.
|
||||
|
||||
### CHG-20260610-IMPL
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-028(+BAT-030 단일 경로·capacity_full e2e) — 모든 AC 가 release-candidate 배치 verification 의 evidence 와 연결됨(단위 367/PG 29/MQ 21 passed + run-the-app 자산 중심 e2e). Blocking Issues 없음.
|
||||
@@ -1,219 +0,0 @@
|
||||
# req-061: intent 계약 자산(portfolio_id) 키 통일 + 중복/무효 규칙
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- 전략↔코어 intent 계약을 **코어 native 키인 `slot_id`** 로 통일한다(CHG-20260610-03, 사용자 결정으로 FR-7 의 portfolio_id 키를 slot_id 로 재정의). 자산 중심 영구 슬롯이라 universe 모든 자산에 슬롯이 선존재하므로 매수도 slot_id 로 지정 가능하다. 스냅샷 `slots[]` 가 계약의 1차 단위이며 portfolio_id 는 표시/자산 정체성으로 잔존(계약 키 아님). (dcy-020 FR-7 재정의/NFR-4)
|
||||
|
||||
## Requirement
|
||||
- 매수·매도 intent 를 모두 **`slot_id`** 키로 식별한다. 매수 = 그 슬롯 활성화(`inactive→pending_buy`, symbol 은 슬롯의 `portfolio_id` 로 resolve), 매도 = 비활성화(`holding→pending_sell`). 매도는 이미 slot_id 계약(불변). **매수는 기존 portfolio_id 계약에서 slot_id 로 이동하되, 외부 전략 무중단을 위해 portfolio_id 를 레거시 dual-accept**(자산 중심 모드에서 portfolio_id → `find_slot_by_portfolio` 로 슬롯 매핑); portfolio_id 매수 계약 완전 폐기는 BAT-δ. 중복/무효 신호 규칙: 이미 활성(`pending_buy`/`holding`/`pending_sell`)인 슬롯에 매수 → 멱등 거부(`already_active`); 보유(holding) 아닌 슬롯에 매도 → 거부(`not_holding`). `intent_id` 멱등(intent_log) 보존.
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given 매수 신호, When `slot_id` 로 제출(자산 중심 모드), Then 그 슬롯이 `inactive→pending_buy` 로 활성화되고 symbol 은 슬롯의 portfolio_id 로 resolve 된다.
|
||||
2. Given 이미 활성(pending_buy/holding/pending_sell)인 슬롯, When 매수, Then `already_active` 로 멱등 거부된다.
|
||||
3. Given 보유(holding) 아닌 슬롯, When 매도, Then `not_holding`(또는 not-holding 사유)로 거부된다.
|
||||
4. Given 레거시 매수(`portfolio_id`), When 제출, Then `find_slot_by_portfolio` 로 슬롯에 매핑되어 동일하게 처리된다(dual-accept, 무중단).
|
||||
5. Given 같은 `intent_id` 재전송, When 처리, Then 슬롯 중복 전이 없이 최초 결정과 동일 응답(멱등).
|
||||
6. Given 보유(holding) 슬롯, When **증액 매수 intent**(qty+price)를 제출, Then `holding→pending_buy` 로 추가 매수가 집행된다(dcy-021, 이미 active 라도 증액은 허용 — `already_active` 예외).
|
||||
7. Given 보유 슬롯, When **부분 매도 intent**(qty+price)를 제출, Then 명시 수량으로 `holding→pending_sell` 집행된다(집행 수량 정책 REQ-062). 사이징 intent 는 명령형(전략이 qty+price 계산·전송), core 는 target/의도 수량을 저장·추적하지 않는다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/runtime-flows.md(intent 흐름), docs/interface-contract.md(메시지 계약)
|
||||
- Modules: trex_core/application/intents.py, 메시지 핸들러/스키마
|
||||
- Tests: tests/application/test_messaging_intent_consumer.py, tests/application/test_*intent*.py
|
||||
|
||||
## Notes
|
||||
- 기존 REQ-007(intent API) 재정의 change-req 동반(sell-by-slot_id 폐기·자산 키 통일). NFR-4(전략 계약 호환): 외부 전략 모듈 동시 전환 또는 한시적 하위호환 — REQ/배치 cutover 에서 명시.
|
||||
- 출처: dcy-020 FR-7, NFR-4.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260610-01
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-020 FR-7/NFR-4 로부터 최초 생성(Proposed). intent 자산(portfolio_id) 키 통일 + sell-by-slot_id 폐기 + already_active/not_holding.
|
||||
|
||||
#### Intent
|
||||
- 매수·매도 신호를 자산 키로 통일하는 계약 변경을 backlog 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 매도 자산키/already_active/not_holding/intent_id 멱등 4개 기준
|
||||
- Updated: 없음
|
||||
- Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/runtime-flows.md, docs/interface-contract.md
|
||||
- Modules: application/intents.py, 메시지 핸들러/스키마
|
||||
- Tests: test_messaging_intent_consumer.py, intent 테스트
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no (REQ-007 재정의 change-req 로 기존 폐기)
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req. NFR-4 외부 전략 계약 cutover 명시.
|
||||
|
||||
#### Validation Plan
|
||||
- 자산 키 매도/거부 규칙/멱등 단위·통합 테스트 green.
|
||||
|
||||
### CHG-20260610-02
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status Proposed → Approved (confirm-req). 필수 필드·구체 AC 충족, source dcy-020(confirmed, handoff 승인)과 모순 없음.
|
||||
|
||||
#### Intent
|
||||
- delivery input 으로 승격.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 없음 / Updated: 없음 / Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/srs/index.md (Register Approved) / Modules: 없음 / Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none / Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no / Existing Implementation Invalidated: no / Status Recommendation: keep-current / Follow-up Action: suggest-batch-reqs / draft-batch.
|
||||
|
||||
#### Validation Plan
|
||||
- 승인 후 batch planning 에서 본 REQ AC 를 검증 기준으로 사용.
|
||||
|
||||
### CHG-20260610-03
|
||||
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-020 FR-7 재정의 — 사용자 결정) intent 계약 키를 `portfolio_id` → **`slot_id`**(buy·sell 공통)로 재정의. 근거: trex-core 는 슬롯 기준 관리이고 스냅샷이 `slots[]` 를 단위로 주므로 코어 native 키(slot_id)로 round-trip 하는 것이 일관적이며 portfolio-hub 식별 체계의 계약 누수를 막는다. 자산 영구 슬롯이라 매수도 slot_id 로 지정 가능(슬롯 선존재). 매도는 이미 slot_id(불변); 매수만 portfolio_id→slot_id 이동(레거시 portfolio_id dual-accept, 폐기 BAT-δ). Approved 유지(사용자 재승인).
|
||||
|
||||
#### Intent
|
||||
- 전략↔코어 계약을 슬롯 native 키로 통일.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Updated: AC 전체를 slot_id 기준으로 재작성(AC-1 매수 slot_id 활성화·symbol resolve, AC-4 portfolio_id dual-accept 추가).
|
||||
- Removed: "매도 portfolio_id 제출" 전제(매도는 slot_id 유지).
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Modules: application/intents.py(BuyIntent slot_id·_admit_buy_asset_centric), 메시지 핸들러 buy 파싱, runtime/cli.py enter
|
||||
- Tests: test_asset_centric_admission(slot_id), 메시지 consumer
|
||||
- 연동: REQ-059(자산 admission)·REQ-007(buy intent) — buy 키 slot_id 로 정합(BAT-029).
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: BAT-029
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: yes (BAT-029)
|
||||
- Existing Implementation Invalidated: BAT-028 의 portfolio_id 매수 admission 은 dual-accept 로 흡수(레거시 경로 유지) — 무효화 아님
|
||||
- Status Recommendation: keep-current (Approved, 사용자 재승인)
|
||||
- Follow-up Action: BAT-029 구현. REQ-059/007 정합.
|
||||
|
||||
#### Validation Plan
|
||||
- BAT-029: 매수 slot_id 활성화 / portfolio_id dual-accept / already_active / 매도 slot_id / 멱등 단위·통합.
|
||||
|
||||
### CHG-20260610-IMPL
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-029(+BAT-030 trading_date 제거·e2e slot_id 매수) — 모든 AC 가 release-candidate 배치 verification 의 evidence 와 연결됨(단위 367/PG 29/MQ 21 passed + run-the-app 자산 중심 e2e). Blocking Issues 없음.
|
||||
|
||||
### CHG-20260610-04
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-021(포지션 사이징) 반영: intent 계약에 **사이징 intent**(보유 슬롯 증액 매수 / 부분 매도)를 추가. 명령형 — 전략이 스냅샷 cash+quantity 로 **정수 주식 수(qty)+가격(price)** 을 계산해 보내고, core 는 실행만 한다(target/의도 수량 미저장·미추적). 증액은 이미 active 슬롯에도 허용(전량 매수 활성화의 `already_active` 와 구분).
|
||||
|
||||
#### Intent
|
||||
- 보유 자산의 수량 조정을 기존 명령형 buy/sell 계약의 최소 additive 확장으로 표현(dcy-021 OQ-1/OQ-2 확정).
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: AC-6(증액 매수 intent → holding→pending_buy), AC-7(부분 매도 intent qty → holding→pending_sell, 명령형·core 미저장)
|
||||
- Updated: 없음(기존 활성/청산 계약 보존)
|
||||
- Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/interface-contract.md(사이징 intent payload), docs/runtime-flows.md
|
||||
- Modules: trex_core/application/intents.py(증액/부분 매도 admission), messaging_handlers.py(payload)
|
||||
- Tests: tests/application/test_*intent*.py, 사이징 admission 신규
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: dcy-021 신규 배치(예정)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: yes (신규 사이징 계약 경로)
|
||||
- Existing Implementation Invalidated: no (기존 slot_id 매수·전량 매도 계약 보존, additive)
|
||||
- Status Recommendation: revert-to-approved (사이징 계약 미구현 — dcy-021 배치에서 구현·검증)
|
||||
- Follow-up Action: dcy-021 배치 구현 후 Implemented 복귀.
|
||||
|
||||
#### Validation Plan
|
||||
- 증액 매수·부분 매도 intent admission 단위 + end-to-end(REQ-066). 명령형·멱등·core 미저장 검증.
|
||||
|
||||
### CHG-20260610-IMPL
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-031(release-candidate) verification — 단위 378 / 통합 422 passed + run-the-app 사이징 e2e(증액 가중평균·부분 매도 잔량·전량 매도) green. Blocking Issues 없음.
|
||||
|
||||
### CHG-20260610-05
|
||||
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-022 실행 정책) buy/sell intent 계약에 **실행 정책 필드**(optional `timeout_sec`·`slippage_pct`) 추가. `timeout_sec`: 주문 유효시간(N초 미체결 시 core 가 cancel_order 송신·롤백). `slippage_pct`: 체결 보호밴드(entry_price 기준 ±pct, entry_price 없으면 무시). 두 필드 모두 optional — 미지정 시 기존 경로 하위호환. `timeout_sec` 미지정 시 운영자 per-instance config(`default_order_timeout_sec`) 적용(미설정=OFF=무기한). Implemented → Approved 되돌림(신규 계약 필드 미구현, BAT-032 에서 재구현·confirm-req-implemented 복귀).
|
||||
|
||||
#### Intent
|
||||
|
||||
- 전략이 intent 제출 시 실행 정책을 함께 실어 미체결 고착을 원천 차단한다(dcy-022 FR-1).
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- AC-8: buy/sell intent 에 optional `timeout_sec` 포함 시 core 가 파싱해 슬롯에 기록하고 집행 루프가 timeout 초과 시 cancel_order 를 송신한다.
|
||||
- AC-9: buy/sell intent 에 optional `slippage_pct` 포함 시 `entry_price` 기준 실효 지정가를 산출해 주문을 제출한다(`entry_price` 없으면 무시).
|
||||
- AC-10: `timeout_sec`/`slippage_pct` 미지정 시 기존 매수/매도 경로와 동일하게 처리된다(하위호환).
|
||||
- Updated: 없음
|
||||
- Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs: docs/interface-contract.md(payload 확장)
|
||||
- Modules: BuyIntent/SellIntent(+timeout_sec/slippage_pct), messaging_handlers.py(파싱), intents.py(transit 전달), slot models(+timeout_sec/slippage_pct 컬럼), execution.py(dispatch slippage·poll timeout)
|
||||
- Tests: timeout/slippage 파싱·집행 단위, 하위호환 회귀
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-032
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (신규 계약 필드 경로)
|
||||
- Existing Implementation Invalidated: no (기존 slot_id 매수·매도 계약 보존, additive)
|
||||
- Status Recommendation: revert-to-approved (신규 필드 미구현 — BAT-032 에서 구현·검증)
|
||||
- Follow-up Action: BAT-032 구현 후 Implemented 복귀.
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- timeout_sec/slippage_pct 파싱·슬롯 기록·집행 단위. 미지정 회귀. end-to-end timeout 취소 시나리오.
|
||||
|
||||
### CHG-20260611-IMPL
|
||||
- Date: 2026-06-11
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-032(release-candidate) verification — 실행 정책(timeout_sec·slippage_pct) 계약·집행·운영자 cancel 백스톱 전 AC acceptance mapping 존재(신규 71 tests), 단위 425 passed 회귀 없음, baseline 2문서 수동 확인(M5). Blocking Issues 없음.
|
||||
@@ -1,135 +0,0 @@
|
||||
# req-063: 운영자 표면 단일화 — slots = 자산 포지션 단일 뷰
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: Medium
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- universe(자산 리스트)와 slots(슬롯 상태)의 이중 표면(BAT-022 혼동 원인)을 해소하기 위해, 슬롯=자산 1:1 모델에서 `trex-core slots` 가 자산 포지션을 단일 뷰로 제공한다. (dcy-020 FR-8)
|
||||
|
||||
## Requirement
|
||||
- `trex-core slots` 가 자산 슬롯(슬롯=자산)을 단일 뷰로 표시한다: `portfolio_id`/symbol/status(inactive/pending_buy/holding/pending_sell/error)/holding 수량 미러/`universe_detached`(tombstone)/`retired`. universe(자산 리스트)와 slots(자산 포지션)는 같은 자산 집합 위의 view 가 되며, 데몬 RPC(스냅샷)로 통일한다(직접 DB 쓰기 없음). 운영자는 자산별 포지션·활성 여부·tombstone 여부를 한 표면에서 본다.
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given universe N개 자산, When `trex-core slots`, Then N개 자산 슬롯이 status·holding·tombstone 표시와 함께 단일 뷰로 출력된다.
|
||||
2. Given tombstone(universe-detached holding) 슬롯, When `slots`, Then `universe_detached` 로 구분 표시된다.
|
||||
3. Given `--status` 필터, When 조회, Then 자산 슬롯 status 로 필터된다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/runtime-flows.md, docs/interface-contract.md(snapshot envelope slots[])
|
||||
- Modules: trex_core/runtime/cli.py, snapshot envelope 빌더
|
||||
- Tests: tests/application/test_messaging_snapshot_consumer.py, CLI 테스트
|
||||
|
||||
## Notes
|
||||
- 기존 REQ-032(운영자 CLI)·REQ-028/029(snapshot envelope) 와 연계 change-req. BAT-022 슬롯 가시화의 자산 중심 재정의.
|
||||
- 출처: dcy-020 FR-8.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260610-01
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-020 FR-8 로부터 최초 생성(Proposed). `trex-core slots` = 자산 포지션 단일 뷰(universe↔slots 이중 표면 해소).
|
||||
|
||||
#### Intent
|
||||
- 운영 관측 단일화(자산별 포지션·활성·tombstone)를 backlog 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 단일 뷰 출력/tombstone 표시/status 필터 3개 기준
|
||||
- Updated: 없음
|
||||
- Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/runtime-flows.md, docs/interface-contract.md
|
||||
- Modules: runtime/cli.py, snapshot envelope 빌더
|
||||
- Tests: test_messaging_snapshot_consumer.py, CLI 테스트
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no (REQ-032/028/029 연계 change-req)
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req.
|
||||
|
||||
#### Validation Plan
|
||||
- slots 단일 뷰 출력·tombstone·필터 단위테스트 green.
|
||||
|
||||
### CHG-20260610-02
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status Proposed → Approved (confirm-req). 필수 필드·구체 AC 충족, source dcy-020(confirmed, handoff 승인)과 모순 없음.
|
||||
|
||||
#### Intent
|
||||
- delivery input 으로 승격.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 없음 / Updated: 없음 / Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/srs/index.md (Register Approved) / Modules: 없음 / Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none / Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no / Existing Implementation Invalidated: no / Status Recommendation: keep-current / Follow-up Action: suggest-batch-reqs / draft-batch.
|
||||
|
||||
#### Validation Plan
|
||||
- 승인 후 batch planning 에서 본 REQ AC 를 검증 기준으로 사용.
|
||||
|
||||
### CHG-20260610-IMPL
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-029(+BAT-030 trading_date 키 제거·buyable=inactive 필터) — 모든 AC 가 release-candidate 배치 verification 의 evidence 와 연결됨(단위 367/PG 29/MQ 21 passed + run-the-app 자산 중심 e2e). Blocking Issues 없음.
|
||||
|
||||
### CHG-20260611-01
|
||||
|
||||
- Date: 2026-06-11
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-025) 운영자 CLI(`trex-core slots`/`universe`)의 데몬 RPC 를 `trex.snapshot.req` → **`trex.slots.req`**(REQ-073)로 교체한다. 운영자 조회는 **`spy=true`** 로 발신(기존 `actor="operator"`/`touch_watchdog=false` 대체 — 비침습 유지). `--status` 필터는 새 `filter`(status 단일: all/inactive/pending/holding/error)로 매핑. 출력 행은 REQ-074 병합 스키마(asset_quantity+qty 미러+warned, cash_balance+cash_estimated, watchdog nested, paused) 사용. universe↔slots 단일 표면 의도(본 REQ Intent)는 새 표면에서 완성된다.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 운영자 단일 뷰를 새 read 표면 위로 이전(비침습·필터·병합 행 유지).
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Updated:
|
||||
- AC-1~3 의 underlying RPC 가 `trex.slots.req` 이고, 조회는 `spy=true`(워치독 무터치)로 수행된다. `--status` → `filter` 매핑(buyable→inactive 동치 포함).
|
||||
- Added:
|
||||
- AC-4: `slots` 출력 행에 REQ-074 병합 필드(asset_quantity/qty/warned/cash_balance/cash_estimated/watchdog/paused)가 표시된다.
|
||||
- Removed: none
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Modules: trex_core/runtime/cli.py(`_cmd_slots`/`_cmd_universe` — 새 큐·spy·filter·행 필드)
|
||||
- Docs: docs/interface-contract.md CLI↔RPC 매핑(REQ-075)
|
||||
- Tests: tests/runtime/test_cli_operator.py(새 payload·행 표시)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: 신규 batch(REQ-073/074/075 와 동일 배치, dcy-025)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (신규 batch 에서 갱신 AC 검증)
|
||||
- Existing Implementation Invalidated: yes (snapshot RPC 기반 CLI evidence 가 표면 교체로 무효화)
|
||||
- Status Recommendation: Implemented → Approved (batch 재구현·재검증 후 복귀)
|
||||
- Follow-up Action: draft-batch → 구현/검증 → confirm-req-implemented
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- 신규 BAT: CLI payload(`trex.slots.req`/spy=true/filter 매핑) 단위 + 행 필드 표시 단위 + buyable→inactive 동치 회귀.
|
||||
@@ -1,95 +0,0 @@
|
||||
# req-066: 보유 자산 포지션 사이징 — 증액·부분 감액 (수량/avg_price 재계산)
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- dcy-021: 자산 중심 영구 슬롯(dcy-020)의 "수량 가변 전제" 위에, 보유(holding) 자산 슬롯의 **수량을 holding 을 유지한 채 조정**(증액·부분 감액)하는 end-to-end 동작과 수량/avg_price 재계산 규칙을 정의한다. 전량 청산만 종료(inactive)한다. (issue #1, dcy-020 OQ-4 후속)
|
||||
|
||||
## Requirement
|
||||
- 보유 슬롯 **증액**: 같은 슬롯이 `HOLDING→PENDING_BUY→HOLDING` 로 순환하며 **실제 체결분만큼** 보유 수량이 누적되고, `avg_price = (기존수량×기존평단 + 체결수량×체결가) / 총수량` 가중평균으로 재계산된다(REQ-057 전이·REQ-061 intent 계약 사용).
|
||||
- 보유 슬롯 **부분 감액**: 같은 슬롯이 `HOLDING→PENDING_SELL` 로 전이하고, 체결 후 브로커 정본 수량을 반영해 잔량>0 이면 `HOLDING`(**cost basis=avg_price 유지**), 잔량 0(전량)이면 `INACTIVE` 로 종료한다(집행 수량 정책은 REQ-062).
|
||||
- **부분 체결**: 증액·감액 모두 **실제 체결분만** 슬롯 수량/원장에 반영하고, 미체결 잔량은 core 가 추적·재시도하지 않는다(재수렴은 전략이 스냅샷 기준으로 재발행). 실현손익은 core 가 계산하지 않고 ledger/portfolio-hub 가 소유한다.
|
||||
- 활성 자산 수(M 캡 대상, REQ-059)는 증액으로 증가하지 않는다(이미 active 인 자산의 수량 변경).
|
||||
- 기존 활성/전량 청산/admission 경로는 무회귀(additive 확장).
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given 100주 holding(avg 1000) 슬롯, When 50주(@1200) 증액 매수가 전량 체결, Then 슬롯은 holding 유지·수량 150·avg_price = (100×1000+50×1200)/150 = 1066.67(반올림 규칙 적용)로 재계산된다.
|
||||
2. Given 100주 holding 슬롯, When 60주 부분 매도가 전량 체결, Then 슬롯은 holding 유지·수량 40·avg_price(cost basis) 불변이다.
|
||||
3. Given 100주 holding 슬롯, When 전량(또는 잔고 이상) 매도가 체결, Then 슬롯은 INACTIVE 로 종료되고 점유 필드가 초기화된다.
|
||||
4. Given 증액/부분 매도 주문이 일부만 체결(예: 50 중 30), When 집행, Then 실제 체결분(30)만 슬롯 수량·ledger 에 반영되고 미체결 잔량은 추적되지 않는다.
|
||||
5. Given dcy-020 기존 경로(신규 활성·전량 청산·admission·M 캡), When 사이징 도입 후 회귀, Then 무회귀(green)다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/data-model.md(수량 가변·avg_price 재계산), docs/runtime-flows.md(사이징 흐름) — REQ-067 에서 정합
|
||||
- Modules: trex_core/domain/slot/service.py(qty 누적·avg_price 가중평균·cost basis 유지), trex_core/domain/slot/state.py(REQ-057 change-req), trex_core/application/execution.py(부분 체결 반영), trex_core/application/intents.py(REQ-061 change-req)
|
||||
- Tests: 증액 avg_price 가중평균, 부분 매도 잔량/전량 분기, 부분 체결 실제만 반영, 회귀 가드
|
||||
|
||||
## Notes
|
||||
- 계약 형태(명령형 qty+price)는 dcy-021 OQ-1, 단위(정수 주식 수+가격)는 OQ-2, avg_price/cost basis/실현손익은 OQ-3, 트리거(intent 당 1회)는 OQ-4 확정.
|
||||
- 본 REQ 는 사이징의 **도메인 수량/avg_price 의미·end-to-end 동작**을 소유한다. 상태 전이(REQ-057)·intent 계약(REQ-061)·집행 매도 수량(REQ-062)의 계약 변경은 각 change-req 로 기록한다.
|
||||
- 반올림 규칙: avg_price 는 기존 슬롯 `avg_price`(float/NUMERIC) 정밀도를 따른다(별도 통화 반올림 정책 없음). 주식 수는 정수.
|
||||
- 출처: dcy-021 FR-1/FR-2 + NFR-1/NFR-2.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260610-01
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-021(포지션 사이징, issue #1)로부터 최초 생성(Proposed). 보유 슬롯 증액·부분 감액 end-to-end + 수량/avg_price 재계산.
|
||||
|
||||
#### Intent
|
||||
- 자산 영구 슬롯의 수량 가변 전제 위에 보유 포지션 리사이즈를 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 증액 가중평균/부분 감액 잔량·전량/부분 체결 실제만/무회귀 5개 기준
|
||||
- Updated: 없음 / Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: data-model/runtime-flows(REQ-067)
|
||||
- Modules: domain/slot service·state(REQ-057), application/execution·intents(REQ-061/062)
|
||||
- Tests: 증액·부분 매도·부분 체결·회귀
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: dcy-021 신규 배치(예정) / Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: yes / Existing Implementation Invalidated: no / Status Recommendation: keep-current / Follow-up Action: confirm-req → dcy-021 배치.
|
||||
|
||||
#### Validation Plan
|
||||
- 단위(avg_price 가중평균·잔량 분기·부분 체결) + run-the-app end-to-end.
|
||||
|
||||
### CHG-20260610-02
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status Proposed → Approved (confirm-req). 필수 필드·구체 AC 충족, source dcy-021(confirmed, handoff 승인, OQ-1~4 Answered)과 모순 없음.
|
||||
|
||||
#### Intent
|
||||
- delivery input 으로 승격.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 없음 / Updated: 없음 / Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/srs/index.md(Register Approved) / Modules: 없음 / Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none / Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no / Existing Implementation Invalidated: no / Status Recommendation: keep-current / Follow-up Action: suggest-batch-reqs → draft-batch.
|
||||
|
||||
#### Validation Plan
|
||||
- 승인 후 dcy-021 배치 planning 에서 본 REQ AC 를 검증 기준으로 사용.
|
||||
|
||||
### CHG-20260610-IMPL
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-031(release-candidate) verification — 단위 378 / 통합 422 passed + run-the-app 사이징 e2e(증액 가중평균·부분 매도 잔량·전량 매도) green. Blocking Issues 없음.
|
||||
@@ -1,97 +0,0 @@
|
||||
# req-068: intent 실행 정책 계약 — timeout_sec + slippage_pct
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- buy/sell intent 계약에 **실행 정책 필드**(`timeout_sec`·`slippage_pct`)를 추가해 전략이 "어떻게 체결할지"를 함께 선언한다. core 는 수신 측 먼저 배포 가능(optional, 하위호환). (dcy-022 FR-1)
|
||||
|
||||
## Requirement
|
||||
- buy/sell intent payload 에 optional 필드 추가: `timeout_sec`(주문 유효시간 — N초 미체결 시 core 가 cancel_order 송신·롤백) · `slippage_pct`(체결 보호밴드 — entry_price 기준 ±pct 실효 지정가). 두 필드 모두 optional — 미지정 시 기존 동작 하위호환(무기한 지정가/시장가). `timeout_sec` 미지정 시 per-instance TOML `default_order_timeout_sec`(opt-in, 미설정=OFF=무기한) 를 기본값으로 적용하고 per-intent 값이 override 한다. `slippage_pct` 기본값 없음(미지정=보호밴드 없음). core 수신 측 먼저 배포(누락 시 무시 — orb-v1 발신과 lockstep 불필요). deprecate 없음(전부 신규 optional 필드, 기존 계약 보존).
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given buy intent 에 `timeout_sec=60` 포함, When core 수신, Then 슬롯에 `timeout_sec=60` 이 기록되어 집행 루프가 읽을 수 있다.
|
||||
2. Given buy intent 에 `slippage_pct=0.1` 포함, When core 수신, Then 슬롯에 `slippage_pct=0.1` 이 기록되어 dispatch 시 실효 지정가 산출에 쓰인다.
|
||||
3. Given `timeout_sec` 미지정 intent, When per-instance config `default_order_timeout_sec=120`, Then 슬롯에 `timeout_sec=120` 이 기록된다(config 기본값 적용).
|
||||
4. Given `timeout_sec` 미지정 + config 미설정, When 수신, Then 슬롯 `timeout_sec` 이 None — 기존 무기한 동작과 동일(하위호환).
|
||||
5. Given 기존 buy/sell intent(timeout/slippage 필드 없음), When 수신, Then 기존 경로와 byte-동등하게 처리된다(회귀 없음).
|
||||
6. Given per-intent `timeout_sec` 와 config `default_order_timeout_sec` 둘 다 있음, When 수신, Then per-intent 값이 우선한다(override).
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/interface-contract.md(payload 확장)
|
||||
- Modules: trex_core/application/intents.py(BuyIntent/SellIntent +timeout_sec/slippage_pct, IntentService +default_order_timeout_sec), trex_core/application/messaging_handlers.py(파싱), trex_core/domain/slot/models.py(+컬럼), trex_core/domain/slot/service.py(transit_slot 전달), trex_core/adapters/persistence/sql/012_add_execution_policy_fields.sql(DB)
|
||||
- Config: DaemonInstanceConfig +default_order_timeout_sec
|
||||
- Tests: 파싱·슬롯 기록·config 기본값·하위호환 단위
|
||||
|
||||
## Notes
|
||||
- `timeout_sec` 는 코어-타이밍(N초 후 cancel_order 송신) 이며 IOC/FOK 등 네이티브 TIF 는 후속 주기(dcy-022 OQ-1).
|
||||
- `slippage_pct` 는 `entry_price` 있을 때만 유효(OQ-2). 필드 역할: `entry_price`=기준·목표, `slippage_pct`=허용폭 → 실효 limit = entry_price*(1±pct). `timeout_sec` ≠ `forced_close_at`(포지션 만기 청산, REQ-037).
|
||||
- 출처: dcy-022 FR-1, OQ-1/OQ-2/OQ-3/OQ-4.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260610-01
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-022 FR-1 로부터 최초 생성(Proposed). intent 실행 정책 계약(timeout_sec + slippage_pct) 신규 정의.
|
||||
|
||||
#### Intent
|
||||
- 실행 정책 optional 필드 계약을 backlog 로 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: AC-1~6 (timeout_sec 기록·config 기본값·slippage_pct 기록·하위호환·override 6개 기준)
|
||||
- Updated: 없음
|
||||
- Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/interface-contract.md
|
||||
- Modules: BuyIntent/SellIntent, messaging_handlers, intents, slot models, service, migration 012
|
||||
- Tests: 파싱·기록·config·하위호환 단위
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 후 BAT-032 편성.
|
||||
|
||||
#### Validation Plan
|
||||
- timeout_sec/slippage_pct 파싱·슬롯 기록·config 기본값·하위호환 단위 테스트.
|
||||
|
||||
### CHG-20260610-02
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status Proposed → Approved (confirm-req). 필수 필드·구체 AC 충족, source dcy-022(confirmed, OQ-1~4 Answered, Freeze 승인)과 모순 없음.
|
||||
|
||||
#### Intent
|
||||
- delivery input 으로 승격.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 없음 / Updated: 없음 / Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/srs/index.md (Register Approved) / Modules: 없음 / Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none / Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no / Existing Implementation Invalidated: no / Status Recommendation: keep-current / Follow-up Action: BAT-032 편성.
|
||||
|
||||
#### Validation Plan
|
||||
- 승인 후 batch planning 에서 본 REQ AC 를 검증 기준으로 사용.
|
||||
|
||||
### CHG-20260611-IMPL
|
||||
- Date: 2026-06-11
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-032(release-candidate) verification — 실행 정책(timeout_sec·slippage_pct) 계약·집행·운영자 cancel 백스톱 전 AC acceptance mapping 존재(신규 71 tests), 단위 425 passed 회귀 없음, baseline 2문서 수동 확인(M5). Blocking Issues 없음.
|
||||
@@ -1,89 +0,0 @@
|
||||
# req-071: 운영자 강제 취소 백스톱 — trex-core cancel <slot_id>
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: Medium
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- timeout 미지정·취소 실패로 잔여 고착된 pending 슬롯을 운영자가 `trex-core cancel <slot_id>` 로 강제 취소·롤백할 수 있는 백스톱 경로를 제공한다. dcy-013 Alert-only 는 기본 유지(REQ-014 회귀 없음). (dcy-022 FR-5)
|
||||
|
||||
## Requirement
|
||||
- CLI `trex-core cancel <slot_id>` 가 daemon 의 control RPC 채널(`trex.control.req`, REQ-043)에 `cancel_pending` 액션을 전송한다. daemon 수신 시: ① 슬롯이 `pending_buy`/`pending_sell` 이면 `broker.cancel_order` 를 송신하고, 다음 집행 루프 poll 에서 rollback 이 수렴한다(기존 is_terminal_reject/is_partial_cancel 경로). ② 슬롯이 HOLDING/INACTIVE 이면 `not_pending` 응답(무동작). ③ 슬롯 없으면 `slot_not_found`. 기존 kill_switch·pause 와 동일하게 운영자 단일-writer 준수(슬롯 직접 쓰기 없음 — cancel_order 만 송신, 상태 전이는 집행 루프).
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given pending_buy 슬롯, When `trex-core cancel <slot_id>`, Then broker.cancel_order 가 호출되고 응답 `{status: "ok", slot_id: ...}` 를 반환한다.
|
||||
2. Given cancel_order 가 호출된 후, When 집행 루프 다음 poll, Then 슬롯이 inactive/holding 으로 수렴한다(기존 is_terminal_reject/is_partial_cancel 경로 재사용).
|
||||
3. Given pending_sell 슬롯, When `trex-core cancel <slot_id>`, Then pending_buy 와 동일하게 cancel_order 호출 + ok 응답.
|
||||
4. Given holding/inactive 슬롯, When `cancel` 시도, Then `{status: "ignored", reason: "not_pending"}` 응답(무동작).
|
||||
5. Given 존재하지 않는 slot_id, When `cancel` 시도, Then `{status: "error", reason: "slot_not_found"}`.
|
||||
6. Given `--dry-run` 옵션, When `cancel`, Then cancel_order 미송신·응답 없이 대상 슬롯 정보만 출력(안전 확인).
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/runtime-flows.md(백스톱 취소 흐름)
|
||||
- Modules: trex_core/runtime/cli.py(`cancel` 서브커맨드), trex_core/application/messaging_handlers.py(`cancel_pending` 액션 추가), execution.py / broker: cancel_order 호출 배선(daemon 제어 핸들러)
|
||||
- Tests: tests/runtime/test_cli.py(cancel 서브커맨드), messaging_handlers cancel 단위
|
||||
|
||||
## Notes
|
||||
- 운영자 처분은 백스톱(FR-5) — timeout 미지정 또는 cancel_order 실패 잔여 고착 대비. dcy-013 stale-alert(Alert-only) 는 회귀 없이 유지.
|
||||
- 슬롯 직접 쓰기 없이 cancel_order 만 송신 → 집행 루프가 다음 poll 에서 전이. 단일 writer 불변식 유지(REQ-013 NFR-2).
|
||||
- 출처: dcy-022 FR-5, NFR-1.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260610-01
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-022 FR-5 로부터 최초 생성(Proposed). 운영자 강제 취소 백스톱 CLI + control RPC 액션.
|
||||
|
||||
#### Intent
|
||||
- 잔여 고착 pending 슬롯의 운영자 처분 경로를 backlog 로 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: AC-1~6 (pending 취소, 집행 루프 수렴, holding 무동작, not_found, dry-run 6개 기준)
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Modules: cli.py(cancel 서브커맨드), messaging_handlers(cancel_pending), daemon 제어 배선
|
||||
- Tests: cli cancel, messaging cancel_pending 단위
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no / Existing Implementation Invalidated: no / Status Recommendation: keep-current
|
||||
|
||||
#### Validation Plan
|
||||
- cancel CLI 송신 + control RPC cancel_pending + 집행 루프 수렴 단위.
|
||||
|
||||
### CHG-20260610-02
|
||||
- Date: 2026-06-10
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- Status Proposed → Approved (confirm-req).
|
||||
|
||||
#### Intent
|
||||
- delivery input 으로 승격.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 없음 / Updated: 없음 / Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/srs/index.md (Register Approved)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no / Existing Implementation Invalidated: no / Status Recommendation: keep-current / Follow-up Action: BAT-032.
|
||||
|
||||
#### Validation Plan
|
||||
- 승인 후 batch planning 에서 AC 검증 기준으로 사용.
|
||||
|
||||
### CHG-20260611-IMPL
|
||||
- Date: 2026-06-11
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-032(release-candidate) verification — 실행 정책(timeout_sec·slippage_pct) 계약·집행·운영자 cancel 백스톱 전 AC acceptance mapping 존재(신규 71 tests), 단위 425 passed 회귀 없음, baseline 2문서 수동 확인(M5). Blocking Issues 없음.
|
||||
@@ -1,206 +0,0 @@
|
||||
# req-073: 전략 read 표면 — `trex.slots.req` RPC 계약 (filter/spy, snapshot.req 즉시 교체)
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- 자산 중심 영구 슬롯 모델(dcy-020)에서 전략 read 표면을 슬롯 단일 테이블 RPC 로 재설계한다. `trex.snapshot.req`(view/assets[]/available_slots/watchdog[] 구조)를 폐기하고 `trex.slots.req` 하나로 교체해, 전략·운영자가 슬롯 테이블 하나로 universe·포지션·워치독을 읽게 한다. (dcy-025 FR-1/2/4/5/6)
|
||||
|
||||
## Requirement
|
||||
- per-instance 큐 `trex.slots.req`(기존 큐명 규칙 — default 는 literal, 그 외 `.{instance_key}` 접미)를 신설하고 `trex.snapshot.req` 파이프라인(큐 선언·핸들러·legacy stub 경로)을 **같은 배포에서 제거**한다(즉시 교체, 과도기 없음 — 전략 모듈 lockstep cutover, dcy-025 OQ-1).
|
||||
- 요청 payload: `{filter?: str, spy?: bool}`.
|
||||
- `filter` 는 **status 단일 값**(상호배타) `{all, inactive, pending, holding, error}`. 미지정 시 `all`. `pending` = `pending_buy ∪ pending_sell`. `inactive` 판정 키는 슬롯 **status**(hub `asset_quantity` 아님). 파생 view(ALL/BUYABLE/HELD)와 `View` enum 은 폐기한다 — 매수 가능 목록 = `filter=inactive`.
|
||||
- `spy=true` 면 워치독을 갱신하지 않는다(생존 신호 미발생 — 기존 `actor="operator"`/`touch_watchdog=false` 의 일반화, REQ-034 정합). 기본 `false`(holding 슬롯 워치독 터치).
|
||||
- 응답 payload: `{slots: [...], available_slots: int|null, degraded: bool, reason, message}`. `assets[]`·`watchdog[]` 는 응답에 포함하지 않는다(워치독은 슬롯 행에 흡수 — REQ-074). `available_slots` 는 capacity hint — `max_active_slots` 미설정 시 `null`, 설정 시 `max(0, M − count_active)`. admission gate(`capacity_full`)는 별도로 유지되며 `available_slots` 가 이를 대체하지 않는다.
|
||||
- `strategy_id`/`strategy_key`/`strategy_params`/`active_strategy_id` 는 본 표면에서 제외한다(요청 필터·응답 필드 모두 없음). 인스턴스=다중 전략이나 전략↔자산 할당 모델은 portfolio-hub 주도 후속 discovery — 확정 시 strategy 필드를 additive 로 재도입한다(dcy-025 OQ-4).
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given 기동된 데몬, When 토폴로지 선언, Then `trex.slots.req`(per-instance) 큐가 존재하고 `trex.snapshot.req` 큐·핸들러·legacy stub 경로는 존재하지 않는다.
|
||||
2. Given `{filter: "inactive"}` 요청, When 처리, Then status 가 `inactive` 인 슬롯 행만 반환된다(매수 가능 목록). `{filter: "pending"}` 은 `pending_buy ∪ pending_sell`, 미지정은 전체. 잘못된 filter 값은 `all` 또는 명시 거부로 일관 처리된다.
|
||||
3. Given 응답 payload, When 키 집합 검사, Then `slots`/`available_slots`/`degraded`/`reason`/`message` 가 있고 `assets`·`watchdog`·strategy 계열 키는 없다.
|
||||
4. Given `spy=true` 요청, When holding 슬롯 포함 조회, Then 워치독 `last_seen_at` 이 갱신되지 않는다. Given 기본(`spy` 미지정/false) 요청, Then holding 슬롯 워치독이 갱신된다(REQ-034 시맨틱 보존).
|
||||
5. Given degraded 상태(universe fetch 실패 등), When 조회, Then `degraded=true` + `reason` 이 기존 REQ-028 신호 의미대로 운반된다.
|
||||
6. Given `max_active_slots` 미설정 인스턴스, When 조회, Then `available_slots = null`. Given `max_active_slots = M` 설정 인스턴스 + 현재 active N, When 조회, Then `available_slots = max(0, M − N)`. `available_slots` 는 hint 이며 admission gate 를 대체하지 않는다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/interface-contract.md(snapshot→slots 계약 — REQ-075), docs/runtime-flows.md
|
||||
- Modules: trex_core/adapters/messaging/topology.py(큐명), trex_core/application/messaging_handlers.py(slots 핸들러·snapshot 핸들러 제거; (CHG-20260612-02) status 필터 repo 위임 + watchdog 조회 재사용), trex_core/application/portfolio.py(`View` enum 폐기)
|
||||
- Tests: tests/application/(slots 핸들러 filter/spy/응답 키 집합), tests/adapters/messaging/(토폴로지)
|
||||
|
||||
## Notes
|
||||
- 즉시 교체(과도기 없음)이므로 전략 모듈(trex-orb-v1) 소비 측을 같은 전환점에 lockstep 변경해야 한다(dcy-025 R-1/NFR-3) — 배포 전 orb-v1 의 `trex.slots.req` 대응 준비 확인. dcy-020 cutover 선례와 동일하게 단일 전환점 관리.
|
||||
- 행 스키마(자산·워치독·overlay 흡수, 정본 라벨)는 REQ-074 가 소유한다.
|
||||
- 운영자 CLI 의 새 표면 사용은 REQ-063 change-req(CHG-20260611-01).
|
||||
- 출처: dcy-025 FR-1/2/4/5/6, NFR-1(워치독 일관성)·NFR-3(cutover 안전)은 본 REQ AC/Notes 에 흡수.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260615-02
|
||||
|
||||
- Date: 2026-06-15
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented, BAT-042). 신규 AC-7(strategy_state 맵+occupancy_seq additive, batched 조립) 구현·검증 완료 — `tests/application/test_slots_handler_strategy_state.py` + 기존 `test_slots_handler.py` 회귀 green. 기존 AC-1~6 불변. 479 passed, ruff clean. Implemented 복귀.
|
||||
|
||||
### CHG-20260615-01
|
||||
|
||||
- Date: 2026-06-15
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, dcy-028/issue #26 C-1) `trex.slots.req` 응답의 각 슬롯 행에 **strategy_state 맵**(`{<strategy_id>: {version,data,updated_at}}`, REQ-079/074)과 **occupancy_seq**(int, REQ-081)를 additive 로 추가한다. 핸들러는 반환 slot_id 들로 `StrategyStateStore`(REQ-079) batched 조회 후 group by 해 행별 맵으로 조립한다(추가 왕복 없음). 미보유 시 omit/`{}`. 기존 envelope 키(`slots`/`available_slots`/`degraded`/`reason`/`message`)·filter·spy·degraded 동작은 불변. AC-3 의 "strategy 계열 키 없음"은 dcy-025 가 제외한 strategy_* **reasoning** 필드(strategy_id/params/active)를 가리키며, 본 변경의 `strategy_state`(opaque 상태 맵)·`occupancy_seq`는 그와 구분되는 신규 additive 필드다.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 전략 데몬이 슬롯과 함께 opaque strategy-state 를 추가 왕복 없이 read(C-1 piggyback). write 는 별도 RPC(REQ-080).
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- AC-7(신규): 행에 `strategy_state` 맵(보유 시)과 `occupancy_seq` 가 포함되고, batched 조회로 조립되어 추가 RPC 왕복이 없다. strategy_* reasoning 필드 부재는 유지(AC-3 정합).
|
||||
- Updated:
|
||||
- AC-3: 응답 키 집합에서 제외되는 "strategy 계열"은 strategy_* reasoning 필드로 한정하고 `strategy_state`/`occupancy_seq` additive 필드는 허용함을 명확화.
|
||||
- Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs: docs/interface-contract.md(strategy_state·occupancy_seq 행 필드 — REQ-082)
|
||||
- Modules: trex_core/application/messaging_handlers.py(slots 핸들러 strategy_state batched 조립), trex_core/application/portfolio.py(slot_to_dict)
|
||||
- Tests: tests/application/(strategy_state 맵·occupancy_seq 행 조립, batched 조회)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-035(dcy-025, 기존 Implemented 근거) 불변 — 신규 AC-7 은 dcy-028 batch 에서 구현·검증.
|
||||
- Releases: REL-006(REQ-073 released) — 기존 계약 영향 없음(additive). 신규 필드는 REL-007 이후 dcy-028 batch.
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (신규 AC-7 만)
|
||||
- Existing Implementation Invalidated: no (기존 envelope/filter/spy 동작 보존)
|
||||
- Status Recommendation: revert-to-approved (Implemented → Approved — 신규 additive AC 구현·검증 대기, 선례 REQ-002/006 CHG-20260612)
|
||||
- Follow-up Action: confirm-req → dcy-028 batch 에서 REQ-079/080/081 과 함께 구현·검증 → confirm-req-implemented
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- slots 핸들러 테스트: 행에 strategy_state 맵(보유/미보유)·occupancy_seq 포함, batched 조회로 추가 왕복 없음, 기존 키 집합/filter/spy/degraded 회귀.
|
||||
|
||||
### CHG-20260612-02
|
||||
|
||||
- Date: 2026-06-12
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- (change-req, issue #25) slots RPC 핸들러(`make_slots_rpc_handler`)가 status 필터링을 `SlotRepository.list_slots(instance_key, status_filter=...)`(REQ-002/006) 에 위임해 per-request full scan + Python 필터를 제거한다. 추가로 watchdog 갱신용 holding 조회를, 응답 필터가 `all`/`holding` 이라 이미 holding 을 포함한 경우 fetch 결과를 재사용해 두 번째 커넥션을 생략한다(그 외 필터는 기존대로 `list_holding_slots`). **관찰 가능한 응답 계약(AC-1~6)은 불변** — filter 결과·키 집합·spy·degraded·available_slots 동일. AC delta 없음 → **Implemented 유지**(BAT-040 재검증).
|
||||
|
||||
#### Intent
|
||||
|
||||
- issue #25 (1) DB 레벨 status 필터 + (2) 두 쿼리 통합. orb-v1 이 매 cycle `{filter:"inactive"}` 로 요청할 때 200-slot 인스턴스에서 전 행 fetch 를 반복하던 비용 제거. 동작 보존 내부 최적화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added/Updated/Removed: 없음 (AC-1~6 관찰 계약 불변, 핸들러 내부 위임만)
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs: 없음
|
||||
- Modules: `trex_core/application/messaging_handlers.py`(`make_slots_rpc_handler` — `list_slots(status_filter)` 위임 + watchdog 조회 재사용)
|
||||
- Tests: 기존 filter/spy/응답 키 집합 테스트 회귀 + status_filter 위임 확인
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches: BAT-040 (예정, issue #25)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes (BAT-040 에서 filter/spy/degraded/available_slots 회귀)
|
||||
- Existing Implementation Invalidated: no (관찰 응답 동일, 내부 위임만 — AC evidence 유효)
|
||||
- Status Recommendation: **Implemented 유지**
|
||||
- Follow-up Action: BAT-040 구현·검증으로 재확인(REQ-002/006 Implemented 복귀와 동일 배치)
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- BAT-040: 기존 `test_filter_*`/`test_spy_*`/`test_response_keys_*`/`test_available_slots_*` 회귀 green + status_filter 위임 경로(필터별 list_slots 인자) 확인.
|
||||
|
||||
### CHG-20260612-IMPL
|
||||
- Date: 2026-06-12
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-037 (release-candidate) — AC-3 반전(available_slots 포함)·AC-6 신규(null/잔여/0 클램프) 16 tests passed, 423 전체 회귀 없음. Blocking Issues 없음.
|
||||
|
||||
### CHG-20260612-01
|
||||
- Date: 2026-06-12
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- 응답 payload 에 `available_slots: int|null` 추가. orb-v1 이 매 cycle `{filter: "inactive"}` 로 슬롯을 요청할 때 capacity 가 차 있어도 intent 를 쏴야만 `capacity_full` 을 알 수 있던 문제 해소. `max_active_slots` 미설정 시 `null`(제한 없음), 설정 시 `max(0, M − active)` 정수.
|
||||
|
||||
#### Intent
|
||||
- slots RPC 를 read 표면으로 유지하면서도 capacity 힌트를 제공해 불필요한 intent 왕복을 줄인다. admission gate(`capacity_full`)는 그대로 유지 — `available_slots` 는 hint 이며 orb-v1 이 skip 최적화에 사용한다.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Updated:
|
||||
- AC-3: 응답 키 집합에서 `available_slots` 제외 → **포함**으로 반전. `assets`·`watchdog`·strategy 계열은 여전히 제외.
|
||||
- Added:
|
||||
- AC-6: `available_slots` 값 규칙 — `max_active_slots` 미설정 시 `null`, 설정 시 `max(0, M − count_active)`. 응답의 `available_slots` 는 hint 이며 admission gate 를 대체하지 않는다.
|
||||
- Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Modules:
|
||||
- `trex_core/application/messaging_handlers.py` — `make_slots_rpc_handler` 응답에 `available_slots` 추가
|
||||
- `trex_core/domain/slot/service.py` — `compute_slot_capacity` 호출 경로 확인
|
||||
- Tests: `tests/application/test_slots_handler.py` — AC-3 키 집합 검사 및 AC-6 값 검증 갱신
|
||||
- Docs: `docs/interface-contract.md` — 응답 스키마 반영 (REQ-075 소관)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: BAT-035 (REQ-073 구현/확인) — AC-3 evidence 무효. 신규 batch 필요.
|
||||
- Releases: REL-006 (배포 완료) — 운영 중 발견, 비파괴적 필드 추가(additive).
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: yes
|
||||
- Existing Implementation Invalidated: yes (AC-3 — `available_slots` 부재 검증이 반전됨)
|
||||
- Status Recommendation: Implemented → **Approved** (차기 batch 구현·검증 후 복귀)
|
||||
- Follow-up Action: draft-batch → implementation → verification → confirm-req-implemented
|
||||
|
||||
#### Validation Plan
|
||||
- 응답에 `available_slots` 키 존재 확인.
|
||||
- `max_active_slots` 설정 인스턴스: active N 개일 때 `available_slots = M − N`, active ≥ M 이면 `0`.
|
||||
- `max_active_slots` 미설정: `available_slots = null`.
|
||||
- 기존 AC-1/2/4/5 회귀 없음 확인.
|
||||
|
||||
### CHG-20260611-01
|
||||
- Date: 2026-06-11
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-025 FR-1/2/4/5/6 로부터 최초 생성(Proposed). `trex.slots.req` RPC 계약(filter=status 단일/spy 워치독 무터치/응답 slots+health 만/strategy 제외/즉시 교체).
|
||||
|
||||
#### Intent
|
||||
- 전략 read 표면을 슬롯 단일 테이블로 재설계 — assets/available_slots/watchdog 병렬 구조와 파생 view 폐기.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- AC-1~5 신규
|
||||
- Updated/Removed: none
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: interface-contract/runtime-flows
|
||||
- Modules: topology/messaging_handlers/portfolio(View 폐기)
|
||||
- Tests: slots 핸들러/토폴로지
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none(승인 후 draft-batch)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no(신규)
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current(Proposed)
|
||||
- Follow-up Action: confirm-req
|
||||
|
||||
#### Validation Plan
|
||||
- 신규 batch: 토폴로지 선언/제거 단위, filter·spy·응답 키 집합 단위, 워치독 터치/무터치, degraded 신호 회귀.
|
||||
@@ -1,87 +0,0 @@
|
||||
# req-080: `trex.slots.strategy_state.set` write RPC 계약 — occupancy_seq·version CAS
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- 전략 데몬이 슬롯의 opaque strategy-state 를 write 하는 신규 RPC 계약을 정의한다. read 는 기존 `trex.slots.req`(REQ-073) 에 piggyback 하고(추가 왕복 없음), write 만 별도 RPC 로 분리해 `evaluate()` 순수성과 재시도 격리를 보존한다. (dcy-028 FR-2/OQ-2, issue #26 C-2)
|
||||
|
||||
## Requirement
|
||||
- 신규 RPC `trex.slots.strategy_state.set` 를 기존 계약 패턴(direct reply-to + JSON + per-instance `queue_name({base}.{instance_key})`)으로 신설한다.
|
||||
- 요청 payload: `{slot_id, strategy_id, expected_version:int, expected_occupancy_seq:int, data:str}`. `correlation_id = "{slot_id}:{strategy_id}:{expected_version}"`(멱등 키), delivery persistent.
|
||||
- 성공 응답: `{ok:true, slot_id, strategy_id, version:<new>}`.
|
||||
- 실패 응답 reason 전체 집합 = `{occupancy_changed, version_conflict, slot_inactive, state_too_large, bad_request}`:
|
||||
- `occupancy_changed`: 슬롯 현재 occupancy_seq ≠ expected_occupancy_seq → `{ok:false, reason, occupancy_seq:<cur>}` (저장 안 함; 데몬 re-read 후 fresh restart).
|
||||
- `version_conflict`: stored version ≠ expected_version → `{ok:false, reason, version:<cur>}`.
|
||||
- `slot_inactive`: 슬롯 inactive/미존재 → `{ok:false, reason}` (저장 안 함).
|
||||
- `state_too_large`: `data` 가 size cap(REQ-079/NFR) 초과 → `{ok:false, reason}` (저장 안 함).
|
||||
- `bad_request:<detail>`: malformed payload(기존 intent 핸들러 패턴) → `{ok:false, reason}`.
|
||||
- 핸들러는 REQ-079 `StrategyStateStore` 의 CAS 로 위임한다(저장 의미는 REQ-079 소유). `data` 는 opaque 로 전달하고 핸들러는 해석하지 않는다.
|
||||
- 동일 `correlation_id` 재전송은 부작용 없음(멱등). 미인식 reason 에 대해 소비자 fail-closed 를 계약에 명시한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given 기동된 데몬, When 토폴로지 선언, Then `trex.slots.strategy_state.set`(per-instance) 큐가 존재하고 direct reply-to 로 응답한다.
|
||||
2. Given 유효 요청(occupancy_seq·version 일치), When set, Then `{ok:true, version:<+1>}` 를 반환하고 저장된다.
|
||||
3. Given occupancy_seq 불일치, Then `{ok:false, reason:"occupancy_changed", occupancy_seq:<cur>}`. Given version 불일치, Then `{ok:false, reason:"version_conflict", version:<cur>}`. 둘 다 저장되지 않는다.
|
||||
4. Given inactive 슬롯, Then `{ok:false, reason:"slot_inactive"}`. Given size cap 초과, Then `{ok:false, reason:"state_too_large"}`. Given malformed payload, Then `{ok:false, reason:"bad_request:<detail>"}`.
|
||||
5. Given 동일 `correlation_id` 재전송, When 처리, Then 부작용 없이 동일 결과가 반환된다.
|
||||
6. Given 응답 reason, When 집합 검사, Then `{occupancy_changed, version_conflict, slot_inactive, state_too_large, bad_request}` 외 값이 없다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/interface-contract.md(strategy_state.set 계약 — REQ-082), docs/runtime-flows.md(write 흐름 — REQ-082)
|
||||
- Modules: trex_core/adapters/messaging/topology.py(큐명), trex_core/application/messaging_handlers.py(신규 set 핸들러 — REQ-079 store 위임), trex_core/runtime/daemon.py(핸들러 와이어링)
|
||||
- Tests: tests/application/(set 핸들러 6 reason 케이스 + 멱등), tests/adapters/messaging/(토폴로지)
|
||||
|
||||
## Notes
|
||||
- 저장·CAS 의미는 REQ-079 가 소유한다 — 본 REQ 는 RPC 계약(요청/응답 shape, reason 운반, 멱등, 큐). 핸들러는 store 로 위임만 한다.
|
||||
- read piggyback(REQ-073/074)과의 비대칭(read 무료/write 분리)은 dcy-028 OQ-2 의도. 사이클당 다중 슬롯 write 시 N개 set RPC — optional batch 변형은 v1 범위 밖 후속.
|
||||
- 출처: dcy-028 FR-2(C-2), OQ-2(별도 RPC), reject reason 집합(trex-tsl #4705990067 답변 정합).
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260615-03
|
||||
- Date: 2026-06-15
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-042 verification — `trex.slots.strategy_state.set` 큐(topology/rabbitmq declare) + `make_strategy_state_set_handler`(store 위임) + daemon consumer 스레드. AC-1~6 evidence: `tests/application/test_strategy_state_set_handler.py`(성공+5 reason+bad_request 2종+멱등+reason 집합). 479 passed, ruff clean. Blocking Issues 없음.
|
||||
|
||||
### CHG-20260615-02
|
||||
- Date: 2026-06-15
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Proposed → Approved (confirm-req). 필수 필드·구체 AC(6개) 충족, source dcy-028(OQ-2 정합) 일치, reject reason 집합 trex-tsl #4705990067 답변과 정합. blocker 없음.
|
||||
|
||||
### CHG-20260615-01
|
||||
- Date: 2026-06-15
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-028 FR-2/OQ-2 로부터 최초 생성(Proposed). strategy_state.set write RPC 계약 + occupancy_seq·version CAS + reject reason 전체 집합.
|
||||
|
||||
#### Intent
|
||||
- write 를 별도 RPC 로 분리해 evaluate 순수성·재시도 격리 보존, read 는 slots.req piggyback.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 큐/성공/occupancy·version reject/inactive·size·bad_request/멱등/reason 집합 6개 기준
|
||||
- Updated: 없음
|
||||
- Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: interface-contract.md, runtime-flows.md(REQ-082)
|
||||
- Modules: topology.py, messaging_handlers.py, daemon.py
|
||||
- Tests: set 핸들러 reason 케이스, 토폴로지
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none (편성 예정)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 후 batch 편성(REQ-079/081/082 + REQ-073/074 CHG 동일 batch)
|
||||
|
||||
#### Validation Plan
|
||||
- set 핸들러 단위 테스트(6 reason 케이스 + 멱등) + 토폴로지 선언 테스트로 RPC 계약 검증.
|
||||
@@ -1,53 +0,0 @@
|
||||
# req-086: 청산 reason+actor 동반 노출 — 안전망/전략 구분 가시화
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: Medium
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- watchdog 소유 안전망 청산이 `reason=stop_loss`로만 보여 "전략의 진짜 손절"로 오해됐다(2026-06-15 064400). 신규 필드 없이, 기존 `reason`(조건축)과 기존 `actor`(주체축)를 **함께** 노출해 "안전망 자율청산(actor=safety_sell)"과 "전략 손절(actor=strategy)"을 운영자가 구분하게 한다. (dcy-029 FR-3, OQ-4=Option A)
|
||||
|
||||
## Requirement
|
||||
- 기존 `reason` 어휘 `{stop_loss, take_profit, forced_close_at, market_close_liquidation}`(safety_sell 발화)와 전략 SellIntent의 reason을 계약으로 고정한다(신규 reason 값·신규 분류 필드 없음).
|
||||
- 슬롯 전이 로그/이벤트/조회 뷰에 `reason`과 `actor`(`safety_sell`/`strategy`/`execution_loop`)를 **함께** 노출한다. 특히 주문 결과 로깅(REQ-085)·조회 CLI(REQ-088)·청산 로그에 actor가 reason과 같이 보이도록 한다.
|
||||
- `docs/interface-contract.md`에 reason+actor 어휘와 "안전망 자율청산 family vs 전략 매도" 구분을 명문화한다.
|
||||
- 기존 `slots.req`/이벤트/전이 기록의 기존 동작은 깨지 않는다(additive 노출).
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given safety_sell이 stop_loss로 발화, When 전이/로그, Then `reason=stop_loss` + `actor=safety_sell`이 함께 기록된다.
|
||||
2. Given 전략 SellIntent 매도, When 전이/로그, Then `actor`가 전략 주체로 기록되어 안전망과 구분된다.
|
||||
3. Given 청산 로그 라인, When 운영자가 확인, Then reason만으로 오해되지 않도록 actor가 동반 노출된다.
|
||||
4. Given safety_sell 4경로(stop_loss/take_profit/forced_close_at/market_close_liquidation), When 발화, Then 각 reason이 actor=safety_sell과 함께 정확히 기록된다.
|
||||
5. Given 기존 reason 소비처(`_SELL_REJECT_RETRYABLE` 등), When 변경 적용, Then 기존 동작 회귀 없음(reason 값 불변).
|
||||
6. Given interface-contract.md, When 갱신 후, Then reason+actor 어휘와 구분 규칙이 문서화돼 있다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/interface-contract.md(reason+actor 어휘), docs/runtime-flows.md(청산 분류 노출)
|
||||
- Modules: trex_core/application/safety_sell.py·execution.py(로그에 actor 동반), 조회 뷰(REQ-088)·주문결과 로깅(REQ-085)과 협조. `slot_transition_log`는 이미 actor 기록.
|
||||
- Tests: safety_sell 각 경로 reason·actor 단위, 노출 형식 단위
|
||||
|
||||
## Notes
|
||||
- 코드 확인: `slot_transition_log`는 이미 `actor`를 기록하고, safety_sell은 이미 구분된 reason으로 발화한다. 본 REQ는 둘을 **함께 노출**(로그/뷰/계약 문서)하는 가시화가 핵심이며 신규 필드·신규 reason 값은 만들지 않는다(dcy-029 OQ-4 Option A).
|
||||
- 출처: dcy-029 FR-3, OQ-4.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260616-01
|
||||
- Date: 2026-06-16
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-029 FR-3로부터 최초 생성(Proposed).
|
||||
|
||||
### CHG-20260616-02
|
||||
- Date: 2026-06-16
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Proposed → **Approved** (confirm-req). 필수 필드·구체 AC 충족, source dcy-029(confirmed, Open OQ 0) 정합. dcy-029 P0/P1 batch 편성 예정.
|
||||
|
||||
### CHG-20260616-IMPL
|
||||
- Date: 2026-06-16
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → **Implemented** (confirm-req-implemented, BAT-046 release-candidate, dcy-029 P1). 근거: 단위/문서 AC 매핑(REQ-086 reason+actor 로그·interface-contract; REQ-088 operator_report 집계·net PnL·KST 경계·CLI report; REQ-089 docs/operations.md 4영역; REQ-090 runtime-flows·project-structure 정합). 14 passed(report+safety_sell), 전체 537 passed/47 skipped 회귀 0, ruff clean. report direct-DB·Loki 실 적재는 release 운영 검증 위임. Blocking Issues 없음.
|
||||
@@ -1,57 +0,0 @@
|
||||
# req-088: 운영 조회 CLI — 보유·오늘 체결·실현 PnL·대기 주문
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: project maintainers
|
||||
|
||||
## Intent
|
||||
- 일일 실현 PnL을 `ledger_outbox`에서 수기 계산해야 했다. 운영자가 단일 CLI 명령으로 현재 보유·오늘 체결·오늘 실현 PnL(수수료·세금 반영)·대기 주문을 조회해 일일 리포트 자동화의 기반을 만든다. (dcy-029 FR-5, OQ-1=CLI, RPC 없음)
|
||||
|
||||
## Requirement
|
||||
- 운영자 CLI(`trex_core/runtime/cli.py`)에 신규 서브커맨드(예: `report` 또는 `pnl`)를 추가해 다음을 출력한다:
|
||||
- **현재 보유**: holding 슬롯의 symbol/portfolio_id/qty/avg_price.
|
||||
- **오늘 체결**: 당일(trading_date, KST 경계) 체결 건수/내역.
|
||||
- **오늘 실현 PnL**: 수수료·세금 반영(BAT-038 정책과 동일 계산), `ledger_outbox`/체결 기록을 단일 권위 출처로 집계.
|
||||
- **대기 주문**: pending_* 슬롯.
|
||||
- 조회는 **DB-backed 시점 집계**다. 신규 RabbitMQ RPC는 추가하지 않는다(dcy-029 OQ-1). 데몬 미경유로 DB를 직접 읽거나 기존 read 경로를 재사용한다.
|
||||
- 청산/체결 항목에 reason+actor(REQ-086)를 함께 보여 안전망/전략 구분이 되게 한다.
|
||||
- 출력은 사람용 표/요약 + 가능하면 머신 파싱용(예: `--json`) 형태를 고려한다(자동화 기반).
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given holding 슬롯 존재, When `report` 실행, Then 보유 symbol/qty/avg_price가 출력된다.
|
||||
2. Given 당일 체결 N건, When 실행, Then 오늘 체결 건수/내역이 출력된다.
|
||||
3. Given 당일 매도 체결, When 실행, Then 실현 PnL이 수수료·세금 반영 값으로 출력되고 `ledger_outbox` 직접 집계와 일치한다.
|
||||
4. Given pending_* 슬롯, When 실행, Then 대기 주문이 출력된다.
|
||||
5. Given "오늘" 경계, When trading_date(KST) 기준, Then 전일 체결은 오늘 집계에서 제외된다.
|
||||
6. Given 신규 표면, When 실행, Then 신규 RabbitMQ RPC 없이 동작한다(CLI/DB-backed, OQ-1).
|
||||
|
||||
## Impacted Area
|
||||
- Docs: docs/runtime-flows.md(운영자 CLI 조회 흐름), docs/operations.md(사용법 — REQ-089)
|
||||
- Modules: trex_core/runtime/cli.py(신규 서브커맨드), PnL 집계 read(신규 헬퍼 — `ledger_outbox`/체결 집계), 기존 slot read 재사용
|
||||
- Tests: 집계 함수 단위(수수료·세금·trading_date 경계), CLI 서브커맨드 단위
|
||||
|
||||
## Notes
|
||||
- PnL 계산은 BAT-038(매도 증권거래세+수수료) 정책을 단일 출처로 재사용(dcy-029 NFR-3/A-3). 부분 정산·재시도 중 outbox 상태는 집계 시점 기준으로 명시.
|
||||
- 출처: dcy-029 FR-5, OQ-1.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260616-01
|
||||
- Date: 2026-06-16
|
||||
- Author: Justin Ko
|
||||
|
||||
#### Change Summary
|
||||
- dcy-029 FR-5로부터 최초 생성(Proposed).
|
||||
|
||||
### CHG-20260616-02
|
||||
- Date: 2026-06-16
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Proposed → **Approved** (confirm-req). 필수 필드·구체 AC 충족, source dcy-029(confirmed, Open OQ 0) 정합. dcy-029 P0/P1 batch 편성 예정.
|
||||
|
||||
### CHG-20260616-IMPL
|
||||
- Date: 2026-06-16
|
||||
- Author: Justin Ko
|
||||
- Type: status
|
||||
- Summary: Approved → **Implemented** (confirm-req-implemented, BAT-046 release-candidate, dcy-029 P1). 근거: 단위/문서 AC 매핑(REQ-086 reason+actor 로그·interface-contract; REQ-088 operator_report 집계·net PnL·KST 경계·CLI report; REQ-089 docs/operations.md 4영역; REQ-090 runtime-flows·project-structure 정합). 14 passed(report+safety_sell), 전체 537 passed/47 skipped 회귀 0, ruff clean. report direct-DB·Loki 실 적재는 release 운영 검증 위임. Blocking Issues 없음.
|
||||
@@ -1,99 +0,0 @@
|
||||
# req-098: 알람 envelope wire 계약 정의
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: trex-core-dev
|
||||
|
||||
## Intent
|
||||
- 제품군 모든 모듈(core/orb/tsl/kdh)이 알람을 발신할 때 사용할 표준 메시지 envelope 스키마를 trex-core가 wire 계약으로 정의하고 `docs/interface-contract.md`에 명시한다.
|
||||
- 이 계약은 trex-notifier가 알람을 수집·분류할 때의 파싱 기준이 되며, 다른 모듈 repo(orb/tsl/kdh)와 trex-notifier가 이 문서를 단일 출처(source of truth)로 참조한다.
|
||||
- 기존 wire 계약(slots RPC/trex.events/trex.control.req)은 일절 변경하지 않는다.
|
||||
|
||||
## Requirement
|
||||
- trex-core는 알람 envelope의 표준 JSON 스키마를 아래 필드로 정의하고, `docs/interface-contract.md`에 신규 섹션 `Interface: trex.alerts (알람 채널, dcy-033)`으로 버전드 명시해야 한다.
|
||||
- `source` :: str — 알람 발신 모듈 식별자 (예: `"trex-core"`, `"trex-orb-v1"`, `"trex-tsl-v1"`, `"kis-data-hub"`)
|
||||
- `severity` :: `"critical"` | `"warn"` | `"info"` — 등급 (소문자 리터럴)
|
||||
- `code` :: str — 알람 식별 코드 (예: `"kill_switch_fired"`, `"fill_price_unresolvable"`)
|
||||
- `title` :: str — 사람이 읽는 1행 요약
|
||||
- `fields` :: dict[str, any] — 선택 구조화 컨텍스트 (예: `{"slot_id": "...", "symbol": "..."}`)
|
||||
- `occurred_at` :: ISO-8601 datetime string (UTC 또는 KST+09:00 offset 포함)
|
||||
- `schema_version` :: str — 현재 값 `"1"` (semver 주 버전 문자열; 소비자는 미인식 버전 무시·경고)
|
||||
- 계약 섹션에 routing key 규약(`alarm.{severity}.{source}`)과 exchange 이름(`trex.alerts`)을 함께 기술한다.
|
||||
- 이 스키마를 변경(필드 추가 포함)하면 `schema_version`을 올리거나 additive 변경 여부를 명시하도록 Update Trigger를 문서에 포함한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Given `docs/interface-contract.md`에 `Interface: trex.alerts (알람 채널, dcy-033)` 섹션이 존재하지 않을 때, When REQ-098 구현을 완료하면, Then 해당 섹션이 위 7개 필드(source/severity/code/title/fields/occurred_at/schema_version)의 JSON 스키마 명세를 포함해야 한다.
|
||||
2. Given 섹션이 추가됐을 때, When 명세를 검토하면, Then `severity` 값이 `"critical"` | `"warn"` | `"info"` 세 리터럴로 제한되고, `schema_version="1"`이 현재 버전으로 명시되어야 한다.
|
||||
3. Given 명세가 추가됐을 때, When 기존 interface-contract.md의 다른 섹션(slots RPC/trex.events/trex.control.req/strategy_state)을 검토하면, Then 기존 섹션의 내용이 변경되지 않아야 한다(가산·격리 불변 — diff는 신규 섹션 추가뿐).
|
||||
4. Given envelope 스키마 명세가 완성됐을 때, When routing key 규약을 확인하면, Then `alarm.{severity}.{source}` 형식이 명시되어야 한다.
|
||||
5. Given 명세가 추가됐을 때, When Update Trigger를 확인하면, Then 알람 envelope 스키마 변경(breaking/additive 모두) 시 이 문서를 갱신해야 한다는 트리거가 포함되어야 한다.
|
||||
6. Given 다른 모듈 repo(orb/tsl/kdh) 개발자가 알람 emitter를 구현할 때, When `docs/interface-contract.md`의 알람 계약 섹션을 읽으면, Then 자체 `trex_core` import 없이 envelope 구성에 필요한 모든 정보(필드·타입·필수 여부·schema_version·routing key)를 얻을 수 있어야 한다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: `docs/interface-contract.md` — 알람 채널 신규 섹션 추가(기존 섹션 불변)
|
||||
- Modules: 코드 변경 없음(이 REQ는 문서 계약만; emitter 구현은 REQ-100)
|
||||
- Tests: `docs/interface-contract.md` diff가 기존 섹션 변경 0임을 확인하는 검증(batch verification 단계에서 수동 검토 또는 diff assertion)
|
||||
|
||||
## Notes
|
||||
- 이 REQ는 **계약 문서화**만 담당한다. envelope을 실제로 직렬화·발행하는 Python 코드(알람 emitter)는 REQ-100이 담당한다.
|
||||
- `fields` 값은 opaque dict — core/notifier 모두 내용을 강제 파싱하지 않는다. 각 code별 권장 fields는 ALARM-INVENTORY.md를 참조한다.
|
||||
- `occurred_at` 형식: 권장은 KST+09:00 offset-aware ISO-8601(기존 코어 로깅 관례와 통일). UTC도 수용.
|
||||
- 다른 모듈(orb/tsl/kdh)은 `trex_core`를 import하지 않는다. 이 계약은 **문서 규약**이며 런타임 공유 코드가 아니다(Discovery 제약 A-1).
|
||||
- trex-notifier가 `schema_version`이 미인식인 envelope을 수신하면 경고 로그 후 무시한다(소비자 책임 — notifier REQ 범위).
|
||||
- dcy-033 성공기준 S-1(CRITICAL 알람 텔레그램 도달)·S-3(wire 계약 무회귀)의 선행 계약.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260621-02
|
||||
- Date: 2026-06-21
|
||||
- Author: trex-core-dev
|
||||
|
||||
#### Change Summary
|
||||
- Status: Approved → Implemented. BAT-049 confirm-batch-verification 팀장 승인(QC PASS-WITH-NOTES blocker 0 + 팀장 실인프라 e2e 통과).
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: BAT-049 (release-candidate)
|
||||
- Releases: 미정
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
|
||||
### CHG-20260621-01
|
||||
- Date: 2026-06-21
|
||||
- Author: trex-core-dev
|
||||
|
||||
#### Change Summary
|
||||
- REQ-098 신규 생성(Proposed). dcy-033 FR-1 대응: 알람 envelope wire 계약 문서화.
|
||||
|
||||
#### Intent
|
||||
- dcy-033(제품군 알람 전달 체계) confirmed Discovery에서 요구하는 표준 알람 envelope 스키마를 trex-core wire 계약으로 정식화한다.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: AC-1~6 (신규 생성)
|
||||
- Updated: (없음)
|
||||
- Removed: (없음)
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- `docs/interface-contract.md` 신규 섹션 추가
|
||||
- Modules:
|
||||
- 코드 변경 없음
|
||||
- Tests:
|
||||
- interface-contract diff 검증(기존 섹션 불변 확인)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: (미정, M2 이후 큐잉)
|
||||
- Releases: (미정)
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 후 batch 편성 시 REQ-099/100/101과 묶어 단일 batch로 처리 예정
|
||||
|
||||
#### Validation Plan
|
||||
- `docs/interface-contract.md`에 알람 채널 섹션이 추가됐는지 수동 확인
|
||||
- 기존 섹션 diff=0 확인(grep 또는 수동 비교)
|
||||
- 7개 필드·severity 리터럴·schema_version·routing key 규약이 모두 명시됐는지 체크리스트 검토
|
||||
@@ -1,143 +0,0 @@
|
||||
# req-104: 전략 차단 게이트 — pause ∨ reconcile-warning 중 하나라도 걸리면 차단
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: trex-core-dev
|
||||
|
||||
## Intent
|
||||
- 현재 전략 차단은 pause(수동 durable) 채널에만 의존한다. reconcile-warning(자동 durable) 채널을 추가해, **pause ∨ reconcile-warning 중 하나라도 존재하면 해당 슬롯/포트폴리오의 전략 수행(intent 수용 + slots read 차단 표면)을 차단**한다.
|
||||
- dcy-034 FR-2 대응: 두 채널이 독립적으로 작동하며 OR 논리로 게이트를 확장한다.
|
||||
- slots RPC wire 계약(`trex.slots.req` 응답 스키마)에서 `reconcile_warned` 플래그를 additive 필드로 노출해 운영자가 차단 원인을 식별할 수 있게 한다(NFR-4 최소 침습).
|
||||
- **차단 범위(OQ-B 확정)**: reconcile-warning 차단은 **외부 전략 intent/read 전용**이다. **내부 안전망(safety-sell · watchdog · kill-switch)은 차단 예외**다. 근거: 집행 수량 정본은 브로커 잔고(execution.py)이므로 안전망은 수량 오류에 안전하며, 차단 시 포지션이 무보호로 방치된다.
|
||||
|
||||
## Requirement
|
||||
- 시스템은 `IntentService._admit_buy` 및 `_admit_sell` 수행 시 대상 슬롯의 `pause_store` 또는 `ReconcileWarningStore` 중 하나라도 차단 기록이 있으면 intent를 `rejected`(reason: `reconcile_warned` 또는 `paused`)로 반환해야 한다.
|
||||
- **내부 안전망 경로(safety-sell / kill-switch / watchdog)는 reconcile-warning 차단을 우회해야 한다.** 이 경로들은 `IntentService._admit_*` 게이트를 거치지 않는 별도 내부 경로를 사용하며, reconcile-warning이 걸린 슬롯에 대해서도 안전망 매도를 실행할 수 있어야 한다(OQ-B 확정, 차단 대상은 외부 전략 intent만).
|
||||
- 시스템은 slots RPC 핸들러(`make_slots_rpc_handler`)에서 각 슬롯 행에 `reconcile_warned: bool` 필드를 추가해 reconcile-warning 차단 여부를 노출해야 한다.
|
||||
- `slot_to_dict` 함수는 `ReconcileWarningStore`를 선택적으로 주입받고, `reconcile_warned` 필드를 산출해야 한다(pause_store의 `paused` 필드 처리 방식과 동형).
|
||||
- 기존 `paused` 필드 및 `warned` 필드는 변경 없이 유지해야 한다(additive only, NFR-4).
|
||||
- reconcile-warning 차단으로 rejected된 buy intent는 `reason="reconcile_warned"` 를 반환해야 한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given 슬롯의 portfolio_id가 ReconcileWarningStore에 warned 상태일 때, When buy intent가 제출되면, Then status=`rejected`, reason=`reconcile_warned`가 반환된다(전략 진입 차단).
|
||||
2. Given 슬롯의 portfolio_id가 ReconcileWarningStore에 warned 상태일 때, When sell intent가 제출되면(외부 전략 경로), Then status=`rejected`, reason=`reconcile_warned`가 반환된다(전략 매도 차단). **단, safety-sell / kill-switch / watchdog의 내부 안전망 매도 경로는 이 차단을 받지 않으며 정상 실행되어야 한다(OQ-B 확정, 차단 예외).**
|
||||
3. Given pause도 reconcile-warning도 없는 정상 슬롯에서, When buy/sell intent가 제출되면, Then 기존 admission 로직이 그대로 동작한다(오발동 없음).
|
||||
4. Given pause만 있는 슬롯에서, When slots RPC가 호출되면, Then `paused=True`, `reconcile_warned=False` 필드가 반환된다(기존 paused 동작 불변).
|
||||
5. Given reconcile-warning만 있는 슬롯에서, When slots RPC가 호출되면, Then `paused=False`, `reconcile_warned=True` 필드가 반환된다.
|
||||
6. Given pause와 reconcile-warning이 모두 있는 슬롯에서, When slots RPC가 호출되면, Then `paused=True`, `reconcile_warned=True`가 모두 반환된다.
|
||||
7. Given ReconcileWarningStore가 주입되지 않은 구성에서, When slots RPC가 호출되면, Then `reconcile_warned=False`(또는 필드 부재 시 기본값)로 반환되어 기존 클라이언트가 깨지지 않는다(하위 호환).
|
||||
8. Given 기존 `warned` 필드(슬롯 qty ≠ hub asset_quantity 로컬 계산), When 신규 필드가 추가돼도, Then `warned` 필드 정의와 동작이 변경되지 않는다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: `docs/interface-contract.md` (slots RPC 응답 스키마 `reconcile_warned` 필드 추가 명시)
|
||||
- Modules:
|
||||
- `trex_core/application/portfolio.py` (`slot_to_dict` — `reconcile_warned` 필드 추가)
|
||||
- `trex_core/application/intents.py` (`IntentService._admit_buy`, `_admit_sell` — reconcile-warning 게이트 추가)
|
||||
- `trex_core/application/messaging_handlers.py` (`make_slots_rpc_handler` — ReconcileWarningStore 주입 파라미터 추가)
|
||||
- `trex_core/runtime/daemon.py` (ReconcileWarningStore 주입 배선)
|
||||
- Tests:
|
||||
- `tests/application/test_intents.py` (reconcile_warned 차단 시나리오, 정상 슬롯 오발동 없음)
|
||||
- `tests/application/test_messaging_handlers.py` (slots RPC reconcile_warned 필드 노출)
|
||||
- `tests/application/test_portfolio.py` (`slot_to_dict` reconcile_warned 필드 검증)
|
||||
|
||||
## Notes
|
||||
- **safety-sell / kill-switch / watchdog 차단 예외(OQ-B 확정)**: 내부 안전망(safety-sell REQ-037~039, kill-switch REQ-045, watchdog REQ-034) 경로는 reconcile-warning 차단 예외다. 집행 수량 정본은 브로커 잔고(`execution.py`)이므로 안전망은 수량 오류에 안전하며, 차단하면 포지션이 무보호로 방치된다. 이 경로들은 `IntentService._admit_*` 게이트를 거치지 않는 별도 내부 호출 경로를 사용하므로 구조적으로 차단을 우회한다. batch design에서 경로 분리 구조를 명시적으로 확인한다.
|
||||
- `reconcile_warned` 필드는 `slot_to_dict` 단에서 `ReconcileWarningStore.is_warned(slot_id)` 또는 `slot_id in list_warned()` 조회로 산출한다. batch design에서 성능(N+1) 고려해 bulk 조회 방식 선택.
|
||||
- AMQP wire 계약 변경 사항: `trex.slots.req` 응답 행에 `reconcile_warned: bool` 필드 additive 추가. trex-orb-v1·trex-tsl-v1이 이 필드를 무시해도 하위 호환이 유지되는지 batch design에서 확인 필요.
|
||||
- dcy-034 FR-2, NFR-4 대응.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260626-01
|
||||
- Date: 2026-06-26
|
||||
- Author: trex-core-dev
|
||||
- Status: Approved → Implemented
|
||||
- Summary: BAT-050(PR #31, ced7eda) origin/main 머지 완료. QC(opus) PASS + 팀장 confirm-batch-verification. pause∨reconcile-warning OR 게이트, 안전망 우회(OQ-B), slots RPC reconcile_warned 필드, 전 AC 검증 완료.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: BAT-050 (core-A)
|
||||
- Releases: M3 (배포 대기)
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Implemented
|
||||
- Follow-up Action: 없음.
|
||||
|
||||
#### Validation Plan
|
||||
- BAT-050 verification.md AC 매핑 전항목 PASS 확인됨.
|
||||
|
||||
### CHG-20260625-02
|
||||
- Date: 2026-06-25
|
||||
- Author: trex-core-dev
|
||||
|
||||
#### Change Summary
|
||||
- REQ-104 **Proposed → Approved** (confirm-req, 팀장 2026-06-25).
|
||||
- OQ-B 결정 반영: reconcile-warning 차단 범위 = 외부 전략 intent/read 전용. 내부 안전망(safety-sell/watchdog/kill-switch)은 차단 예외로 확정. AC-2에 예외 명시.
|
||||
- Intent, Requirement, Notes에 OQ-B 결정 근거(집행 수량 정본=브로커, 차단 시 포지션 무보호) 추가.
|
||||
|
||||
#### Intent
|
||||
- 팀장 confirm-req 결정(OQ-B 차단 예외 확정)을 REQ에 반영.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 없음.
|
||||
- Updated: AC-2(safety-sell/kill-switch/watchdog 차단 예외 명시).
|
||||
- Removed: 없음.
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Notes: 안전망 경로 차단 예외 설계 원칙 구체화.
|
||||
- Modules: `intents.py` — 차단 게이트가 외부 전략 intent 경로에만 적용됨을 구현 시 명시.
|
||||
- Tests: safety-sell/kill-switch가 reconcile-warning 슬롯에서도 실행됨을 확인하는 테스트 추가 필요.
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: 미정 (suggest-batch-reqs 이후)
|
||||
- Releases: 미정
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Approved
|
||||
- Follow-up Action: batch design에서 안전망 경로 분리 구조 명시 확인.
|
||||
|
||||
#### Validation Plan
|
||||
- 외부 intent reconcile_warned 차단 테스트 pass / safety-sell 차단 우회 테스트 pass / slots RPC reconcile_warned 필드 반환 테스트 pass / 기존 paused/warned 동작 회귀 pass.
|
||||
|
||||
### CHG-20260625-01
|
||||
- Date: 2026-06-25
|
||||
- Author: trex-core-dev
|
||||
|
||||
#### Change Summary
|
||||
- REQ-104 신규 생성 (Proposed) — dcy-034 FR-2 대응, draft-req 단계.
|
||||
|
||||
#### Intent
|
||||
- pause 단독 게이트를 pause ∨ reconcile-warning OR 게이트로 확장해 자동 차단 채널을 활성화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: AC-1~8 전부 신규.
|
||||
- Updated: 없음.
|
||||
- Removed: 없음.
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: interface-contract.md 갱신 예정.
|
||||
- Modules: portfolio.py, intents.py, messaging_handlers.py.
|
||||
- Tests: 신규 게이트 테스트.
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: 미정
|
||||
- Releases: 미정
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no (신규 REQ)
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 후 wire 계약 영향 확인 포함 batch design.
|
||||
|
||||
#### Validation Plan
|
||||
- reconcile_warned 차단 및 정상 슬롯 오발동 없음 테스트 pass / slots RPC reconcile_warned 필드 반환 테스트 pass / 기존 paused/warned 동작 회귀 pass.
|
||||
@@ -1,148 +0,0 @@
|
||||
# req-105: trex-core sync 명령 — 슬롯 수량을 브로커에 맞춰 갱신 + warning 해제
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: trex-core-dev
|
||||
|
||||
## Intent
|
||||
- 운영자가 `trex-core sync` 명령으로 **브로커 잔고(정본)를 기준으로 대상 슬롯의 보유 수량을 갱신**(INACTIVE→HOLDING 전이 포함)하고, 갱신 후 브로커와 일치하면 해당 슬롯의 reconcile-warning을 자동 해제한다.
|
||||
- cold-start 시 실계좌에 이미 보유 중인 종목(B 케이스)의 슬롯 onboarding 경로이기도 하다.
|
||||
- dcy-034 FR-3, OQ-2/OQ-3 확정 반영: **브로커 잔고 정본 유지, 슬롯 qty ← 브로커**. 브로커에만 있고 portfolio-hub에 없는 종목(슬롯 부재)은 sync 대상 아님(자동 슬롯 생성 금지).
|
||||
- portfolio-hub WAC(보유 평단) read 엔드포인트(FR-7, portfolio-hub **dcy-008 / REQ-043** `GET /v1/portfolios/{id}/holdings/cost-basis`) 가용 시 슬롯 avg_price를 seed한다. 포트 미가용 또는 조회 실패 시 수량만 갱신하고 WARN 로그를 남긴다(graceful degrade).
|
||||
- **INACTIVE→HOLDING 전이 엣지 추가 승인(OQ-A)**: `ALLOWED_TRANSITIONS`에 `(INACTIVE, HOLDING)` 전이를 추가한다. 이 전이는 **actor=sync 또는 reconcile/reconcile_sync로 제한**되며, 일반 전략 경로(INACTIVE→PENDING_BUY→HOLDING)는 유지된다. transition_log reason은 `onboarding` 또는 `reconcile_sync`류로 식별 가능하게 기록한다. **wire 계약 무영향**: SlotState enum 상태값 5개(INACTIVE/PENDING_BUY/HOLDING/PENDING_SELL/ERROR) 불변, 전이 엣지만 추가이므로 slots RPC 스키마·상태값 변화 없음.
|
||||
|
||||
## Requirement
|
||||
- 시스템은 `trex-core sync [--portfolio-id <pid> | --all]` 서브커맨드를 제공해야 한다.
|
||||
- sync는 portfolio-hub 유니버스에 있어 슬롯이 생성된 종목만 대상으로 한다. 브로커에만 있고 슬롯이 없는 종목은 sync가 건드리지 않고 unmanaged 경고를 로그에 남긴다(자동 슬롯 생성 금지).
|
||||
- sync 실행 시 대상 슬롯마다 브로커 잔고(`BrokerPort.get_balance()`)를 조회하여 슬롯 qty를 브로커 수량으로 갱신해야 한다. 브로커 수량 > 0이고 슬롯이 INACTIVE이면 **INACTIVE→HOLDING 전이(actor=sync, reason=onboarding/reconcile_sync)**를 수행해야 한다. 이 전이는 OQ-A 승인으로 `ALLOWED_TRANSITIONS`에 추가되는 새 엣지를 사용하며 일반 전략 진입 경로와 구분된다.
|
||||
- portfolio-hub WAC read 포트(FR-7: **portfolio-hub dcy-008 / REQ-043**, `GET /v1/portfolios/{id}/holdings/cost-basis`)가 연결되어 있으면, sync 시 보유 평단(WAC)을 읽어 슬롯 avg_price에 seed해야 한다. 포트가 없거나 조회 실패 시 avg_price seed를 건너뛰고 WARN 로그를 남긴다(graceful degrade).
|
||||
- sync 후 슬롯 qty == 브로커 수량이면 `ReconcileWarningStore.clear_warned(slot_id)`로 reconcile-warning을 해제해야 한다.
|
||||
- sync 실행 전 before 상태, 실행 후 after 상태(슬롯 qty, 브로커 qty, warning 해제 여부)를 출력해야 한다.
|
||||
- sync는 confirmation 프롬프트(`--yes` 스킵 가능)와 `--dry-run` 모드를 지원해야 한다. live 계좌에서는 `--yes --live` 이중 확인을 요구해야 한다.
|
||||
- sync는 직접-DB 경로(pause/resume 방식)로 구현하며, 데몬 RPC를 거치지 않는다.
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given cold-start 상태(슬롯 INACTIVE, 브로커 보유 qty > 0)에서 `trex-core sync --portfolio-id <pid>` 실행 시, When sync가 완료되면, Then 슬롯 qty = 브로커 qty이고 슬롯 상태가 HOLDING으로 전이되며 reconcile-warning이 해제된다(S-2, OQ-A 승인 전이).
|
||||
2. Given 슬롯 qty ≠ 브로커 qty인 B 케이스에서 sync 실행 시, When sync가 완료되면, Then 슬롯 qty = 브로커 qty로 갱신되고 reconcile-warning이 해제된다.
|
||||
3. Given 브로커에만 있고 슬롯이 없는 종목(슬롯 부재)에서 sync 실행 시, When sync가 실행되면, Then 슬롯이 자동 생성되지 않고 unmanaged 경고가 로그에 남는다.
|
||||
4. Given portfolio-hub WAC read 포트(portfolio-hub dcy-008 / REQ-043 `GET /v1/portfolios/{id}/holdings/cost-basis`)가 연결되어 있을 때, When sync를 실행하면, Then 슬롯 avg_price에 WAC 값이 seed된다.
|
||||
5. Given portfolio-hub WAC read 포트가 없거나 조회 실패 시, When sync를 실행하면, Then avg_price seed 없이 수량 갱신만 수행하고 WARN 로그를 남긴다(graceful degrade).
|
||||
6. Given `--dry-run` 플래그로 sync 실행 시, When 명령이 실행되면, Then 슬롯 qty 변경 없이 before/after 예상치만 출력된다.
|
||||
7. Given live 계좌에서 `--yes` 없이 sync 실행 시, When 명령이 실행되면, Then 오류 메시지와 함께 실행을 거부한다(live double-ack 게이트).
|
||||
8. Given sync 실행 후 슬롯 qty가 여전히 브로커 수량과 다를 경우(갱신 실패 등), When sync가 완료되면, Then reconcile-warning이 해제되지 않는다.
|
||||
9. Given `--all` 플래그로 sync 실행 시, When 명령이 실행되면, Then 인스턴스의 모든 B-warned 슬롯에 대해 sync가 실행된다.
|
||||
10. Given INACTIVE→HOLDING 전이 시, When transition_log 또는 로그를 확인하면, Then actor 및 reason 필드에 sync/onboarding(또는 reconcile_sync)이 기록되어 일반 전략 진입 경로(INACTIVE→PENDING_BUY)와 구분된다(OQ-A actor 식별).
|
||||
|
||||
## Impacted Area
|
||||
- Docs: `docs/operations.md` (cold-start onboarding 절차 신설), `docs/runtime-flows.md` (sync 흐름 추가)
|
||||
- Modules:
|
||||
- `trex_core/runtime/cli.py` (`sync` 서브커맨드 추가, `_build_parser`, `_cmd_sync`)
|
||||
- `trex_core/application/reconciliation.py` (sync 로직 또는 별도 `sync_slot_to_broker` 함수 — batch design에서 결정)
|
||||
- `trex_core/application/ports.py` 또는 `application/portfolio.py` (WAC read 포트 의존 명시)
|
||||
- `trex_core/adapters/portfolio/` (WAC read 어댑터 — portfolio-hub FR-7 REQ 선행 의존)
|
||||
- Tests:
|
||||
- `tests/application/test_sync.py` 또는 `tests/integration/test_sync.py` (cold-start onboarding, warning 해제, unmanaged 슬롯 처리, dry-run, WAC seed 유무)
|
||||
- `tests/runtime/test_cli.py` (sync 서브커맨드 인수 파싱, 확인 프롬프트, live double-ack)
|
||||
|
||||
## Notes
|
||||
- **FR-7 의존 구체화(OQ-A 팀장 결정)**: portfolio-hub WAC read 엔드포인트는 **portfolio-hub dcy-008 / REQ-043**, `GET /v1/portfolios/{id}/holdings/cost-basis`. 2026-06-25 confirm-discovery 완료. 가용 시 avg_price seed, 미가용/실패 시 수량만 갱신 + WARN(graceful degrade). 구현 시 portfolio-hub REQ-043 완료 여부 확인 필요.
|
||||
- **INACTIVE→HOLDING 전이 엣지 추가(OQ-A 팀장 승인)**: `state.py:ALLOWED_TRANSITIONS`에 `(INACTIVE, HOLDING)` 엣지 추가가 승인되었다. 이 전이는 **actor=sync 또는 reconcile로 제한**되며 일반 전략 경로(INACTIVE→PENDING_BUY→HOLDING)는 유지된다. transition_log reason은 `onboarding` 또는 `reconcile_sync`류로 식별. **wire 무영향**: SlotState enum 5개(inactive/pending_buy/holding/pending_sell/error) 불변, 엣지만 추가이므로 slots RPC 스키마·상태값 변화 없음. batch design에서 `_BASE_TRANSITIONS` 확장 또는 별도 `_SYNC_TRANSITIONS` 집합 구성을 결정한다.
|
||||
- sync 대상 슬롯 결정 방법(portfolio_id 명시 vs all warned 슬롯 vs all INACTIVE 슬롯)은 batch design에서 구체화.
|
||||
- dcy-034 FR-3, OQ-2/3, OQ-A(팀장 2026-06-25 confirm), R-1 대응.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260626-01
|
||||
- Date: 2026-06-26
|
||||
- Author: trex-core-dev
|
||||
- Status: Approved → Implemented
|
||||
- Summary: BAT-051(PR #32, 07b393d) origin/main 머지 완료. QC(opus) PASS + 팀장 confirm-batch-verification. sync CLI(--portfolio-id/--all/--dry-run/--live), INACTIVE→HOLDING 전이, WAC seed, warning 해제, 전 AC 검증 완료.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: BAT-051 (core-B)
|
||||
- Releases: M3 (배포 대기)
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Implemented
|
||||
- Follow-up Action: M3 배포 시 cold-start 운영 검증.
|
||||
|
||||
#### Validation Plan
|
||||
- BAT-051 verification.md AC 매핑 전항목 PASS 확인됨.
|
||||
|
||||
### CHG-20260625-02
|
||||
- Date: 2026-06-25
|
||||
- Author: trex-core-dev
|
||||
|
||||
#### Change Summary
|
||||
- REQ-105 **Proposed → Approved** (confirm-req, 팀장 2026-06-25).
|
||||
- OQ-A 결정 반영: INACTIVE→HOLDING 전이 엣지 추가 승인(actor=sync/reconcile 제한, wire 무영향 명시).
|
||||
- FR-7 의존 구체화: portfolio-hub dcy-008 / REQ-043 (`GET /v1/portfolios/{id}/holdings/cost-basis`) 로 참조 갱신.
|
||||
- AC-10 신규 추가(전이 actor 식별).
|
||||
|
||||
#### Intent
|
||||
- 팀장 confirm-req 결정(OQ-A 승인 + FR-7 참조 구체화)을 REQ에 반영.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: AC-10 신규(INACTIVE→HOLDING 전이 actor/reason 식별).
|
||||
- Updated: AC-1(OQ-A 전이 명시), AC-4(FR-7 참조 구체화), AC-5(graceful degrade 명시).
|
||||
- Removed: 없음.
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Notes: FR-7 참조 및 전이 엣지 추가 내용 구체화.
|
||||
- Modules: `trex_core/domain/slot/state.py` — `ALLOWED_TRANSITIONS`에 `(INACTIVE, HOLDING)` 엣지 추가 필요(batch implementation 단계).
|
||||
- Tests: AC-10 actor 식별 테스트 신규.
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: 미정 (suggest-batch-reqs 이후)
|
||||
- Releases: 미정
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Approved
|
||||
- Follow-up Action: batch design에서 state.py 전이 집합 확장 방식 결정 및 actor 제한 구현 방안 확정.
|
||||
|
||||
#### Validation Plan
|
||||
- cold-start onboarding 시나리오 테스트 pass / INACTIVE→HOLDING 전이 actor 식별 테스트 pass / warning 해제 확인 / unmanaged 슬롯 자동 생성 없음 테스트 pass / FR-7 graceful degrade 테스트 pass.
|
||||
|
||||
### CHG-20260625-01
|
||||
- Date: 2026-06-25
|
||||
- Author: trex-core-dev
|
||||
|
||||
#### Change Summary
|
||||
- REQ-105 신규 생성 (Proposed) — dcy-034 FR-3 대응, draft-req 단계.
|
||||
|
||||
#### Intent
|
||||
- cold-start 시 운영자가 안전하게 슬롯을 브로커에 맞춰 onboarding하는 표준 CLI 경로 신설.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: AC-1~9 전부 신규.
|
||||
- Updated: 없음.
|
||||
- Removed: 없음.
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: operations.md 신설, runtime-flows.md 갱신.
|
||||
- Modules: cli.py, reconciliation.py.
|
||||
- Tests: sync 통합 테스트 신규.
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: 미정
|
||||
- Releases: 미정
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no (신규 REQ)
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: INACTIVE→HOLDING 전이표 추가 여부 팀장 확인 후 batch design 진행.
|
||||
|
||||
#### Validation Plan
|
||||
- cold-start onboarding 시나리오 테스트 pass / warning 해제 확인 / unmanaged 슬롯 자동 생성 없음 테스트 pass.
|
||||
@@ -1,167 +0,0 @@
|
||||
# req-106: trex-core verify 명령 — C 불일치 슬롯 재대조 + warning 해제
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: trex-core-dev
|
||||
|
||||
## Intent
|
||||
- 운영자가 portfolio-hub CLI로 원장을 정정한 뒤 `trex-core verify [--portfolio-id <pid>]` 명령으로 **C 불일치(원장↔슬롯) 차단 슬롯을 재대조**하여, 일치 시 warning을 해제하고 불일치 시 사유와 함께 해제를 거부한다.
|
||||
- dcy-034 FR-4, OQ-2/5, **OQ-C 확정** 반영: read-중심 명령(슬롯 수량 변경 없음), 강제 해제(force-clear) 없음.
|
||||
- 재대조 로직은 현행 `reconcile_positions`(브로커 경유 2-대조)를 재사용한다(OQ-5).
|
||||
- **verify는 C 케이스(원장↔슬롯 수량 불일치) 전용**이다. B 케이스(슬롯↔브로커 수량 불일치)는 sync 명령(REQ-105)이 해소 경로이며 verify 범위에 포함되지 않는다(OQ-C 확정).
|
||||
|
||||
## Requirement
|
||||
- 시스템은 `trex-core verify [--portfolio-id <pid>]` 서브커맨드를 제공해야 한다.
|
||||
- verify는 대상 슬롯(portfolio_id 기반)에 대해 `reconcile_positions`를 다시 실행해(브로커=정본, 원장↔브로커 대조) 일치 여부를 판정해야 한다.
|
||||
- 대조 결과 일치(원장 수량 == 브로커 수량)이면 `ReconcileWarningStore.clear_warned(slot_id)` 로 reconcile-warning을 해제하고 "해제됨" 메시지를 출력해야 한다.
|
||||
- 대조 결과 불일치이면 warning을 해제하지 않고 불일치 사유(원장 수량, 브로커 수량, 차이)를 출력하고 비-0 종료코드를 반환해야 한다(강제 해제 경로 없음).
|
||||
- verify는 슬롯 qty를 변경하지 않는다(read-중심 — 슬롯 수량 변경 없음).
|
||||
- verify는 C 케이스(case_code='C')로 warned된 슬롯만을 대상으로 한다. **B 케이스(슬롯↔브로커 수량 불일치)에 대한 해소는 sync 명령(REQ-105) 책임이며, verify는 B 케이스에 적용하지 않는다(OQ-C 확정, C 전용).**
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given C 불일치로 차단된 슬롯에서 운영자가 portfolio-hub CLI로 원장을 정정하고 `trex-core verify --portfolio-id <pid>` 실행 시, When 원장 수량 == 브로커 수량이면, Then reconcile-warning이 해제되고 "해제됨" 메시지가 출력된다(S-3 1차).
|
||||
2. Given C 불일치로 차단된 슬롯에서 `trex-core verify` 실행 시, When 원장 수량 ≠ 브로커 수량이면, Then reconcile-warning이 해제되지 않고 불일치 사유(원장qty, 브로커qty, 차이)가 출력되며 비-0 종료코드를 반환한다(S-3 2차, 강제 해제 없음).
|
||||
3. Given verify 실행 시, When 어떤 경우에도, Then 슬롯 qty가 변경되지 않는다(read-중심 불변식).
|
||||
4. Given reconcile-warning이 없는 슬롯에 대해 verify 실행 시, When 명령이 실행되면, Then 이미 해제 상태임을 알리는 메시지 출력 후 0 종료코드로 반환한다(idempotent).
|
||||
5. Given `--json` 플래그로 verify 실행 시, When 명령이 실행되면, Then `{portfolio_id, slot_id, result: "cleared"|"rejected", hub_qty, broker_qty, reason?}` JSON이 stdout에 출력된다.
|
||||
6. Given `trex-core verify` (--portfolio-id 없이) 실행 시, When 명령이 실행되면, Then 인스턴스의 모든 C-warned 슬롯에 대해 재대조를 수행하고 결과를 슬롯별로 출력한다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs: `docs/operations.md` (원장 정정 후 verify 절차 추가), `docs/runtime-flows.md` (verify 흐름 추가)
|
||||
- Modules:
|
||||
- `trex_core/runtime/cli.py` (`verify` 서브커맨드 추가)
|
||||
- `trex_core/application/reconciliation.py` (`reconcile_positions` 재사용 또는 호출 래퍼 — batch design에서 결정)
|
||||
- Tests:
|
||||
- `tests/runtime/test_cli.py` (verify 서브커맨드 인수 파싱)
|
||||
- `tests/application/test_verify.py` 또는 `tests/integration/test_verify.py` (일치→해제, 불일치→거부, read-중심 불변식, idempotent)
|
||||
|
||||
## Notes
|
||||
- OQ-5 확정: verify의 재대조는 `reconcile_positions`(원장↔브로커 2-대조, 브로커=정본)를 재사용한다. 별도 대조 로직을 만들지 않는다.
|
||||
- verify는 read-중심이므로 pause/resume의 live double-ack 게이트는 불필요하다. --yes, --live 옵션이 필요 없다.
|
||||
- **OQ-C 확정: verify는 C 전용**. B 케이스(슬롯↔브로커 수량 불일치)는 sync(REQ-105)로 해소한다. verify가 B-warned 슬롯 ID로 호출되면 "C 케이스 대상 아님" 안내 후 0 종료코드를 반환한다(batch design에서 메시지 확정).
|
||||
- dcy-034 FR-4, OQ-2/5, OQ-C(팀장 2026-06-25 confirm), S-3 대응.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260630-01
|
||||
- Date: 2026-06-30
|
||||
- Author: 팀장(Claude) — change-req (라이브 릴리즈 핫픽스 + postmortem)
|
||||
|
||||
#### Change Summary
|
||||
- **REL-010 STEP2 배포 스모크서 `trex-core verify` ImportError 핫픽스.** Status `Implemented` 유지(구현 결함 수정, AC 불변).
|
||||
|
||||
#### Intent / 증상·근본원인 (핫픽스 예외 경로)
|
||||
- **증상**: 운영 배포(`ababf80`) 후 `trex-core verify --config ... --portfolio-id ...` 실행 시 `ImportError: cannot import name 'make_broker' from 'trex_core.adapters.broker'`.
|
||||
- **근본원인**: `runtime/cli.py` `_cmd_verify()`가 **코드베이스에 존재하지 않는** `trex_core.adapters.broker.make_broker`를 import(정의 0건, 참조는 verify 한 곳뿐). 형제 명령 `_cmd_sync()`는 올바르게 `trex_core.runtime.daemon._build_broker`를 사용. → verify 경로에만 잘못된 import가 박혀 있었음.
|
||||
- **수정**: `_cmd_verify`를 `from trex_core.runtime.daemon import _build_broker` / `_build_broker(cfg)`로 교체(sync와 동일, 검증된 경로). 커밋 `51cc3cc`.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added/Updated/Removed: 없음 (기존 AC 동일 — 깨진 구현을 정정)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- 핫픽스 커밋 `51cc3cc`(main 직접, fast-path). 회귀 테스트 2종 추가(`tests/runtime/test_cli_operator.py`): `test_verify_cmd_broker_import_does_not_raise`(paper config+DB stub로 verify 경로 import 통과 검증), `test_verify_cmd_uses_build_broker_not_make_broker`(make_broker 심볼 부재 구조검증).
|
||||
|
||||
#### Verification
|
||||
- 전체 스위트 747 passed / 47 skipped / 0 failed(회귀 0). **운영 재검증(2026-06-30, `51cc3cc`)**: verify OK(slot already cleared) · sync --dry-run OK(broker_qty_zero guard SKIP) · report OK.
|
||||
|
||||
#### Postmortem (테스트 갭)
|
||||
- **왜 미검출**: BAT-051 verification이 verify의 **broker import 경로를 런타임 실행하지 않음**(import가 함수 내부라 호출 시에만 트리거). 단위 테스트가 verify 명령을 끝까지 돌리지 않아 phantom import가 통과됨.
|
||||
- **재발 방지**: 위 회귀 테스트 2종으로 import 경로를 실제 실행/구조검증. 후속 권고 — operator CLI 명령들의 lazy import를 스모크 수준으로 한 번씩 실행하는 테스트 추가 검토.
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no (회귀테스트+운영 재검증 완료) / Existing Implementation Invalidated: no
|
||||
- Status Recommendation: implemented
|
||||
- Rollback: `git revert 51cc3cc` (CLI 전용, trading/wire/daemon 무관 — 실행 중 데몬 무영향).
|
||||
- ⚠️ 거버넌스 노트: 라이브 블로커 해소를 위해 **main 직접 푸시**(사전 결재 게이트 절차 생략) — 사장님 사후 추인.
|
||||
|
||||
### CHG-20260626-01
|
||||
- Date: 2026-06-26
|
||||
- Author: trex-core-dev
|
||||
- Status: Approved → Implemented
|
||||
- Summary: BAT-051(PR #32, 07b393d) origin/main 머지 완료. QC(opus) PASS + 팀장 confirm-batch-verification. verify CLI(--portfolio-id/--json), C케이스 재대조+warning 해제, B케이스 거부+sync 안내, 전 AC 검증 완료.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: BAT-051 (core-B)
|
||||
- Releases: M3 (배포 대기)
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Implemented
|
||||
- Follow-up Action: 없음.
|
||||
|
||||
#### Validation Plan
|
||||
- BAT-051 verification.md AC 매핑 전항목 PASS 확인됨.
|
||||
|
||||
### CHG-20260625-02
|
||||
- Date: 2026-06-25
|
||||
- Author: trex-core-dev
|
||||
|
||||
#### Change Summary
|
||||
- REQ-106 **Proposed → Approved** (confirm-req, 팀장 2026-06-25).
|
||||
- OQ-C 결정 반영: verify = C 케이스(원장↔슬롯) 전용 확정. B 케이스는 sync(REQ-105) 책임. Intent, Requirement, Notes에 "C 전용, B는 sync 책임" 명시.
|
||||
|
||||
#### Intent
|
||||
- 팀장 confirm-req 결정(OQ-C 확정: verify는 C 전용)을 REQ에 반영.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 없음.
|
||||
- Updated: 없음(기존 AC는 이미 C 케이스 중심으로 작성됨).
|
||||
- Removed: 없음.
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Notes: OQ-C 확정 및 B-warned 슬롯 호출 시 처리 방침 추가.
|
||||
- Modules: cli.py verify 서브커맨드 — B-warned 슬롯 필터링 로직 추가 필요.
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: 미정 (suggest-batch-reqs 이후)
|
||||
- Releases: 미정
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Approved
|
||||
- Follow-up Action: batch design에서 B-warned 슬롯 필터링 메시지 확정.
|
||||
|
||||
#### Validation Plan
|
||||
- 일치→해제, 불일치→거부 시나리오(C 케이스) 테스트 pass / B-warned 슬롯에 verify 적용 시 "대상 아님" 처리 테스트 pass / 슬롯 qty 불변 검증 / 기존 reconcile_positions 회귀 pass.
|
||||
|
||||
### CHG-20260625-01
|
||||
- Date: 2026-06-25
|
||||
- Author: trex-core-dev
|
||||
|
||||
#### Change Summary
|
||||
- REQ-106 신규 생성 (Proposed) — dcy-034 FR-4 대응, draft-req 단계.
|
||||
|
||||
#### Intent
|
||||
- C 불일치 차단 해소를 위한 운영자 read-중심 재대조 경로 신설. 강제 해제 없이 재대조 일치 시에만 차단 해제.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: AC-1~6 전부 신규.
|
||||
- Updated: 없음.
|
||||
- Removed: 없음.
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: operations.md, runtime-flows.md 갱신.
|
||||
- Modules: cli.py, reconciliation.py.
|
||||
- Tests: verify 시나리오 테스트 신규.
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: 미정
|
||||
- Releases: 미정
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no (신규 REQ)
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 후 batch design.
|
||||
|
||||
#### Validation Plan
|
||||
- 일치→해제, 불일치→거부 시나리오 테스트 pass / 슬롯 qty 불변 검증 / 기존 reconcile_positions 회귀 pass.
|
||||
@@ -1,150 +0,0 @@
|
||||
# req-110: 운영 리포트 WAC 실현손익 통합 — 전 인스턴스 공통
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: trex-core-dev
|
||||
- Approved By: 팀장 (Claude), 2026-06-26 (confirm-req)
|
||||
|
||||
## Intent
|
||||
- 현재 `operator_report.py`(REQ-088)의 `realized_pnl(trades)`은 당일 net 현금흐름(`Σ매도대금 − Σ매수대금 − 수수료 − 세금`)을 사용한다. 중장기 인스턴스에서 전일 매수→당일 매도 시 cost basis가 반영되지 않아 실현손익이 왜곡된다. portfolio-hub WAC API(`/pnl/realized`)를 소비해 전 인스턴스 공통으로 정확한 실현손익을 산출하고 리포트에 표시한다. (dcy-035 FR-2, FR-3, FR-4, OQ-1=전 인스턴스 WAC 통일, NFR-2)
|
||||
|
||||
## Requirement
|
||||
- `operator_report.py`의 `OperatorReport`에 WAC 실현손익 관련 필드를 추가한다: `realized_pnl_wac: float`, `realized_pnl_wac_by_asset: dict[str, float]`, `data_completeness_warning: bool`. (CHG-20260626-02: `buy_fee_only_assets` 필드 제거 — 아래 매수 fee 편입 결정 반영.)
|
||||
- 운영 리포트(`trex-core report` CLI)는 당일 net 대신 portfolio-hub WAC 실현손익(`/pnl/realized`)을 **전 인스턴스 공통**으로 사용해 실현손익을 표시한다.
|
||||
- 매도가 있는 자산: WAC 기준 실현손익(`(매도가 − WAC) × qty − fee − tax`)을 자산별로 분해해 출력한다. portfolio-hub WAC는 **매수 수수료를 cost basis에 편입**(REQ-041 CHG-20260626-01)하므로 이 실현손익은 매수·매도 fee를 모두 정확히 반영한다.
|
||||
- 매수만 한 기간(해당 자산의 매도 0): 실현손익 0으로 표시한다. **매수 수수료는 cost basis(WAC)에 편입되어 매도 시 실현**되므로, 별도 "수수료 비용" 라인은 두지 않는다(CHG-20260626-02 — 별도 라인은 매도 시 실현분과 이중계상되어 제거).
|
||||
- portfolio-hub 응답의 `data_completeness_warning: true` 시 리포트 출력에 경고를 표면화한다(텍스트/JSON 모두 포함).
|
||||
- `render_text` / `render_json`을 WAC 모드에 맞게 갱신한다.
|
||||
- CLI `report` 서브커맨드에서 portfolio-hub 설정(`cfg.portfolio_hub.base_url`)이 있을 때 WAC 경로를 사용하고, 미설정이면 REQ-111 degrade 경로로 위임한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given 전일 매수 + 당일 매도 시나리오(portfolio-hub `/pnl/realized` 모킹 응답), When `report` 실행, Then 실현손익이 WAC 기준 정확값(`(매도가 − WAC) × qty − fee − tax`)으로 표시되고 당일 net 왜곡값과 다르다.
|
||||
2. Given 동일 날 **닫힌** 매수+매도(일중, buy_qty==sell_qty) 시나리오, When `report` 실행, Then WAC 실현손익이 기존 당일 net과 **정확히 일치**한다(`==`, NFR-2 회귀 보장). (CHG-20260626-02: 매수 fee 편입(REQ-041)으로 일중 닫힌 거래는 WAC==net이 엄격 성립 — `≈`가 아니라 `==`로 단언.)
|
||||
3. Given 매수만 한 기간(매도 0), When `report` 실행, Then 실현손익 0으로 표시되고 별도 수수료 비용 라인은 없다(매수 fee는 cost basis 편입, 매도 시 실현). (CHG-20260626-02: 기존 `buy_fee_only_assets` 별도 라인 제거.)
|
||||
4. Given portfolio-hub 응답에 `data_completeness_warning: true`, When `report` 실행, Then 텍스트 출력과 `--json` 출력 모두에 completeness 경고가 표시된다.
|
||||
5. Given 자산별 실현손익 분해, When `report` 실행, Then `realized_pnl_wac_by_asset`에 자산(symbol)별 WAC 실현손익이 분해된다.
|
||||
6. Given `--json` 플래그, When `report` 실행, Then `render_json` 출력에 `realized_pnl_wac`, `realized_pnl_wac_by_asset`, `data_completeness_warning` 필드가 포함된다. (CHG-20260626-02: `buy_fee_only_assets` 제거.)
|
||||
7. Given portfolio-hub `base_url` 미설정(cfg.portfolio_hub None 또는 base_url 미정의), When `report` 실행, Then REQ-111 degrade 경로로 처리된다(에러 표시).
|
||||
|
||||
## Impacted Area
|
||||
- Docs:
|
||||
- `docs/operations.md` — 리포트 실현손익 정의 갱신(당일 net → WAC 기준, 매수일 수수료 표시 명시)
|
||||
- `docs/runtime-flows.md` — operator report 흐름에 portfolio-hub WAC 호출 경로 추가
|
||||
- Modules:
|
||||
- `trex_core/application/operator_report.py` — `OperatorReport` 필드 확장, 기존 `realized_pnl(trades)` 함수는 legacy/테스트 목적 유지(NFR-2 회귀 비교용), WAC 모드 신규 함수/빌더, `render_text`/`render_json` 갱신
|
||||
- `trex_core/runtime/cli.py` — `_cmd_report` 내 portfolio-hub WAC 호출 분기, `from_dt`/`to_dt` 파라미터 전달 (OQ-2 deferred: 기본값=오늘 KST 경계로 구현)
|
||||
- Tests:
|
||||
- 신규: 멀티데이 픽스처(전일 매수+당일 매도) 통합 테스트, 매수만 기간 테스트, data_completeness_warning 테스트, NFR-2 일중 회귀 단위 테스트
|
||||
- 기존 `test_operator_report.py` 회귀 (당일 net 함수 동작 보존)
|
||||
|
||||
## Notes
|
||||
- OQ-2(기간 모델): from_dt/to_dt는 오늘(KST 경계) 기본값으로 구현. 기간 범위 확장(지정 기간)은 design/팀장 결정 대기 → 기본 구현은 "당일 KST 매도 기준" 유지, `--from`/`--to` CLI 옵션 추가는 OQ-2 확정 후 별도 change-req 또는 design 인계.
|
||||
- OQ-3(수수료 출처): 매수만 한 날의 수수료는 `ledger_outbox` 당일 거래에서 집계(기존 경로 재사용). portfolio-hub 거래내역(REQ-039) 사용 여부는 design 인계.
|
||||
- OQ-4(N콜 vs 집계): 슬롯↔portfolio 1:1이므로 portfolio_id별 N콜이 기본 구현. 집계 최적화는 design 인계.
|
||||
- 기존 `realized_pnl(trades)` 함수는 삭제하지 않고 유지한다(NFR-2 회귀 비교, 기존 테스트 보존).
|
||||
- NFR-1(wire 계약 불변): report는 read-only 운영 표면 — slots RPC/AMQP 계약 무관. REQ 명시 불필요.
|
||||
- NFR-3(데몬 본업 격리): `_cmd_report`는 CLI 직접 실행 경로이며 데몬 루프와 무관 — 격리는 구조적으로 보장됨.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260626-03
|
||||
- Date: 2026-06-26
|
||||
- Author: trex-core-dev
|
||||
|
||||
#### Change Summary
|
||||
- BAT-052 구현·검증 완료(PR #33, 머지 커밋 81d06d9). confirm-batch-verification + confirm-req-implemented. Approved → Implemented.
|
||||
|
||||
#### Intent
|
||||
- dcy-035 FR-2/FR-3/FR-4 delivery 완료 확인 및 상태 전환.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Updated:
|
||||
- none (모든 AC-1~7 검증 완료, 상태 전환만)
|
||||
- Added:
|
||||
- none
|
||||
- Removed:
|
||||
- none
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: 없음
|
||||
- Modules: 변경 없음 (구현 완료 상태 유지)
|
||||
- Tests: 717 passed / 47 skipped / 0 fail (BAT-052 verification)
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- BAT-052 (verified, PR #33, 머지 커밋 81d06d9, 2026-06-26)
|
||||
- Releases:
|
||||
- none (M3 배포 대기)
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Implemented
|
||||
- Follow-up Action: none
|
||||
|
||||
### CHG-20260626-02
|
||||
- Date: 2026-06-26
|
||||
- Author: 팀장 (Claude)
|
||||
|
||||
#### Change Summary
|
||||
- 사장님 결정(2026-06-26): portfolio-hub WAC에 매수 수수료 편입(REQ-041 CHG-20260626-01). 그 결과 (1) 일중 닫힌 거래에서 WAC 실현손익 == 당일 net이 **엄격히** 성립 → AC-2를 `≈`에서 `==`로 강화. (2) 매수 fee가 cost basis에 편입되므로 매수전용일의 별도 "수수료 비용" 라인(`buy_fee_only_assets`)은 매도 시 실현분과 **이중계상** → 제거.
|
||||
|
||||
#### Intent
|
||||
- 매수 fee 편입 결정과 정합: 단일 정확 실현손익 숫자, NFR-2 엄격 성립, 이중계상 제거.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Updated:
|
||||
- AC-2: 일중 닫힌 거래 WAC==net **엄격 일치**(`==`)로 강화.
|
||||
- AC-3: 매수전용일 별도 수수료 비용 라인 제거(매수 fee는 cost basis 편입·매도 시 실현).
|
||||
- AC-6: `--json` 필드에서 `buy_fee_only_assets` 제거.
|
||||
- Removed:
|
||||
- `OperatorReport.buy_fee_only_assets` 필드 및 관련 산출/렌더.
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Modules: operator_report.py(buy_fee_only_assets 제거, NFR-2 테스트 강화), cli.py(해당 표시 제거)
|
||||
- Tests: NFR-2 일중 회귀 테스트를 `==` 단언으로 강화, buy_fee_only_assets 테스트 제거/대체
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: yes (BAT-052 보정 후 재검증)
|
||||
- Existing Implementation Invalidated: partial (BAT-052 구현 중 buy_fee_only_assets 부분)
|
||||
- Status Recommendation: keep-current (Approved)
|
||||
- Follow-up Action: BAT-052 보정 → 재QC → confirm-batch-verification
|
||||
|
||||
### CHG-20260626-01
|
||||
- Date: 2026-06-26
|
||||
- Author: trex-core-dev
|
||||
|
||||
#### Change Summary
|
||||
- dcy-035 FR-2/FR-3/FR-4, OQ-1(전 인스턴스 WAC 통일), NFR-2(일중 회귀)로부터 최초 생성(Proposed).
|
||||
|
||||
#### Intent
|
||||
- 중장기 인스턴스 실현손익 왜곡 해소 + 단기 회귀 보장 + 매수일 수수료 표시 + completeness 경고 표면화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- AC-1~7 신규
|
||||
- Updated:
|
||||
- none
|
||||
- Removed:
|
||||
- none
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- docs/operations.md, docs/runtime-flows.md
|
||||
- Modules:
|
||||
- operator_report.py 확장, cli.py _cmd_report 분기
|
||||
- Tests:
|
||||
- 신규 멀티데이/매수전용/completeness/NFR-2 테스트, 기존 회귀
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches:
|
||||
- none (미배치)
|
||||
- Releases:
|
||||
- none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 승인 게이트 후 suggest-batch-reqs
|
||||
@@ -1,144 +0,0 @@
|
||||
# req-116: `trex.slots.req` 전략 필드 노출 + `strategy` 요청 필터 (additive)
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: trex-core-dev
|
||||
|
||||
## Intent
|
||||
|
||||
- 신규 전략 데몬 trex-tvr-v1(TVR — Target-Value Rebalancing)이 `trex.slots.req` 응답 행에서 `strategy_name`·`strategy_params`·`markets` 를 읽어 자기 슬롯을 식별하고 리밸런싱 목표 비중(`target_weight` 등)을 파라미터로 수신해야 한다. 또한 `strategy="tvr_v1"` 요청 필터로 자기 전략 슬롯만 수신하려 한다.
|
||||
- REQ-074 AC-5 는 dcy-025 OQ-4 당시 결정을 유보한 것이었고, 본 REQ 는 그 additive 재도입(dcy-025 OQ-4 후속)이다. **기존 소비자(orb·tsl)에게 byte-동일 기본 동작을 보장**하면서 필드를 추가한다.
|
||||
- 근거: trex-tvr-v1 Discovery(dcy-001/dcy-002 v3 FR-8, confirmed) — portfolio-hub 측 `strategy_name`/`markets`/`strategy_params` 노출 REQ(①)가 선행 배포된 뒤 본 REQ(②)를 배포한다.
|
||||
|
||||
## Requirement
|
||||
|
||||
### 행 필드 추가 (additive — 기존 필드 불변)
|
||||
|
||||
- `slot_to_dict()`(application/portfolio.py)가 `SnapshotStore` 의 `PortfolioItem` 에서 아래 세 필드를 읽어 슬롯 행에 추가한다:
|
||||
- `strategy_name: str | null` — portfolio-hub `strategy_name`. PortfolioItem 에 없거나 빈 값이면 `null`.
|
||||
- `strategy_params: dict` — portfolio-hub `strategy_params` opaque dict. PortfolioItem 에 없으면 `{}`.
|
||||
- `markets: list[str]` — portfolio-hub `markets` 배열. PortfolioItem 에 없으면 `[]`.
|
||||
- 이 세 필드의 정본 출처는 portfolio-hub(SnapshotStore 경유)이다. hub 응답에 없으면 safe default(null/`{}`/`[]`)를 사용하고 데몬을 중단하지 않는다.
|
||||
- hub_read.py(`get_portfolios`) 가 portfolio-hub 응답에서 `strategy_name` 과 `markets` 를 파싱해 `PortfolioItem` 에 담는다. 구버전 hub 응답(미존재 키)에서는 각각 `None`/`[]` 로 safe-default 한다.
|
||||
- `PortfolioItem` 도메인 객체에 `strategy_name: Optional[str]` 과 `markets: list[str]` 필드를 추가한다.
|
||||
|
||||
### 요청 `strategy` 필터 추가 (additive — 기존 필터 불변)
|
||||
|
||||
- `trex.slots.req` 요청 payload 에 선택적 파라미터 `strategy: str` 을 추가한다.
|
||||
- 지정 시: `strategy_name == strategy` 인 슬롯 행만 반환한다. 대소문자 exact-match.
|
||||
- 미지정 시: 기존과 완전 동일(전체 반환).
|
||||
- `strategy` 필터는 기존 `filter`(status 필터) 와 **AND 조합**된다. 두 필터를 동시에 지정하면 status 조건과 strategy 조건 모두 만족하는 행만 반환한다.
|
||||
- `available_slots` 힌트는 `strategy` 필터 적용 여부와 **무관하게 인스턴스 전체 활성 슬롯 기준**으로 계산한다(capacity 의미 불변 — REQ-073 AC-6).
|
||||
|
||||
### interface-contract.md 갱신
|
||||
|
||||
- `trex.slots.req` 요청 payload 에 `strategy: str (optional)` 파라미터를 추가한다.
|
||||
- 응답 슬롯 행 스키마에 `strategy_name`·`strategy_params`·`markets` 필드와 정본 소스 테이블을 추가한다.
|
||||
- REQ-074 AC-5 주석("strategy 필드 없음")을 본 REQ 에 의한 additive 재도입으로 갱신한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. **행 필드 노출**: Given portfolio-hub 가 `strategy_name="tvr_v1"`, `strategy_params={"target_weight": 0.05}`, `markets=["KRX"]` 를 반환하는 환경에서, When `trex.slots.req` 조회, Then 해당 슬롯 행에 `strategy_name="tvr_v1"`, `strategy_params={"target_weight": 0.05}`, `markets=["KRX"]` 가 포함된다.
|
||||
|
||||
2. **hub 미제공 safe-default**: Given portfolio-hub 응답에 `strategy_name`·`markets` 키가 없는 구버전 응답 환경에서, When `trex.slots.req` 조회, Then 행의 `strategy_name=null`, `strategy_params={}`, `markets=[]` 이고 데몬이 중단되지 않는다.
|
||||
|
||||
3. **strategy 필터 — 매칭**: Given `strategy_name="tvr_v1"` 인 슬롯과 `strategy_name="orb_v1"` 인 슬롯이 공존하는 인스턴스에서, When `{strategy:"tvr_v1"}` 요청, Then `strategy_name="tvr_v1"` 인 슬롯 행만 반환된다.
|
||||
|
||||
4. **strategy 필터 — 미지정**: Given 동일 인스턴스에서, When `strategy` 없이 요청(기존 포맷), Then 모든 슬롯 행이 반환되고 응답 내용이 `strategy` 도입 전과 동일하다(기존 필드 불변 — 신규 필드만 추가).
|
||||
|
||||
5. **AND 조합**: Given `strategy_name="tvr_v1"` 인 holding 슬롯과 `strategy_name="tvr_v1"` 인 inactive 슬롯이 있는 환경에서, When `{filter:"holding", strategy:"tvr_v1"}` 요청, Then `strategy_name="tvr_v1"` + status `holding` 인 슬롯만 반환된다.
|
||||
|
||||
6. **available_slots 불변**: Given `max_active_slots=10`, 현재 active 3개인 인스턴스에서, When `{strategy:"tvr_v1"}` 요청(tvr_v1 슬롯이 1개뿐이라도), Then `available_slots=7`(인스턴스 전체 기준). strategy 필터가 available_slots 계산에 영향을 미치지 않는다.
|
||||
|
||||
7. **orb·tsl 회귀 없음**: Given 기존 orb-v1 또는 tsl-v1 소비자가 `strategy` 파라미터 없이 기존 요청 포맷을 전송하는 경우, When 처리, Then 응답 키 집합 및 기존 필드 값이 변경 전과 동일하다(신규 `strategy_name`·`strategy_params`·`markets` 필드 추가는 backward compatible — unknown 필드 무시 계약).
|
||||
|
||||
8. **계약 테스트 갱신**: Given 슬롯 계약 테스트(`EXPECTED_SLOT_FIELDS` 등)가 존재하는 경우, When 본 REQ 구현, Then 계약 테스트가 신규 필드를 포함하도록 갱신되고 통과한다.
|
||||
|
||||
## Impacted Area
|
||||
|
||||
- Docs:
|
||||
- `docs/interface-contract.md` — 요청 파라미터(`strategy` 추가) + 행 스키마(`strategy_name`·`strategy_params`·`markets` 추가) + 정본 소스 테이블 + REQ-074 AC-5 주석 갱신
|
||||
- Modules:
|
||||
- `trex_core/application/portfolio.py` — `PortfolioItem` 에 `strategy_name: Optional[str]`·`markets: list[str]` 필드 추가; `slot_to_dict()` 에서 SnapshotStore 의 `PortfolioItem` strategy 필드 읽기
|
||||
- `trex_core/adapters/portfolio/hub_read.py` — `get_portfolios()` 에서 `strategy_name`·`markets` 파싱 추가
|
||||
- `trex_core/application/messaging_handlers.py` — `make_slots_rpc_handler()` 에서 `strategy` 파라미터 파싱 + strategy 필터 적용(행 후처리 or slot_to_dict 이후 Python 필터)
|
||||
- Tests:
|
||||
- `tests/application/test_slots_handler.py` (또는 신규) — strategy 필터 AC-3/4/5, available_slots 불변 AC-6, 회귀 AC-7
|
||||
- `tests/application/test_slot_to_dict.py` (또는 기존 행 스키마 테스트) — strategy 필드 노출 AC-1/2
|
||||
- 슬롯 계약 테스트(`EXPECTED_SLOT_FIELDS` 등) — AC-8 갱신
|
||||
|
||||
## Notes
|
||||
|
||||
- **REQ-074 AC-5 와의 관계**: REQ-074 AC-5 는 dcy-025 OQ-4 당시 "전략↔자산 할당 모델 미확정" 사유로 strategy 필드 전체를 제외했다. 본 REQ 는 그 유보 결정을 additive 로 개정(OQ-4 후속 확정)하며, REQ-074 의 기존 AC(1~6) 는 불변이다. REQ-074 에 change-req 를 별도로 기록하지 않고 본 REQ Notes 에 관계를 명기하는 것으로 충분하다 — 이유: REQ-074 는 Implemented 상태이고 AC-5 의 "strategy 계열 제외" 불변식 자체를 파괴하지 않으며, 본 REQ 가 additive 재도입이라는 별도 REQ 근거를 남기는 것이 추적성 측면에서 더 명확하다. 단, 구현 batch 에서 REQ-074 CHG 항목으로도 참조를 남긴다.
|
||||
- **라이브 wire 계약 변경 — 고위험**: orb-v1·tsl-v1 이 현재 `trex.slots.req` 를 소비 중이다. 신규 필드는 additive(unknown 필드 무시)이므로 orb·tsl 파손 없음이 예상되나, 계약 테스트(AC-8)·회귀 테스트(AC-7) 필수. 구현은 worktree+PR+QC 정식 플로로 진행한다.
|
||||
- **배포 선행 조건**: portfolio-hub 측 `strategy_name`/`markets`/`strategy_params` 노출 REQ(①)가 배포된 뒤 본 REQ(②)를 배포한다. 선행 배포 전에는 safe-default(AC-2) 로 동작한다.
|
||||
- **`strategy` 필터 적용 위치**: `strategy_name` 은 SnapshotStore(in-memory) 에 있으므로 DB 레벨 필터가 아닌 Python 레벨 후처리 필터로 구현한다. status 필터(`list_slots(status_filter=...)`)가 먼저 DB 에서 실행되고, 그 결과에 strategy 필터를 Python 으로 적용한다. available_slots 는 필터 이전에 계산한다(AC-6).
|
||||
- **`strategy` 값 오타/미존재**: `strategy` 로 지정한 값에 매칭되는 슬롯이 없으면 빈 `slots=[]` 를 반환한다(에러 없음 — REQ-073 AC-2 의 unrecognized filter 처리 선례).
|
||||
- **`PortfolioItem.markets` 타입**: portfolio-hub 가 `markets: list[str]` 를 반환하지 않는 경우(None 또는 키 부재) `[]` 로 처리. `PortfolioItem.markets` 기본값 `field(default_factory=list)`.
|
||||
- **Open Question**: portfolio-hub 가 `strategy_name` 필드를 `active_strategy_id` 와 별도로 반환하는지, 아니면 `active_strategy_id` 를 `strategy_name` 의미로 사용하는지 portfolio-hub REQ(①) 확정 후 확인 필요. 구현 전에 portfolio-hub 응답 스키마를 검증한다. (현재 hub_read.py 는 `active_strategy_id` 를 파싱하지만 `strategy_name` 은 별도 필드일 수 있다.)
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260704-03
|
||||
- Date: 2026-07-04
|
||||
- Author: 팀장(Claude) — confirm-req-implemented
|
||||
|
||||
#### Change Summary
|
||||
- Approved → **Implemented**: bat-055 구현 완료. 독립 QC **opus 승격** PASS-WITH-NOTES(blocker 0) — 777 passed 일치, AC 8/8, ★watchdog 굶김 없음 실증 프로브 확인(필터는 응답에만 적용), 미지정 요청 byte-동일 검증. PR #37 사장님 결재·머지(dc6d7a9) = confirm-batch-verification 완료.
|
||||
- **배포 게이트**: portfolio-hub REQ-055(PR #20) 선행 배포 후 본 변경 배포(선행 전엔 safe-default 무해).
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: bat-055_20260704_slots-strategy-field-filter (merged, PR #37)
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no / Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Implemented
|
||||
|
||||
### CHG-20260704-02
|
||||
- Date: 2026-07-04
|
||||
- Author: 팀장(Claude) — confirm-req
|
||||
|
||||
#### Change Summary
|
||||
- Proposed → Approved: 팀장 검토·승인. tvr e2e 배관 ②(흘려주기). Notes의 오픈질문(strategy_name 별도 필드 여부)은 portfolio-hub REQ-055(Approved)가 `active_strategy_id`와 **별도 필드 `strategy_name`으로 확정** — 필드명 4종(active_strategy_id/strategy_name/strategy_params/markets) 상호 잠금. 라이브 wire 계약 변경이므로 구현은 worktree+PR+QC 정식 플로, 배포는 REQ-055 후.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added/Updated/Removed: 없음
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no / Existing Implementation Invalidated: no
|
||||
- Status Recommendation: Approved
|
||||
|
||||
### CHG-20260704-01
|
||||
- Date: 2026-07-04
|
||||
- Author: trex-core-dev
|
||||
|
||||
#### Change Summary
|
||||
- trex-tvr-v1 Discovery(dcy-001/dcy-002 v3 FR-8, confirmed)로부터 최초 생성(Proposed). `trex.slots.req` additive 확장 — 행 `strategy_name`·`strategy_params`·`markets` 필드 추가 + 요청 `strategy` 필터 추가. REQ-074 AC-5 additive 재도입(dcy-025 OQ-4 후속).
|
||||
|
||||
#### Intent
|
||||
- trex-tvr-v1 이 `strategy="tvr_v1"` 필터로 자기 슬롯만 수신하고 행의 `strategy_params.target_weight` 로 리밸런싱할 수 있도록 wire 계약을 확장.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- AC-1~8 신규
|
||||
- Updated: none
|
||||
- Removed: none
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: docs/interface-contract.md (요청·응답 스키마 갱신)
|
||||
- Modules: portfolio.py / hub_read.py / messaging_handlers.py
|
||||
- Tests: slots 핸들러·행 스키마·계약 테스트
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none (승인 후 draft-batch)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no (신규)
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current (Proposed)
|
||||
- Follow-up Action: confirm-req → suggest-batch-reqs → draft-batch
|
||||
|
||||
#### Validation Plan
|
||||
- 신규 batch: 행 필드 단언(AC-1/2), strategy 필터 단위(AC-3/4/5), available_slots 불변(AC-6), orb·tsl 회귀(AC-7), 계약 테스트 갱신(AC-8).
|
||||
Reference in New Issue
Block a user