chore(governance): remove legacy StagePilot artifacts
This commit is contained in:
@@ -1,22 +0,0 @@
|
||||
# Release Index
|
||||
|
||||
## 목적
|
||||
- 이 문서는 release 단위의 전역 인덱스다.
|
||||
- 각 release는 하나 이상의 release-candidate batch를 묶고, profile(`docs-only` | `tooling` | `app-service`)에 맞는 배포와 후속 환류를 추적한다.
|
||||
|
||||
## Release Register
|
||||
|
||||
| REL ID | Profile | Status | Included Batch | Discovery/REQ Input | Link |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| REL-001 | app-service | feedback-captured | BAT-001~008 | Discovery: orb-v1 전략 모듈, 부분 매도(#5) / Change-req: REQ-030 옵션 D, 전략 필드 실데이터, 이벤트 publisher idle 견고성, paper execution_id Redis(#4) | [rel-001](rel-001_20260606_trex-core-slot-core-baseline.md) |
|
||||
| REL-002 | tooling | feedback-captured | BAT-009 | Change-req: paper execution_id Redis(#4) | [rel-002](rel-002_20260606_paper-broker-env-tuning.md) |
|
||||
| REL-003 | app-service | feedback-captured | BAT-010, BAT-011, BAT-012, BAT-013 | dcy-007 (자율 안전 매도) + dcy-008 (kill-switch) + dcy-009 (다중 인스턴스 토폴로지) — 통합 릴리즈 | [rel-003](rel-003_20260607_safety-killswitch-multi-instance.md) |
|
||||
| REL-004 | app-service | feedback-captured | BAT-014, BAT-015, BAT-016, BAT-017, BAT-018, BAT-019, BAT-020, BAT-021, BAT-022, BAT-023 | dcy-010 (safety-sell 쿨다운) + dcy-011~017 (buy/sell 계약·KIS 취소·trading_date TZ·ledger 백오프 버그픽스 + 운영자 CLI + 워치독 가시화) + dcy-016 후속(슬롯 상태 가시화) + dcy-018 (ledger 현금/포지션 write-back, option D) — 통합 릴리즈 | [rel-004](rel-004_20260608_safety-cooldown-bugfix-hardening-cli.md) |
|
||||
| REL-005 | app-service | feedback-captured | BAT-024, BAT-025 | dcy-016 후속/issue #17 (operator enter --forced-close-at) + dcy-019/issue #18 (slot entry_count + closed 슬롯 재할당) — 통합 릴리즈 | [rel-005](rel-005_20260609_operator-forced-close-and-slot-reallocation.md) |
|
||||
| REL-006 | app-service | feedback-captured | BAT-026, BAT-027, BAT-028, BAT-029, BAT-030, BAT-031, BAT-032, BAT-033, BAT-034, BAT-035, BAT-036 | dcy-020 (자산 중심 영구 슬롯 α~δ cutover) + dcy-021 (포지션 사이징/issue #1·#5) + dcy-022 (실행 정책/issue #21) + dcy-023 (allocated_capital 제거/issue #22) + dcy-024 (safety_sell_enabled/issue #15) + dcy-025 (slots.req 교체·REQ-028 Deprecated) + REQ-048·010 CHG (config-dir) + REQ-032 CHG (enter --qty/issue #23) — 통합 릴리즈 | [rel-006](rel-006_20260611_asset-centric-sizing-execution-policy.md) |
|
||||
| REL-007 | app-service | feedback-captured | BAT-037, BAT-038, BAT-039, BAT-040, BAT-041 | dcy-025 (REQ-073 CHG — available_slots hint) + dcy-026/issue #24 (매도세 정정) + issue #4 (paper seq Redis) + issue #25 (slots RPC DB 필터) + dcy-027/issue #20 (중장기 인스턴스 프로파일) — 통합 릴리즈 | [rel-007](rel-007_20260612_slots-rpc-fee-paper-longterm.md) |
|
||||
| REL-008 | app-service | feedback-captured | BAT-042, BAT-043, BAT-044, BAT-045, BAT-046 | dcy-028/issue #26 (slot strategy-state) + issue #27 (sell retryable) + dcy-030/issue #28 (호가단위 스냅, P0 체결 복구) + dcy-029/issue #29 (운영 관측성 — 구조화 로깅·주문결과·거부ERROR·reason+actor·PnL CLI·런북) — 통합 릴리즈 | [rel-008](rel-008_20260616_tick-snap-and-observability.md) |
|
||||
| REL-009 | app-service | feedback-captured | BAT-047, BAT-048, BAT-049 | dcy-031/OPS-005 (이벤트 발행 신뢰성 — idle keepalive·재시도·DLQ 경보) + dcy-032 (체결가 0/None 백필 가드·WARN 로깅) + dcy-033 (알람 emitter + trex.alerts exchange 1단계) + dcy-017 후속(무데이터/죽은 종목 위생 런북 docs-only) — M2 통합 릴리즈. 환류: OPS-005 해소 확인, slot_filled NO_ROUTE/DLQ 신규 발견(M3 Discovery 입력) | [rel-009](rel-009_20260625_event-reliability-fill-guard-alarm-runbook.md) |
|
||||
| REL-010 | app-service | released | BAT-050, BAT-051, BAT-052, BAT-053, BAT-054 | dcy-034 (차단형 reconcile + sync/verify cold-start) + dcy-035 (WAC 실현손익 운영리포트) + dcy-036 (KIS 인증정보 휴면 배포 — credential_fetch_enabled=OFF) — M3 통합 릴리즈. 배포 revision `314047b`(2026-06-30). verify ImportError 핫픽스 `51cc3cc` 포함. | [rel-010](rel-010_20260629_reconcile-coldstart-wac-report-credential-dormant.md) |
|
||||
| REL-011 | app-service | released | BAT-057 | dcy-037 (operator broker truth / managed non-holding divergence hotfix) — **M5 trex-core P0 release**. Justin Ko approval (`32675`, 2026-07-16 17:22:50 KST), target `6d90f89`, rollback SHA `7845fbe`, controlled daemon restart, and read-only/dry-run smoke PASS; live sync, config activation, DB migration remain out of scope. | [rel-011](rel-011_20260716_m5_operator-broker-truth-hotfix.md) |
|
||||
| REL-012 | app-service | released | BAT-058 | dcy-038 / REQ-123 (cost-basis canonical parse + unavailable WAC safe sync seed) — **긴급 consumer hotfix**. Immutable daemon payload `81a853a` deployed; manifest `869e07f`; restart and read-only/dry-run acceptance PASS. `sync --live`, config activation, DB migration remain outside rollout scope. | [rel-012](rel-012_20260717_cost-basis-safe-sync-seed-hotfix.md) |
|
||||
@@ -1,114 +0,0 @@
|
||||
# REL-001: trex-core slot-core baseline (daemon + broker + ledger + RabbitMQ transport + portfolio-hub snapshot read)
|
||||
|
||||
- Status: feedback-captured
|
||||
- Profile: app-service
|
||||
- Included Batch: BAT-001, BAT-002, BAT-003, BAT-004, BAT-005, BAT-006, BAT-007, BAT-008
|
||||
|
||||
## Scope
|
||||
- Included:
|
||||
- BAT-001 (REQ-001~004): slot 도메인 seed — 슬롯 상태/전이/일일 preallocate 도메인.
|
||||
- BAT-002 (REQ-005~009): slot-core 데몬 골격 + 슬롯 영속(PostgreSQL single-writer). (당시 HTTP API 는 BAT-007 에서 RabbitMQ transport 로 대체됨 — 아래 Excluded 참조)
|
||||
- BAT-003 (REQ-010): 데몬 dotenv config 로딩.
|
||||
- BAT-004 (REQ-011~015): 브로커 실행 루프 + KIS 주문 어댑터 + 내구성 outbox handoff.
|
||||
- BAT-005 (REQ-016): KIS 토큰 Redis 캐시(재기동/멀티프로세스 생존).
|
||||
- BAT-006 (REQ-017~020): portfolio-hub ledger 통합(fill→ledger 기록, outbox 내구성/idempotency, baseline 정합).
|
||||
- BAT-007 (REQ-021~026): 전략 모듈 ↔ trex-core RabbitMQ(AMQP) 메시지 transport. snapshot/intent/pause RPC + 이벤트 토픽 + DLQ. **HTTP /v1 API 제거.**
|
||||
- BAT-008 (REQ-027~029, 031~033): portfolio-hub 스냅샷 read 레이어 — universe read 포트/어댑터, 일일 스냅샷 스케줄러(baseline), KIS 잔고 기반 포지션 정합 + warning 마스킹, Postgres pause/resume, slot overlay·view·strategy_key 자산 선별, snapshot RPC envelope + degraded 신호, baseline 3문서 정합.
|
||||
- Excluded:
|
||||
- **REQ-030 AC-2/AC-3 (옵션 D — ledger write `*_after` 로 cash/position 갱신)**: portfolio-hub#8 (`ledger/trades` 응답에 `cash_balance_after`/`asset_quantity_after`) 배포 대기로 **이월**. REQ-030 은 AC-1(baseline 스케줄러)만 충족하여 status **Approved 유지(Implemented 아님)**. wiring point(`SnapshotStore.update_cash_position`)는 노출되어 있어 배포 후 1줄 활성화 예정.
|
||||
- **portfolio-hub `/v1/portfolios` 의 전략 필드(active_strategy_id/strategy_params) 실데이터 채움**: 실 `PortfolioItem` 미제공으로 None/`{}` 통과(REQ-027 CHG-04, REQ-029 CHG-04). 단일 전략(orb-v1, strategy_key 미사용) 단계에서 무해. 2번째 전략 도입 시 detail `strategy_set` 보강 또는 별도 change-req 로 해소.
|
||||
- **전략 모듈(orb-v1) 자체**: 본 릴리즈는 trex-core 코어만 포함. 전략 모듈은 별도 Discovery/배포.
|
||||
- BAT-002 가 당시 제공한 HTTP /v1 API 표면: BAT-007 에서 제거됨 — 운영 배포 표면은 RabbitMQ 기반.
|
||||
|
||||
## Rollout Plan
|
||||
1. 사전 점검: PostgreSQL / RabbitMQ / portfolio-hub 도달성 확인. `.env` 구성 검증(`TREX_POSTGRESQL_DSN`, `TREX_RABBITMQ_URL`, `TREX_PORTFOLIO_HUB_BASE_URL`(스킴 포함)·`TREX_PORTFOLIO_HUB_TOKEN`, `TREX_BROKER`(+ kis 시 `TREX_KIS_*`), 선택 `TREX_KIS_REDIS_URL`).
|
||||
2. DB 마이그레이션 적용: `trex_core/adapters/persistence/sql/001~003`(`003_create_snapshot_pause.sql` 포함). 모두 additive.
|
||||
3. 배포 대상 commit SHA 로 trex-core 설치 후 데몬 기동(6 워커 스레드: execution / ledger / intent-rpc / snapshot-rpc / pause-rpc / snapshot-scheduler).
|
||||
4. 기동 직후: 큐 declare 기반 readiness 확인 → snapshot RPC(view=all/buyable/held) → pause/resume RPC → 부팅 스냅샷 `degraded=false`(live portfolio-hub) 확인.
|
||||
|
||||
## Rollback Plan
|
||||
- 첫 릴리즈라 되돌릴 이전 가동 버전이 없음 → 롤백 = **데몬 중지(서비스 정지)**.
|
||||
- DB 마이그레이션은 additive(신규 테이블/컬럼)라 데이터 파괴 없음. 필요 시 데몬 정지 상태 유지하고 `snapshot_pause` 등 신규 테이블은 보존(드롭 불필요).
|
||||
- 트리거 조건 예: 기동 실패, snapshot/pause RPC 비정상, ledger outbox 누락, 정합 검증 오탐으로 과도한 warning 마스킹.
|
||||
|
||||
## Verification Checklist
|
||||
- 배포 전:
|
||||
- 전체 테스트 통과(인프라 게이트 포함): `TREX_RABBITMQ_TEST_URL=... TREX_POSTGRESQL_TEST_DSN=... pytest -q`.
|
||||
- `ruff check trex_core tests` → All checks passed.
|
||||
- REQ-027 CHG-04 정정 계약 재검증 evidence 확인(BAT-008 verification Re-verification Addendum).
|
||||
- 마이그레이션 001~003 적용 확인.
|
||||
- 배포 후:
|
||||
- 데몬 기동 + 6 워커 스레드 + 큐(`trex.snapshot.req`/`trex.intent.req`/`trex.pause.req`)·exchange(`trex.events`)·DLQ 선언 확인.
|
||||
- snapshot RPC envelope: `assets`(배열, null 금지) + meta(`view`/`available_slots`/`degraded`/`reason`), live portfolio-hub 대상 `degraded=false` + universe 수신.
|
||||
- pause RPC: pause → 응답 마스킹, resume → 복귀, 재기동 후 영속 확인.
|
||||
- 브로커 실행/ledger outbox flush 동작(paper 또는 kis 모의).
|
||||
- 포지션 정합 1회 수행 + 불일치 시 warning 마스킹 동작.
|
||||
|
||||
## Release Execution Evidence
|
||||
- Release Status Transition Target: released
|
||||
|
||||
### Deployment Facts
|
||||
- Executed At:
|
||||
- 2026-06-06T11:18:16Z (운영자 Hermes Agent 기동)
|
||||
- Completed At:
|
||||
- 2026-06-06T11:18:16Z (데몬 기동 + RabbitMQ 연결 + intent→KIS→rollback 흐름 검증 완료)
|
||||
- Environment:
|
||||
- Host: 86ba33f2997a / Workdir: /root/release/trex-core / Runtime: `.venv/bin/trex-core-daemon` (실 KIS 계좌 연동, `broker=kis` LIVE)
|
||||
- Operator:
|
||||
- Hermes Agent (운영자) — evidence 본 release 문서로 전달, Claude Code 세션이 문서화/검증 보강.
|
||||
- Revision or Artifact:
|
||||
- 71faa23 (현재 origin/main HEAD). REL-001 코드(BAT-001~008)는 이 revision의 부분집합이며 BAT-009(REL-002)까지 포함된 빌드로 배포됨.
|
||||
- Commands or Procedure:
|
||||
- `.env` 로드 후 `.venv/bin/trex-core-daemon` 기동 → RabbitMQ 연결 및 워커 실행 확인 → RabbitMQ RPC 로 intent 수신 → KIS 제출 → (휴장일) 거절 → slot rollback 흐름 검증.
|
||||
|
||||
### Profile-Specific Checks
|
||||
- app-service:
|
||||
- Health Endpoint:
|
||||
- HTTP health 없음(RabbitMQ transport). 운영자 확인: 데몬 기동 후 RabbitMQ 연결 성립 로그 확인 = 큐 declare readiness 동등 신호. 개별 큐/exchange declare 완료 로그는 부분 확인(코드상 `trex.snapshot.req`/`trex.intent.req`/`trex.pause.req`/`trex.events`/`trex.events.dlq` 선언, RabbitMQ 연결 로그 확인됨).
|
||||
- Startup Log Fields:
|
||||
- 6 워커 스레드 구성 확인(trex-execution / trex-ledger / trex-intent-rpc / trex-snapshot-rpc / trex-pause-rpc / trex-snapshot-scheduler). 데몬 정상 기동 + RabbitMQ 연결 성공 로그.
|
||||
- Request Log Fields:
|
||||
- intent RPC 가 admitted 처리됨(correlation_id 기반 RPC 동작 확인). 개별 request_id 로그 필드는 부분 확인.
|
||||
- Smoke or Manual Verification:
|
||||
- 배포 시점 운영자 검증: RabbitMQ → intent 수신 → execution loop → KIS 실제 제출 → KIS 거절 → slot `pending_buy→idle` 복구 흐름 의도대로 동작 확인(아래 Rollback Outcome).
|
||||
- 보강(동일 revision 71faa23, Claude Code 세션): snapshot RPC `degraded=false` + universe 수신 확인(이전 검증), pause→resume RPC live 검증(이 세션), paper e2e 전체 그룹(admission/read + broker-behavior) 통과. **pre-deploy 테스트 게이트 재현**: 단위 166 passed / 23 skipped, 메시징 통합 16 passed, `ruff check` All passed. (KIS sandbox 1건은 `.env=LIVE` 산물로 deselect — 코드 결함 아님.)
|
||||
|
||||
### Rollback Outcome
|
||||
- Rollback Required:
|
||||
- no (배포/서비스 롤백은 발생하지 않음 — 데몬은 계속 정상 가동)
|
||||
- Rollback Trigger:
|
||||
- none (배포 차원의 롤백 트리거 없음). 참고: 운영자가 보고한 "rollback yes"는 **배포 롤백이 아니라 slot 상태 머신의 정상 거동**이다 — KIS 가 휴장일(2026-06-06 현충일)로 주문을 거절("장운영일자가 주문일과 상이합니다")하자, intent 는 admitted 였던 슬롯이 `pending_buy→idle` 로 복구된 것. broker_order_id / ledger_outbox 체결 흔적 없음 = 정상(체결 안 됨). 이는 매수 거부 경로 smoke 의 **성공 관찰**이다.
|
||||
- Rollback Action:
|
||||
- none (배포 유지). slot-level rollback 은 설계대로 자동 수행됨(REQ-011~015 실행 루프).
|
||||
|
||||
### Release Decision Evidence
|
||||
- Released Decision:
|
||||
- yes (confirmed → released)
|
||||
- Rationale:
|
||||
- 실 환경 배포 + 데몬 정상 기동(6 워커) + RabbitMQ 연결 성공 + 핵심 slot-core 경로(RabbitMQ → intent admitted → execution loop → KIS 실제 제출 → 거절 → slot rollback) live 동작 확인. app-service profile 검증 바(큐 declare readiness=health 동등, startup/RPC 로그, live RPC smoke) 충족. pre-deploy 테스트/ruff 게이트는 동일 revision(71faa23) 재현으로 보강.
|
||||
- **잔여 항목(blocker 아님, 차기 거래일 확인 대상)**: (a) ledger outbox flush(fill→ledger 기록, BAT-006/REQ-017~020)는 휴장일 거절로 **실 체결이 없어 운영 미실증**(paper e2e 에서만 검증). (b) DB 마이그레이션 001~003 적용은 명시 로그 부재 — 단 데몬 boot `apply_migrations` + intent admitted(슬롯 테이블 기록 성공)로 스키마 존재 implicit 확인. (c) 포지션 정합/warning 마스킹 개별 결과 로그 부분 확인(루프는 동작).
|
||||
- Recorded By:
|
||||
- Hermes Agent (released 결정) / Claude Code 세션 (evidence 문서화·게이트 보강)
|
||||
- Recorded At:
|
||||
- 2026-06-06T11:18:16Z (운영자 결정) / 2026-06-07 (KST, 문서 반영)
|
||||
|
||||
## Feedback Handoff
|
||||
> 주의: 아래 Observation Summary 의 1~2번 항목은 **배포 전(pre-deployment) paper-broker e2e/smoke 관찰**이다. REL-001 은 2026-06-06 실 환경 배포 완료로 status `released` 전환됨(Release Execution Evidence 참조). 남은 거버넌스 단계는 `capture-release-feedback`(release `feedback-captured` 전환 + 포함 batch BAT-001~008 `released` 갱신 + 아래 후속 입력 정리)이다.
|
||||
>
|
||||
> 배포 후(post-deployment) 잔여 확인 대상(차기 거래일): (a) **ledger outbox flush(fill→ledger)** — 휴장일 거절로 실 체결이 없어 운영 미실증(paper e2e 에서만 검증). 다음 거래일 실 체결 1건으로 확인 필요. (b) DB 마이그레이션 001~003 명시 적용 로그 확보. (c) 포지션 정합/warning 마스킹 개별 결과 로그 확보.
|
||||
|
||||
- Observation Summary:
|
||||
- (배포 전) paper-broker e2e (2026-06-06): admission/read 그룹(멱등성·매수 거부 no_idle_slot·매도 거부 slot_not_found·pause/resume RPC·pause 는 intent 비차단·snapshot buyable 마스킹·happy-path 이벤트 캡처)과 broker-behavior 그룹(거부 롤백 `idle→pending_buy→idle`·지연 체결 `+3.7s`·부분 체결 qty 누적 `+2.5s`) 전부 통과. snapshot/pause RPC envelope·ledger outbox·슬롯 전이 정상.
|
||||
- (배포 전) 견고성 관찰: 데몬 부팅 후 오래 idle 였던 이벤트 publisher pika 연결이 **첫 발행 시 `StreamLostError(EOF)` 로 1회 끊겼다가 자동 복구**(best-effort 경로, 롤백 없음, 슬롯/ledger 정합 영향 없음). 첫 이벤트 1건 유실 가능.
|
||||
- (배포 후, 2026-06-06T11:18:16Z, 운영자 Hermes Agent) 실 환경(host 86ba33f2997a, `broker=kis` LIVE) 데몬 정상 기동(6 워커) + RabbitMQ 연결 성공. 실 KIS 계좌 대상 RabbitMQ → intent admitted → execution loop → KIS 실제 제출 → KIS 거절(휴장일 "장운영일자가 주문일과 상이합니다") → slot `pending_buy→idle` 자동 복구 흐름 의도대로 동작. broker_order_id/ledger 체결 흔적 없음(정상).
|
||||
- (배포 후 잔여) **ledger outbox flush(fill→ledger)는 운영 미실증** — 현충일 휴장으로 실 체결이 발생하지 않음(paper e2e 에서만 검증). 차기 거래일 실 체결 1건으로 확인 필요. 마이그레이션 001~003 명시 적용 로그·포지션 정합/warning 마스킹 개별 결과 로그도 차기 거래일 보강 대상.
|
||||
- Discovery Input:
|
||||
- 전략 모듈(orb-v1) Discovery — REQ-029 CHG-04 소비 참고 사항 입력.
|
||||
- 부분 매도(한 슬롯 수량 일부) 능력 — 현재 미구현(전량 매도만). 신규 Discovery 후보. (GitHub #5)
|
||||
- REQ Input:
|
||||
- 없음 (본 release 환류에서 신규 REQ 후보 없음; 후속 작업은 Discovery/Change Request 입력 및 차기 거래일 운영 실증으로 처리)
|
||||
- Change Request Input:
|
||||
- REQ-030 옵션 D 활성화(portfolio-hub#8 배포 후) — cash/position `*_after` 갱신.
|
||||
- 전략 필드 실데이터 채움(2번째 전략 도입 시) — REQ-027/REQ-029 연계.
|
||||
- 이벤트 publisher idle 연결 견고성(BAT-007 / REQ-022·024) — 발행 전 heartbeat/재연결 또는 idle 후 첫 발행 재시도로 첫 이벤트 유실 방지. (배포 전 관찰)
|
||||
- paper 모드 마지막 execution_id Redis 영속 — 재기동 시 PAPER seq 리셋에 의한 correlation_id 충돌(ON CONFLICT dedup) 회피. paper 전용 테스트 견고성(운영 KIS odno 는 고유라 무해). (GitHub #4)
|
||||
@@ -1,86 +0,0 @@
|
||||
# REL-002: paper broker 튜닝 env 노출 (e2e 시나리오 재현)
|
||||
|
||||
- Status: feedback-captured
|
||||
- Profile: tooling
|
||||
- Included Batch: BAT-009
|
||||
|
||||
## Scope
|
||||
- Included:
|
||||
- BAT-009 (REQ-010 CHG-20260606-01 / AC-5): paper broker 튜닝 knob(REQ-011 AC-2 지연/부분/거부 시나리오)을 데몬 env(`TREX_PAPER_FILL_AFTER_POLLS`/`TREX_PAPER_QTY_PER_POLL`/`TREX_PAPER_REJECT_SYMBOLS`)로 노출. `PaperBrokerConfig` + `DaemonConfig.from_env` 파싱 + `_build_broker` 주입 + `.env.example` 문서화.
|
||||
- Excluded:
|
||||
- PaperBroker 내부 체결 로직(REQ-011 에서 구현·검증, 본 release 변경 아님).
|
||||
- kis broker 경로(`broker=kis` 시 paper config 무시).
|
||||
- REL-001(BAT-001~008) baseline — 별도 release.
|
||||
|
||||
## Rollout Plan
|
||||
1. 사전 점검: 본 변경은 `broker=paper` 일 때만 동작하며 미설정 env == 기존 `PaperBroker()` 동작(byte-for-byte). 운영(`broker=kis`) 데몬에는 런타임 영향 없음.
|
||||
2. 대상 commit SHA(`bat-009` 브랜치)를 main 에 병합 후 배포 대상에 설치.
|
||||
3. 별도 데몬 재기동/마이그레이션 불필요(코드/설정 표면 추가뿐, DB 스키마 변경 없음). e2e 환경에서 필요 시 `TREX_PAPER_*` env 로 시나리오 구성.
|
||||
|
||||
## Rollback Plan
|
||||
- 되돌릴 이전 동작 = paper 기본 동작이며, `TREX_PAPER_*` 를 미설정으로 두면 본 변경 이전과 동일. 코드 롤백 필요 시 BAT-009 커밋만 revert(타 batch 비의존).
|
||||
- 트리거 조건: env 파싱 회귀, 미설정 시 기본 동작 변화 징후(있을 경우). 운영 broker=kis 경로는 본 변경 미참조라 트리거 대상 아님.
|
||||
|
||||
## Verification Checklist
|
||||
- 배포 전:
|
||||
- 단위: `pytest tests/runtime/test_config_dotenv.py` 6 passed(기존 4 + paper 기본/파싱 2). 전체 `pytest --deselect ...::test_sandbox_token_and_submit` 167 passed / 23 skipped.
|
||||
- `ruff check trex_core tests` All checks passed.
|
||||
- BAT-009 verification.md(Ready for Release: true, blocker 없음) 확인.
|
||||
- 배포 후:
|
||||
- `broker=paper` 데몬에서 `TREX_PAPER_*` 미설정 → 즉시 전량 체결·거부 없음(기존 동작) 확인.
|
||||
- 필요 시 e2e: 거부 롤백(`TREX_PAPER_REJECT_SYMBOLS`)·지연(`TREX_PAPER_FILL_AFTER_POLLS`)·부분(`TREX_PAPER_QTY_PER_POLL`) 재현(BAT-009 evidence 동일).
|
||||
- `broker=kis` 데몬 동작 무변화(paper config 무시) 확인.
|
||||
|
||||
## Release Execution Evidence
|
||||
- Release Status Transition Target: released
|
||||
|
||||
### Deployment Facts
|
||||
- Executed At:
|
||||
- 2026-06-06 (KST) — `bat-009` → main 병합 시작
|
||||
- Completed At:
|
||||
- 2026-06-06 (KST) — origin/main push 완료
|
||||
- Environment:
|
||||
- main @ origin (GitHub fourblocks2020/trex-core). 코드/패키지 변경 — 별도 서비스 배포 대상 없음(tooling).
|
||||
- Operator:
|
||||
- Justin Ko (Claude Code 세션)
|
||||
- Revision or Artifact:
|
||||
- 7b6ed55 (REL-002 docs) / 2f57aad (BAT-009 코드). push: `ca75700..7b6ed55 main -> main`
|
||||
- Commands or Procedure:
|
||||
- `git merge --ff-only bat-009-paper-broker-env-tuning` → `git push origin main`. DB 마이그레이션·데몬 재기동 없음.
|
||||
|
||||
### Profile-Specific Checks
|
||||
- tooling:
|
||||
- Install or Upgrade Smoke:
|
||||
- `DaemonConfig.from_env()` 정상 로드(단위 test_config_dotenv 6 passed). paper 기본값 미설정 시 정상.
|
||||
- CLI or Script Execution:
|
||||
- 데몬 `TREX_PAPER_*` env 재기동으로 거부 롤백 / 지연(+3.7s) / 부분(+2.5s) 시나리오 재현 확인(BAT-009 verification evidence).
|
||||
- Compatibility Note:
|
||||
- 미설정 시 기존 `PaperBroker()` 동작 byte-for-byte(회귀 없음, 전체 167 passed). `broker=kis` 경로 paper config 미참조 → 운영 데몬 무영향.
|
||||
|
||||
### Rollback Outcome
|
||||
- Rollback Required:
|
||||
- no
|
||||
- Rollback Trigger:
|
||||
- none
|
||||
- Rollback Action:
|
||||
- none (필요 시 2f57aad revert; 타 batch 비의존)
|
||||
|
||||
### Release Decision Evidence
|
||||
- Released Decision:
|
||||
- yes (confirmed → released)
|
||||
- Rationale:
|
||||
- 배포 전/후 검증 충족, blocker 없음, additive·하위호환·운영 런타임 무영향 tooling 변경. main 병합 + origin push 로 변경 게시 완료.
|
||||
- Recorded By:
|
||||
- Justin Ko (Claude Code 세션)
|
||||
- Recorded At:
|
||||
- 2026-06-06 (KST)
|
||||
|
||||
## Feedback Handoff
|
||||
- Observation Summary:
|
||||
- 소규모 tooling 릴리즈(BAT-009, paper 브로커 env 튜닝 — REQ-010 CHG-20260606-01/AC-5). additive·하위호환·운영 런타임 무영향. 배포 후 별도 운영 관찰 이슈 없음.
|
||||
- Discovery Input:
|
||||
- 없음
|
||||
- REQ Input:
|
||||
- 없음
|
||||
- Change Request Input:
|
||||
- paper 모드 마지막 execution_id Redis 영속(재기동 PAPER seq 리셋 → correlation_id 충돌 회피, GitHub #4) — paper 전용 테스트 견고성.
|
||||
@@ -1,125 +0,0 @@
|
||||
# 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 <path>.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) 후속 검토.
|
||||
@@ -1,154 +0,0 @@
|
||||
# REL-004: safety-sell 쿨다운 + 운영 버그픽스/하드닝 + 운영자 CLI + 슬롯 가시화·현금 write-back 통합 릴리즈
|
||||
|
||||
- Status: feedback-captured
|
||||
- Profile: app-service
|
||||
- Included Batch: BAT-014, BAT-015, BAT-016, BAT-017, BAT-018, BAT-019, BAT-020, BAT-021, BAT-022, BAT-023
|
||||
|
||||
## Scope
|
||||
- Included:
|
||||
- BAT-014 (dcy-010 / REQ-052~054): safety-sell per-slot 재시도 쿨다운 + 영속 거부 경고
|
||||
- BAT-015 (dcy-011 / REQ-007·018·021 change-req + REQ-055): buy intent portfolio_id 필수화 + symbol 서버 resolve + ledger skip 가시화 + closed↔outbox anti-join 점검
|
||||
- BAT-016 (dcy-012 / REQ-002·003·006·007·013·015·036 change-req): 매도 가격 버그 정정 — 슬롯 `entry_price`→`limit_price` rename(+마이그레이션 006) + dispatch 단일 필드 + sell optional 가격
|
||||
- BAT-017 (dcy-013 / REQ-012·013·014·015·018·031 change-req): KIS 외부 취소 감지(cncl_yn) + 부분 체결 회계 + pending stale 워치독(Alert-only)
|
||||
- BAT-018 (dcy-014 / REQ-005·009·048 change-req): trading_date 설정 타임존(KST) 분리 + 일자 경계 일일 preallocation
|
||||
- BAT-019 (dcy-015 / REQ-017·018·019·020 change-req): ledger outbox 영속 오류 분류 + 지수 백오프/dead-letter(+마이그레이션 007)
|
||||
- BAT-020 (dcy-016 / REQ-021·022·026·032·034 change-req): 운영자 CLI 확장(universe/slots/enter/exit, 데몬 RPC 통일) + 워치독 억제 읽기
|
||||
- BAT-021 (dcy-017 / REQ-021·032·034·037·038·039·042 change-req): 워치독 소유권 가시화(snapshot 워치독 상태 + safety-sell 발동 로깅)
|
||||
- BAT-022 (dcy-016 후속 / REQ-028·032 change-req): `trex-core slots` 가 universe `assets[]` 대신 실제 슬롯 상태를 표시 — snapshot envelope 에 read-only `slots[]`(slot_id/status/symbol/qty/limit_price/avg_price/portfolio_id) additive 추가, `universe`/`slots` 표면 분리
|
||||
- BAT-023 (dcy-018 / REQ-017·019·029·030 change-req, REQ-030 Approved→Implemented): ledger write 응답 cash/position write-back(option D 활성화) — portfolio-hub#8 응답 `cash_balance_after`/`asset_quantity_after` 파싱 후 `SnapshotStore` write-back(best-effort), 체결~write-back 공백은 추정 현금 오버레이(`cash_estimated`)로 메움. "수량 live·현금 stale" 비대칭 제거
|
||||
- Excluded:
|
||||
- BAT-001~013 (REL-001/002/003 에서 이미 released)
|
||||
- dcy-018 이후 후속 주제, Redis projection·push 알림(dcy-017 OQ-1 미채택), dead-letter 재처리 트리거(dcy-015 후속), 슬롯 오버레이 제거(dcy-018 OQ-1 B 로 유지 확정)
|
||||
|
||||
## Rollout Plan
|
||||
1. 배포 전: 대상 인스턴스 데몬 정지(또는 거래 세션 외 시간), 현재 리비전 SHA 기록.
|
||||
2. DB 마이그레이션 적용(멱등): `006_rename_entry_price_to_limit_price.sql`(daily_slot 컬럼 rename) + `007_ledger_outbox_delivery_failed_and_backoff.sql`(status enum/next_retry_at). 데몬 기동 시 `apply_migrations` 가 자동 적용하나, 운영 `trex_core` DB 에 최초 적용되므로 사전 백업 권장.
|
||||
3. 신 리비전(`6d7bca1` 또는 그 이후 main HEAD) 배포 + 데몬 재기동(`--config <inst>.toml`). 기동 로그에서 RUNNING/비-degraded 확인.
|
||||
4. 스냅샷 RPC degraded=false·available_slots·asset_count 확인. snapshot envelope 에 `slots[]`(per-slot 상태)·`watchdog[]` 노출 확인(BAT-022). trading_date 가 KST 당일과 일치하는지 확인.
|
||||
5. 운영자 CLI 스모크: `trex-core universe`(=`assets[]`)/`slots`(=실제 슬롯 상태·status·워치독 표시, BAT-022) — paper 또는 비거래 시간.
|
||||
6. (가능 시) paper buy/sell 1회 후 `trex-core universe` 에서 `cash_balance`·`asset_quantity` 가 **함께** 갱신(write-back) 또는 `cash_estimated` 추정 라벨 노출 확인(BAT-023).
|
||||
7. 거래 세션 재개.
|
||||
|
||||
## Rollback Plan
|
||||
- 조건: 기동 실패, 마이그레이션 오류, buy/sell admission·집행 회귀, ledger 전송 비정상, safety-sell 오작동.
|
||||
- 절차: 신 리비전 → 직전 released 리비전(REL-003 시점)으로 롤백 + 데몬 재기동.
|
||||
- 주의: 마이그레이션 006(컬럼 rename)은 비가역적 rename 이다 — 롤백 시 구 코드는 `entry_price` 컬럼을 기대하므로, 코드 롤백과 함께 역마이그레이션(`limit_price`→`entry_price` rename) 또는 컬럼 alias 가 필요하다. 007 은 additive(컬럼/enum 추가)라 구 코드와 공존 가능. 배포 전 역마이그레이션 스크립트를 준비한다.
|
||||
- 데이터: 마이그레이션은 순수 rename/additive 라 행 데이터 보존. ledger_outbox `delivery_failed` 행은 롤백 후 구 코드가 모르는 status 이므로 list_pending 에서 자연 제외(무해).
|
||||
|
||||
## Verification Checklist
|
||||
- 배포 전:
|
||||
- 전체 인프라 게이트 테스트 green (PG `trex_core_test` + RabbitMQ): BAT-023 verification 시점(main HEAD `2bfecd5`, BAT-022 `63da87c` 포함) **`385 passed`**(pending_cash_delta SQL 포함) — 확장 범위 반영 완료. (참고: 최초 confirm 시점 BAT-014~021 범위는 `369 passed`)
|
||||
- `ruff check trex_core tests` All passed (BAT-022/023 변경 파일 포함).
|
||||
- 마이그레이션 006/007 idempotent 재적용 확인(컬럼 계약 가드 green). BAT-022/023 은 신규 마이그레이션 없음(snapshot 필드 additive + 코드-only write-back).
|
||||
- 역마이그레이션(006 rename 되돌리기) 스크립트 준비.
|
||||
- 배포 후:
|
||||
- 데몬 RUNNING + 비-degraded, 8개 백그라운드 스레드 기동(`trex-preallocation` 포함).
|
||||
- trading_date == KST 당일, 슬롯 preallocation 정상.
|
||||
- 스냅샷 RPC envelope(assets/available_slots/degraded) 정상 + `watchdog`·`slots[]` 필드 노출(BAT-022).
|
||||
- `trex-core universe`(assets[])/`slots`(실제 슬롯 상태·status·워치독 소유 표시) 응답 정상.
|
||||
- (가능 시) paper buy/sell 1회 e2e: portfolio_id 기반 admission → 체결 → ledger 기록 → `cash_balance`·`asset_quantity` write-back(또는 `cash_estimated` 추정 라벨) 확인(BAT-023).
|
||||
|
||||
## Pre-Release Run Evidence (operator-facing smoke)
|
||||
|
||||
confirm-release 전 "운영자가 쓰는 프로그램이 실제로 동작한다"는 run-the-app 증거. 테스트 통과(369 passed)와 별개로 실 데몬 기동 + `trex-core` CLI 구동을 검증했다.
|
||||
|
||||
> 주: 아래 base run 증거는 BAT-014~021 범위(REL-004 최초 confirm) 시점의 것이다. BAT-022·BAT-023 편입 범위의 run/test 증거는 바로 아래 "확장 범위 증거(BAT-022/023)"에 추가했다.
|
||||
|
||||
### 확장 범위 증거 (BAT-022 / BAT-023, 재-confirm)
|
||||
|
||||
- **BAT-022 (슬롯 상태 가시화) — 실 인프라 운영 재현 PASS**: 신규 코드 데몬 재기동(`trex-core-daemon --config config/test.toml`, PID 2965049) 후 `trex-core slots` → `instance=test status=all count=10` 으로 **10개 슬롯 각각 status(idle)·slot_id·qty·limit·avg·pid 표시**(이전 갭: universe 1개·status 없음 해소). `slots --status holding` → `count=0`(필터 동작). `trex-core universe` → `assets=1`(universe 유지, slots↔universe 분리 실증). DB `daily_slot (2026-06-08,'idle',10)` 와 정확히 일치. 요청은 `actor=operator`/`touch_watchdog=false`(비침습). 단위 회귀 `338 passed`.
|
||||
- **BAT-023 (현금/포지션 write-back, option D) — 인프라 게이트 PASS**: PG `trex_core_test` + RabbitMQ 인프라 게이트 **`385 passed`**(option D write-back 11 + adapter `*_after` 파싱 + `pending_cash_delta` SQL 포함), 단위 `350 passed / 35 skipped`, `ruff` clean. write-back(new/duplicate 멱등)·`*_after` 누락 skip·best-effort 무차단·추정 현금 오버레이(`cash_estimated`) 수렴 전부 green.
|
||||
- **한계(운영 배포 검증으로 이월)**: BAT-023 의 실 portfolio-hub#8 full-stack option D e2e(실 `*_after` 응답 → 스냅샷 cash/quantity 갱신)는 paper/단위로 커버했고, LIVE full-stack 은 아래 Release Execution Evidence(실 배포)에서 확인한다. BAT-022 의 pytest 인프라 게이트 미실행은 verification Human Approval Memo 로 수용된 잔여(실 인프라 운영 재현이 동등 이상 경로 커버).
|
||||
|
||||
- 환경: paper 브로커 + 테스트 PostgreSQL(`trex_core_test`) + 테스트 RabbitMQ, portfolio-hub stub(universe 2종), `--config <inst.toml>`(instance_key=`rel004-smoke`), revision = main HEAD(수정 후).
|
||||
- 데몬 기동: `trex-core-daemon --config ...` → 마이그레이션 적용(006/007 포함), RabbitMQ 연결, snapshot scheduler boot(stub universe swap), preallocation, 8 스레드 기동, RUNNING. 기동 후 에러 로그 없음.
|
||||
- 운영자 CLI(데몬 RPC 통일) 구동 결과:
|
||||
- `trex-core universe` → snapshot RPC, assets 출력, degraded=false (BAT-020).
|
||||
- `trex-core slots` / `slots --status held --json` → 보유 슬롯 + `watchdog` 필드(slot_id/expired/last_seen) 노출 (BAT-021/dcy-016).
|
||||
- `trex-core enter pf-005930 --capital ... --yes` → `status=admitted slot_id=...` → paper 체결 → holding (BAT-015/018).
|
||||
- `trex-core enter ... --dry-run` → 미제출 미리보기(안전장치), `--json`+enter 는 `--yes` 강제 (BAT-020).
|
||||
- `trex-core exit <slot_id> --yes` → `status=admitted` → 시장가 매도 체결 → closed(held count 0) (BAT-016).
|
||||
- `ledger_outbox`: buy/sell 모두 `status=completed`(outbox durability + writer drain, BAT-019 경로 정상).
|
||||
- **검출·수정한 결함(이 run 이 아니었으면 release 에 포함됐을 버그)**: `Daemon._resolve_symbol` 이 `SnapshotAsset.symbol`(존재하지 않음)을 접근해 데몬 buy admission 이 매 요청 `AttributeError` → intent RPC 타임아웃. **실 데몬 buy 가 전면 불능**이었으나 단위 테스트는 stub resolver 를 주입해 미검출(369 passed). `asset.item.symbol` 로 수정 + 회귀 테스트(`tests/runtime/test_daemon_resolve_symbol.py`) 추가 → 재기동 후 buy/sell e2e 정상(REQ-007 CHG-20260608-03). 수정 후 단위 `337 passed`.
|
||||
- 한계: 실계좌(LIVE KIS) 주문은 미검증(paper 한정) — LIVE full-stack 은 운영자 배포 evidence(아래)에서 확인.
|
||||
|
||||
## Release Execution Evidence
|
||||
- Release Status Transition Target: released
|
||||
|
||||
### Deployment Facts
|
||||
- Executed At:
|
||||
- 2026-06-09 13:31:33 KST (+0900)
|
||||
- Completed At:
|
||||
- 2026-06-09 13:31:33 KST (+0900)
|
||||
- Environment:
|
||||
- 운영 trex_core DB + instance_key `trex-admin-daily-trading`
|
||||
- Operator:
|
||||
- 진환 고
|
||||
- Revision or Artifact:
|
||||
- `fec9411d330d0722c5b7970ad33e651ee479fd30` (`fec9411`)
|
||||
- Commands or Procedure:
|
||||
- 배포 후 데몬 재기동 및 운영자 CLI 스모크 검증(`trex-core universe`, `trex-core slots`, buy/sell e2e, ledger outbox/portfolio-hub 반영 확인)
|
||||
|
||||
### Profile-Specific Checks
|
||||
- app-service:
|
||||
- Health Endpoint:
|
||||
- 2026-06-09 13:31:33 KST 기준 snapshot RPC `degraded=False`, `assets=45` 확인
|
||||
- Startup Log Fields:
|
||||
- 데몬 기동 상태 양호; `trex-core-daemon --config temp/config_trex-admin-daily-trading.toml` 정상 실행 중, `watchdog_owned` 슬롯 존재 및 CLI 응답 정상
|
||||
- Request Log Fields:
|
||||
- buy/sell intent RPC 및 safety-sell 처리 로그에서 correlation/transition 확인 가능
|
||||
- Smoke or Manual Verification:
|
||||
- `trex-core universe --config temp/config_trex-admin-daily-trading.toml` 정상 응답
|
||||
- `trex-core slots --config temp/config_trex-admin-daily-trading.toml` 정상 응답
|
||||
- buy/sell e2e 확인: `holding -> pending_sell -> closed` via `take_profit` 및 `forced_close_at` 트리거 모두 확인
|
||||
|
||||
### Rollback Outcome
|
||||
- Rollback Required:
|
||||
- no
|
||||
- Rollback Trigger:
|
||||
- none
|
||||
- Rollback Action:
|
||||
- none
|
||||
|
||||
### Release Decision Evidence
|
||||
- Released Decision:
|
||||
- released
|
||||
- Rationale:
|
||||
- REL-004 범위의 safety-sell 쿨다운/forced_close_at/take_profit/stop_loss, operator CLI, ledger write-back, slot 가시화가 실 운영 검증에서 동작함을 확인했고, 회귀를 유발하는 배포 장애나 롤백 트리거는 관측되지 않았다.
|
||||
- Recorded By:
|
||||
- 진환 고
|
||||
- Recorded At:
|
||||
- 2026-06-09 13:31:33 KST (+0900)
|
||||
|
||||
### Post-release Verification Evidence (2026-06-09)
|
||||
- Trading flow evidence:
|
||||
- buy intent admitted for portfolio `1c53b936-d69d-41c4-9ce2-4a2b5baa4301`
|
||||
- sell intent admitted for the same slot
|
||||
- final slot state: `closed`
|
||||
- slot id: `73e7cfae-1a92-498a-bf3d-bfe347f7b5e4`
|
||||
- symbol: `316140`
|
||||
- qty: `1.0`
|
||||
- avg price: `28950.0`
|
||||
- take-profit verification: slot `3a95d0cb-0f4c-49da-88d5-5a709f671ccc` transitioned `holding -> pending_sell -> closed` with `reason=take_profit` and daemon log `safety-sell fired: phase=take_profit`
|
||||
- Ledger/outbox evidence:
|
||||
- daemon log recorded `POST http://localhost:8002/v1/portfolios/1c53b936-d69d-41c4-9ce2-4a2b5baa4301/ledger/trades` returning `HTTP/1.1 201 Created` for both buy and sell writes
|
||||
- `ledger_outbox` rows for buy/sell were both `status=completed` and `last_outcome=completed`
|
||||
- portfolio-hub visibility evidence:
|
||||
- `GET /v1/portfolios` returned the portfolio row for `1c53b936-d69d-41c4-9ce2-4a2b5baa4301`
|
||||
- visible state in portfolio-hub list: `symbol=316140`, `cash_balance=-208.65499999999884`, `asset_quantity=0.0`, `price=28750.0`, `updated_at=2026-06-09T00:11:29.252209Z`
|
||||
- the openapi contract exposes `POST /v1/portfolios/{portfolio_id}/ledger/trades`; no read-only GET ledger endpoint was found, so visibility was confirmed through the portfolio summary row and outbox completion logs
|
||||
|
||||
## Feedback Handoff
|
||||
- Observation Summary:
|
||||
- 2026-06-09 실 운영 배포(instance `trex-admin-daily-trading`, rev `fec9411`)에서 REL-004 범위가 정상 동작 확인: buy/sell e2e(`holding→pending_sell→closed`, slot `73e7cfae…` symbol 316140), `take_profit` 트리거(slot `3a95d0cb…`, daemon log `safety-sell fired: phase=take_profit`)·`forced_close_at` 트리거 발동, ledger `POST …/ledger/trades 201 Created`(buy/sell)·`ledger_outbox status=completed`, snapshot RPC `degraded=False assets=45`, portfolio-hub `GET /v1/portfolios` 가시성. 롤백 트리거 없음(Rollback Required=no).
|
||||
- 관찰 포인트: 한 바퀴(buy→sell) 후 portfolio-hub 상태가 `cash_balance=-208.65…`(음수)·`asset_quantity=0.0`. 수수료/세금 반영의 정상 순값인지 vs 초기 cash seed 부재/현금 회계 갭인지 확인 가치 있음(option D write-back 경로는 동작).
|
||||
- 별개 운영 환류: issue #16(00:00 KST 일자 경계 자동 preallocation 누락)이 동일 인스턴스에서 관측됨 — 데몬은 RPC 응답(살아 있음)하나 당일 슬롯 미생성. REL-004 BAT-018(일자 경계 일일 preallocation) 범위와 직접 관련.
|
||||
- Discovery Input:
|
||||
- issue #16: 00:00 KST 일자 경계 자동 preallocation 누락 — `trex-preallocation` 스레드 생존/일자 경계 발화 검증 + 견고화(boot run_once 예외 흡수 등). BAT-018 후속 운영 환류(High 우선).
|
||||
- issue #18 → **dcy-019**(slot `entry_count` + closed 슬롯 재할당 정책) 이미 confirmed — REQ 초안 대기.
|
||||
- (관찰) portfolio-hub 음수 `cash_balance` 정합성 — 필요 시 별도 Discovery 후보.
|
||||
- REQ Input:
|
||||
- issue #17 → **BAT-024**(operator `enter --forced-close-at`, REQ-032 CHG-20260609-01/02) 이미 release-candidate. **REL-004 미포함** → 차기 release(REL-005 또는 통합)로 별도 배포 필요.
|
||||
- 신규 REQ 특이 후보 없음(이번 주기 변경은 대부분 change-req 로 처리됨).
|
||||
- Change Request Input:
|
||||
- `daily_symbol_entries`(심볼 재진입 카운터) 제거 — production 소비자 없음 확인 + 심볼 재진입 제한 미사용 결정(dcy-019). **REQ-002 change-req 트랙**(별도 batch-lite).
|
||||
@@ -1,119 +0,0 @@
|
||||
# REL-005: operator enter --forced-close-at + slot entry_count·closed 재할당 통합 릴리즈
|
||||
|
||||
- Status: feedback-captured
|
||||
- Profile: app-service
|
||||
- Included Batch: BAT-024, BAT-025
|
||||
|
||||
## Scope
|
||||
- Included:
|
||||
- BAT-024 (dcy-016 후속 / issue #17 / REQ-032 CHG-20260609-01): 운영자 `trex-core enter` 에 `--forced-close-at <ISO8601>`(절대시간) 옵션 추가 — 매수 진입 명령 하나로 시간 기반 자동청산(forced_close) 시각 지정. CLI 가 buy intent payload 의 기존 `forced_close_at` 필드에 매핑(계약·도메인·forced-close 루프 이미 구현·불변, CLI 노출 갭만 보완). 잘못된 형식 사전 거부, 미지정 시 미포함(하위호환). 상대시간(`--hold-minutes`) 미채택.
|
||||
- BAT-025 (dcy-019 / issue #18 / REQ-002·003·006·007·009 CHG-20260609-01): slot-scoped `entry_count`(기본 0) 필드 + 멱등 마이그레이션 008, 상태 머신 `closed→pending_buy` 신규 전이(base 8→9), buy admission 후보를 idle∪closed 로 확장하고 `entry_count→updated_at→slot_id` 결정적 정렬로 선택(`find_allocatable_slot`) + closed 직접 재할당, `→pending_buy` 시 entry_count +1 / closed→pending_buy clean-slate 점유 초기화. 기존 `daily_symbol_entries`(symbol-scoped) 분리·미변경.
|
||||
- Excluded:
|
||||
- BAT-001~023 (REL-001/002/003/004 에서 이미 released)
|
||||
- `daily_symbol_entries` 제거(dcy-019 Out of Scope — 별도 REQ-002 change-req 트랙)
|
||||
- 운영자 CLI/스냅샷에 slot `entry_count` 노출 (dcy-019 §5 제외 — 후속 후보)
|
||||
- snapshot `available_slots`(=idle_count) capacity 의미 변경 (dcy-019 범위 밖)
|
||||
|
||||
## Rollout Plan
|
||||
1. 배포 전: 대상 인스턴스 데몬 정지(또는 거래 세션 외 시간), 현재 리비전 SHA 기록.
|
||||
2. DB 마이그레이션 적용(멱등): `008_add_slot_entry_count.sql`(daily_slot 에 `entry_count INTEGER NOT NULL DEFAULT 0` additive 추가). 데몬 기동 시 `apply_migrations` 가 자동 적용. additive 컬럼이라 기존 행은 0 으로 채워짐(무해).
|
||||
3. 신 리비전(REL-005 배포 SHA) 배포 + 데몬 재기동(`--config <inst>.toml`). 기동 로그에서 RUNNING/비-degraded 확인.
|
||||
4. 스냅샷 RPC degraded=false·available_slots·asset_count 확인. trading_date 가 KST 당일과 일치하는지 확인.
|
||||
5. 운영자 CLI 스모크(paper 또는 비거래 시간):
|
||||
- `trex-core enter <pf> --capital ... --forced-close-at 2026-06-09T15:00:00+09:00 --yes` → admitted + 슬롯 `forced_close_at` 설정 확인(BAT-024). 잘못된 형식(`--forced-close-at zzz`)은 제출 전 거부.
|
||||
- idle 슬롯 소진 후(또는 일부 closed 상태에서) 추가 buy → closed 슬롯 재할당으로 admit 되고 `no_idle_slot` 거부가 사라지는지 확인(BAT-025). 슬롯 회전이 `entry_count` 기준 고르게 분산되는지 관측.
|
||||
6. 거래 세션 재개.
|
||||
|
||||
## Rollback Plan
|
||||
- 조건: 기동 실패, 마이그레이션 오류, buy admission/슬롯 선택 회귀(잘못된 슬롯 재사용·상태 오염), CLI `--forced-close-at` 오작동.
|
||||
- 절차: 신 리비전 → 직전 released 리비전(REL-004 시점, `fec9411`)으로 롤백 + 데몬 재기동.
|
||||
- 마이그레이션: 008 은 **additive(ADD COLUMN)** 라 구 코드와 공존 가능(구 코드는 `entry_count` 컬럼을 읽지/쓰지 않고, DEFAULT 0 으로 INSERT 무해) — 역마이그레이션 불필요. 필요 시 `ALTER TABLE daily_slot DROP COLUMN IF EXISTS entry_count` 로 제거 가능(데이터 영향: entry_count 값만 소실, slot 핵심 상태 보존).
|
||||
- 데이터: closed→pending_buy 재할당으로 전이한 슬롯은 롤백 후에도 구 코드 상태 머신과 호환(pending_buy/holding/closed 는 기존 상태) — 추가 조치 불필요.
|
||||
|
||||
## Verification Checklist
|
||||
- 배포 전:
|
||||
- 단위 전체 회귀 green: BAT-025 verification 시점 `366 passed / 35 skipped / 1 deselected`(`::test_sandbox_token_and_submit` 은 LIVE `.env` KIS URL 환경 의존으로 deselect — 본 릴리즈 무관). BAT-024 단위 `353 passed`.
|
||||
- `ruff check trex_core tests` All passed.
|
||||
- 마이그레이션 008 idempotent 재적용 + 컬럼 계약 가드(`EXPECTED_SLOT_FIELDS`↔information_schema, entry_count 포함) green — test DSN 환경(`TREX_POSTGRESQL_TEST_DSN`)에서 확인(라이브 runtime DSN 은 `pg_clean` TRUNCATE 가 파괴적이라 미사용).
|
||||
- 배포 후:
|
||||
- 데몬 RUNNING + 비-degraded, 백그라운드 스레드 기동(`trex-preallocation` 포함).
|
||||
- trading_date == KST 당일, 슬롯 preallocation 정상, daily_slot `entry_count` 컬럼 존재.
|
||||
- `trex-core enter <pf> --forced-close-at <ISO8601> --yes` → admitted + 슬롯 forced_close_at 설정. 잘못된 형식 사전 거부.
|
||||
- closed 슬롯 재할당 e2e: idle 소진 상황에서 buy 가 closed 슬롯으로 admit(`entry_count` +1), 선택이 최저 진입 우선·결정적인지 확인.
|
||||
|
||||
## Pre-Release Run Evidence (operator-facing smoke)
|
||||
|
||||
confirm-release 전 "운영자가 쓰는 프로그램이 실제로 동작한다"는 run-the-app 증거. 단위 테스트(366 passed)와 별개로, 실 데몬(RabbitMQ + 실 PostgreSQL) 기동 + `trex-core` CLI 구동으로 REL-005 의 두 신규 동작(BAT-024 `enter --forced-close-at`, BAT-025 closed 슬롯 재할당)을 검증했다. (`run-trex-core-daemon` 프로젝트 skill 경로 사용.)
|
||||
|
||||
- 환경: paper 브로커 + **테스트 PostgreSQL `trex_core_test`**(운영 DB 비사용 — `pg_clean` TRUNCATE 파괴성 회피) + 테스트 RabbitMQ, portfolio-hub **stub**(`pf-005930`/`pf-000660`), `TREX_TOTAL_SLOTS=1`(idle 1개만 두어 재할당 강제), instance_key `rel005smoke`(운영/기존 데몬과 큐 격리), 리비전 = 작업 트리(`941d324` + dcy-019 미커밋 변경).
|
||||
- **마이그레이션 008 실 PG 적용**: `apply_migrations` 가 001~008 적용 후 `daily_slot.entry_count` 컬럼 존재 확인(실 PostgreSQL round-trip, additive·멱등). 즉, 앞서 단위에서 이월했던 PG 게이트 마이그레이션이 실 DB 에서 실제로 검증됨.
|
||||
- 데몬 기동: `trex-core-daemon --config /tmp/rel005smoke.toml` → RabbitMQ 토폴로지 선언(`trex.intent.req.rel005smoke`/`trex.snapshot.req.rel005smoke`), 2026-06-09 idle 슬롯 1개(`entry_count=0`) preallocation, 에러 로그 없음, 종료 시 `Normal shutdown`.
|
||||
- **BAT-024 (`enter --forced-close-at`) — PASS**:
|
||||
- `trex-core enter pf-005930 --capital 1000000 --strategy-id STRAT-A --forced-close-at "2026-06-09T15:00:00+09:00" --yes --json` → `{"status":"admitted","slot_id":"4fc104cf-…"}`. DB 슬롯: `status=holding symbol=005930 entry_count=1 forced_close_at=2026-06-09 06:00:00+00`(=15:00 KST 정확 변환).
|
||||
- `--forced-close-at "not-a-time"` → 제출 전 거부 `{"error":"invalid --forced-close-at (expected ISO8601): 'not-a-time'"}`, exit=1 (RPC 미발생 — 사전 검증).
|
||||
- **BAT-025 (slot entry_count + closed 직접 재할당) — PASS**:
|
||||
- 진입 시 `entry_count` 0→1 증가 확인(위 BAT-024 슬롯).
|
||||
- `trex-core exit 4fc104cf… --yes` → `pending_sell` → `closed`(entry_count=1 보존, symbol 005930 audit 유지).
|
||||
- idle 슬롯 0개 상태에서 **다른** 포트폴리오 진입 `trex-core enter pf-000660 --capital 500000 --strategy-id STRAT-B --yes` → `{"status":"admitted","slot_id":"4fc104cf-…"}` — **이전과 동일한 물리 슬롯**으로 admit(이전엔 `no_idle_slot` 거부됐을 상황). closed→pending_buy 직접 재할당 실증.
|
||||
- 재할당 후 DB: `status=holding symbol=000660 entry_count=2 forced_close_at=NULL strategy_id=STRAT-B` — clean-slate(005930→000660 교체, 이전 forced_close_at 클리어)·entry_count 누적(1→2) 확인.
|
||||
- 전이 로그(slot 4fc104cf): `idle→pending_buy → pending_buy→holding → holding→pending_sell → pending_sell→closed → closed→pending_buy → pending_buy→holding` — dcy-019 신규 전이 `closed→pending_buy` 가 실 데몬에서 발화.
|
||||
- 운영자 RPC 정합: `trex-core slots --json` 가 재할당 슬롯(symbol 000660, STRAT-B, holding) 응답. `ledger_outbox` 3행(buy/sell/buy) 모두 `status=completed`.
|
||||
- **한계(운영 배포 검증으로 이월)**: 실계좌(LIVE KIS) 주문은 미검증(paper 한정). portfolio-hub 는 stub(실 #8 연동은 본 릴리즈 변경 범위 아님 — 슬롯 도메인/CLI). LIVE full-stack 은 아래 Release Execution Evidence(실 배포)에서 확인한다.
|
||||
|
||||
## Release Execution Evidence
|
||||
- Release Status Transition Target: released
|
||||
|
||||
### Deployment Facts
|
||||
- Executed At:
|
||||
- 2026-06-10
|
||||
- Completed At:
|
||||
- 2026-06-10
|
||||
- Environment:
|
||||
- paper 브로커 + 테스트 PostgreSQL(`trex_core_test`) + 테스트 RabbitMQ + portfolio-hub stub(`pf-005930`/`pf-000660`) + `TREX_TOTAL_SLOTS=1` + instance_key `rel005smoke`(운영/기존 데몬과 큐 격리). 실계좌(LIVE KIS) 미사용 — paper 한정.
|
||||
- Operator:
|
||||
- Justin Ko
|
||||
- Revision or Artifact:
|
||||
- 작업 트리(`941d324` + dcy-019 미커밋 변경 포함)
|
||||
- Commands or Procedure:
|
||||
- `trex-core-daemon --config /tmp/rel005smoke.toml` 기동 후 CLI 스모크(단계 3~5의 Rollout Plan 수행)
|
||||
|
||||
### Profile-Specific Checks
|
||||
- app-service:
|
||||
- Health Endpoint:
|
||||
- RabbitMQ 토폴로지 선언(`trex.intent.req.rel005smoke` / `trex.snapshot.req.rel005smoke`) 성공, idle 슬롯 1개 preallocation 완료, 에러 로그 없음, `Normal shutdown` 정상 종료 확인
|
||||
- Startup Log Fields:
|
||||
- 마이그레이션 001~008 적용 후 `daily_slot.entry_count` 컬럼 존재 확인(실 PostgreSQL round-trip, additive·멱등 검증)
|
||||
- Request Log Fields:
|
||||
- 전이 로그(slot 4fc104cf): `idle→pending_buy → pending_buy→holding → holding→pending_sell → pending_sell→closed → closed→pending_buy → pending_buy→holding` — dcy-019 신규 전이 `closed→pending_buy` 실 데몬 발화 확인. `ledger_outbox` 3행(buy/sell/buy) 모두 `status=completed`.
|
||||
- Smoke or Manual Verification:
|
||||
- **BAT-024 PASS**: `trex-core enter pf-005930 --capital 1000000 --strategy-id STRAT-A --forced-close-at "2026-06-09T15:00:00+09:00" --yes --json` → `{"status":"admitted","slot_id":"4fc104cf-…"}`. DB: `status=holding symbol=005930 entry_count=1 forced_close_at=2026-06-09 06:00:00+00`(=KST 15:00 정확 변환). 잘못된 형식 `--forced-close-at "not-a-time"` → 제출 전 거부 `{"error":"invalid --forced-close-at (expected ISO8601): 'not-a-time'"}`, exit=1.
|
||||
- **BAT-025 PASS**: 진입 시 `entry_count` 0→1 증가. `trex-core exit` → `pending_sell → closed`(entry_count=1 보존). idle 0개 상태에서 `trex-core enter pf-000660 --capital 500000 --strategy-id STRAT-B --yes` → 동일 물리 슬롯 admitted(closed→pending_buy 직접 재할당). 재할당 후 DB: `status=holding symbol=000660 entry_count=2 forced_close_at=NULL strategy_id=STRAT-B`(clean-slate·entry_count 누적 확인).
|
||||
|
||||
### Rollback Outcome
|
||||
- Rollback Required:
|
||||
- no
|
||||
- Rollback Trigger:
|
||||
- none
|
||||
- Rollback Action:
|
||||
- none
|
||||
|
||||
### Release Decision Evidence
|
||||
- Released Decision:
|
||||
- released (feedback-captured로 전환)
|
||||
- Rationale:
|
||||
- 배포 실패·회귀 없음. `--forced-close-at` 동작 정상(유효 → admitted·KST 변환, 잘못된 형식 → 사전 거부). `entry_count` 기반 closed 슬롯 재할당 실 데몬 발화 확인. 슬롯 상태 전이 완전. ledger 3행 completed.
|
||||
- Recorded By:
|
||||
- Justin Ko
|
||||
- Recorded At:
|
||||
- 2026-06-10
|
||||
|
||||
## Feedback Handoff
|
||||
- Observation Summary:
|
||||
- REL-005 동작 모두 confirmed. `--forced-close-at` 사전 검증·UTC 변환 정상. closed 슬롯 재할당(entry_count 최저 우선)이 실 데몬에서 발화됨. entry_count 누적·clean-slate 교체 정상. 전이 로그 완전. ledger 3행 completed. 배포 실패·롤백 없음.
|
||||
- 한계 이월: 실계좌(LIVE KIS) 주문 미검증(paper 한정), portfolio-hub stub 사용(실 #8 연동 미검증 — 슬롯 도메인/CLI 범위 밖).
|
||||
- Discovery Input:
|
||||
- none (이번 릴리즈 관찰 범위에서 신규 후속 탐색 트리거 없음)
|
||||
- REQ Input:
|
||||
- none
|
||||
- Change Request Input:
|
||||
- `daily_symbol_entries`(심볼 재진입 카운터) 제거 — production 소비자 없음 + 심볼 재진입 제한 미사용 확정(dcy-019). REQ-002 change-req 트랙(별도 batch-lite) — REL-005 범위 밖.
|
||||
@@ -1,152 +0,0 @@
|
||||
# REL-006: 자산 중심 영구 슬롯 cutover + 포지션 사이징 + 실행 정책 + 운영 정리 통합 릴리즈
|
||||
|
||||
- Status: feedback-captured
|
||||
- Profile: app-service
|
||||
- Included Batch: BAT-026, BAT-027, BAT-028, BAT-029, BAT-030, BAT-031, BAT-032, BAT-033, BAT-034, BAT-035, BAT-036
|
||||
|
||||
## Scope
|
||||
- Included:
|
||||
- BAT-026 (batch-lite / REQ-048·010 CHG): config 디렉터리 기반 설정 관리 — `--config <name>` + `--config-path <dir>` + config-dir `.env` 결정적 해석(`--env-file` 우선), legacy 루트 `.env` 폴백 유지(완전 하위호환). 데몬·운영자 CLI 양쪽 적용.
|
||||
- BAT-027 (dcy-020 BAT-α / REQ-056·057): **자산 1:1 영구 슬롯 기반** — `(instance_key, portfolio_id)` 키 영구 슬롯 + `inactive↔pending_buy↔holding↔pending_sell` 상태머신, 인스턴스 스코프 advisory lock. 마이그레이션 009(instance_key·retired_at)·010(literal inactive).
|
||||
- BAT-028 (dcy-020 BAT-β / REQ-058·059·060): universe reconcile(슬롯 생성/retire, 대량 소멸 가드) + 자산 중심 buy admission(`max_active_slots` 동시 활성 상한).
|
||||
- BAT-029 (dcy-020 BAT-γ / REQ-061·062·063): intent 계약 자산 키 통일(slot_id 정본 + portfolio_id 수용) + 수량 정본=hub·core 미러 divergence reconcile + slots 단일 뷰(universe_detached 표기).
|
||||
- BAT-030 (dcy-020 BAT-δ / REQ-064·065 + 056·057·062 잔여): **pool 모델 폐기 cutover** — daily preallocation 제거(영구 슬롯은 universe reconcile 이 소유), 마이그레이션 011(`trading_date`·`entry_count` DROP, 비가역).
|
||||
- BAT-031 (dcy-021 / REQ-066·067 + 057·061·062 CHG): 포지션 사이징 — 보유 슬롯 증액(holding→pending_buy, avg_price 가중평균), 부분 매도(집행 수량=min(intent,브로커잔고), 잔량 holding/전량 inactive, cost basis 유지), 부분 체결 실제만 반영.
|
||||
- BAT-032 (dcy-022 / REQ-068~072 + 013·061 CHG): 주문 실행 정책 — intent `timeout_sec`(미체결 자동 취소·cancel-fill race 처리)·`slippage_pct`(보호 지정가 buy ceil/sell floor), per-instance TOML `default_order_timeout_sec`, 운영자 `trex-core cancel` 백스톱. 마이그레이션 012(execution policy 필드).
|
||||
- BAT-033 (batch-lite / REQ-032 CHG-06, issue #23): `trex-core enter` `--qty` 필수 검증 — 미지정 시 RPC 전 즉시 오류(0주 주문 silent 실패 제거).
|
||||
- BAT-034 (dcy-023 / REQ-002·006·007·028·032 CHG, issue #22): 죽은 필드 `allocated_capital` 전 경로 제거 — CLI `--capital` argparse 거부, BuyIntent·payload 수신 무시, Slot/`EXPECTED_SLOT_FIELDS`, snapshot `slots[]`. 마이그레이션 013(컬럼 DROP, 비가역).
|
||||
- BAT-035 (dcy-025 / REQ-073·074·075 신규 + REQ-021·034·063 CHG): `trex.snapshot.req` → `trex.slots.req` 즉시 교체 — 요청 `{filter: all|inactive|pending|holding|error, spy: bool}`, 응답 `{slots[], degraded, reason, message}`. 슬롯 단일 행 스키마: `asset_quantity`(hub 정본)·`qty`(slot 미러)·`warned`·`cash_balance`·`cash_estimated`·`watchdog{expired,last_seen}`·`paused`; strategy 필드 제외. `spy=true` → watchdog 무터치. REQ-028(`build_snapshot_envelope`/`View`/`SnapshotEnvelope`) Deprecated + 코드 삭제.
|
||||
- BAT-036 (dcy-024 / REQ-048·005 CHG, issue #15): per-instance TOML `safety_sell_enabled: bool = True` — `false` 시 `trex-safety-sell` 워커 미기동·물리 차단 + `no autonomous liquidation` WARNING 로그. `ExecutionService`·kill-switch·전략 sell intent 불변.
|
||||
- Excluded:
|
||||
- BAT-001~025 (REL-001~005 에서 released)
|
||||
- trex-orb-v1 등 외부 전략 모듈 저장소 변경(발신 계약 전환·allocated_capital 송신 정리 — 별도 합의)
|
||||
- `daily_symbol_entries` 잔재 제거(REL-005 환류 — 별도 change-req 트랙)
|
||||
|
||||
## Rollout Plan
|
||||
|
||||
- **배포 대상 커밋**: `f0ad37747b4e9d43dc798bfeda5b543cab048890` (main, 2026-06-11)
|
||||
|
||||
1. 배포 전: 거래 세션 외 시간 확보, 현재 운영 리비전 SHA 기록, 위 배포 SHA(`f0ad377`) 확인.
|
||||
2. **DB 백업(필수)**: 마이그레이션 011·013 은 비가역 컬럼 DROP — 적용 전 운영 `daily_slot`(권장: DB 전체) 백업. BAT-030 design §4 절차 준용.
|
||||
3. 신 리비전 배포 + 데몬 재기동. `apply_migrations` 가 009~013 자동 적용(전부 멱등). 기동 로그에서 마이그레이션 적용·RUNNING·비-degraded 확인.
|
||||
4. **cutover 확인**: daily preallocation 부재가 정상 — 영구 자산 슬롯은 snapshot scheduler 의 universe reconcile 이 생성/retire 한다. 기동 직후 universe fetch → 슬롯 생성 로그 확인, `trex-core slots` 로 자산 수 = 슬롯 수 확인.
|
||||
5. 운영자 CLI 스모크(paper 또는 비거래 시간):
|
||||
- `trex-core slots` — 응답 형식 `{slots[], degraded, reason, message}` 확인 (BAT-035: 구 `{assets[], available_slots}` 형식 부재); inactive/holding 상태·universe_detached 표기 (BAT-027~030)
|
||||
- `trex-core slots --status holding` → `filter=holding` 서버 필터 작동 확인 (BAT-035 filter)
|
||||
- `trex-core universe` → `trex.slots.req` 큐 사용, spy=true 확인 (BAT-035)
|
||||
- `trex-core enter <pf> --yes` → `--qty` 누락 즉시 오류 (BAT-033); `--qty N --yes` → admitted (BAT-029 자산 키)
|
||||
- `trex-core enter ... --capital ...` → argparse 거부 (BAT-034)
|
||||
- 증액/부분 매도 intent e2e (BAT-031), timeout_sec/slippage_pct intent + `trex-core cancel` (BAT-032)
|
||||
6. **BAT-035 외부 소비자 없음 확인**: `trex.snapshot.req` 구독자는 운영자 CLI 전용이며 CLI 는 이미 `trex.slots.req` 로 갱신됨. 전략 모듈(trex-orb-v1)은 `trex.intent.req` 생산자만이고 snapshot 소비자가 아니므로 차단 없음.
|
||||
7. 전략 모듈(trex-orb-v1) 재연결 후 buy intent 정상 admit 확인 — `allocated_capital` 송신 잔존은 unknown key 로 무시되어 무해.
|
||||
8. **BAT-036 확인(해당 시)**: TOML 에 `safety_sell_enabled = false` 설정 시 데몬 기동 로그에 `no autonomous liquidation` WARNING 출력·`trex-safety-sell` 워커 미기동 확인. 기본값 `true` 유지 시 변화 없음.
|
||||
9. 거래 세션 재개.
|
||||
|
||||
## Rollback Plan
|
||||
- 조건: 기동 실패, 마이그레이션 오류, universe reconcile 슬롯 생성 실패(전 자산 미생성), buy admission 회귀, 집행 루프(timeout/slippage) 오작동, CLI 회귀.
|
||||
- 절차: 직전 released 리비전(REL-005 시점)으로 롤백 + 데몬 재기동 + **백업 복원**.
|
||||
- 마이그레이션: 011(`trading_date`·`entry_count` DROP)·013(`allocated_capital` DROP)은 구 코드의 SELECT/UPDATE 가 해당 컬럼을 참조하므로 **구 리비전과 공존 불가** — 롤백은 반드시 2번 백업 복원과 함께 수행한다. 009·010·012 는 additive/호환이라 단독으로는 무해.
|
||||
- 데이터: cutover 후 생성된 영구 슬롯 행은 구 pool 모델 코드와 호환되지 않음 — 복원 시점 이후 거래가 없도록 비거래 시간 배포를 전제로 한다.
|
||||
|
||||
## Verification Checklist
|
||||
- 배포 전 (각 batch verification evidence):
|
||||
- BAT-026: 단위 23 + 전체 375 passed, ruff clean, 라이브 스모크(name·path 동일 결과)
|
||||
- BAT-027~030 (dcy-020): 단위 367 / PG 29 / MQ 21 passed + run-the-app 자산 중심 e2e(영구 슬롯 생성·reconcile·slot_id 매수)
|
||||
- BAT-031 (dcy-021): 단위 378 / 통합 422 passed + 사이징 e2e(증액 가중평균·부분 매도 잔량·전량 매도)
|
||||
- BAT-032 (dcy-022): 425 passed(신규 71 tests — policy lifecycle·timeout·slippage·cancel), 회귀 없음
|
||||
- BAT-033: 426 passed (AC-7 `--qty` guard + 기존 enter 회귀 보완)
|
||||
- BAT-034 (dcy-023): 428 passed + PG 게이트 21 passed + ruff clean, 마이그레이션 013 테스트 DSN 멱등 round-trip + 컬럼 부재, `grep allocated_capital` 전수 0건
|
||||
- BAT-035 (dcy-025): 420 passed / 45 skipped — `test_slots_handler.py` 신규 13 cases(REQ-073 AC-1~5·REQ-074 AC-1~5 망라), 삭제 4 files(snapshot_handler/snapshot_selection/snapshot_rpc_watchdog/messaging_snapshot_consumer), ruff clean, REQ-028 코드 전수 제거 확인
|
||||
- BAT-036 (dcy-024): 420 passed / 45 skipped — `test_instance_config.py` 신규 3 cases(default True·false toml·true toml), ruff clean
|
||||
- SRS: 포함 REQ 전부 Implemented(Approved/Proposed 0건), batch register 11건 release-candidate
|
||||
- 배포 후 (app-service profile):
|
||||
- 데몬 RUNNING + 비-degraded, 마이그레이션 009~013 적용 로그, 백그라운드 스레드(snapshot scheduler·execution loop) 기동
|
||||
- universe reconcile 슬롯 생성: 자산 수 = 슬롯 수, retire/tombstone 동작
|
||||
- `trex-core enter`(--qty 필수·--capital 거부)·`slots`·`cancel` 스모크
|
||||
- buy→fill→증액→부분 매도 e2e + timeout/slippage 정책 발화 확인
|
||||
- `ledger_outbox` completed, `daily_slot` 에 `trading_date`/`entry_count`/`allocated_capital` 컬럼 부재 확인
|
||||
|
||||
## Pre-Release Run Evidence (operator-facing smoke)
|
||||
|
||||
confirm-release 전 run-the-app 증거 (2026-06-11, `run-trex-core-daemon` 프로젝트 skill 경로). 실 데몬(RabbitMQ + 실 PostgreSQL) 기동 + 메시징/CLI 구동으로 본 릴리즈의 신규 동작을 검증했다.
|
||||
|
||||
- 환경: paper 브로커 + **테스트 PostgreSQL `trex_core_test`**(운영 DB 미사용) + 테스트 RabbitMQ, portfolio-hub **stub**(pf-005930/pf-000660), instance_key `rel006smoke`(큐 격리), `--config /tmp/rel006smoke/rel006smoke.toml --env-file /tmp/rel006smoke/.env`(BAT-026 config-dir 경로 실사용), `max_active_slots=5`.
|
||||
- **기동 + cutover (BAT-027~030) — PASS**: 토폴로지 선언(`trex.intent.req.rel006smoke` 등) 후 데몬 ready. daily preallocation 없이 snapshot scheduler 의 universe reconcile 이 영구 자산 슬롯 생성: `slot reconcile: {'created': 2, 'retired': 0, 'tombstoned': 0}` — 자산 수(2) = 슬롯 수(2), status `inactive`.
|
||||
- **e2e 메시징 smoke (`smoke.py`) — PASS**: snapshot RPC(slots=2, available_slots=5) → slot_id 키 buy admitted → 동일 intent_id 중복 재전송 identical(멱등) → paper fill 로 `holding qty=10 avg_price=1000` → sell admitted → `inactive`(점유 해제·자산 바인딩 유지).
|
||||
- **BAT-033 (`--qty` 필수) — PASS**: `enter pf-005930 --yes`(qty 없음) → `error: --qty is required...`, rc=1, RPC 미발생.
|
||||
- **BAT-034 (`--capital` 제거) — PASS**: `enter ... --capital 100000` → argparse `unrecognized arguments: --capital`, rc=2. `slots` detail 에 allocated_capital 행 없음.
|
||||
- **BAT-031 (포지션 사이징) — PASS**: holding(10@1000) 슬롯에 증액 매수 `--qty 5 --entry-price 2000` → admitted(holding→pending_buy) → fill 후 `qty=15.0 avg_price=1333.3333`(정확한 가중평균). 전량 매도 → `inactive qty=None portfolio_id 유지`.
|
||||
- **BAT-032 (운영자 cancel 백스톱) — PASS**: holding 슬롯에 `trex-core cancel` → `ignored: not_pending`, rc=0 (control RPC 경로 end-to-end).
|
||||
- **DB 계약 (마이그레이션 009~013) — PASS**: `daily_slot` 에 `trading_date`/`entry_count`(011)·`allocated_capital`(013) 컬럼 **부재** 확인. `ledger_outbox` 5행 전부 `completed`.
|
||||
- 종료: SIGTERM → `Normal shutdown`, 에러/traceback 0건(로그의 error-매칭 라인은 전부 pika INFO).
|
||||
- **한계(운영 배포 검증으로 이월)**: LIVE KIS 주문 미검증(paper 한정), portfolio-hub stub(실 universe/ledger 연동은 배포 후 확인), timeout_sec/slippage_pct 정책 발화는 전략 intent 필드라 CLI 미노출 — BAT-032 단위(71 tests) evidence 로 갈음하고 배포 후 전략 모듈 경유로 확인.
|
||||
- **BAT-035 (`trex.slots.req` 교체) — 단위 검증 갈음**: Pre-release 실 데몬 smoke 는 BAT-026~034 범위로 수행됐으며 BAT-035 라이브 RPC 응답은 미확인. 갈음 근거: `test_slots_handler.py` 13 cases(REQ-073 AC-1~5·REQ-074 AC-1~5) + `test_cli_operator.py` slots queue/spy=true 경로 + `test_topology.py` 상수 교체 전수. 외부 소비자 분석: `trex.snapshot.req` 구독은 운영자 CLI 전용이고 CLI 는 이미 갱신됨 — 차단 없음. 배포 후 첫 `trex-core slots` 호출로 즉시 확인 가능(Rollout 5단계).
|
||||
- **BAT-036 (`safety_sell_enabled`) — 단위 검증 갈음**: `safety_sell_enabled=false` 라이브 데몬 smoke 미수행. 갈음 근거: `test_instance_config.py` 3 cases(default·false·true toml 경로) + `daemon.py` 코드 경로 검토. 기본값 `true` 유지 시 배포 직후 동작 변화 없음 — `false` 설정은 운영자 명시적 TOML 변경 시에만 활성화되므로 위험도 낮음.
|
||||
|
||||
## Release Execution Evidence
|
||||
- Release Status Transition Target: released
|
||||
|
||||
### Deployment Facts
|
||||
- Executed At:
|
||||
- 2026-06-11 (최초 배포 `002340e`)
|
||||
- Completed At:
|
||||
- 2026-06-12 (긴급패치 포함 최종 `808a851`)
|
||||
- Environment:
|
||||
- 운영 — 인스턴스 `trex-admin-daily-trading` (KIS LIVE 브로커 + 운영 PostgreSQL `trex_core` + RabbitMQ + portfolio-hub)
|
||||
- Operator:
|
||||
- Justin Ko
|
||||
- Revision or Artifact:
|
||||
- 최초 배포 `002340e` → 긴급패치 후 최종 **`808a851`** (계획 SHA `f0ad377` 이후 main 진행분 포함 배포)
|
||||
- Commands or Procedure:
|
||||
- 데몬 중단 → `git pull` → `pip install -e .` → 데몬 재기동. `apply_migrations` 009~013 자동 적용(멱등).
|
||||
|
||||
#### Hotfix 경위 (배포 중 결함 → 무롤백 패치)
|
||||
- 최초 배포(`002340e`) 후 재기동 시 **슬롯 symbol 전부 `None`** 로딩 — universe reconcile 이 슬롯 생성 시 symbol 미저장 결함.
|
||||
- `221a163` fix(smoke): topology API 변경 반영(snapshot_queue→slots_queue) / `24a6017` **fix(reconcile): symbol 저장 + NULL backfill** / `808a851` docs(req-058): CHG-20260611-01 반영.
|
||||
- 패치 후 재기동: **45/45 슬롯 symbol 정상 로딩** 확인.
|
||||
|
||||
### Profile-Specific Checks
|
||||
- app-service:
|
||||
- Health Endpoint:
|
||||
- PASS — 데몬 RUNNING(PID 가동, RabbitMQ 3연결 OPEN), portfolio-hub HTTP 200, KIS inquire-balance HTTP 200, slots RPC degraded=None (2026-06-12)
|
||||
- Startup Log Fields:
|
||||
- PASS — 마이그레이션 009~013 적용(운영 DB information_schema 직접 확인: `trading_date`/`entry_count`/`allocated_capital` 부재, `instance_key` 존재, `ledger_outbox` 미완료 0건). universe reconcile 영구 슬롯 45개 생성(daily preallocation 부재 정상), universe_detached 0건.
|
||||
- Request Log Fields:
|
||||
- PASS — 실거래 e2e 전이 로그: ①장외 enter(2026-06-11 19:31): admitted → `inactive→pending_buy` → KIS order-cash 200 → 거부(장운영시간 아님) rollback `pending_buy→inactive`. ②장중 full e2e(2026-06-12, 005930 1주): 09:32 buy intent `inactive→pending_buy` → 09:32 체결 `pending_buy→holding`(qty=1, avg 334,000) → 14:37 **safety-sell stop_loss 자동 발화** `holding→pending_sell` → 14:37 체결 `pending_sell→inactive`. ledger buy/sell 2건 completed. slot qty(1.0)==hub asset_quantity(1.0) divergence 없음.
|
||||
- Smoke or Manual Verification:
|
||||
- PASS — BAT-035: `slots`(count=45, slots[] 형식·assets[] 부재)/`--status holding·buyable` 서버 필터/`universe`(slots.req 큐, spy=true)/JSON 스키마(allocated_capital 부재·watchdog·asset_quantity 포함). BAT-033: `--qty` 누락 즉시 오류 rc=1. BAT-034: `--capital` argparse 거부 rc=2 + 45개 전수 allocated_capital 부재. BAT-032: `cancel` dry-run rc=0. BAT-036: TOML 미설정 → default true 워커 기동 확인.
|
||||
|
||||
### Rollback Outcome
|
||||
- Rollback Required:
|
||||
- no
|
||||
- Rollback Trigger:
|
||||
- none
|
||||
- Rollback Action:
|
||||
- none — 최초 배포의 symbol 누락 결함은 롤백 없이 긴급패치(`24a6017`)로 해소(REQ-058 CHG-20260611-01 로 문서 정합 완료).
|
||||
|
||||
### Release Decision Evidence
|
||||
- Released Decision:
|
||||
- **released 전환** — 운영팀 배포 근거 종합 판정 전 항목 PASS(마이그레이션/기동·cutover/심볼 로딩/BAT-031~036 스모크/실거래 full e2e), 롤백 불요.
|
||||
- Rationale:
|
||||
- 운영 실거래(005930 매수→보유→stop_loss 자동 청산)로 자산 중심 슬롯 lifecycle·포지션 사이징·safety-sell·ledger 전 경로 무결 검증. 손익 −7,099.15원(−2.13%)은 손절 청산 결과이며 시스템 동작 관점 PASS.
|
||||
- Recorded By:
|
||||
- Justin Ko (운영팀 배포 근거) / 기록 정리: stage-pilot capture
|
||||
- Recorded At:
|
||||
- 2026-06-12
|
||||
|
||||
## Feedback Handoff
|
||||
- Observation Summary (2026-06-12, 운영팀 배포 근거 §8 + 실거래 데이터):
|
||||
- **배포 중 결함 1건(긴급패치 해소)**: universe reconcile 슬롯 생성 시 symbol 미저장 → 재기동 후 45슬롯 전부 symbol=None. `24a6017` 패치(생성 시 저장 + NULL backfill) 후 45/45 정상. REQ-058 CHG-20260611-01 로 AC-5 추가 완료 — 회귀 방지 테스트는 기존 reconcile 테스트(symbol 포함 시그니처)로 커버됨.
|
||||
- **실거래 full e2e 검증**: 005930 매수(09:32)→보유→stop_loss 자동 청산(14:37) 완주. 포지션 사이징(avg_price/qty 반영, 브로커 잔고 기준 청산), safety-sell 자동 발화, slot↔hub 수량 일치(divergence 0), ledger buy/sell completed.
|
||||
- **잔존 관찰 1 — watchdog_expired 상시**: 전략 모듈(trex-orb-v1) 미연결 상태라 watchdog expired 가 일상 — 전략 연결 시 해소. 수동 주문은 forced_close_at 기반 관리로 영향 없음. (중장기 인스턴스의 동일 문제는 dcy-027/BAT-041 `watchdog_timeout_sec` per-instance TOML 로 별도 해소됨 — 차기 릴리즈)
|
||||
- **잔존 관찰 2 — 매도세 tax=0 왜곡 지속**: 본 릴리즈 리비전(`808a851`)은 BAT-038(매도 증권거래세, dcy-026/issue #24) 이전 — 2026-06-12 매도 체결도 `세금 0` 으로 기록됨(수수료 49.05 만). 수정은 BAT-038(release-candidate)에 있으며 **차기 릴리즈 배포 전까지 신규 매도 ledger 의 tax=0 왜곡이 계속됨**. 과거 행 소급 보정은 안 함(dcy-026 OQ-3).
|
||||
- **운영 메모**: `trex-admin-daily-trading` 은 계좌 전체 cash 공유 모델(portfolio-hub 는 자산별 PnL 만 기록) — 슬롯 cash_balance 음수는 정상.
|
||||
- Discovery Input:
|
||||
- 없음 (자율 청산 OFF 모드 issue #15 → dcy-024 완료, 중장기 전략 슬롯 issue #20 → dcy-027 완료. watchdog 소유권 진입 외부 알림(슬랙·이메일)은 dcy-027 OQ-3 주석으로 이미 후속 Discovery 백로그에 등재)
|
||||
- REQ Input:
|
||||
- 없음 — 신규 요구사항 후보 없음(잔존 관찰은 전부 기존 트랙으로 커버)
|
||||
- Change Request Input:
|
||||
- `daily_symbol_entries` 잔재 제거(REL-005 환류 승계 — REQ-002/006 change-req 트랙, 미착수)
|
||||
- ~~paper 브로커 order seq Redis 영속화(issue #4)~~ — **완료**(REQ-011 CHG-20260612-01, BAT-039 release-candidate)
|
||||
- `default_order_timeout_sec` TOML 전파 누락(BAT-041 구현 중 발견 pre-existing — `from_toml` 파싱되나 `from_config` 미전파로 런타임 무시. REQ-048/068 change-req 트랙, 미착수)
|
||||
- 차기 릴리즈 입력: BAT-037~041 5건 release-candidate 대기(REL-007 후보) — **BAT-038 매도세 수정 포함이므로 조기 배포 권장**(위 잔존 관찰 2).
|
||||
@@ -1,124 +0,0 @@
|
||||
# REL-007: slots RPC 개선 + 매도세 정정 + paper seq 영속화 + 중장기 인스턴스 프로파일 통합 릴리즈
|
||||
|
||||
- Status: feedback-captured
|
||||
- Profile: app-service
|
||||
- Included Batch: BAT-037, BAT-038, BAT-039, BAT-040, BAT-041
|
||||
|
||||
## Scope
|
||||
|
||||
- Included:
|
||||
- BAT-037 (dcy-025 REQ-073 CHG-20260612-01): `trex.slots.req` 응답에 `available_slots: int|null` capacity hint 추가. `max_active_slots` 미설정 시 `null`, 설정 시 `max(0, M − active)`. orb-v1 의 불필요한 intent 왕복 제거. AC-3 반전(포함), AC-6 신규.
|
||||
- BAT-038 (dcy-026 REQ-018 CHG-20260612-01): 매도 체결 `tax=0.0` 하드코딩 버그(issue #24) 수정. `calculate_tax(side, amount)` 신규, 수수료율(`TREX_KIS_FEE_BPS`=1.5)·세율(`TREX_KRX_TAX_SELL_BPS`=20.0) env 상수화. KIS 어댑터는 브로커 응답 fee/tax 정본 우선, 없으면 정책 폴백.
|
||||
- BAT-039 (issue #4 REQ-011 CHG-20260612-01): paper 브로커 order seq Redis 영속화. 재시작 시 `PAPER-000001` 재발번 → `correlation_id` 충돌 → 매도 원장 조용히 누락되는 결정성 버그 해소. optional `SeqStore` 포트(Redis INCR / in-memory 폴백), `TREX_PAPER_REDIS_URL` 설정.
|
||||
- BAT-040 (issue #25 REQ-002/006/073 CHG-20260612-01/02): `trex.slots.req` per-request full scan 제거. `list_slots(status_filter)` DB 레벨 `status = ANY(%s)` 필터 추가(포트 + PG 구현). watchdog 갱신 holding 조회는 응답 결과 재사용해 두 번째 커넥션 생략. RPC 계약(AC-1~6) 불변.
|
||||
- BAT-041 (dcy-027 REQ-076/077/078): 중장기 인스턴스 운영 토대 완성. `DaemonInstanceConfig.watchdog_timeout_sec`(TOML) per-instance timeout 노출(env 폴백), `config/longterm.example.toml` 표준 프로파일 레시피(safety_sell off·market-close 미설정·watchdog 1800s), baseline 문서(`runtime-flows.md`) 중장기 운영 흐름 + 보호 규칙 경계(전략 모듈 전적 책임 + CLI exit 백스톱) + `forced_close_at` 중장기 미사용 명시.
|
||||
- Excluded:
|
||||
- 과거 누락 원장 행 소급 보정 (BAT-038/039 공통 — 보정 안 함)
|
||||
- overlay(paused/warned) 서버측 필터 — 후속
|
||||
- watchdog 소유권 진입 외부 알림(슬랙·이메일) — 후속 Discovery
|
||||
- 중장기 보호 규칙 코어 구현 — 전략 모듈 전적 책임으로 확정(dcy-027 OQ-2)
|
||||
|
||||
## Rollout Plan
|
||||
|
||||
1. 실행 중인 데몬 정지: `kill -TERM <PID>` (정상 종료 대기, 마지막 로그 `Normal shutdown` 확인)
|
||||
2. 코드 배포: `git pull` (또는 패키지 업데이트)
|
||||
3. DB 스키마 변경 없음 — 마이그레이션 불필요
|
||||
4. 중장기 인스턴스를 운영 중이라면 per-instance TOML 에 `watchdog_timeout_sec = 1800` 추가 (선택 — 미설정 시 기존 env 폴백 유지)
|
||||
5. paper 브로커 Redis 영속화를 사용할 경우 `TREX_PAPER_REDIS_URL` 환경 변수 설정 (미설정 시 in-memory 폴백, 재시작 시 seq 리셋)
|
||||
6. 데몬 재기동: `.venv/bin/trex-core-daemon --config <instance>`
|
||||
7. 기동 후 slots RPC 응답 및 로그 확인
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
- 트리거 조건: 기동 실패, slots RPC 응답 이상, 브로커 체결 이상
|
||||
- 롤백 절차:
|
||||
1. 데몬 정지
|
||||
2. `git revert` 또는 이전 커밋으로 체크아웃 후 재기동
|
||||
3. DB 스키마 변경 없으므로 데이터 무손실 롤백 가능
|
||||
- 주의: 과거 paper seq 가 Redis 에 저장된 경우 롤백 후 seq 연속성은 깨질 수 있으나 기능 무영향 (seq 는 execution_id 고유성 보장용)
|
||||
|
||||
## Verification Checklist
|
||||
|
||||
### 배포 전
|
||||
- [ ] `pytest tests/` — 전체 통과 확인 (회귀 없음)
|
||||
- [ ] BAT-037~041 각 `verification.md` Status: confirmed 확인
|
||||
|
||||
### 배포 후
|
||||
- [ ] 데몬 기동 로그 정상 (`Normal startup`, 워커 스레드 4개, RabbitMQ 토폴로지 선언)
|
||||
- [ ] `trex.slots.req` 응답에 `available_slots` 필드 존재 확인 (BAT-037)
|
||||
- [ ] `filter=inactive` 요청 시 inactive 슬롯만 반환 확인 (BAT-040 회귀)
|
||||
- [ ] paper 브로커 매도 체결 후 ledger `tax > 0` 확인 (BAT-038)
|
||||
- [ ] paper 브로커 `TREX_PAPER_REDIS_URL` 설정 시 재시작 후 seq 연속성 확인 (BAT-039)
|
||||
- [ ] 중장기 TOML(`longterm.example.toml` 참고) 로 기동 시 `safety_sell_enabled=false` + `watchdog_timeout_sec` 반영 확인 (BAT-041)
|
||||
- [ ] 기존 당일 인스턴스 동작 무회귀 확인
|
||||
|
||||
## Release Execution Evidence
|
||||
|
||||
- Release Status Transition Target: released
|
||||
|
||||
### Deployment Facts
|
||||
|
||||
- Executed At:
|
||||
- 2026-06-12 22:28 KST (데몬 재기동, PID 802942)
|
||||
- Completed At:
|
||||
- 2026-06-12 22:35 KST
|
||||
- Environment:
|
||||
- 로컬 운영 환경, instance_key=test, PostgreSQL + RabbitMQ (amqp://localhost:5672)
|
||||
- Operator:
|
||||
- Justin Ko
|
||||
- Revision or Artifact:
|
||||
- `d30e915b75df3b44258cac04a60ce2baad9857f1` (main, 2026-06-12)
|
||||
- Commands or Procedure:
|
||||
- 기존 데몬(PID 765497) SIGTERM 종료 → `trex-core-daemon --config test` 재기동 → RabbitMQ 토폴로지 선언 확인(ready) → slots RPC 스모크 실행
|
||||
|
||||
### Profile-Specific Checks
|
||||
|
||||
- app-service:
|
||||
- Health Endpoint:
|
||||
- RabbitMQ 토폴로지 선언 확인 — `trex.intent.req.test` + `trex.slots.req.test` 큐 수동 passive declare 성공 (2026-06-12 22:28 KST)
|
||||
- Startup Log Fields:
|
||||
- 데몬 기동 후 워커 스레드 4개 정상 기동, `trex.slots.req.test` consumer 선언, universe reconcile 슬롯 23개 확인
|
||||
- Request Log Fields:
|
||||
- slots RPC `{filter: "all"}` 요청 → 응답 키 `['available_slots', 'degraded', 'message', 'reason', 'slots']` 정상 (available_slots=5, degraded=False, slots 23개)
|
||||
- Smoke or Manual Verification:
|
||||
- BAT-037: `available_slots=5` 응답 포함 확인 (max_active_slots=5, active=0 → 5) ✓
|
||||
- BAT-040: `filter=all` 응답 23개 슬롯, DB-level 필터 경로 정상 동작 확인 ✓
|
||||
- 데몬 로그 ERROR/CRITICAL 없음 ✓
|
||||
- BAT-038/039/041: 구조 변경(fee 정책·paper seq·TOML config) — 기동 경로 정상, 단위 테스트 confirmed evidence 유효
|
||||
|
||||
### Rollback Outcome
|
||||
|
||||
- Rollback Required:
|
||||
- no
|
||||
- Rollback Trigger:
|
||||
- none
|
||||
- Rollback Action:
|
||||
- none
|
||||
|
||||
### Release Decision Evidence
|
||||
|
||||
- Released Decision:
|
||||
- yes
|
||||
- Rationale:
|
||||
- BAT-037~041 전체 verification confirmed (단위·통합 테스트 통과, smoke 근거 기록). DB 스키마 변경 없어 롤백 비용 낮음. slots RPC 응답 키·available_slots 값·슬롯 수 스모크 통과. 운영 중 데몬 정상 동작 확인. 비파괴적 additive 변경(fee/tax 정책·paper seq·TOML 필드·baseline 문서) 중심으로 회귀 위험 낮음.
|
||||
- Recorded By:
|
||||
- Justin Ko
|
||||
- Recorded At:
|
||||
- 2026-06-12 22:35 KST
|
||||
|
||||
## Feedback Handoff
|
||||
|
||||
- Observation Summary:
|
||||
- (2026-06-16 13:10 KST, 배포 에이전트) REL-007이 운영 인스턴스 `trex-admin-daily-trading`(실거래 KIS 91254)에 반영됨을 실환경 검증. 현 HEAD `1f59322`가 REL-007 커밋 `d30e915`를 조상 포함(`git merge-base --is-ancestor`=YES), 데몬 PID 1778 약 2일 무중단, DB 스키마 변경 없음.
|
||||
- **BAT-038(매도세 정정) 라이브 결정적 검증**: 2026-06-15 064400 매도 체결(`ledger_outbox`) 4주@97,200=388,800 KRW → tax 777.60 = **20.0bps**(=`TREX_KRX_TAX_SELL_BPS`), fee 58.32 = **1.5bps**(=`TREX_KIS_FEE_BPS`). 수정 전 `tax=0.0` 자리에 세금 정확 반영 → 실현 PnL 과대계상 버그 해소 확정.
|
||||
- BAT-037/040(slots RPC) 라이브 정상: `--json` 응답·`watchdog{expired,last_seen}` 구조·`available_slots` 힌트(orb-v1 소비)·`filter=inactive` 정상.
|
||||
- 본 실거래 당일매매 인스턴스에 BAT-039(paper seq)·BAT-041(중장기)는 N/A(기능 무영향).
|
||||
- Discovery Input:
|
||||
- watchdog 소유권 진입 시 외부 알림(슬랙·이메일·웹훅) — dcy-027 OQ-3 후속 Discovery 명시 (※ dcy-029 OQ-3 알림 전송 채널 Deferred와 합류 후보)
|
||||
- 전략↔자산 할당 모델(다중 전략 per-instance, strategy 필드 복원) — dcy-025 Out of Scope 이월
|
||||
- **(2026-06-16 라이브 테스트 환류) 호가단위 주문 거부(P0)**: `slippage_pct` 한계가가 KRX 호가단위 미스냅으로 KIS 거부(issue #28) → **dcy-030 생성·confirmed, REQ-083/070(BAT-044) Implemented**로 처리 완료.
|
||||
- **(2026-06-16 라이브 테스트 환류) 운영 관측성 부족**: 주문 거부가 로그에 없고 타임스탬프 부재로 진단 지연(issue #29) → **dcy-029 생성·confirmed, REQ-084~090(BAT-045/046) Implemented**로 처리 완료.
|
||||
- REQ Input:
|
||||
- none (라이브 환류는 위 dcy-030/dcy-029로 정규화되어 REQ-083/070/084~090로 이미 처리)
|
||||
- Change Request Input:
|
||||
- none (REQ-070 호가단위 정정은 dcy-030 CHG-20260616-01로 처리 완료)
|
||||
@@ -1,122 +0,0 @@
|
||||
# REL-008: 호가단위 스냅(#28) + 운영 관측성(#29) + slot strategy-state(#26)·retryable(#27) 통합 릴리즈
|
||||
|
||||
- Status: feedback-captured
|
||||
- Profile: app-service
|
||||
- Included Batch: BAT-042, BAT-043, BAT-044, BAT-045, BAT-046
|
||||
|
||||
## Scope
|
||||
- Included:
|
||||
- **BAT-042** (dcy-028 / issue #26): slot strategy-state 저장소 — `slot_strategy_state` 테이블 + StrategyStateStore(occupancy_seq·version CAS) + write RPC `trex.slots.strategy_state.set` + occupancy_seq 가드/close 삭제 + slots.req strategy_state·occupancy_seq additive (REQ-079·080·081·082, REQ-073/074 CHG). **마이그레이션 014/015**.
|
||||
- **BAT-043** (issue #27): rejected SellIntent 응답 additive `retryable: bool` (REQ-007 CHG-20260615-01).
|
||||
- **BAT-044** (dcy-030 / issue #28, P0): slippage 보호 지정가 KRX 호가단위 스냅. `domain/pricing.py`(tick 유틸, REQ-083) + `execution.py` 스냅(REQ-070 CHG-20260616-01) — 상한 준수(매수 floor/매도 ceil) + band<1tick 하한/상한 보장 + 부동소수 epsilon 가드. slippage_pct>0 매수의 호가단위 위반 전량 거부 해소.
|
||||
- **BAT-045** (dcy-029 P0): 구조화 로깅 기반 — ISO8601(KST) 타임스탬프·레벨, Loki JSON 출력(`TREX_LOG_FORMAT`), correlation id(slot_id)(REQ-084); 주문 결과 로깅 `event=order_submit|order_fill|order_reject`(REQ-085); 거부 ERROR 가시화(REQ-087).
|
||||
- **BAT-046** (dcy-029 P1): 청산 reason+actor 동반 노출(REQ-086); 운영 조회 CLI `trex-core report`(보유·오늘 체결·실현 PnL net·대기, direct-DB)(REQ-088); 운영자 런북 `docs/operations.md`(REQ-089); baseline 정합(REQ-090).
|
||||
- Excluded:
|
||||
- 알림 전송 채널(dcy-029 OQ-3 Deferred — 후속 반복).
|
||||
- ETF/ETN 비주식 호가체계(dcy-030 OQ-1 — 주식 전용).
|
||||
- 실현 PnL의 cost-basis 매칭(net 매매 현금흐름 정의 채택).
|
||||
- Scope Note:
|
||||
- BAT-042/043은 단일 main 브랜치상 배포 HEAD(`00ce5d9`)의 조상으로 함께 배포되는 release-candidate 배치다. 초안 시 제외했으나, "남아있는 배치 전부를 REL-008로" 지시에 맞춰 본 릴리스에 포함하도록 정정(배포 현실 = main 통째 배포와 일치). 마이그레이션 014/015는 BAT-042 소속.
|
||||
|
||||
## Rollout Plan
|
||||
1. 배포 전: 전체 테스트 green 확인(537 passed/47 skipped), ruff clean, DB 스키마 변경 없음 확인(마이그레이션 불필요).
|
||||
2. main 배포 커밋 체크아웃(REL-008 내용 포함) → 운영 인스턴스 데몬 재기동.
|
||||
3. 배포 후: 로그에 ISO8601(KST)+레벨 prefix 확인, `event=order_submit|fill|reject` 라인 확인, slippage 매수 주문이 유효 호가로 제출(거부 0) 확인, `trex-core report` 동작 확인.
|
||||
4. (옵션) `TREX_LOG_FORMAT=json` 설정 시 Loki 적재 확인.
|
||||
|
||||
## Rollback Plan
|
||||
- 트리거: 기동 실패 / 주문 제출 이상(호가단위·가격 오류) / 로그 포맷으로 인한 수집 파이프라인 장애 / report 오류.
|
||||
- 절차: 데몬 정지 → 이전 커밋(REL-008 이전, REL-007 라인 = `1f59322`) 체크아웃 → 재기동. **DB 스키마 변경 없어 데이터 무손실**.
|
||||
- 부분 롤백: `TREX_LOG_FORMAT`을 `text`(기본)로 두면 JSON/Loki 경로 비활성(비파괴적). 호가단위 스냅은 코드 경로라 부분 비활성 불가 — 전체 롤백.
|
||||
|
||||
## Verification Checklist
|
||||
- 배포 전:
|
||||
- 전체 단위/통합 테스트 green (537 passed, 47 skipped), ruff clean.
|
||||
- BAT-044/045/046 verification.md 모두 Ready for Release: true.
|
||||
- DB 스키마 변경 없음(마이그레이션 불필요) 재확인.
|
||||
- 배포 후:
|
||||
- 로그 라인에 ISO8601(KST)+레벨 prefix 존재.
|
||||
- slippage 적용 매수 주문이 유효 KRX 호가로 제출되고 `event=order_reject` 호가단위 거부가 사라짐(issue #28 해소).
|
||||
- 거부 발생 시 `event=order_reject`가 ERROR 레벨로 가시화.
|
||||
- `trex-core report`가 보유·오늘 체결·실현 PnL·대기 주문을 출력.
|
||||
|
||||
## 배포 전 준비 근거 (Pre-Deployment Readiness — 운영자 확인용)
|
||||
|
||||
운영자가 배포 직전 확인할 근거. 본 릴리스는 confirm 시점(2026-06-16) 기준 아래를 모두 충족한다(실 운영 배포·환류는 capture-release-feedback 단계).
|
||||
|
||||
| 항목 | 근거 | 상태 |
|
||||
| --- | --- | --- |
|
||||
| 전체 테스트 green | `.venv/bin/python -m pytest -q` → **537 passed, 47 skipped**(47 skip = 실 DB/RabbitMQ 게이트), 회귀 0 | ✅ |
|
||||
| Lint | `.venv/bin/ruff check trex_core/ tests/` → All checks passed | ✅ |
|
||||
| Batch 검증 완료 | BAT-044/045/046 `verification.md` 모두 Ready for Release: true, Blocking Issues 없음 | ✅ |
|
||||
| DB 스키마 변경 | **마이그레이션 014/015**(BAT-042 소속, 본 릴리스 포함) — 기동 시 자동 적용(additive·idempotent: `daily_slot.occupancy_seq`, `slot_strategy_state` 테이블). 구버전은 두 객체 미참조라 롤백 무손실 | ✅ |
|
||||
| 호가단위 스냅(#28) | issue #28 케이스 단위 검증(147,700→148,400 / 54,500→54,700), 상한 미초과·유효 호가 불변식 테스트 | ✅ |
|
||||
| 로깅 포맷(REQ-084) | text/json·ISO8601(KST)·correlation id 포맷터 단위 검증, `configure_logging` idempotent | ✅ |
|
||||
| 주문 결과·거부 ERROR | `event=order_submit\|fill\|reject` + 거부 ERROR 레벨 단위 검증(caplog) | ✅ |
|
||||
| 실현 PnL 집계(REQ-088) | `operator_report` net 현금흐름·KST 경계·렌더 단위 검증 | ✅ |
|
||||
| 비파괴성/하위호환 | slippage 미사용·시장가·0% 경로 회귀 없음; 로그 포맷 `text` 기본; report·reason+actor additive | ✅ |
|
||||
| 롤백 경로 | 이전 커밋 `1f59322`(REL-007 라인) 체크아웃 + 재기동, DB 무변경 | ✅ |
|
||||
|
||||
배포 후 운영자 확인 항목은 아래 `Verification Checklist > 배포 후` 및 `Profile-Specific Checks(app-service)` 참조.
|
||||
|
||||
## Release Execution Evidence
|
||||
- Release Status Transition Target: released
|
||||
|
||||
### Deployment Facts
|
||||
- Executed At:
|
||||
- 2026-06-16 13:41:22 KST
|
||||
- Completed At:
|
||||
- 2026-06-16 13:41:26 KST
|
||||
- Environment:
|
||||
- `/root/release` 운영, instance_key=`trex-admin-daily-trading` (실거래 KIS 계좌 91254)
|
||||
- Operator:
|
||||
- 배포 에이전트
|
||||
- Revision or Artifact:
|
||||
- `1f59322`(REL-007) → **`00ce5d9`(REL-008)**. PID 1778 → 193867.
|
||||
- Commands or Procedure:
|
||||
- `scripts/deploy-trex-core.sh --update-only`(git pull) → `--restart-only`(데몬 재기동). 마이그레이션 014/015는 데몬 기동 시 `apply_migrations` 자동 적용. 배포 전 포지션 0(재시작 안전).
|
||||
|
||||
### Profile-Specific Checks
|
||||
- app-service:
|
||||
- Health Endpoint:
|
||||
- N/A(데몬은 HTTP 표면 없음 — BAT-007). "ready" = 4 워커 스레드 + RabbitMQ 토폴로지 선언, 로그 ERROR/traceback 0. (배포 후 확인)
|
||||
- Startup Log Fields:
|
||||
- ✅ 배포 후 확인: 기동 로그가 `2026-06-16T13:41:24.044+09:00 INFO pika...` 형태로 **ISO8601(KST)+레벨** prefix 전환(이전 `INFO:pika:` 타임스탬프 없음). ERROR/CRITICAL/Traceback 0.
|
||||
- Request Log Fields:
|
||||
- 배포 후 포지션 0이라 실거래 주문 미발생 — 단위 검증(`TestOrderResultLogging`, cid=slot_id submit→fill)으로 보장. 다음 거래일(06-17) 실거래 주문에서 재확인.
|
||||
- Smoke or Manual Verification:
|
||||
- ✅ #28 호가단위 스냅: 배포된 `domain/pricing.py`로 어제 거부 2건 재계산 — 000720 entry 147,700 → 148,400(유효), 006800 entry 54,500 → 54,700(유효). ✅ `trex-core report` 동작(보유 0/대기 0/오늘 체결 0/실현 PnL 0). ✅ slots RPC 145개 정상, RabbitMQ ESTABLISHED 5. 실거래 slippage 매수 거부 0 체결은 06-17 거래일 확인.
|
||||
|
||||
### Rollback Outcome
|
||||
- Rollback Required:
|
||||
- no
|
||||
- Rollback Trigger:
|
||||
- none (기동 정상, #28 스냅·로깅·report 검증 통과)
|
||||
- Rollback Action:
|
||||
- none
|
||||
|
||||
### Release Decision Evidence
|
||||
- Released Decision:
|
||||
- **released** (2026-06-16 13:41 KST 운영 배포 완료, `00ce5d9`, PID 193867)
|
||||
- Rationale:
|
||||
- BAT-044/045/046 전 verification confirmed. 운영 배포 후 #28 호가단위 스냅(147,700→148,400 / 54,500→54,700)·구조화 로깅(ISO8601 KST prefix)·`trex-core report`·데몬 건강(ERROR 0, slots RPC 145) 실환경 검증. 마이그레이션 014/015 자동 적용(additive·idempotent). 롤백 불요.
|
||||
- Recorded By:
|
||||
- Justin Ko (confirm) / 배포 에이전트 (운영 배포 근거)
|
||||
- Recorded At:
|
||||
- 2026-06-16 13:25 KST (confirm) / 2026-06-16 13:43 KST (배포 완료 근거)
|
||||
|
||||
## Feedback Handoff
|
||||
- Observation Summary:
|
||||
- (2026-06-16 13:43 KST, 배포 에이전트) REL-008 운영 배포 완료(`00ce5d9`, PID 193867, `--restart-only`). **#28 호가단위 스냅 라이브 검증**(어제 거부 2건 재계산: 147,700→148,400 / 54,500→54,700, 유효 호가·상한 준수), **구조화 로깅 전환**(`...+09:00 INFO` KST prefix), **`trex-core report` 동작**, 마이그레이션 014/015 자동 적용 확인, 데몬 ERROR 0·slots RPC 145 정상.
|
||||
- 사전 테스트: 537 passed/46 skipped/1 failed. 1 failed = `test_sandbox_token_and_submit` — 운영 `.env`(:9443)가 샌드박스 테스트에 새어든 **환경 아티팩트, REL-008 회귀 아님**.
|
||||
- **거버넌스 정정(§4)**: main 단일 브랜치라 HEAD 배포 시 dcy-028(BAT-042/043, #26/#27) 코드가 동반 배포됨. 초안 시 본 릴리스에서 제외했으나 사용자 지시("남아있는 배치 전부")에 맞춰 **BAT-042/043을 REL-008에 정식 포함하도록 정정** → 추적 갭 해소(운영 실체 = 배포 HEAD와 일치). `occupancy_seq` 코어 활성, `slot_strategy_state` 핸들러는 전략 호출 시만 동작(orb-v1 미사용)→저위험.
|
||||
- Discovery Input:
|
||||
- **#30 Loki push 핸들러**: 현재 구조화 로그 text/json stdout만. Loki 적재(push)는 후속(이슈 #30 등록됨) — dcy-029 OQ-2/A-4(배포측 수집기) 연장선.
|
||||
- REQ Input:
|
||||
- none (관측성·호가단위는 REQ-070/083/084~090로 처리 완료)
|
||||
- Change Request Input:
|
||||
- none
|
||||
- Follow-up Actions (비차단):
|
||||
- **BAT-042/043(dcy-028 #26/#27) 운영 동반 배포 정식화** — 별도 release(REL-009 후보)로 retroactive 추적 권장(아래 사용자 결정 필요).
|
||||
- 실거래 #28 검증: 06-17 거래일 slippage 매수가 호가단위 거부 0으로 체결되는지 확인.
|
||||
- GitHub #28(수정 반영)·#29(기반 반영) close — 사용자 승인 후.
|
||||
@@ -1,194 +0,0 @@
|
||||
# REL-009: OPS-005 이벤트 발행 신뢰성 + 체결가 가드 + 알람 emitter + 무데이터 런북 (M2 통합 릴리즈)
|
||||
|
||||
- Status: confirmed
|
||||
- Profile: app-service
|
||||
- Included Batch: BAT-047, BAT-048, BAT-049
|
||||
|
||||
## Scope
|
||||
|
||||
- Included:
|
||||
- **BAT-047** (dcy-031 / OPS-005): 이벤트 발행 연결 신뢰성 — `publish_event` 1회 실패 시 강제 재연결+재시도(REQ-091), 발행 전용 연결 idle keepalive `process_data_events` 틱(REQ-092), DLQ 유입/emit 최종 실패 ERROR 경보(REQ-093), baseline 문서 정합(REQ-094). **M1 프로덕션(9e35467) 미반영 결함 해소 — idle 60초 후 첫 전이 이벤트 유실 제거.**
|
||||
- **BAT-048** (dcy-032): 체결가 0/None 백필 가드 + WARN 로깅 — `_on_filled`/`_on_partial_cancel`에서 avg_price=0/None 시 지정가 백필(REQ-095), 백필/unresolvable WARN 로그(reason 필드 포함)(REQ-096), 알람 능력 스파이크 산출물·후보 A/B/C 분석(REQ-097 — 알람 실제 구현은 dcy-033 이월). **슬롯 avg_price·원장 cost basis의 무경고 0오염 제거.**
|
||||
- **BAT-049** (dcy-033): 알람 시스템 1단계 — 알람 envelope 표준 JSON 스키마·`trex.alerts`(topic, durable=True) exchange 신규 선언(REQ-098/099), application `AlarmEmitter` + CRITICAL code 8종 배선(REQ-100), `runtime-flows.md` 알람 발신 흐름 기술(REQ-101). **기존 wire 계약(exchange/큐/라우팅) 불변 — 가산·격리 추가.**
|
||||
- **dcy-017 후속 운영자 런북** (docs-only, 2026-06-22): 지속 무데이터/죽은 종목 위생 절차 `docs/operations.md §7` 신규 기재 — pause/resume 시맨틱 검증·Step 1~3b 절차·고아 방지 순서 명시. 코드 변경 없음.
|
||||
|
||||
- Excluded:
|
||||
- 이벤트 발행 영속 outbox(옵션 C) — M3 후보
|
||||
- consumer(orb/tsl) idempotency 구현 — OQ-2(각 repo 추적)
|
||||
- 알람 수신·텔레그램 전달(trex-notifier) — **배포 의존성(아래 참조)**
|
||||
- INFO·WARN 알람 code 배선 — M3 이후
|
||||
- 과거 0 기록 원장/슬롯 소급 정정
|
||||
|
||||
- Scope Note:
|
||||
- BAT-047은 origin/main(`b2165ea`) 기준 이미 푸시됨 — 이번 배포는 현재 local main HEAD(`5bdd720`) 전체를 싣는 체크아웃 갱신이다.
|
||||
- dcy-017 런북은 별도 Discovery/Batch를 생성하지 않은 docs-only 패치(커밋 `5bdd720`)이며 코드 변경 없음.
|
||||
|
||||
## 배포 의존성 및 순서 (필독)
|
||||
|
||||
### trex-notifier 선행 조건
|
||||
|
||||
`trex.alerts` exchange 선언은 데몬 기동 시 `declare_topology()`가 자동 수행한다. 알람 발행(`mandatory=False`)은 notifier 미연결 시 silent drop — **core 기동 자체는 notifier 없이도 안전**하다.
|
||||
|
||||
그러나 알람 수신·텔레그램 전달(trex-notifier)이 연결되지 않은 상태에서 CRITICAL 이벤트가 발생하면 알람이 유실(drop)된다. 따라서:
|
||||
|
||||
1. **trex-notifier 배포·바인딩 선행**: `trex.alerts`에 바인딩된 notifier 큐가 없으면 알람이 RabbitMQ에서 곧바로 drop된다. trex-notifier를 먼저 띄우고 `trex.alerts` 바인딩을 확인한 뒤 trex-core를 재시작한다.
|
||||
2. **trex-core는 orb/tsl 이벤트 발행 경로의 중심**이다. trex-core 재시작 시간 동안 orb/tsl이 AMQP를 통해 trex-core로 전송하는 slot 의도(intent)가 일시 지연될 수 있다. 가능하면 거래 비활성 시간대(장 외)에 배포한다.
|
||||
|
||||
### 배포 순서 요약
|
||||
|
||||
```
|
||||
1. (장 외 시간) trex-notifier 배포 및 trex.alerts 바인딩 확인
|
||||
2. trex-core main 갱신 → pip install -e . (의존성 변경 없음 — 확인 후 생략 가능) → 데몬 재시작
|
||||
3. (선택) trex-orb-v1 / trex-tsl-v1 재시작 — 코드 변경 없어 강제 아님, keepalive/재연결은 core 측 개선임
|
||||
```
|
||||
|
||||
## Rollout Plan
|
||||
|
||||
1. **배포 전 준비**
|
||||
- 전체 테스트 green 확인: `python3 -m pytest -q` → **608 passed, 47 skipped** (현재 HEAD `5bdd720` 기준 검증 완료).
|
||||
- ruff clean 확인: `ruff check trex_core/ tests/` → `All checks passed!`.
|
||||
- BAT-047/048/049 `verification.md` 상태: BAT-047 approved, BAT-048 verified(팀장 confirm 완료), BAT-049 release-candidate(팀장 실인프라 e2e 포함 confirmed).
|
||||
- DB 스키마 변경 없음 — 신규 마이그레이션 없음. `apply_migrations` 기존 001~015 idempotent 재실행.
|
||||
- trex-notifier 배포·`trex.alerts` 바인딩 완료 확인 (선행 조건).
|
||||
|
||||
2. **배포 실행** (운영 환경 — bare .venv, instance_key=`trex-admin-daily-trading`)
|
||||
- `git pull` (또는 `git fetch && git checkout 5bdd720`) — local main을 프로덕션 체크아웃 경로에 반영.
|
||||
- 의존성 변경 여부 확인: `git diff 9e35467 HEAD -- pyproject.toml` → 변경 없으면 `pip install -e .` 생략 가능.
|
||||
- `trex-core-daemon` 재시작 (기존 PID 종료 후 신규 기동).
|
||||
- 기동 로그에서 `trex.alerts` exchange 선언 성공(`declare_topology` 완료) 확인.
|
||||
|
||||
3. **배포 후 검증** (아래 Verification Checklist 참조)
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
- **트리거**: 데몬 기동 실패 / `trex.alerts` exchange 선언 오류 / 이벤트 발행 경로 이상(재시도 루프 과다·DLQ 급증) / 체결 처리 이상(백필 WARN 폭증·슬롯 PENDING 고착) / 기존 서비스 연동 장애.
|
||||
- **절차**:
|
||||
1. 데몬 정지.
|
||||
2. 이전 커밋 체크아웃: `git checkout 9e35467` (REL-008 배포본 = M1 프로덕션 라인).
|
||||
3. `trex-core-daemon` 재기동.
|
||||
4. **DB 스키마 변경 없음** — 마이그레이션 없으므로 롤백 시 데이터 무손실.
|
||||
5. `trex.alerts` exchange는 롤백 후에도 RabbitMQ에 남아있으나 발행자가 없어 무해. 필요 시 관리 UI에서 수동 삭제 가능(비필수).
|
||||
- **부분 완화**: `AlarmEmitter`는 best-effort 삼킴 패턴으로 기동·발행 경로가 알람 실패에 비차단. 알람 발행 오류만 발생하면 롤백 대신 notifier 재바인딩을 먼저 시도한다.
|
||||
|
||||
## Verification Checklist
|
||||
|
||||
### 배포 전
|
||||
|
||||
- [ ] 전체 테스트 green: `python3 -m pytest -q` → 608 passed, 47 skipped, 0 fail (HEAD `5bdd720`).
|
||||
- [ ] ruff clean: `ruff check trex_core/ tests/` → `All checks passed!`.
|
||||
- [ ] BAT-047 verification: Status=approved (confirmed 2026-06-19).
|
||||
- [ ] BAT-048 verification: Status=verified (confirmed 2026-06-21).
|
||||
- [ ] BAT-049 verification: Status=release-candidate (팀장 실인프라 e2e confirmed 2026-06-21).
|
||||
- [ ] trex-notifier 배포·`trex.alerts` 바인딩 완료 (선행).
|
||||
- [ ] DB 스키마 변경 없음 재확인 (마이그레이션 없음).
|
||||
- [ ] `docs/interface-contract.md` 변경 범위 확인: BAT-049 `trex.alerts` 섹션 추가(기존 섹션 diff=0).
|
||||
- [ ] **OPS-005 배포갭 인지**: 현재 프로덕션 M1(`9e35467`)은 idle keepalive·재시도 미포함 — 이번 배포가 해소.
|
||||
|
||||
### 배포 후
|
||||
|
||||
- [ ] **OPS-005 해소 확인 (BAT-047 핵심)**: 장 시작 후 orb/tsl → core idle 60초 이상 경과 후 첫 slot 전이 이벤트가 정상 수신되는지 확인. `ConnectionReset` / `StreamLostError` 로그 무재발 확인. `slot_filled` / `slot_entered` 이벤트가 orb/tsl에 도달하는지 확인.
|
||||
- [ ] 데몬 기동 로그: `declare_topology` 정상 완료, `trex.alerts` exchange 선언 포함, ERROR/CRITICAL/Traceback 0.
|
||||
- [ ] keepalive 동작 확인: 기동 후 60초 경과 시 `keepalive_tick` 호출 로그(또는 무오류) 확인.
|
||||
- [ ] 알람 발행 경로 확인: CRITICAL 이벤트 발생 시 `alarm.critical.trex-core` routing key로 `trex.alerts`에 발행되고 trex-notifier가 텔레그램 전달하는지 확인 (e2e 경로).
|
||||
- [ ] 체결 처리: 정상 체결 시 avg_price 백필 WARN 미발생 확인. KIS avg_price 이상 케이스 발생 시 WARN 로그 필드(slot_id/symbol/backfill_price/reason) 확인.
|
||||
- [ ] **AMQP wire 무회귀**: `trex.events`, `trex.intent.req`, `trex.slots.req`, `trex.control.req` exchange/큐/라우팅 형식 불변 확인. orb/tsl 연동 장애 없음 확인.
|
||||
- [ ] `trex-core report` 정상 동작 (REL-008 기능 회귀 없음).
|
||||
|
||||
## AMQP Wire 계약 무회귀 체크포인트
|
||||
|
||||
이번 릴리즈의 AMQP 변경 범위는 아래로 한정된다. orb/tsl 연동에 영향 없음을 명시한다.
|
||||
|
||||
| 항목 | 변경 여부 | 근거 |
|
||||
|---|---|---|
|
||||
| `trex.events` exchange/토폴로지 | 불변 | BAT-047 Out of Scope 명시, verification NFR-1 PASS |
|
||||
| `trex.intent.req` 큐/라우팅 | 불변 | BAT-047/048/049 모두 불변 확인 |
|
||||
| `trex.slots.req` 큐/스키마 | 불변 | BAT-047/048/049 모두 불변 확인 |
|
||||
| `trex.control.req` 큐 | 불변 | 변경 없음 |
|
||||
| 슬롯 이벤트 페이로드 스키마 | 불변 | BAT-047 wire 무회귀 PASS |
|
||||
| `trex.alerts` exchange | **신규 추가** (가산·격리) | BAT-049 REQ-099. 기존 exchange/큐에 무영향. mandatory=False — unroutable silent drop |
|
||||
| `docs/interface-contract.md` | **trex.alerts 섹션 신규** (기존 섹션 diff=0) | BAT-049 REQ-098 AC-3 PASS |
|
||||
|
||||
## Release Execution Evidence
|
||||
|
||||
- Release Status Transition Target: released
|
||||
|
||||
### Deployment Facts
|
||||
|
||||
- Executed At:
|
||||
- 2026-06-25
|
||||
- Completed At:
|
||||
- 2026-06-25 PASS (34700f3 on 5bdd720, PID 849009)
|
||||
- Environment:
|
||||
- 운영 (`/root/release` 또는 해당 경로, instance_key=`trex-admin-daily-trading`, 실거래 KIS 계좌 91254), bare .venv
|
||||
- Operator:
|
||||
- 사장님
|
||||
- Revision or Artifact:
|
||||
- `9e35467`(REL-008 M1 현재 프로덕션) → **`34700f3` on `5bdd720`(REL-009 배포본)**.
|
||||
- BAT-047: `d182464`, BAT-048: `f1b649c`, BAT-049: `d4c5fcb`, dcy-017 런북: `5bdd720`.
|
||||
- Commands or Procedure:
|
||||
- `git pull` (또는 체크아웃 `5bdd720`) → `pip install -e .` (의존성 변경 시) → `trex-core-daemon` 재시작.
|
||||
- 마이그레이션: 기동 시 `apply_migrations` 자동 실행 (001~015 idempotent, 신규 없음).
|
||||
|
||||
### Profile-Specific Checks
|
||||
|
||||
- app-service:
|
||||
- Health Endpoint:
|
||||
- N/A (데몬은 HTTP 표면 없음). "ready" = 워커 스레드 + RabbitMQ 토폴로지 선언(`trex.alerts` 포함) 완료, 로그 ERROR/Traceback 0.
|
||||
- Startup Log Fields:
|
||||
- PASS. `declare_topology` 완료 로그, `trex.alerts` exchange 선언 확인(AMQP 5연결 정상), ERROR/CRITICAL/Traceback 0.
|
||||
- Request Log Fields:
|
||||
- PASS. `slot_filled` 이벤트 정상 발행 확인. OPS-005 ConnectionReset 무재발 확인. 12:02 sell_filled 집행 정상.
|
||||
- Smoke or Manual Verification:
|
||||
- PASS. idle keepalive 동작, `slot_filled` 이벤트 발행 경로 정상. `trex.alerts` exchange 선언 5연결 확인.
|
||||
|
||||
### Rollback Outcome
|
||||
|
||||
- Rollback Required:
|
||||
- No
|
||||
- Rollback Trigger:
|
||||
- none
|
||||
- Rollback Action:
|
||||
- none
|
||||
|
||||
### Release Decision Evidence
|
||||
|
||||
- Released Decision:
|
||||
- released
|
||||
- Rationale:
|
||||
- 2026-06-25 배포 PASS. 2026-06-26 첫 거래일 OPS-005(RabbitMQ ConnectionReset) 무재발(0건) 확인. slot_filled 이벤트 정상 발행. 12:02 sell_filled 집행 정상. AMQP 5연결 정상. 롤백 없음.
|
||||
- Recorded By:
|
||||
- 팀장
|
||||
- Recorded At:
|
||||
- 2026-06-26
|
||||
|
||||
## Feedback Handoff
|
||||
|
||||
### M2 배포 + 첫 거래일 환류 (2026-06-26)
|
||||
|
||||
- Observation Summary:
|
||||
- **배포**: 2026-06-25 PASS (34700f3 on 5bdd720, PID 849009). trex.alerts 선언, AMQP 5연결 정상.
|
||||
- **첫 거래일 검증**: OPS-005(RabbitMQ ConnectionReset) 무재발(0건) — 해소 확인. slot_filled 이벤트 정상 발행. 12:02 sell_filled 집행 정상.
|
||||
- **신규 발견**: slot_filled 이벤트 NO_ROUTE → DLQ 유입 확인. 라우팅키 `slot_filled_*._.{symbol}`(strategy_id 자리 `_`). 원인: `_emit_event`(execution.py:345/398)가 자산중심 슬롯(dcy-020, portfolio_id 단위, strategy_id 미보유) 기반 발행 → orb/tsl의 `trex.events.strategy.{strategy_id}` 바인딩과 불일치. 체결이벤트 채널(REQ-003) 미전달(전략은 slots RPC 폴링 주력이라 비치명적이나 채널 깨짐+DLQ 누적).
|
||||
|
||||
- Discovery Input:
|
||||
- **★ slot_filled NO_ROUTE / fill→strategy 라우팅 재설계** (trex-core/P1/M3): 자산중심 모델에서 fill 이벤트를 strategy 바인딩으로 전달하는 라우팅 매핑이 없음. `_emit_event`의 라우팅키 생성 로직이 strategy_id를 참조하지 않아 orb/tsl의 `trex.events.strategy.{strategy_id}` 바인딩과 불일치 → NO_ROUTE → DLQ 누적. 자산중심 슬롯(portfolio_id 단위)에서 fill→strategy 라우팅 재설계 필요. 보드 등록됨. **교차 영향 사안**: wire 계약(exchange/라우팅키/바인딩) 변경 — 팀장 검토 후 Discovery 개시 필요.
|
||||
- **이벤트 발행 영속 outbox**: BAT-047 Out of Scope으로 이월됨(M3 후보). at-least-once 중복 이벤트 소비자 멱등성도 함께 추적.
|
||||
- **실 broker 통합 CI**: half-open/idle 60초/broker 재시작 시나리오는 현재 mock unit으로만 검증. `TREX_RABBITMQ_TEST_URL` 포함 통합 환경 구성(M3 후보).
|
||||
- **INFO·WARN 알람 code 배선**: CRITICAL 8종 이후 후속 범위(dcy-033 범위 경계 밖, M3 후보).
|
||||
|
||||
- REQ Input:
|
||||
- none
|
||||
|
||||
- Change Request Input:
|
||||
- none
|
||||
|
||||
## 미해결 / 잔여 위험
|
||||
|
||||
| 항목 | 수준 | 설명 | 해소 방안 |
|
||||
|---|---|---|---|
|
||||
| trex-notifier 미선행 시 알람 유실 | Medium | notifier 없이 core 배포 시 CRITICAL 알람 silent drop | 배포 순서 준수: notifier → core |
|
||||
| 지정가 백필 추정치 오차 | Medium | BAT-048 R-1: 실제 체결가 ≠ 지정가 가능. reason=avg_price_backfill WARN으로 추적 가능 | 운영자 WARN 발생 시 operations.md §5 절차 참조 |
|
||||
| fill_price_unresolvable 슬롯 고착 | Low | BAT-048 R-2: limit_price=None 시 PENDING 고착 → watchdog 탐지 필요 | 기존 stale_pending watchdog 동작, 운영자 개입 |
|
||||
| half-open/idle 실인프라 검증 | Low | BAT-047 mock unit 검증 — 실 broker 통합 skip (환경 미구성) | 배포 후 OPS-005 재발 모니터링으로 실증, M3 통합 CI |
|
||||
| NFR-2 publish 블록 최악 케이스 | Low | BAT-047: 1차 실패 시 원 socket_timeout(5.0s) 초과 가능 | 배포 후 모니터링, 필요 시 후속 REQ(publish timeout 강화) |
|
||||
| BAT-049 통합(실 RabbitMQ) 3건 | Low | declare_topology/mandatory=False/기존 topology 불변은 팀장 실인프라 e2e에서 확인됨(2026-06-21) | 배포 후 Smoke 체크포인트로 재확인 |
|
||||
@@ -1,204 +0,0 @@
|
||||
# REL-010: 차단형 reconcile + cold-start + WAC 운영리포트 + KIS 인증정보 휴면 배포 (M3 통합 릴리즈)
|
||||
|
||||
- Status: released
|
||||
- Profile: app-service
|
||||
- Included Batch: BAT-050, BAT-051, BAT-052, BAT-053, BAT-054
|
||||
|
||||
## Scope
|
||||
|
||||
- Included:
|
||||
- **BAT-050** (dcy-034 / core-A): 차단형 reconcile 게이트 — reconcile-warning durable store(`slot_reconcile_warning` 테이블, REQ-102), B/C 불일치 슬롯 → warning 전이(REQ-103), 전략 차단 게이트(pause ∨ reconcile-warning 중 하나 → buy/외부sell 차단, 안전망 우회 보장, REQ-104), 차단/해제 전이 구조화 로깅 + 고영향 알람(REQ-107), 비기능 요건 — 내구성·회귀 방지·자동 정정 금지·wire 계약 최소 침습(REQ-108).
|
||||
- **BAT-051** (dcy-034 / core-B): sync/verify CLI cold-start onboarding — `trex-core sync` 명령(INACTIVE→HOLDING 전이 + WAC seed + reconcile-warning 해제, REQ-105), `trex-core verify` 명령(C-case 슬롯 재대조 + warning 해제, REQ-106). INACTIVE→HOLDING 전이 엣지 도메인 추가.
|
||||
- **BAT-052** (dcy-035): WAC 실현손익 운영리포트 통합 — portfolio-hub `/pnl/realized` read 포트+어댑터+stub(REQ-109), `trex-core report`에 WAC 실현손익 섹션 통합(REQ-110), portfolio-hub 미가용 시 degrade(폴백 없음, REQ-111). **매수 수수료를 WAC에 편입(CHG-20260626-02)**. 전일매수+당일매도 시나리오에서 운영리포트가 portfolio-hub WAC 정확값을 표시.
|
||||
- **BAT-053** (dcy-036): 그날-시작 KIS 인증정보 fetch + fail-safe 로드 스캐폴드 — portfolio-hub broker credential read 포트+어댑터+stub(REQ-112), KISConfig 소스 우선순위 opt-in(`credential_fetch_enabled`) + break-glass 환경변수(REQ-113), fail-closed 신규 진입 차단 + CRITICAL 알람(REQ-114), 그날 고정 캐시 + portfolio-hub 장애 비중단(REQ-115). **`credential_fetch_enabled` 기본값 = `false` — opt-in OFF 시 기존 동작 byte-for-byte 보존.**
|
||||
- **BAT-054** (dcy-036): 그날-시작 KIS 인증정보 양의 경로 주입 — KISBroker `reinitialize(cred)` 메서드(REQ-113 AC-2, REQ-115 AC-1), break-glass 로그 content assert 보강(REQ-113 AC-4). **`credential_fetch_enabled = false`(기본) 경로 완전 보존 — 코드는 배포되나 비활성(휴면). 실거래 KIS 인증정보 경로 미전환.**
|
||||
|
||||
- Excluded:
|
||||
- **dcy-036 실거래 활성화(credential_fetch_enabled = true 플립)**: 이번 릴리즈에서 비활성 배포. 플립 전환은 별도 절차(사장님 결재 + pf-hub dcy-010 배포 선행 + 실 KIS 통합검증 포함) 필요 — 아래 "후속 플립 선결 조건" 참조.
|
||||
- reconcile 비차단 거버넌스 후속(AC-9 change-req 등): M3 백로그.
|
||||
- 실 portfolio-hub 통합 E2E 검증(dcy-010 배포 후 가능): REL-010 go 조건 아님.
|
||||
- INFO·WARN 알람 code 배선: dcy-033 범위 경계 밖, M3 이후.
|
||||
|
||||
- Scope Note:
|
||||
- **dcy-036 휴면 배포**: BAT-053/BAT-054 코드는 `credential_fetch_enabled = false`(기본값) 경로에서 완전히 비활성. QC가 opt-in OFF 경로에서 byte-for-byte 회귀 보존 확인. 라이브 실거래 무영향 보장.
|
||||
- **BAT-054 PR #35 머지 완료**: 배포 선결 조건 충족.
|
||||
- **배포 대상 revision**: `314047b`(origin/main). BAT-050~054 전체 + slot_filled 라우팅 수정 #36 + verify ImportError 핫픽스 `51cc3cc` 포함.
|
||||
- **REL-010 구성**: dcy-034(BAT-050+051 = core-A+B) + dcy-035(BAT-052) + dcy-036(BAT-053+054 = 휴면).
|
||||
- **dcy-036 양의경로 휴면 배포**: `credential_fetch_enabled=false`(기본값) 유지. 코드는 `314047b`에 포함되나 비활성. 실 KIS 인증정보 경로 미전환 — 실거래 무영향 확인. 플립 활성화는 중장기 인스턴스 후속(portfolio-hub dcy-010 배포 + 실 KIS 통합검증 선행 필요) — 이번 릴리즈 go 조건 아님.
|
||||
|
||||
## 배포 선결 조건 (충족 완료)
|
||||
|
||||
1. **PR #35 사장님 결재·머지** — 완료. BAT-054 `feat/dcy-036-kis-credential-inject` → main 머지 완료.
|
||||
2. **QC confirm-batch-verification** (BAT-054) — 완료. release-candidate 전환 확인.
|
||||
3. **전체 테스트 green** — 완료. main HEAD `314047b` 기준 0 fail (757 passed, 47 skipped 기준).
|
||||
|
||||
## 후속 플립 선결 조건 (이번 릴리즈 go 조건 아님, 별도 기재)
|
||||
|
||||
`credential_fetch_enabled = true` 전환(실거래 KIS 인증정보 경로 활성화)은 이 릴리즈와 **분리**된 별도 절차다. 활성화 전 아래 조건이 모두 충족되어야 한다.
|
||||
|
||||
- portfolio-hub dcy-010 배포 완료 및 `/v1/user_info` broker credential 엔드포인트 정상 응답 확인.
|
||||
- 실 portfolio-hub + 실 KIS mock(또는 openapivts) 환경에서 그날-시작 fetch → KISBroker reinitialize → 장중 주문 처리까지 end-to-end 통합 검증(REQ-115 AC-1 완전 충족).
|
||||
- REQ-113 AC-1 실 KIS 통합검증 통과.
|
||||
- 사장님 결재.
|
||||
|
||||
## Rollout Plan
|
||||
|
||||
1. **배포 전 준비**
|
||||
- PR #35 머지 확인 — main HEAD가 BAT-054 구현 커밋 포함인지 git log로 검증.
|
||||
- 전체 테스트 green 확인: PR #35 머지 후 main에서 `python3 -m pytest -q` → 0 fail (기준: 757 passed, 47 skipped).
|
||||
- BAT-050 Status = release-candidate / BAT-051 Status = release-candidate / BAT-052 Status = release-candidate / BAT-053 Status = release-candidate 확인.
|
||||
- BAT-054 Status = release-candidate 전환 확인 (QC confirm 완료 후).
|
||||
- DB 마이그레이션 확인: BAT-050이 `slot_reconcile_warning` 테이블 신규 마이그레이션(`016_...sql`) 추가. 기동 시 `apply_migrations` 자동 실행 — 신규 테이블 생성 정상 완료 확인 필요.
|
||||
- 의존성 변경 확인: `git diff 5bdd720 HEAD -- pyproject.toml` → 변경 없으면 `pip install -e .` 생략 가능(BAT-050~054 범위 기준 의존성 추가 없음).
|
||||
|
||||
2. **배포 실행** (운영 환경 — `/root/release/trex-core`, instance_key=`trex-admin-daily-trading`, PID 849009 기준)
|
||||
- 대상 커밋으로 체크아웃: `git fetch origin && git checkout main && git pull` (PR #35 머지 완료 후).
|
||||
- 의존성 변경 시: `pip install -e .`
|
||||
- 마이그레이션: `trex-core-daemon` 기동 시 `apply_migrations` 자동 실행 (001~016 idempotent, `slot_reconcile_warning` 신규 생성 포함).
|
||||
- `trex-core-daemon` 재시작 (기존 PID 종료 → 신규 기동).
|
||||
- 기동 로그에서 마이그레이션 완료(`apply_migrations` success) 및 워커 스레드 정상 기동 확인.
|
||||
- tsl instance_key 데몬 동일 절차 반복 (동일 코드베이스 공유).
|
||||
|
||||
3. **배포 후 검증** (아래 Verification Checklist 참조)
|
||||
|
||||
4. **저녁 장외 윈도우 메모**: 장외 배포이므로 orb/tsl 전략 데몬 일시 연결 단절 허용. 무중단 절차 불필요. 배포 완료 후 reconcile sync/verify 동작 스모크 먼저 수행.
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
- **트리거**: 데몬 기동 실패 / `slot_reconcile_warning` 마이그레이션 오류 / reconcile 차단 오발동(정상 슬롯 차단) / INACTIVE→HOLDING 전이 에러 / 운영리포트 이상(WAC 섹션 오류로 리포트 전체 불렌더) / 기존 AMQP wire 연동 장애 / credential_fetch_enabled OFF 경로에서 예상치 못한 fetch 시도 로그.
|
||||
- **절차**:
|
||||
1. 데몬 정지.
|
||||
2. 이전 커밋 체크아웃: `git checkout 5bdd720` (REL-009 배포본).
|
||||
3. `pip install -e .` (필요 시).
|
||||
4. `trex-core-daemon` 재기동.
|
||||
5. **마이그레이션 롤백 주의**: `slot_reconcile_warning` 테이블은 자동 롤백 없음. 롤백 후에도 테이블이 DB에 잔존하나, 이전 코드에서 참조하지 않아 무해. 수동 삭제 필요 시:
|
||||
```sql
|
||||
DROP TABLE IF EXISTS slot_reconcile_warning;
|
||||
```
|
||||
6. **데이터 무손실**: 기존 slots / pause_store 스키마 불변. reconcile_warning 테이블만 가산. 롤백 후 운영 상태 정합 유지됨.
|
||||
- **부분 완화**: credential_fetch_enabled=OFF(기본값) 배포이므로 BAT-053/054 코드 경로가 실행되지 않아, 해당 코드 관련 트리거는 이 릴리즈에서 사실상 발생 불가.
|
||||
|
||||
## Verification Checklist
|
||||
|
||||
### 배포 전
|
||||
|
||||
- [x] PR #35 머지 완료 확인 (BAT-054 `feat/dcy-036-kis-credential-inject` → main) — PASS.
|
||||
- [x] BAT-054 confirm-batch-verification 완료 확인 (Status = release-candidate) — PASS.
|
||||
- [x] 전체 테스트 green: main HEAD `314047b`에서 `python3 -m pytest -q` → 0 fail (기준: 757 passed, 47 skipped) — PASS.
|
||||
- [x] BAT-050 / BAT-051 / BAT-052 / BAT-053 / BAT-054 모두 Status = release-candidate 확인 — PASS.
|
||||
- [x] DB 마이그레이션 파일 확인: `trex_core/adapters/persistence/migrations/016_*.sql` 존재 여부 — PASS.
|
||||
- [x] `pyproject.toml` 의존성 변경 유무 확인 — 의존성 추가 없음, `pip install -e .` 생략 가능.
|
||||
- [x] `docs/interface-contract.md` 변경 범위 확인: BAT-050~054 범위에서 AMQP wire 계약 변경 없음(기존 섹션 diff=0) — PASS.
|
||||
- [x] **credential_fetch_enabled 기본값 = false 확인** — PASS. 기본값 false 유지 확인.
|
||||
|
||||
### 배포 후 — 스모크
|
||||
|
||||
- [x] **데몬 기동 로그**: `apply_migrations` 완료(016번 포함) / 워커 스레드 정상 / ERROR/CRITICAL/Traceback 0 — PASS.
|
||||
- [x] **`slot_reconcile_warning` 테이블 생성 확인**: `SELECT COUNT(*) FROM slot_reconcile_warning;` → 0 rows (초기 상태, 에러 없음) — PASS.
|
||||
- [x] **dcy-034 reconcile sync 동작 확인 (BAT-051 핵심)**: `trex-core sync --all --dry-run` exit0 (A-case guard skip 포함) — PASS.
|
||||
- [x] **dcy-034 reconcile verify 동작 확인 (BAT-051 핵심)**: `trex-core verify` exit0 (no C-warned slots) — PASS. 초기 기동 시 `ImportError: make_broker` 발생 → 핫픽스 `51cc3cc`(make_broker→_build_broker) 반영 후 PASS.
|
||||
- [x] **dcy-035 WAC 운영리포트 정합 확인 (BAT-052 핵심)**: `trex-core report --json` exit0 — PASS.
|
||||
- [x] **dcy-036 휴면 확인 (BAT-053/054 핵심)**: `credential_fetch_enabled=false` 경로 동작 확인. portfolio-hub fetch 시도 로그 미발생 — PASS.
|
||||
- [x] **AMQP wire 무회귀**: `slot_filled_sell.<strategy>.<symbol>` 라우팅 synthetic RabbitMQ probe — NO_ROUTE/DLQ 증가 없음 PASS. `trex.events`, `trex.intent.req`, `trex.slots.req`, `trex.control.req` 정상 동작 확인 — PASS.
|
||||
- [x] **reconcile 차단 오발동 없음**: 재기동 후 ERROR/CRITICAL/Traceback 미발생 확인 — PASS.
|
||||
- [x] `trex-core report` 정상 동작 (REL-009 기능 회귀 없음) — PASS.
|
||||
|
||||
## AMQP Wire 계약 무회귀 체크포인트
|
||||
|
||||
| 항목 | 변경 여부 | 근거 |
|
||||
|---|---|---|
|
||||
| `trex.events` exchange/토폴로지 | 불변 | BAT-050~054 전체 Out of Scope 명시 |
|
||||
| `trex.intent.req` 큐/라우팅 | 불변 | BAT-050 REQ-108 NFR-4 PASS |
|
||||
| `trex.slots.req` 큐/스키마 | `reconcile_warned` 필드 **additive 추가** | BAT-050 REQ-104 AC-4~8. 기존 클라이언트 무시 가능 (JSON extra key). orb/tsl 영향 없음. |
|
||||
| `trex.control.req` 큐 | 불변 | 변경 없음 |
|
||||
| `trex.alerts` exchange | 불변(REL-009에서 이미 추가됨) | BAT-053 CRITICAL 알람 사용(기존 경로 활용) |
|
||||
| 슬롯 이벤트 페이로드 스키마 | 불변 | BAT-050 `test_slot_state_enum_unchanged` PASS |
|
||||
| SlotState enum 값 | 불변(5개) | BAT-050 `test_slot_state_enum_unchanged` PASS |
|
||||
| ALLOWED_TRANSITIONS | **14개** (13→14: INACTIVE→HOLDING 추가) | BAT-051 sync-only 엣지. 일반 전략 경로(INACTIVE→PENDING_BUY) 무영향. `test_normal_strategy_path_unchanged` PASS |
|
||||
|
||||
## Release Execution Evidence
|
||||
|
||||
- Release Status Transition Target: released
|
||||
|
||||
### Deployment Facts
|
||||
|
||||
- Executed At:
|
||||
- 2026-06-30 (M3 배포 윈도우, 장외)
|
||||
- Completed At:
|
||||
- 2026-06-30
|
||||
- Environment:
|
||||
- 운영 (`/root/release/trex-core`, instance_key=`trex-admin-daily-trading`, 실거래 KIS 계좌 91254), bare .venv
|
||||
- Operator:
|
||||
- 운영팀 확인
|
||||
- Revision or Artifact:
|
||||
- `5bdd720`(REL-009 배포본 = 이전 프로덕션) → **`314047b`** (origin/main; BAT-050~054 전체 + slot_filled 라우팅 수정 #36 + verify ImportError 핫픽스 `51cc3cc` 포함)
|
||||
- BAT-050: commit `c193388`, BAT-051: commit `07b393d`, BAT-052: commit `73d3b35`+`d3e4af5`, BAT-053: commit `e4e5c70`, BAT-054: commit `6b066e1`
|
||||
- 핫픽스: `51cc3cc` (verify ImportError `make_broker` → `_build_broker` 수정, 배포 중 검출·즉시 반영)
|
||||
- Commands or Procedure:
|
||||
- `git fetch origin && git checkout main && git pull` (→ `314047b`)
|
||||
- 의존성 추가 없음 — `pip install -e .` 생략
|
||||
- 마이그레이션: `trex-core-daemon` 기동 시 `apply_migrations` 자동 실행 (001~016 idempotent, 016번 신규 `slot_reconcile_warning` 테이블 생성)
|
||||
- `trex-core-daemon` 재시작 (기존 PID 종료 → 신규 기동)
|
||||
|
||||
### Profile-Specific Checks
|
||||
|
||||
- app-service:
|
||||
- Health Endpoint:
|
||||
- N/A (데몬은 HTTP 표면 없음). "ready" = 워커 스레드 + RabbitMQ 토폴로지 선언 완료 + 016번 마이그레이션 완료, 로그 ERROR/Traceback 0.
|
||||
- Startup Log Fields:
|
||||
- `apply_migrations` 완료 (016번 신규 포함), 워커 스레드 정상 기동, ERROR/CRITICAL/Traceback 0 확인.
|
||||
- Request Log Fields:
|
||||
- N/A (데몬 구조 — AMQP 메시지 처리, HTTP 없음).
|
||||
- Smoke or Manual Verification:
|
||||
- `trex-core report --json` exit0 PASS.
|
||||
- `trex-core sync --all --dry-run` exit0 (A-case guard skip) PASS.
|
||||
- `trex-core verify` exit0 (no C-warned slots) PASS — 초기 `ImportError: make_broker` 핫픽스 `51cc3cc` 반영 후 PASS.
|
||||
- `slot_filled_sell.<strategy>.<symbol>` synthetic RabbitMQ probe: NO_ROUTE/DLQ 증가 없음 PASS.
|
||||
- 재기동 후 ERROR/CRITICAL/Traceback 미발생 PASS.
|
||||
- `credential_fetch_enabled=false` 유지 — portfolio-hub fetch 시도 로그 미발생 PASS.
|
||||
|
||||
### Rollback Outcome
|
||||
|
||||
- Rollback Required:
|
||||
- 불필요. 스모크 전 항목 PASS.
|
||||
- Rollback Trigger:
|
||||
- N/A
|
||||
- Rollback Action:
|
||||
- N/A. 배포 중 verify `ImportError: make_broker` 발생 시 핫픽스 `51cc3cc`(make_broker→_build_broker)를 즉시 반영 후 재기동으로 해소 — 전체 롤백 미실행.
|
||||
|
||||
### Release Decision Evidence
|
||||
|
||||
- Released Decision:
|
||||
- GO. 모든 스모크 항목 PASS. 핫픽스 `51cc3cc` 포함 배포 revision `314047b` 운영 적용 완료.
|
||||
- Rationale:
|
||||
- BAT-050~054 전 항목 release-candidate 확인 완료. 스모크(report/sync/verify/wire/credential) 전 항목 PASS. verify ImportError는 배포 중 핫픽스로 즉시 해소됨. `credential_fetch_enabled=false` 유지로 dcy-036 양의경로 비활성 — 실거래 무영향 확인. 플립 활성화는 중장기 인스턴스 후속에서 별도 처리.
|
||||
- Recorded By:
|
||||
- 운영팀 (M3 배포 윈도우, 2026-06-30)
|
||||
- Recorded At:
|
||||
- 2026-06-30
|
||||
|
||||
## Feedback Handoff
|
||||
|
||||
- Observation Summary:
|
||||
- M3 배포 완료(2026-06-30). 스모크 전 항목 PASS. 배포 중 verify `ImportError: make_broker` 1건 검출 → 핫픽스 `51cc3cc`(make_broker→_build_broker) 즉시 반영으로 해소. 이후 재기동·스모크 전 PASS. `credential_fetch_enabled=false`(dcy-036 휴면) 유지 — 실거래 무영향. slot_filled 라우팅(#36) PASS 확인.
|
||||
- Discovery Input:
|
||||
- **dcy-036 실거래 활성화**: `credential_fetch_enabled = true` 플립 — portfolio-hub dcy-010 배포 + 실 KIS 통합검증 선행 후 별도 릴리즈. REQ-115 AC-1 완전 충족 선결.
|
||||
- **slot_filled NO_ROUTE / fill→strategy 라우팅 재설계** (REL-009 환류 이월): M3 P1. fill 이벤트 라우팅키 strategy_id 미참조 문제.
|
||||
- **reconcile 비차단 거버넌스 후속**: AC-9 change-req 등 M3 백로그.
|
||||
- REQ Input:
|
||||
- none
|
||||
- Change Request Input:
|
||||
- none
|
||||
|
||||
## 알려진 리스크
|
||||
|
||||
| 항목 | 수준 | 설명 | 해소 방안 |
|
||||
|---|---|---|---|
|
||||
| ~~BAT-054 PR #35 미머지~~ | ~~Critical~~ | ~~배포 선결 조건 미충족~~ | **해소됨** — PR #35 머지 완료, 배포 revision `314047b` 반영 |
|
||||
| ~~BAT-054 confirm-batch-verification 미완료~~ | ~~High~~ | ~~verification.md Status=draft~~ | **해소됨** — release-candidate 전환 완료 |
|
||||
| slot_reconcile_warning 마이그레이션 실패 | Medium | DB 권한 부족 또는 기존 테이블 충돌 시 기동 실패 | **배포 중 미발생** — 016번 마이그레이션 정상 완료 확인 |
|
||||
| reconcile 차단 오발동 | Medium | B/C 케이스 오탐 시 정상 슬롯 차단 가능 | 배포 후 장 시작 1 reconcile 주기 집중 모니터링 유지. 현재 미발생. |
|
||||
| WAC 리포트 degrade | Low | portfolio-hub BASE_URL 미설정 또는 미가용 시 WAC 섹션만 에러 표시 | 타 섹션 정상 — 비치명적. `trex-core report --json` exit0 PASS 확인 |
|
||||
| dcy-036 휴면 — byte-for-byte 회귀 보존 의존 | Low | opt-in OFF 경로에서 KIS fetch 로직 완전 비활성 의존 | **배포 중 확인 완료** — `credential_fetch_enabled=false` 유지, portfolio-hub fetch 시도 로그 미발생 PASS |
|
||||
| REQ-115 AC-1 통합 검증 미완 | Low | 실 portfolio-hub + KIS mock 환경 미확보 — stub 기반만 검증. 이번 릴리즈 go 조건 아님 | 후속 플립 절차(중장기 인스턴스)에서 선결 조건으로 관리 |
|
||||
| verify ImportError(배포 중 검출·해소) | Low | 초기 기동 시 `ImportError: make_broker` 발생 | **해소됨** — 핫픽스 `51cc3cc`(make_broker→_build_broker) 즉시 반영, 재기동 후 PASS |
|
||||
@@ -1,90 +0,0 @@
|
||||
# REL-011: M5 trex-core operator broker truth hotfix
|
||||
|
||||
- Status: **Released**
|
||||
- Profile: `app-service`
|
||||
- Target window: M5 장외 배포 윈도우 (승인 후)
|
||||
- Owner: 팀장 / 운영팀
|
||||
- Included batch: **BAT-057** (`REQ-119`, `REQ-120`, `REQ-121`, `REQ-122`)
|
||||
- Source discovery: `dcy-037_20260714_operator-broker-truth-and-managed-slot-divergence-hotfix.md`
|
||||
- Project control card: `★M5 core release: operator broker truth hotfix (BAT-057 / REL-011)` — Project #7, `P0`, `Release-Pending`
|
||||
- M5 coordination: [M5 coordinated release train readiness](../runbooks/m5-coordinated-release-train-readiness.md)
|
||||
|
||||
## Release intent
|
||||
|
||||
`credential_fetch_enabled=true` KIS 인스턴스에서 daemon과 운영자 `sync`/`verify`가 동일한 broker credential source와 holding truth를 사용하게 한다. KIS balance/token/auth/transport 실패를 성공한 빈 balance로 축소하지 않고 fail-loud로 종료하며, managed slot이 없는 broker holding과 managed non-holding divergence를 구분해 자동 보정 없이 보존한다.
|
||||
|
||||
이 릴리즈는 M5의 trex-core 선행 배포다. `portfolio-hub` 및 `trex-web`의 M5 배포 게이트와는 별도 release artifact지만, M5 release train의 필수 구성요소로 함께 추적한다.
|
||||
|
||||
## Source and baseline
|
||||
|
||||
| Item | Evidence |
|
||||
| --- | --- |
|
||||
| Release source pin | `6d90f8951dbf354eb41301492d0bcaf0af24d882` (`main`; BAT-057 requirement-implementation confirmation 포함) |
|
||||
| Runtime implementation | PR #42 merge `94e148940adb008db0bbd215052a1e984f7c566b` |
|
||||
| Prior operational core baseline | Project #7 M4 evidence: `7845fbe` (배포 당일 실제 checkout SHA를 다시 캡처해야 하며, 이를 현 운영 상태의 추정값으로 사용하지 않는다) |
|
||||
| Batch gate | BAT-057 `confirmed` (`confirm-batch-verification`, 2026-07-15); independent QC `PASS-WITH-NOTES`, acceptance blocker 0 |
|
||||
| DB/dependency delta from M4 baseline | `pyproject.toml` 및 persistence migration 변경 없음 |
|
||||
| Wire delta | AMQP 및 portfolio-hub external wire contract 변경 없음; `docs/interface-contract.md`에는 broker-read failure/reconciliation boundary만 명문화 |
|
||||
|
||||
## Included scope
|
||||
|
||||
1. daemon, `sync`, `verify`의 공통 broker provider를 통한 fetched credential source parity.
|
||||
2. fetched credential read 실패 시 무음 env/config fallback 금지(명시 break-glass만 예외), env-only 및 Paper 경로 회귀 보존.
|
||||
3. KIS balance 인증·권한·transport·malformed response·broker rejection을 `BrokerBalanceError`로 fail-loud 처리. 실패는 CLI exit `1`이며 정상 empty balance와 구별한다.
|
||||
4. `unmanaged_position`과 instance-scoped `managed_non_holding_divergence` 분류. 이 분류는 자동 주문, 자동 청산, slot 생성, slot/warning write를 하지 않는다.
|
||||
5. 안전한 source mode/label 관찰성 및 remediation은 별도 release gate라는 운영 문서 정합.
|
||||
|
||||
## Explicitly excluded
|
||||
|
||||
- `sync --live --yes` 실행, target portfolio 선택, 자동 remediation 및 실제 slot/ledger/broker write.
|
||||
- `credential_fetch_enabled` 또는 break-glass 설정의 변경·활성화. 배포 전후 해당 인스턴스 설정은 동일해야 한다.
|
||||
- KIS key/token, account identifier, DSN, portfolio-hub token의 출력·기록·수집.
|
||||
- PostgreSQL schema migration, dependency upgrade, AMQP topology/wire 변경.
|
||||
- TVR 및 전략 데몬 배포 범위.
|
||||
|
||||
## Draft verification evidence
|
||||
|
||||
| Check | Result | Evidence / boundary |
|
||||
| --- | --- | --- |
|
||||
| Full regression at target source | **PASS** — `807 passed, 47 skipped` | 2026-07-16, repository `.venv/bin/python -m pytest -q` |
|
||||
| Diff hygiene | **PASS** | `git diff --check 7845fbe..origin/main` |
|
||||
| CLI surface inspection | **PASS** | `trex-core sync --help`, `trex-core verify --help`; both support per-instance `--config` and `--dry-run` where applicable |
|
||||
| Batch focused suite | **PASS** — `69 passed, 1 skipped, 1 deselected` | BAT-057 verification evidence; in-process `pika` stub |
|
||||
| Full Ruff | **Known baseline debt** | target 21 findings; M4 baseline has 22. BAT-057 introduced no new full-suite Ruff failure. Track cleanup separately; do not claim lint-green. |
|
||||
| Live broker / live PostgreSQL / deployment | **PASS (release scope)** | Controlled production daemon rollout, startup acceptance, and both approved read-only smoke commands are recorded in [REL-011 execution evidence](evidence/rel-011_20260717_execution-evidence.md). No DB migration, live sync, or broker mutation occurred. |
|
||||
|
||||
BAT-057 retains one verification note: fake-driver parity covered the PostgreSQL adapter query/row mapping, but an actual PostgreSQL engine integration fixture was not executed. This is documented evidence debt, not a passed live-database claim.
|
||||
|
||||
## Release approval and completion record
|
||||
|
||||
All functional release gates are confirmed in the [REL-011 execution evidence](evidence/rel-011_20260717_execution-evidence.md):
|
||||
|
||||
- [x] Lead reviewed BAT-057 status, target `6d90f895…`, source lineage, and no-migration/no-wire-delta boundary.
|
||||
- [x] Operations provided the captured pre-deploy `ROLLBACK_REVISION` `7845fbe856e125e712ac481e36ac582c1a2fe54b`, source checkout, Supervisor restart, instance, and startup-health records.
|
||||
- [x] Justin Ko authorized the release execution in Mattermost message `32675` at `2026-07-16 17:22:50 KST`; the read-only broker smoke did not authorize any `sync --live` action.
|
||||
- [x] Operations recorded unchanged `credential_fetch_enabled` / break-glass semantics.
|
||||
- [x] Target checkout, restart, runtime health, and both read-only smoke results are evidenced.
|
||||
- [x] Release owner directed closure after the evidence intake; no `sync --live` authorization is implied.
|
||||
|
||||
## Rollout summary
|
||||
|
||||
1. Capture current revision and existing instance configuration fingerprint (without secrets).
|
||||
2. Fetch and check out the pinned target source; confirm no migration or dependency action is required by source diff.
|
||||
3. Stop the existing trex-core daemon using the host’s approved supervisor procedure, then start the same approved instance configuration with the target source.
|
||||
4. Confirm startup completion, RabbitMQ topology readiness, and no `ERROR`, `CRITICAL`, or traceback in the deployment-window logs.
|
||||
5. Run only the read/dry-run smoke steps in `docs/runbooks/rel-011-m5-operator-broker-truth-hotfix-deployment.md`.
|
||||
6. If a failure occurs, stop immediately, restore the captured pre-deploy revision, restart with the unchanged configuration, and collect redacted evidence.
|
||||
|
||||
## Rollback boundary
|
||||
|
||||
Rollback target is the **actual pre-deploy revision captured in the operational preflight**, not an assumed SHA. Since this release adds no migration or dependency change, rollback is source restoration plus daemon restart using the unchanged configuration. Do not delete or alter database data as a rollback action.
|
||||
|
||||
## `confirm-release` decision
|
||||
|
||||
**Released.** The release-specific evidence records Justin Ko’s approval reference, immutable target revision, pre-deploy rollback SHA `7845fbe…`, controlled restart, startup health, both required read-only smoke checks, no-write boundary, and no-rollback disposition. This decision does not authorize live sync, configuration activation, remediation, DB changes, or deployment of other M5 services.
|
||||
|
||||
## Release feedback
|
||||
|
||||
- **Operational outcome:** the reconstructed record shows a clean controlled restart, no startup fatal log, and successful read-only smoke for both approved instances; no release-scope rollback or incident was recorded.
|
||||
- **Evidence recovery outcome:** the final secret-free record now includes the approval reference and exact pre-deploy rollback revision, alongside the operational smoke evidence.
|
||||
- **Next Discovery input:** standardize first-pass release evidence capture: a redacted approval reference, exact rollback revision, instance identity, per-command timestamp/exit/result/no-write classification, and rollback disposition must be recorded before a future release gate is closed.
|
||||
Reference in New Issue
Block a user