feat(rel-007): dcy-025/024 + BAT-035/036 — slots.req 즉시 교체 + safety_sell_enabled
BAT-035 (dcy-025): trex.snapshot.req → trex.slots.req 즉시 교체
- topology: SNAPSHOT_REQ_QUEUE 제거, SLOTS_REQ_QUEUE = "trex.slots.req" 추가
- portfolio.py: View/build_snapshot_envelope/SnapshotEnvelope/_asset_to_dict 제거;
slot_to_dict 시그니처 확장(snapshot_store/watchdog_store/pause_store/watchdog_timeout_sec)
— asset_quantity(hub)/cash_balance/cash_estimated/warned/watchdog{}/paused 병합 (REQ-074)
- messaging_handlers.py: make_snapshot_rpc_handler 제거, make_slots_rpc_handler 추가
— filter(all/inactive/pending/holding/error) + spy(bool) 처리; strategy 필드 제외 (REQ-073/074)
- daemon.py: _snapshot_rpc_loop → _slots_rpc_loop, make_slots_rpc_handler 연결
- cli.py: universe/slots → slots_queue + spy=True + server-side filter; buyable→inactive 매핑 (REQ-063)
- rabbitmq.py: snapshot_queue → slots_queue
- docs: interface-contract.md + runtime-flows.md slots.req 계약으로 업데이트 (REQ-075)
- REQ-028: Implemented → Deprecated (코드 삭제 완료)
- 테스트: test_snapshot_handler/selection/rpc_watchdog/messaging_snapshot_consumer 삭제;
test_slots_handler.py(신규, 13 cases), test_killswitch_masking_resume 재작성,
test_ledger_option_d._apply_cash_estimate → slots handler 경유, test_topology/cli_operator 갱신
BAT-036 (dcy-024): per-instance safety_sell_enabled 플래그
- config.py: DaemonInstanceConfig + DaemonConfig 에 safety_sell_enabled: bool = True 추가;
from_toml 파싱, from_config 전파
- daemon.py: start() workers 조건부 — safety_sell_enabled=false 시 trex-safety-sell 미기동 + WARNING
- tests: test_instance_config.py 에 safety_sell_enabled 파싱 3개 케이스 추가
REQ: 073/074/075/021/034/063/048/005 Approved → Implemented
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
# 0. 문서 상태
|
||||
|
||||
- 상태: confirmed
|
||||
- 문서 ID: dcy-024_20260611_safety-sell-disable-mode
|
||||
- 이슈명: safety-sell 자율 청산 비활성화 모드 (issue #15)
|
||||
- 작성 시각(KST): 2026-06-11
|
||||
- 마지막 갱신 시각(KST): 2026-06-11 13:50 KST (change-req 진행: REQ-048 CHG-20260611-01(safety_sell_enabled TOML) + REQ-005 CHG-20260611-01(조건부 워커·기동 로그·runtime-flows), 둘 다 Implemented→Approved. 신규 REQ 없음(OQ-1).)
|
||||
- 대체됨: 없음
|
||||
- 후속 Discovery 참조: 없음
|
||||
- 생성된 REQ 참조: 없음 (change-req only, dcy-024 OQ-1). Delivery: REQ-048(CHG-20260611-01)·REQ-005(CHG-20260611-01) change-req → 차기 batch.
|
||||
|
||||
# 1. 계획 상태 요약
|
||||
|
||||
- 연계 문서 현황:
|
||||
- 관련 점수 파일: 없음
|
||||
- 관련 TODO/메모: GitHub issue #15 (자율 청산 비활성화 모드 설계 전문 포함)
|
||||
- 해석:
|
||||
- REL-006 피드백 환류 Discovery 후보로 식별됨. 자율 청산(forced_close / SL·TP / market_close) 워커를 완전히 끄고 전략·운영자 지시 매도만 허용하는 운영 모드 요구.
|
||||
- REQ-048(per-instance TOML) + REQ-005(daemon bootstrap) change-req 2건으로 닫는다 — OQ-1·OQ-2 확정. SafetySellConfig(env) 변경 없음.
|
||||
|
||||
# 2. 요구사항 판정 결과
|
||||
|
||||
- 판정: 신규
|
||||
- 근거
|
||||
- dcy-007(core-autonomous-safety-sell)은 자율 매도 기능을 구현한 Discovery로 REL-003에서 released됨. 비활성화 모드는 그 기능의 확장이 아닌 운영 정책 플래그 추가 — 독립 후속 주기.
|
||||
- 현재 SafetySellConfig에 `enabled` 플래그가 없고, `daemon.start()`의 workers 리스트에 `trex-safety-sell` 스레드가 조건 없이 포함됨. 코드 갭이 실존하는 신규 요구.
|
||||
|
||||
# 3. 문제점의 요약
|
||||
|
||||
- 현재 상태
|
||||
- `trex_core/runtime/daemon.py:335`: `("trex-safety-sell", self._safety_sell_loop)` 이 workers 리스트에 항상 포함되어 데몬 기동 시 매번 자율 청산 워커가 시작됨.
|
||||
- `SafetySellConfig`(config.py:113)에는 `enabled` 플래그가 없고, per-trigger 비활성화 수단도 없음. 관찰 전용 인스턴스·신규 전략 검증 환경에서 자율 청산을 막을 방법이 없음.
|
||||
- 기대 상태
|
||||
- `DaemonInstanceConfig`(per-instance TOML)에 `safety_sell_enabled: bool = True` 추가(OQ-2 — env 제외, `max_active_slots`/`default_order_timeout_sec` 선례)로, `false` 시 `trex-safety-sell` 스레드를 데몬 기동부에서 아예 시작하지 않음.
|
||||
- 기동 로그에 `safety_sell=disabled` 표시로 운영자가 안전망 없는 인스턴스임을 즉시 인지 가능(스냅샷 응답 미포함 — OQ-3).
|
||||
- 이해관계자
|
||||
- 운영자/시스템 관리자 (Justin Ko): 관찰 전용 인스턴스·신규 전략 검증 시 자율 청산 OFF 필요
|
||||
- 전략 모듈(trex-orb-v1): 전략 지시 매도는 항상 유지되어야 함
|
||||
- 리뷰어/승인자: 안전망 없음을 명시한 운영 가이드 확인
|
||||
- 제약사항
|
||||
- `ExecutionService`(집행 루프), 운영자 CLI, kill-switch는 이 플래그에 영향받지 않아야 함 — 자율 청산(safety-sell 워커)만 OFF.
|
||||
- Redis·RabbitMQ·PostgreSQL 의존성 변경 없음. config.py + daemon.py 한정 수정.
|
||||
|
||||
## 주요 사용자 시나리오
|
||||
|
||||
- 관찰 전용 인스턴스: per-instance TOML `safety_sell_enabled = false` 설정 후 데몬 기동 → 기동 로그에 `safety_sell=disabled` 확인 → 포지션 유지 중 자동 청산 미발생, 전략 sell intent는 정상 집행.
|
||||
- 신규 전략 검증(paper 브로커): safety-sell 없이 전략 모듈 매도 타이밍만 테스트 — 의도치 않은 장마감 강제청산 없이 전략 e2e 검증.
|
||||
- 기본 운영(enabled=true): 기존 동작과 완전 동일. 하위 호환 변경 없음.
|
||||
|
||||
# 4. 이번에 정의할 변경
|
||||
|
||||
- `DaemonInstanceConfig`(per-instance TOML)에 `safety_sell_enabled: bool = True` 필드 추가(OQ-2 — env 제외, SafetySellConfig 변경 없음).
|
||||
- `daemon.start()` workers 리스트 구성부에서 `safety_sell_enabled=false` 시 `trex-safety-sell` 스레드 제외 — run_once 내부 if-가드보다 스레드 미기동이 물리적으로 자율 청산을 차단.
|
||||
- 기동 로그(`RUNNING`)에 `safety_sell_enabled` 상태 노출(스냅샷 응답 미포함 — OQ-3) — 운영자가 인지 없이 안전망 없는 인스턴스를 운영하는 사고 방지.
|
||||
|
||||
## 영향 범위
|
||||
|
||||
- 코드 영향:
|
||||
- `trex_core/runtime/config.py`: `DaemonInstanceConfig`에 `safety_sell_enabled: bool = True` 필드 추가 + `from_toml()` 파싱 (SafetySellConfig 변경 없음)
|
||||
- `trex_core/runtime/daemon.py`: `start()` workers 조건부 구성 — `config.instance.safety_sell_enabled` 참조 + 기동 로그 `safety_sell=disabled/enabled`
|
||||
- 문서 영향:
|
||||
- REQ-048(per-instance TOML 설정) change-req: `safety_sell_enabled` 필드 추가
|
||||
- REQ-005(daemon bootstrap) change-req: 워커 조건부 기동 명시
|
||||
- `docs/runtime-flows.md`: safety-sell 비활성 모드 플로우 추가
|
||||
- 운영 영향:
|
||||
- 기본값 `true` — 기존 운영 인스턴스 동작 무변. 기동 전 `.env` 또는 TOML에 `TREX_SAFETY_SELL_ENABLED=false` 추가 시에만 비활성 모드로 전환.
|
||||
- 비활성 모드 인스턴스는 손절/강제만기/장마감 안전망 없음 — 운영 가이드·기동 로그 명시 필수.
|
||||
|
||||
# 5. 요구사항 목록
|
||||
|
||||
## 기능 요구사항
|
||||
|
||||
- FR-1: `DaemonInstanceConfig`(per-instance TOML)에 `safety_sell_enabled: bool = True` 필드를 추가하고, TOML `safety_sell_enabled = false`로 인스턴스별 비활성화를 제어한다. 기본값 `true`(미지정 시 기존 동작 유지). env var 경로 미노출 — 인스턴스별 운영 모드 차이(`max_active_slots` 선례).
|
||||
- FR-2: `daemon.start()` 시 `DaemonInstanceConfig.safety_sell_enabled == False` 이면 `trex-safety-sell` 워커 스레드를 workers 리스트(`daemon.py:335`)에 포함하지 않는다. `True`(기본)이면 기존과 동일하게 기동한다.
|
||||
- FR-3: 기동 시 RUNNING 로그에 `safety_sell_enabled=<true|false>` 필드를 포함한다. 비활성 모드(`false`)이면 추가로 `no autonomous liquidation` 경고를 로그에 남긴다.
|
||||
- FR-4: `safety_sell_enabled` 모드는 **기동 로그(FR-3)로만** 노출하고 **스냅샷/slots 응답에는 포함하지 않는다**(OQ-3). 근거: 인스턴스 config 이지 per-slot 데이터가 아니며, dcy-025 가 read 표면을 "응답=상태(slots[])+health"로 최소화하므로 config 를 응답에 싣지 않는 패턴과 정합한다. 런타임 노출이 필요해지면 per-slot 이 아니라 dcy-025 envelope-level(또는 별도 instance-status 표면)에서 조율한다.
|
||||
|
||||
## 비기능 요구사항
|
||||
|
||||
- NFR-1: `enabled=false` 시 `ExecutionService`(집행 루프)·운영자 CLI(`enter`/`exit`/`cancel`)·kill-switch·messaging handler에는 영향 없음. 자율 청산(safety-sell 워커)만 미기동.
|
||||
- NFR-2: 기본값 `true` — 기존 운영 인스턴스 재배포 시 config 변경 없이 기존 동작 보존(완전 하위 호환).
|
||||
- NFR-3: 비활성 모드는 테스트에서 `config.safety_sell.enabled=False`를 주입하는 것만으로 재현 가능. 추가 mocking 불필요.
|
||||
|
||||
## 범위 경계
|
||||
|
||||
- In Scope
|
||||
- SafetySellConfig `enabled` 필드 + env + TOML 파싱
|
||||
- daemon.start() workers 조건부 구성
|
||||
- 기동 로그에 모드 노출(스냅샷 응답 미포함 — OQ-3)
|
||||
- REQ-048(per-instance TOML) change-req + REQ-005(daemon bootstrap) change-req + runtime-flows 갱신
|
||||
- Out of Scope
|
||||
- per-trigger 개별 플래그(forced_close / SL·TP / market_close 각각 ON/OFF) — 마스터 플래그 이후 별도 후속 이슈로 분리
|
||||
- kill-switch 포함 여부 변경 — 운영자 지시 경로이므로 유지(혼용 금지)
|
||||
- 비활성 모드용 별도 watchdog 가시화 — 워커 미기동 시 로깅 없어도 무방(과설계 회피)
|
||||
- trex-orb-v1 전략 모듈 변경 — 전략 sell intent는 messaging handler 경로이며 영향 없음
|
||||
|
||||
# 6. 리스크/가정 목록
|
||||
|
||||
## 리스크
|
||||
|
||||
- R-1 (Medium): 비활성 모드 인스턴스에서 전략 모듈이 죽어 폴링이 끊겨도 안전망 없이 포지션이 계속 유지됨 — 의도적 모드이지만 운영자 인지 없이 설정하면 무제한 손실 리스크.
|
||||
- 완화 방안: 기동 로그 `no autonomous liquidation` 경고로 운영자가 즉시 인지(스냅샷 응답 미포함 — OQ-3). 운영 가이드에 위험 명시.
|
||||
- R-2 (Low): TOML `safety_sell_enabled` 오타/잘못된 타입이 의도와 다르게 해석될 경우 기대와 반대로 자율 청산이 활성화됨.
|
||||
- 완화 방안: TOML bool 파싱 규약을 따르되(미지정/비-false → `true`), 기동 로그에 파싱된 값을 항상 출력해 운영자가 확인 가능하게 함.
|
||||
- R-3 (Low): 기존 SafetySellConfig 단위 테스트가 `enabled` 필드 추가 후 drift할 수 있음.
|
||||
- 완화 방안: `EXPECTED_SLOT_FIELDS` drift test 선례처럼 config 계약 가드 테스트 추가 또는 기존 테스트 보완.
|
||||
|
||||
## 가정
|
||||
|
||||
- A-1: 단일 마스터 플래그(`enabled`) 구현으로 시작하고, per-trigger 세분화는 후속 이슈로 분리한다.
|
||||
- A-2: `enabled=false` 시 kill-switch, 운영자 CLI exit, 전략 sell intent는 그대로 동작한다.
|
||||
- A-3: 신규 REQ 없이 REQ-048(per-instance TOML) + REQ-005(daemon bootstrap) change-req 2건으로 닫는다 — OQ-1·OQ-2 Justin Ko 확정. SafetySellConfig(env) 변경 없음.
|
||||
|
||||
## 오픈 질문
|
||||
|
||||
- OQ-1: 신규 REQ 없이 change-req 경로(REQ-041·005)만으로 진행할지, 별도 Configuration REQ를 신규 발행할지?
|
||||
- 상태: Answered
|
||||
- 처리 방안: Justin Ko 확정 — **change-req 우선(신규 REQ 미발행)**. REQ-048(DaemonInstanceConfig TOML) + REQ-005(daemon bootstrap) change-req 2건으로 닫는다.
|
||||
- 종료 조건: 완료
|
||||
- OQ-2: per-instance TOML `[safety_sell] enabled = false` 지원 포함 여부(env만 지원할지 TOML도 포함할지)?
|
||||
- 상태: Answered
|
||||
- 처리 방안: Justin Ko 확정 — **TOML 포함(env 제외)**. 당일 매매 인스턴스는 enabled=true, 중장기 보유 인스턴스는 enabled=false — 인스턴스마다 다른 운영 모드이므로 `DaemonInstanceConfig`(TOML)에 배치. `max_active_slots`·`default_order_timeout_sec` 선례 동일. REQ-048 change-req 추가.
|
||||
- 종료 조건: 완료
|
||||
- OQ-3: 스냅샷 응답(`slots[]` envelope)에 `safety_sell_enabled` 필드 추가 포함 여부(FR-4)?
|
||||
- 상태: Answered (2026-06-11, 사용자 결정)
|
||||
- 결정: **기동 로그만, 스냅샷/slots 응답 미포함.** 근거: `safety_sell_enabled`는 인스턴스 config(per-slot 데이터 아님)이고, dcy-025 가 read 표면을 "응답=상태(slots[])+health"로 최소화하므로 config 를 응답에 싣지 않는 패턴과 정합. **per-slot 행에 넣지 않는다.** 런타임 노출이 필요해지면 per-slot 이 아니라 dcy-025 envelope-level(또는 별도 instance-status 표면)에서 조율(후속). 반영: FR-4.
|
||||
|
||||
# 7. 초기 성공 기준
|
||||
|
||||
- S-1: per-instance TOML `safety_sell_enabled = false`로 데몬 기동 시 `trex-safety-sell` 스레드가 시작되지 않는다. 기동 로그에 `safety_sell_enabled=false`와 `no autonomous liquidation` 경고가 포함된다.
|
||||
- S-2: 비활성 모드에서 forced_close_at 만기·SL·TP·장마감 시각이 지나도 슬롯이 자동 청산되지 않는다. 전략 모듈 sell intent + 운영자 CLI exit는 정상 집행된다.
|
||||
- S-3: `enabled=true`(기본값) 시 기존 동작과 동일하며 기존 단위·통합 테스트 회귀가 없다.
|
||||
|
||||
## 측정 방식 및 데이터 출처
|
||||
|
||||
- S-1 측정 방식: 단위 테스트 — `enabled=False` config 주입 + `daemon.start()` 후 thread 이름 목록에 `trex-safety-sell` 부재 확인 / 데이터 출처: `tests/runtime/test_daemon.py` 또는 신규 테스트
|
||||
- S-2 측정 방식: run-the-app 스모크 — 비활성 모드 데몬 기동 후 holding 슬롯 유지 중 장마감 시각 경과 → 슬롯 상태 `holding` 유지 + 전략 sell intent 처리 확인 / 데이터 출처: 데몬 기동 로그(`safety_sell_enabled=false`) + 슬롯 상태(`trex-core slots`로 holding 유지 확인 — slots 출력 자체엔 safety_sell_enabled 미포함, OQ-3)
|
||||
- S-3 측정 방식: `pytest` 전체 실행 회귀 없음, `ruff check` clean / 데이터 출처: CI 또는 로컬 테스트 결과
|
||||
|
||||
# 8. REQ로 넘기기 전 확인 체크
|
||||
|
||||
- [x] 범위(In Scope/Out of Scope) 확정
|
||||
- 기준: per-trigger 플래그 Out of Scope + TOML 지원(OQ-2 TOML·env 제외) 확정
|
||||
- [x] 성공 지표의 측정 방식/데이터 출처 확정
|
||||
- 기준: S-1 단위(스레드 부재)·S-2 run-the-app 스모크·S-3 회귀로 정의됨
|
||||
- [x] High 영향 리스크 우선순위 및 해소 책임자 지정
|
||||
- 기준: R-1(비활성 모드 손실)은 기동 로그 경고 + 운영 가이드로 해소, 가이드 작성 담당 = 구현 batch/Justin Ko(아래)
|
||||
- [x] 모든 오픈 질문(OQ) `Open` 상태 없음 확인
|
||||
- 기준: OQ-1/2/3 전부 Answered
|
||||
- [x] Freeze 확정 담당자(CONFIRMED_BY) 지정
|
||||
- 기준: Justin Ko 승인 후 `confirm-discovery` 수행
|
||||
- [ ] (delivery 인계) 비활성 모드 운영 가이드(손실 리스크 경고) 작성 — 구현 batch 단계 산출물, 담당 project maintainers/Justin Ko (Discovery confirm 비차단)
|
||||
|
||||
# 9. 파일 처리 결과
|
||||
|
||||
- 처리 결과: 생성
|
||||
- 생성 경로: docs/discovery/dcy-024_20260611_safety-sell-disable-mode.md
|
||||
- 참조 문서:
|
||||
- GitHub issue #15 — 자율 청산 비활성화 모드 설계 전문 (영향 범위·구현 방안·OQ 상세)
|
||||
- docs/discovery/dcy-007_20260606_core-autonomous-safety-sell.md — 자율 매도 구현 Discovery (선행 참조)
|
||||
- trex_core/runtime/config.py:113 — SafetySellConfig (변경 대상)
|
||||
- trex_core/runtime/daemon.py:335 — workers 리스트 (`trex-safety-sell` 항목, 변경 대상)
|
||||
|
||||
# 10. 사용자 결정 필요 항목 요약
|
||||
|
||||
## DECIDE
|
||||
|
||||
- 없음 (OQ-1·OQ-2 확정 완료)
|
||||
|
||||
## CONFIRM
|
||||
|
||||
- 없음. (1) 스냅샷 응답 노출 = OQ-3 Answered(기동 로그만). (2) kill-switch·운영자 CLI exit가 `safety_sell_enabled=false`와 무관하게 유지됨은 설계로 확정(A-2/NFR-1) — 저장소상 `KillSwitchService`(daemon.py:166)·운영자 CLI exit 는 `trex-safety-sell` 워커와 **독립 경로**라 워커 미기동이 그 둘에 영향 없음(확인 완료).
|
||||
|
||||
## DATA
|
||||
|
||||
- 없음. (운영 가이드(손실 리스크 경고) 작성은 Discovery 정책 결정이 아니라 **delivery 단계 산출물**이므로 §8 인계 체크로 이동 — 담당은 구현 batch/project maintainers.)
|
||||
|
||||
# 11. Discovery Freeze
|
||||
|
||||
## 섹션 참조
|
||||
|
||||
- 범위: [# 5. 요구사항 목록 > 범위 경계](#5-요구사항-목록)
|
||||
- 리스크/오픈 질문: [# 6. 리스크/가정 목록](#6-리스크가정-목록)
|
||||
- 성공 기준: [# 7. 초기 성공 기준](#7-초기-성공-기준)
|
||||
- 인계 전 확인: [# 8. REQ로 넘기기 전 확인 체크](#8-req로-넘기기-전-확인-체크)
|
||||
- 사용자 결정 필요: [# 10. 사용자 결정 필요 항목 요약](#10-사용자-결정-필요-항목-요약)
|
||||
|
||||
## Freeze 플래그
|
||||
|
||||
- Handoff Decision: 승인
|
||||
- Handoff Rationale: OQ-1/2/3 전부 Answered(change-req 경로·TOML·기동 로그만). C형 플레이스홀더 0(CONFIRM/DATA 해소). 저장소 사실 재확인 일치. 운영 가이드 작성만 delivery 단계 비차단 인계. REQ Drafting 인계 가능.
|
||||
- Ready for REQ Drafting: true
|
||||
- Confirmed By: Justin Ko
|
||||
- Confirmed At (KST): 2026-06-11 13:29 KST
|
||||
@@ -0,0 +1,228 @@
|
||||
# 0. 문서 상태
|
||||
이 문서의 현재 상태와 식별 정보를 기록한다. 문서 추적과 승인 흐름에 필요한 최소 메타데이터를 적는다.
|
||||
|
||||
- 상태: confirmed
|
||||
- 문서 ID: dcy-025_20260611_strategy-read-surface-slots-req
|
||||
- 이슈명: 전략 read 표면 재설계 — `trex.snapshot.req`→`trex.slots.req` + 슬롯 상태 필터 + 슬롯 단일 행(assets[]/available_slots/watchdog[] 흡수·제거)
|
||||
- 작성 시각(KST): 2026-06-11 12:38 KST
|
||||
- 마지막 갱신 시각(KST): 2026-06-11 14:05 KST (draft-req 완료: REQ-073/074/075 신규 + REQ-021/034/063 change-req(Approved 강등) + REQ-028 폐기 예정 forward-link)
|
||||
- 대체됨: 없음
|
||||
- 후속 Discovery 참조: 전략↔자산 할당 모델(portfolio-hub 주도 다중 전략 설정) — 미생성, 후속 예정(본 표면에 strategy 필드 additive 추가 시점)
|
||||
- 생성된 REQ 참조: REQ-073(slots.req RPC 계약), REQ-074(슬롯 단일 행 스키마), REQ-075(baseline 정합). 변경 REQ: REQ-021/034/063(각 CHG-20260611-01, Implemented→Approved), REQ-028(CHG-20260611-01, keep-current — delivery 배치에서 Deprecated 전환)
|
||||
|
||||
# 1. 계획 상태 요약
|
||||
현재 Discovery가 어떤 배경에서 작성되고 있는지, 연계 문서가 있는지, 지금 시점의 해석이 무엇인지 짧게 요약한다.
|
||||
|
||||
- 연계 문서 현황:
|
||||
- 관련 점수 파일: 미생성
|
||||
- 관련 TODO/메모: dcy-020(자산 중심 영구 슬롯·REQ-063 slots 단일 뷰 — 직접 토대), BAT-022(universe↔slots 이중 표면 분리 선례), dcy-005(스냅샷 universe read 기원), REQ-028(snapshot 메시지 계약), REQ-021(messaging 토폴로지).
|
||||
- 해석:
|
||||
- dcy-020 이 "슬롯=자산 1:1 영구 슬롯"으로 모델을 바꾸면서, 전략이 universe 를 받던 스냅샷 표면(`trex.snapshot.req`, view=all/buyable/held + `assets[]`/`slots[]`/`available_slots`/`watchdog[]`)이 과도하게 분리·중복된 상태가 됐다. 자산 중심 모델에선 **슬롯 테이블 하나**가 곧 universe 이므로 `assets[]`·`watchdog[]` 같은 병렬 배열을 슬롯 행에 흡수할 수 있다.
|
||||
- 본 Discovery 는 전략 read 표면을 **`trex.slots.req`(슬롯 단일 테이블 + 상태 필터)**로 재설계한다 — `assets[]`/`available_slots`/`watchdog[]` 제거, watchdog·자산 데이터(symbol/portfolio_id/cash_balance/asset_quantity)를 슬롯 행에 흡수, `spy`(워치독 무터치) 옵션, `degraded/reason/message` 유지. BAT-022·dcy-020(REQ-063)가 향하던 통합의 종착점이다.
|
||||
|
||||
# 2. 요구사항 판정 결과
|
||||
이번 요청이 기존 요구사항과 비교해 신규인지, 유사한지, 중복인지 판단하고 그 근거를 남긴다.
|
||||
|
||||
- 판정: 신규
|
||||
- 근거
|
||||
- 큐 표면 교체(`trex.snapshot.req`→`trex.slots.req`)·응답 구조 재설계(assets/available_slots/watchdog 제거 + 슬롯 행 흡수)는 REQ-028(snapshot 계약)·REQ-021(토폴로지)·REQ-063(slots 뷰)을 동시에 재정의하는 인터페이스 변경이라 단일 REQ 미세 조정으로 흡수되지 않는다.
|
||||
- dcy-020 이 자산 중심 모델을 confirmed·delivery(BAT-027~031)했으나 전략 read 표면의 통합은 별도 주제로 남겨졌다. 본 주기는 그 read 계약을 독립적으로 재설계한다.
|
||||
|
||||
# 3. 문제점의 요약
|
||||
문제의 현재 상태, 기대 상태, 관련 이해관계자, 제약사항을 정리한다. Discovery의 핵심 맥락을 가장 먼저 이해할 수 있어야 한다.
|
||||
|
||||
- 현재 상태
|
||||
- **요청 표면 `trex.snapshot.req`**: payload `{view: all|buyable|held, strategy_key?, trading_date?, actor?/touch_watchdog?}`(`messaging_handlers.py` snapshot 핸들러). view 는 파생 집합(`View` enum, `portfolio.py:65`): ALL=universe∪holding, BUYABLE=universe−occupied−masked, HELD=holding.
|
||||
- **응답 envelope**(`build_snapshot_envelope`): `assets[]`(view 필터된 자산: symbol/asset_id/cash_balance/asset_quantity/active_strategy_id/strategy_params) + `slots[]`(인스턴스 전체 슬롯 테이블, view 무관 — BAT-022) + `available_slots`(M−active capacity) + `degraded`/`reason`/`message` + `watchdog[]`(별도 배열, `_attach_watchdog`).
|
||||
- **이중 표면·병렬 배열**: `assets[]`(universe view)와 `slots[]`(슬롯 테이블)가 공존하고, `watchdog[]`는 슬롯과 조인해야 하는 별도 배열이다. 자산 중심 모델(슬롯=자산 1:1)에선 `assets[]`가 사실상 `slots[]`의 부분집합이라 중복이다.
|
||||
- **워치독 터치 시맨틱**: 전략 폴링은 holding 슬롯 워치독을 갱신(생존 신호, REQ-034)하고, 운영자 조회는 `actor="operator"`/`touch_watchdog=false`로 억제(REQ-021 R-4) — 두 갈래가 ad-hoc 플래그로 표현됨.
|
||||
- **strategy 필터**: `strategy_key`로 소유 자산 필터, `assets[]`에 `active_strategy_id`/`strategy_params` 노출.
|
||||
- legacy stub 경로(`{view, strategy_id, slots[], capacity{}}`)도 잔존(구버전·테스트 호환).
|
||||
- baseline(`docs/interface-contract.md` snapshot 섹션)이 이 표면을 기술 — 재설계 시 갱신 대상.
|
||||
- 기대 상태
|
||||
- 전략이 **`trex.slots.req`** 하나로 슬롯 테이블을 받는다. 응답 = `slots[]` + `degraded`/`reason`/`message` 만.
|
||||
- `slots[]` 각 행이 슬롯 상태(slot_id/status/qty/avg_price/limit_price/forced_close_at…)와 자산 데이터(symbol/portfolio_id/cash_balance/asset_quantity)와 **워치독 상태(expired/last_seen)**를 함께 운반한다 — 병렬 배열·조인 제거.
|
||||
- `filter`로 슬롯 상태별(all/inactive/holding/pending/paused…) 조회. `spy=true`면 워치독 무터치(생존 신호로 오인 안 함).
|
||||
- `assets[]`·`available_slots`·`watchdog[]` 제거. 매수 가능 목록 = `filter=inactive` 결과, capacity 는 admission(`capacity_full`)이 게이트.
|
||||
- 이해관계자
|
||||
- 문서 작성자(AI agent) — Discovery/REQ/Batch 산출물
|
||||
- 리뷰어/승인자 — read 계약·토폴로지 재설계 승인
|
||||
- 전략 모듈(orb-v1 등) — 요청 큐·응답 구조 변경(외부 repo 소비 측)
|
||||
- 운영 담당자 — `spy` 조회·슬롯 단일 뷰 관측
|
||||
- 제약사항
|
||||
- 큐 교체는 토폴로지(REQ-021/050 동적 큐명·per-instance)·전략 모듈 소비 측을 함께 바꿔야 한다 — cutover/과도기 필요.
|
||||
- 슬롯 행에 브로커 정본(qty/avg)과 hub 정본(cash_balance/asset_quantity)이 공존하며 divergence(REQ-031/062) 가능 — 필드별 source 명시 필요.
|
||||
- 단일 writer·워치독(REQ-034)·degraded 신호(REQ-028)의 의미를 새 표면에서 보존.
|
||||
|
||||
## 주요 사용자 시나리오
|
||||
사용자 또는 운영자가 실제로 어떤 상황에서 이 변경을 필요로 하는지 대표 시나리오를 적는다.
|
||||
|
||||
- 전략이 `trex.slots.req {filter: "inactive"}` 로 매수 가능(잔고 0·미보유) 슬롯만 받아 신호를 낸다 — `assets[]` 없이 `slots[]` 한 배열로.
|
||||
- 전략이 `{filter: "holding"}` 로 보유 슬롯의 수량·avg·워치독 상태를 한 행에서 본다(별도 watchdog[] 조인 불필요).
|
||||
- 운영자가 `{filter: "all", spy: true}` 로 전 슬롯을 조회하되 워치독을 건드리지 않아 죽은 전략의 safety-sell 을 억제하지 않는다.
|
||||
- 전략이 `{filter: "pending"}` 로 진행 중 주문 슬롯을 관측한다.
|
||||
|
||||
# 4. 이번에 정의할 변경
|
||||
이번 Discovery에서 다루는 핵심 변경 항목을 목록으로 적는다. 기능, 구조, 규칙 변경을 함께 포함해도 된다.
|
||||
|
||||
- **요청 표면 교체**: `trex.snapshot.req` 파이프라인 제거, `trex.slots.req` 추가(토폴로지·핸들러·전략 소비 측 cutover, OQ-1).
|
||||
- **슬롯 상태 필터**: `filter` = status 단일 값 `{all, inactive, pending(buy∪sell), holding, error}`(상호배타, OQ-2). `inactive` 판정=슬롯 status(잔고 아님). overlay(`paused`/`warned`)는 행 플래그(직교 축), 서버측 overlay 필터는 후속. 파생 view(ALL/BUYABLE/HELD) 폐기.
|
||||
- **`spy` 옵션**: `spy=true` 면 워치독 무터치(현 `actor=operator`/`touch_watchdog=false` 일반화). 기본 false(터치=생존 신호).
|
||||
- **슬롯 단일 행 흡수**(OQ-3 (a)): `slots[]` 각 행에 자산 데이터(symbol/portfolio_id/cash_balance/asset_quantity) + 워치독(`watchdog:{expired,last_seen}` nested) + overlay(`paused`/`warned`) 포함. 수량은 `asset_quantity`(hub 정본)+`qty`(미러) **둘 다** 노출(REQ-062), 어긋나면 `warned`. 현금은 `cash_balance`+`cash_estimated`. 필드별 정본 라벨 명시.
|
||||
- **응답 정리**: `assets[]`·`available_slots`·`watchdog[]` **제거**, `degraded`/`reason`/`message` **유지**.
|
||||
- **strategy 필드 제외(이번 범위)**: `strategy_id`/`strategy_key`/`strategy_params`/`active_strategy_id` 제외(OQ-4 — 인스턴스=전략 스코프 전제).
|
||||
- baseline(`docs/interface-contract.md`/`docs/runtime-flows.md`) snapshot→slots 표면 갱신.
|
||||
|
||||
## 영향 범위
|
||||
변경이 미칠 코드/문서/운영 범위를 명시해 REQ 정제와 batch planning에서 추정 누락을 줄인다.
|
||||
|
||||
- 코드 영향:
|
||||
- `trex_core/adapters/messaging/topology.py` 등 — `trex.snapshot.req`→`trex.slots.req` 큐명/바인딩(per-instance, REQ-021/050)
|
||||
- `trex_core/application/messaging_handlers.py` — snapshot 핸들러 → slots 핸들러(filter/spy 파싱, 응답 구조), `_attach_watchdog` 제거(슬롯 행 흡수), legacy stub 경로 정리
|
||||
- `trex_core/application/portfolio.py` — `View` enum·`build_snapshot_envelope`(assets/available_slots/watchdog 제거, 슬롯 행에 자산·워치독 흡수), `slot_to_dict` 확장
|
||||
- `trex_core/runtime/cli.py` — 운영자 `slots`/`universe` 명령이 새 표면 사용(`spy`)
|
||||
- (전략 모듈 orb-v1 — 외부 repo 소비 측 cutover)
|
||||
- 문서 영향:
|
||||
- `docs/interface-contract.md`(snapshot→slots 계약), `docs/runtime-flows.md`(read 표면)
|
||||
- 운영 영향:
|
||||
- 전략 모듈 동시 cutover 필요(큐 교체). 운영자 조회는 `spy`로 일원화.
|
||||
|
||||
# 5. 요구사항 목록
|
||||
실제로 구현과 검증으로 이어질 요구사항을 기능/비기능으로 나누어 정리하고, 범위 경계를 명확히 적는다.
|
||||
|
||||
## 기능 요구사항
|
||||
- FR-1: `trex.snapshot.req` 를 제거하고 `trex.slots.req`(per-instance 큐명) RPC 를 추가한다 — 요청 `{filter?, spy?}`, 응답 `{slots[], degraded, reason, message}`. **즉시 교체**(과도기 없음, OQ-1): 두 큐를 한 배포에 교체하고 전략 모듈을 lockstep 전환한다.
|
||||
- FR-2: `filter` 는 **status 단일 값**(상호배타) `{all, inactive, pending(=pending_buy∪pending_sell), holding, error}` 로 조회한다(OQ-2). 미지정 시 `all`. `inactive` 판정 키는 슬롯 **status**(hub `asset_quantity` 아님 — 정합 정본은 상태머신). overlay(`paused`/`warned`)는 필터 값이 아니라 각 슬롯 행의 플래그로 노출하며(FR-3), 서버측 overlay 필터는 후속(MVP는 행 플래그 + client 필터).
|
||||
- FR-3: `slots[]` 각 행은 아래를 **필드별 정본 라벨**과 함께 운반한다(OQ-3 (a)):
|
||||
- 슬롯/코어 정본: `slot_id`, `status`, `portfolio_id`, `symbol`, `avg_price`, `limit_price`, `forced_close_at`
|
||||
- 수량(REQ-062 정합, **둘 다 노출**): `asset_quantity`(**hub 정본** — 전략 reasoning primary) + `qty`(**슬롯 미러** — 코어 confirmed local). 정상 시 일치, 어긋나면 `warned=true`. 라이브 브로커 잔고는 행에 미포함(청산/reconcile 시점 정본).
|
||||
- 현금: `cash_balance`(hub 정본) + `cash_estimated`(bool, dcy-018 추정 현금 오버레이)
|
||||
- 워치독: `watchdog: {expired: bool, last_seen: ISO}` (nested object)
|
||||
- overlay 플래그(직교 축, OQ-2): `paused`, `warned`
|
||||
- 계약 문서(interface-contract)에 각 필드 정본 출처(hub/슬롯·코어/브로커/watchdog/overlay)를 명시한다.
|
||||
- FR-4: `spy=true` 면 워치독을 갱신하지 않는다(생존 신호 미발생). 기본 false(holding 슬롯 워치독 터치, REQ-034 계승).
|
||||
- FR-5: 응답에서 `assets[]`·`available_slots`·`watchdog[]` 를 제거하고 `degraded`/`reason`/`message` 는 유지한다. 매수 가능 목록은 `filter=inactive`, capacity 는 admission(`capacity_full`) 게이트로 대체한다.
|
||||
- FR-6: `strategy_id`/`strategy_key`/`strategy_params`/`active_strategy_id` 는 본 표면에서 제외한다(OQ-4).
|
||||
- FR-7: `docs/interface-contract.md`·`docs/runtime-flows.md` 를 새 read 표면으로 갱신한다.
|
||||
|
||||
## 비기능 요구사항
|
||||
성능, 운영성, 일관성, 자동화 안정성 등 기능 외 요구사항을 적는다.
|
||||
|
||||
- NFR-1: 워치독 일관성 — 전략 폴링(기본)은 생존 신호로 터치, `spy` 는 무터치(REQ-034 R-4 의미 보존).
|
||||
- NFR-2: 단일 표면 — 한 응답이 슬롯 테이블 하나로 자산·워치독을 모두 담아 소비자 조인이 불필요하다.
|
||||
- NFR-3: cutover 안전 — 즉시 교체(과도기 없음, OQ-1)이므로 전략 모듈(orb-v1)을 같은 배포에 lockstep 전환한다. dcy-020 자산 중심 cutover(BAT-030)와 묶어 단일 전환점으로 관리한다.
|
||||
|
||||
## 범위 경계
|
||||
이번 반복에서 반드시 포함할 범위와 명시적으로 제외할 범위를 구분한다.
|
||||
|
||||
- In Scope
|
||||
- `trex.slots.req` 표면(요청 filter/spy, 응답 slots[]+degraded) + 슬롯 행 흡수(자산·워치독)
|
||||
- `assets[]`/`available_slots`/`watchdog[]` 제거, `trex.snapshot.req` 폐기
|
||||
- interface-contract/runtime-flows 정합
|
||||
- Out of Scope
|
||||
- strategy_id/key/params/active(이번 제외 — 인스턴스=다중 전략이나 할당 모델 portfolio-hub 미정의, 후속 discovery. loose JSON 미채택, 추후 명시 필드 additive 추가)
|
||||
- intent admission/capacity 정책 자체(dcy-020 — read 표면만 변경)
|
||||
- 포지션 사이징·실행 정책(dcy-021/022 — 별개)
|
||||
- 전략 모듈(orb-v1) 내부 구현(외부 repo, 소비 계약만 합의)
|
||||
|
||||
# 6. 리스크/가정 목록
|
||||
불확실성과 전제 조건을 분리해서 적는다. 리스크는 영향과 완화 방안을, 가정은 현재 판단의 전제를 기록한다.
|
||||
|
||||
## 리스크
|
||||
- R-1 (High): **즉시 교체**(OQ-1, 과도기 없음)라 전략 모듈(외부 repo)이 같은 배포에 전환되지 않으면 전략이 스냅샷을 즉시 못 받는다.
|
||||
- 완화 방안: 전략 모듈 lockstep cutover를 dcy-020 자산 중심 cutover(BAT-030, 이미 전략 계약 변경 동반)와 **단일 전환점으로 묶어** 조율. 배포 전 전략 모듈 `trex.slots.req` 대응 준비 확인.
|
||||
- R-2 (Medium): 슬롯 행에 브로커 정본(qty/avg)과 hub 정본(cash_balance/asset_quantity)이 공존해 divergence(REQ-031/062) 시 소비자가 어느 값을 믿을지 모호.
|
||||
- 완화 방안: 필드별 정본 출처·라벨을 OQ-3 에서 확정하고 계약 문서에 명시.
|
||||
- R-3 (Medium): `available_slots` 제거로 전략이 capacity 사전 확인 불가 → 거부(`capacity_full`) 후 재시도 부담.
|
||||
- 완화 방안: admission 게이트로 충분함을 합의(가정 A-3), 필요 시 별도 capacity 조회는 후속.
|
||||
|
||||
## 가정
|
||||
아직 확정되지 않았지만 현재 문서 작성의 기반이 되는 전제를 적는다.
|
||||
|
||||
- A-1: dcy-020 자산 중심 영구 슬롯(슬롯=자산 1:1)이 구현 상태라 `assets[]`가 `slots[]`에 흡수 가능하다.
|
||||
- A-2: (정정) 한 인스턴스 = **다중 전략**이다. 전략↔자산 할당은 **portfolio-hub 가 내려주는 미정의 설정**으로 별도 후속 discovery 에서 정의한다. 따라서 이번 read 표면은 전략 정보를 받지 않고(전략-무관), 전략 모델 확정 시 strategy 필드를 additive(비파괴)로 추가한다.
|
||||
- A-3: capacity 사전 확인 없이 admission(`capacity_full`) 거부로 충분하다.
|
||||
|
||||
## 오픈 질문
|
||||
답을 아직 모르는 항목을 적는다. 추정으로 덮지 말고 REQ 초안 작성 이전에 확인할 질문으로 남긴다.
|
||||
|
||||
- OQ-1: 큐 교체 방식 — `trex.slots.req` 신규 + `trex.snapshot.req` 즉시 폐기 vs 한시적 dual-listen/dual-publish 과도기.
|
||||
- 상태: Answered (2026-06-11, 사용자 결정)
|
||||
- 결정: **즉시 교체** — `trex.snapshot.req` 파이프라인 제거 + `trex.slots.req` 추가를 같은 배포에. dual-listen/dual-publish 과도기 **없음**. 전략 모듈(orb-v1)은 **lockstep cutover**(동시 전환)로 조율하며, dcy-020 자산 중심 cutover(BAT-030, 이미 전략 계약 변경 동반)와 함께 묶는 것을 권장. 반영: FR-1, NFR-3, R-1.
|
||||
- OQ-2: `filter` 분류·조합 — status + overlay 혼합/단일, `inactive` 정의, `pending` buy/sell 합 여부.
|
||||
- 상태: Answered (2026-06-11, 사용자 결정)
|
||||
- 결정: `filter` = **status 단일 값**(상호배타) `{all, inactive, pending(=pending_buy∪pending_sell), holding, error}`. **status와 overlay는 직교 축** — overlay(`paused`/`warned`)는 필터 값이 아니라 **각 슬롯 행의 플래그**로 항상 노출, 서버측 overlay 필터는 후속(MVP는 행 플래그 + client 필터, "paused holding" 조합도 client에서). `inactive` 판정 키는 슬롯 **status**(hub `asset_quantity` 아님 — 상태머신 정본, 행에 asset_quantity 동반 노출). 임의 다중 status 조합 미지원(`pending` 묶음이 흡수). 반영: FR-2/3, §4.
|
||||
- OQ-3: 병합 슬롯 행 필드·정본 — 수량 정본/미러 노출, divergence 표기, 워치독 형태.
|
||||
- 상태: Answered (2026-06-11, 사용자 결정 (a))
|
||||
- 결정: **(a) 둘 다 노출** — `asset_quantity`(hub 정본, REQ-062)와 `qty`(슬롯 미러)를 행에 함께, 어긋나면 `warned`. `cash_balance`(hub)+`cash_estimated`(dcy-018). 워치독 = **nested `{expired,last_seen}`**. overlay `paused`/`warned` 플래그. 라이브 브로커 잔고는 행 미포함(청산/reconcile 시점 정본). interface-contract 에 필드별 정본 출처 라벨 명시. 반영: FR-3, §4.
|
||||
- OQ-4: strategy 필드 제외의 전제·처리.
|
||||
- 상태: Answered (2026-06-11, 사용자 결정)
|
||||
- 결정: 인스턴스는 **다중 전략**이나 전략↔자산 할당 모델이 **portfolio-hub 주도로 미정의** → **후속 discovery 로 연기**. 이번 표면은 전략 정보(strategy_id/key/params/active)를 **제외**(받지 않음). **loose JSON 필드는 미채택**(undefined blob은 OQ-3 정본 라벨 원칙에 반하고, 나중에 명시 필드로 additive 추가가 비파괴). 한계: 미래 모델 전까지 `trex.slots.req` 는 전략-무관(인스턴스 전체 슬롯, per-strategy 스코핑 없음). 반영: A-2, FR-6, §5 Out of Scope, 후속 Discovery 참조.
|
||||
|
||||
# 7. 초기 성공 기준
|
||||
이 변경이 성공했다고 판단할 기준을 측정 가능하게 정의한다. 가능하면 데이터 출처까지 연결한다.
|
||||
|
||||
- S-1: 전략이 `trex.slots.req {filter}` 로 슬롯 테이블을 받고, 응답에 `assets[]`/`available_slots`/`watchdog[]` 가 없으며 `slots[]`+`degraded`/`reason`/`message` 만 있다.
|
||||
- S-2: `slots[]` 각 행이 슬롯 상태 + 자산(symbol/portfolio_id/cash_balance/asset_quantity) + 워치독(expired/last_seen)을 함께 담아, 별도 배열 조인 없이 소비된다.
|
||||
- S-3: `spy=true` 조회는 워치독을 갱신하지 않고(생존 신호 미발생), 기본 조회는 holding 워치독을 터치한다. `filter=inactive` 가 매수 가능 목록을 반환한다.
|
||||
|
||||
## 측정 방식 및 데이터 출처
|
||||
각 성공 기준을 어떻게 측정할지와 어떤 데이터나 문서를 근거로 쓸지 적는다.
|
||||
|
||||
- S-1 측정 방식: `trex.slots.req` 응답 키 집합 단언(assets/available_slots/watchdog 부재) 단위/통합 / 데이터 출처: RPC 응답 payload
|
||||
- S-2 측정 방식: 슬롯 행 필드 단언(자산·워치독 포함) / 데이터 출처: slot_to_dict 확장 결과
|
||||
- S-3 측정 방식: spy on/off 워치독 갱신 여부 + filter=inactive 결과 단언 / 데이터 출처: WatchdogStore, 슬롯 상태
|
||||
|
||||
# 8. REQ로 넘기기 전 확인 체크
|
||||
REQ 초안 작성 단계로 넘기기 전에 무엇이 확정되어야 하는지 확인한다. 미완료 항목은 후속 결정이 필요함을 뜻한다.
|
||||
|
||||
- [x] 범위(In Scope/Out of Scope) 확정
|
||||
- 기준: 필터 분류(OQ-2)·strategy 제외 전제(OQ-4) 합의 완료
|
||||
- [x] 성공 지표의 측정 방식/데이터 출처 확정
|
||||
- 기준: S-1~3 측정 시나리오·데이터 출처가 테스트 가능한 형태로 정의됨
|
||||
- [x] High 영향 리스크 우선순위 및 해소 책임자 지정
|
||||
- 기준: R-1(큐 cutover)은 즉시교체(OQ-1) lockstep + dcy-020 cutover(BAT-030) 묶음으로 해소 방향 확정. 책임 = 구현 batch + 전략팀 조율.
|
||||
- [x] 모든 오픈 질문(OQ) `Open` 상태 없음 확인
|
||||
- 기준: OQ-1~4 전부 Answered (2026-06-11 사용자 결정)
|
||||
- [x] Freeze 확정 담당자(CONFIRMED_BY) 지정
|
||||
- 기준: 승인자 Justin confirm-discovery 수행
|
||||
|
||||
# 9. 파일 처리 결과
|
||||
이 Discovery 문서 생성/갱신 결과와 참조 문서를 기록한다. 이후 추적과 리뷰 시 근거로 사용한다.
|
||||
|
||||
- 처리 결과: 생성
|
||||
- 생성 경로: docs/discovery/dcy-025_20260611_strategy-read-surface-slots-req.md
|
||||
- 참조 문서:
|
||||
- docs/discovery/dcy-020_20260610_asset-centric-slot-model.md (자산 중심 영구 슬롯·REQ-063 slots 단일 뷰 — 토대)
|
||||
- docs/discovery/dcy-005_20260604_portfolio-hub-asset-snapshot-api.md (스냅샷 universe read 기원)
|
||||
- docs/interface-contract.md(snapshot 계약), docs/runtime-flows.md (baseline — 갱신 대상)
|
||||
- 코드: trex_core/application/portfolio.py(View/build_snapshot_envelope), messaging_handlers.py(snapshot 핸들러/_attach_watchdog)
|
||||
|
||||
# 10. 사용자 결정 필요 항목 요약
|
||||
사용자나 승인자가 결정해야 하는 항목만 모아 정리한다. 결정, 확인, 데이터 요청을 구분해서 적는다.
|
||||
|
||||
## DECIDE
|
||||
- 없음 (OQ-1/2/3 Answered — §6 참조)
|
||||
|
||||
## CONFIRM
|
||||
- 없음 (OQ-4 Answered — 인스턴스=다중 전략, 할당 모델은 후속 discovery, 이번 표면 전략 정보 제외)
|
||||
|
||||
## DATA
|
||||
- 없음 (외부 데이터 의존 없음 — 내부 계약/토폴로지 + 전략 발신 합의)
|
||||
|
||||
# 11. Discovery Freeze
|
||||
REQ 초안 작성 인계 시점의 확정 플래그와 섹션 참조만 기록한다. 내용 재작성 없이 원본 섹션을 링크로 대신한다.
|
||||
|
||||
## 섹션 참조
|
||||
- 범위: [# 5. 요구사항 목록 > 범위 경계](#5-요구사항-목록)
|
||||
- 리스크/오픈 질문: [# 6. 리스크/가정 목록](#6-리스크가정-목록)
|
||||
- 성공 기준: [# 7. 초기 성공 기준](#7-초기-성공-기준)
|
||||
- 인계 전 확인: [# 8. REQ로 넘기기 전 확인 체크](#8-req로-넘기기-전-확인-체크)
|
||||
- 사용자 결정 필요: [# 10. 사용자 결정 필요 항목 요약](#10-사용자-결정-필요-항목-요약)
|
||||
|
||||
## Freeze 플래그
|
||||
- Handoff Decision: 승인
|
||||
- Handoff Rationale: OQ-1~4 전부 Answered(즉시교체·filter=status 단일·행 정본(a)·전략 정보 제외). C형 플레이스홀더 0, 저장소 사실 재확인 일치(trex.snapshot.req·View enum·_attach_watchdog 존재). REQ Drafting 인계 가능.
|
||||
- Ready for REQ Drafting: true
|
||||
- Confirmed By: Justin
|
||||
- Confirmed At (KST): 2026-06-11 13:32 KST
|
||||
@@ -29,3 +29,5 @@
|
||||
| dcy-021_20260610_position-sizing-target-intent | 20260610 | 포지션 사이징 — 활성 자산 슬롯 보유 수량 변경(HOLDING→HOLDING)·부분 매도·선언형 target intent (issue #1, dcy-020 OQ-4 후속) | [Discovery](./dcy-021_20260610_position-sizing-target-intent.md) | confirmed |
|
||||
| dcy-022_20260610_stuck-pending-order-recovery | 20260610 | 전략 발신 intent 실행 정책 — 주문 timeout(TIF)/슬리피지 허용 + 미체결 고착 백스톱 (issue #21, dcy-020/021 모델 전제) | [Discovery](./dcy-022_20260610_stuck-pending-order-recovery.md) | confirmed |
|
||||
| dcy-023_20260610_allocated-capital-dead-field-removal | 20260610 | allocated_capital 죽은 필드 제거 — `enter --capital` 옵션 + slot/intent/snapshot 계약 정리 (issue #22) | [Discovery](./dcy-023_20260610_allocated-capital-dead-field-removal.md) | confirmed |
|
||||
| dcy-024_20260611_safety-sell-disable-mode | 20260611 | safety-sell 자율 청산 비활성화 모드 — per-instance TOML `safety_sell_enabled=false` 시 워커 미기동 (issue #15) | [Discovery](./dcy-024_20260611_safety-sell-disable-mode.md) | confirmed |
|
||||
| dcy-025_20260611_strategy-read-surface-slots-req | 20260611 | 전략 read 표면 재설계 — `trex.snapshot.req`→`trex.slots.req` + 슬롯 상태 필터 + 슬롯 단일 행(assets[]/available_slots/watchdog[] 흡수·제거) | [Discovery](./dcy-025_20260611_strategy-read-surface-slots-req.md) | confirmed |
|
||||
|
||||
Reference in New Issue
Block a user