# 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 ` (절대시간)** 옵션을 제공한다. 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 ... --forced-close-at `, 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 제출 전 검증 오류로 거부된다. ## 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` 매핑 - Tests: pause→호출→resume→호출 시퀀스, 재시작/refresh 후 영속, (CHG-20260609-01) enter `--forced-close-at` payload 매핑·형식 검증 ## 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 ` (절대시간) 옵션** 추가. 운영자가 매수 진입 명령 하나로 시간 기반 자동청산(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 ... --forced-close-at ` 가 주어지면 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 ` → 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.