# REL-003: trex-core 통합 app-service 릴리즈 — 자율 안전 매도 + kill-switch + 다중 인스턴스 토폴로지 - Status: feedback-captured - Profile: app-service - Included Batch: BAT-010, BAT-011, BAT-012, BAT-013 > 통합 릴리즈: dcy-007(자율 안전 매도) + dcy-008(kill-switch, 구 REL-004) + dcy-009(다중 인스턴스 토폴로지, 구 REL-005)를 단일 app-service 릴리즈로 묶는다. 세 기능 모두 동일 데몬·동일 배포 대상이며 함께 배포한다. 구 REL-004/REL-005 draft 는 본 릴리즈로 통합·폐기됨. 포함 batch 가 확장됐으므로 confirm-release 재수행 필요(draft 로 되돌림). ## Scope - Included: - **BAT-010 (REQ-034/035/036/041)**: safety-sell 기반 — per-slot WatchdogStore(snapshot RPC last_seen_at 갱신), `stop_loss_price`/`take_profit_price` 도메인 필드 + `004_add_price_thresholds.sql`, `SlotService.sell()`(idempotent), safety-sell env 5종. - **BAT-011 (REQ-037/038/039/040/042)**: safety-sell 트리거 — `trex-safety-sell` worker(forced_close 만기 / stop-loss·take-profit KIS 현재가 polling `FHKST01010100` / 장 마감 청산) + `update_thresholds` intent RPC + baseline 정합. - **BAT-012 (REQ-043~047)**: 비상 정지/kill-switch — `trex.pause.req`→`trex.control.req` 제어 채널 + action dispatch, day-scoped `killswitch_exclusion`(`005_*.sql`) + store, 범위별 holding 즉시 청산 + 이력, 당일 제외 masking + 자동복귀 + `resume_kill_switch`, baseline 정합. - **BAT-013 (REQ-048~051)**: 다중 인스턴스 토폴로지 — per-instance TOML 로더 + `--config` 필수, `instance_key` 동적 큐명(default 리터럴 하위호환), `trex.direct`(topic)/`trex.broadcast`(fanout) exchange + 바인딩, baseline 정합. - Excluded: - REQ-030 AC-2/3(옵션 D) — portfolio-hub#8 대기(REL-001 이월). - pending_buy 슬롯 롤백(dcy-008 OQ-3 Deferred), 부분 수량 청산(#5), strategy 모듈(orb-v1) publish 변경(계약만 정의), WatchdogStore Redis 외부화, 전체 env TOML 일원화. ## Rollout Plan 1. 사전 점검: PostgreSQL / RabbitMQ 도달성. 인스턴스별 TOML 준비(`instance_key`, `portfolio_hub_token`). 2. DB 마이그레이션: `004_add_price_thresholds.sql` + `005_create_killswitch_exclusion.sql`(둘 다 additive, `IF NOT EXISTS`). 데몬 boot `apply_migrations` 자동 적용(사전 적용 권장). 3. **⚠️ 파괴적 기동 변경(BAT-013/REQ-048)**: 데몬 기동에 `--config .toml` 가 **필수**. 기존 인자 없는 배포 스크립트는 반드시 `--config` 추가(누락 시 즉시 오류 종료, fallback 없음). `portfolio_hub_token` 을 `.env`→TOML 이관 후 `.env` 에서 제거. 단일 인스턴스 유지 시 `instance_key="default"`(기존 리터럴 큐명 무회귀). 4. **제어 큐 전환(BAT-012/REQ-043)**: `trex.pause.req`→`trex.control.req`. CLI 무영향, RPC pause 클라이언트는 `trex.control.req` 로 이전. old 큐 자연 소멸 허용(admin console 수동 삭제). 5. 배포 대상 commit SHA(≥ 9f83c64; BAT-010~013 포함) 설치 → 데몬 재기동 → 7 워커 스레드(execution/ledger/intent-rpc/snapshot-rpc/control-rpc/snapshot-scheduler/safety-sell) + `trex.direct`/`trex.broadcast` exchange + 인스턴스 큐 선언 확인. 6. **운영 안전 주의(중요)**: - safety-sell(BAT-011): LIVE 에서 워치독 만료 슬롯에 자동 매도. `TREX_WATCHDOG_TIMEOUT` 을 전략 snapshot 폴링 주기보다 크게. 영속 거부 시 재시도 반복(후속 백오프 후보). - kill_switch(BAT-012): LIVE 에서 운영자 명령 시 범위 holding 실매도. 전역 발동 의도적으로만. resume 은 매매 차단만 해제(청산 비가역). ## Rollback Plan - 코드 롤백: 통합 단위. BAT-010~013 커밋(a30efa8/7e23648/9f83c64) revert. 단 의존 순서(010→011→012→013) 역순. **`--config` 의존이 추가됐으므로 BAT-013 롤백 시 기동 인자를 env-only 로 되돌려야 함.** - 데이터: `004`/`005` additive — 데이터 파괴 없음, 롤백 시 컬럼/테이블 보존. - exchanges/binding(trex.direct/broadcast)은 additive — 잔류 무해. default 큐명 불변. - 즉시 무력화: safety-sell 은 임계값/만기 미설정 슬롯엔 무영향, kill_switch 는 운영자 명령 시에만 동작. 긴급 시 데몬 정지. - 트리거: 정상 운용 슬롯 오발동, 의도치 않은 청산, `--config` 누락 기동 실패, 라우팅 오배달, 제어 큐 호환 문제. ## Verification Checklist - 배포 전: - 단위 `pytest -q --deselect ...::test_sandbox_token_and_submit` → **271 passed / 30 skipped**(BAT-013 시점, 누적). - 인프라 게이트(PG+RabbitMQ) → **301 passed**(마이그레이션 001~005 round-trip + killswitch PG + directed 라우팅 격리 S-2 + broadcast dual S-3 + default 무회귀 S-4). - `ruff check trex_core tests` → All passed. - 실 KIS LIVE(읽기 전용): stop-loss/take-profit 시세 `get_current_price('005930')=329000`(tr `FHKST01010100`, BAT-011 CHG-04 정정 검증). - 실데몬 e2e(paper): forced_close 청산 / 장 마감 청산 / update_thresholds RPC / kill_switch global→청산→masking→resume — 전부 PASS. - 실 KIS LIVE SL/TP e2e: 시세→stop_loss 트리거→실 KIS 매도 제출→휴장 거부→롤백 PASS. - 배포 후: - 데몬 `--config` 기동 + 7 워커 + 인스턴스 큐(`trex.*.req[.{instance_key}]`) + `trex.direct`/`trex.broadcast`/control 큐 선언. - 마이그레이션 004/005 적용 확인. - control RPC(pause/resume/list/kill_switch/resume_kill_switch) + update_thresholds RPC 동작. - `instance_key="default"` 무회귀 + `portfolio_hub_token` TOML 주입(S-5). - **차기 거래일 실 KIS**: safety-sell 트리거(SL/TP·forced_close·장 마감) + kill_switch 실매도 → 상황별 에러/체결 관찰. (다중 인스턴스 운영 시) directed 격리 + broadcast manual 확인. ### 검증 한계 / 미검증 영역 (운영자 핸드오프 — 배포 후 차기 거래일/스테이징 실증 대상) > 아래는 배포 차단 사유가 아니라, 운영자가 무엇이 검증됐고 무엇이 안 됐는지 알고 배포하도록 명시한 한계다. 자동화(단위 271 + 인프라 게이트 301) + paper 실데몬 e2e + 읽기전용 LIVE 시세는 통과했으나, **실 KIS 쓰기(체결) 경로**는 아래가 미실증이다. 1. **LIVE 체결 → ledger 기록 미실증**: 모든 LIVE KIS 주문이 휴장(현충일/주말) 거부라 실제 fill 이 발생하지 않음 → `fill → ledger outbox → portfolio-hub` 경로가 실 KIS 환경에서 한 번도 실행되지 않음(REL-001 이월 잔여와 동일 성격). paper e2e 에서만 검증됨. 2. **kill_switch LIVE 미실행**: kill-switch full cycle 은 paper 데몬 e2e 로만 검증. 실 KIS `kill_switch` 실매도 제출 경로는 (SL/TP LIVE e2e 와 달리) LIVE 로 미실행. — SL/TP 와 동일한 `SlotService.sell()`→execution→KIS submit 경로를 공유하므로 간접 신뢰는 있으나 직접 LIVE 관찰은 없음. 3. **실 2-인스턴스 동시 기동 미검증**: directed 라우팅 격리(S-2)/broadcast(S-3)는 실 RabbitMQ 토폴로지(raw pika)로 확인했으나, 실제 `trex-core-daemon --config` **데몬 2개 동시 구동**으로 split-brain 방지(NFR-3)를 실증하진 않음. 현재 배포는 단일 인스턴스(`instance_key="default"`) 기준. 4. **거래일 성공 LIVE 주문 0건 + 운영 환경 최초 적용**: LIVE 주문은 전부 휴장 거부라 실 거래 세션 full-stack 성공 사례 없음. `--config` 필수화(파괴적 기동 변경)와 `005_*.sql` 마이그레이션의 **운영 `trex_core` DB 적용**은 본 배포가 최초(테스트는 `trex_core_test`). 권장 후속(배포 후): 차기 거래일에 (a) safety-sell/kill_switch 실 체결 1건 + ledger 기록 확인, (b) 운영 DB 마이그레이션 004/005 적용 로그 확보, (c) 다중 인스턴스 도입 시 2-인스턴스 라우팅 실증. ## Release Execution Evidence - Release Status Transition Target: released ### Deployment Facts - Executed At: - 2026-06-07 (KST) — trex-core 운영자 배포 - Completed At: - 2026-06-07 (KST) — daemon RUNNING + snapshot RPC live 확인 - Environment: - 운영 대상 trex-core. config: `/root/release/trex-core/temp/config_trex-admin-daily-trading.toml` (`instance_key = "trex-admin-daily-trading"`, `portfolio_hub_token` .env→TOML 이관 완료). 실행 세션 ID: `proc_389fe66bd134`. - Operator: - trex-core 운영자 - Revision or Artifact: - origin/main ≥ `cc063af` (BAT-010~013 포함) - Commands or Procedure: - `.env`→TOML `portfolio_hub_token` 이관 → `trex-core-daemon --config /root/release/trex-core/temp/config_trex-admin-daily-trading.toml` 기동. 마이그레이션 001~005 는 daemon boot `apply_migrations` 로 적용(snapshot/RPC 정상 동작으로 스키마 존재 implicit 확인; 명시 적용 로그는 미회신). ### Profile-Specific Checks - app-service: - Health Endpoint: - HTTP health 없음(RabbitMQ transport). 운영자 확인: daemon **RUNNING / non-degraded**. snapshot RPC `degraded=false`, `reason=null` = 큐 declare readiness + portfolio-hub 도달 동등 신호. - Startup Log Fields: - daemon 기동 + `instance_key="trex-admin-daily-trading"` 로 인스턴스 큐 선언(아래 Request 참조). 7 워커/exchange 개별 기동 로그는 미회신(부분). - Request Log Fields: - **instance_key 접미 큐로 RPC 동작 확인**: `trex.snapshot.req.trex-admin-daily-trading` 호출 → 정상 응답. = BAT-013 `--config` 기동(REQ-048) + 동적 큐명(REQ-049) + token TOML 주입(REQ-048 S-5) LIVE 실증. - Smoke or Manual Verification: - snapshot RPC envelope: `degraded=false`, `reason=null`, `available_slots=10`, `view="all"`, `asset_count=45`. universe 종목 수신 확인(예: 207940, 034020, 009540). → portfolio-hub read + snapshot read 레이어(BAT-008/REQ-027~033) + token 주입 정상. - 미실증(검증 한계 참조, 차기 거래일): 실 KIS 체결→ledger, kill_switch LIVE 실매도, safety-sell 실 트리거, 2-인스턴스 동시 라우팅. (스냅샷은 읽기전용이라 쓰기 경로 미관찰) ### Rollback Outcome - Rollback Required: - no (배포/서비스 롤백 없음 — daemon RUNNING/non-degraded 유지) - Rollback Trigger: - none - Rollback Action: - none ### Release Decision Evidence - Released Decision: - yes (confirmed → released) - Rationale: - 실 환경 배포 + daemon RUNNING/non-degraded + `--config` TOML 기동·instance_key 동적 큐(`trex.snapshot.req.trex-admin-daily-trading`)·portfolio_hub_token TOML 주입·snapshot RPC(degraded=false, universe 45종) LIVE 동작 확인. app-service 운영 확인 바(health 동등 + RPC smoke + universe 수신) 충족. 배포 전 단위 271 + 인프라 게이트 301 + 전 e2e(paper/LIVE 읽기전용) 통과 보강. - **잔여(차기 거래일 실증, blocker 아님)**: Verification Checklist 의 "검증 한계 / 미검증 영역" 4건 — 실 KIS 체결→ledger, kill_switch LIVE, safety-sell 실 트리거, 2-인스턴스 동시 split-brain. 읽기전용 스냅샷 배포 검증 단계에선 미관찰이며 차기 거래일/다중 인스턴스 도입 시 실증. - Recorded By: - trex-core 운영자 (배포·live 확인) / Claude Code 세션 (evidence 문서화) - Recorded At: - 2026-06-07 (KST) ## Feedback Handoff - Observation Summary: - (배포 후, 2026-06-07) 운영자 실 배포 — `config_trex-admin-daily-trading.toml`(instance_key=`trex-admin-daily-trading`, 세션 `proc_389fe66bd134`)로 daemon RUNNING/non-degraded. instance_key 접미 큐 `trex.snapshot.req.trex-admin-daily-trading` snapshot RPC → degraded=false, available_slots=10, asset_count=45, universe 수신(207940/034020/009540 등). `--config` 기동·동적 큐명·token TOML 주입·portfolio-hub read LIVE 실증. (쓰기 경로 4건은 검증 한계대로 차기 거래일 실증 대상) - (배포 전, 2026-06-07) 단위 271 + 인프라 게이트 301 passed, ruff clean. - safety-sell: 실데몬 paper e2e(forced_close/장 마감/update_thresholds) PASS, 실 KIS LIVE SL/TP e2e(시세→트리거→실매도→휴장 거부→롤백) PASS. tr_id 결함 LIVE 검증으로 포착·정정(CHG-04/05). - kill-switch: paper control RPC e2e(kill_switch global→2 청산→masking→resume) PASS. - multi-instance: 인프라 게이트 directed 격리(S-2)/broadcast dual(S-3)/default 무회귀(S-4) 실 RabbitMQ 확인. - Discovery Input: - strategy 모듈(orb-v1) routing key 갱신(`{instance_key}.{channel_type}`) — 별도 모듈 범위. - REQ Input: - pending_buy 슬롯 롤백(dcy-008 OQ-3 Deferred). - Change Request Input: - safety-sell 영속 거부 재시도 백오프/쿨다운(BAT-011 LIVE e2e 발견, 우선순위↑). - 제어 큐 `trex.pause.req` alias 유지 기간/제거 시점 정책. - `--config` 필수화에 따른 배포 스크립트/문서 갱신. - 전체 설정 TOML 일원화(KIS/DSN/RABBITMQ_URL) 후속 검토.