docs(req): dcy-008 kill-switch confirm-discovery + REQ-043~047 (Approved)

dcy-008(비상 정지/kill-switch) OQ-2(별도 테이블/store)·OQ-4(수동 해제
resume_kill_switch) 결정 → confirm-discovery(confirmed) → draft-req →
confirm-req(5개 Approved).

- REQ-043 (Interface): trex.pause.req → trex.control.req 제어 채널 + action dispatch (OQ-1)
- REQ-044 (Data): day-scoped killswitch_exclusion 테이블 + store + 005 마이그레이션 (OQ-2)
- REQ-045 (Interface): kill_switch 실행 — 범위별 holding 순차 sell() + idempotency + 이력 (NFR-1/2 흡수)
- REQ-046 (Interface): 당일 제외 masking + 다음 거래일 자동복귀 + resume_kill_switch (OQ-4, NFR-3 흡수)
- REQ-047 (Documentation): baseline 3문서 정합

OQ-3(pending_buy 롤백)은 REQ Deferred. srs index Next ID REQ-048, Register +5,
요약 갱신. dcy-008 생성된 REQ 참조 기록.

dcy-009(멀티 인스턴스 RabbitMQ, draft)는 별도 주제로 제외.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-07 11:29:31 +09:00
co-authored by Claude Opus 4.8
parent 6fda381f62
commit c912c08071
8 changed files with 638 additions and 45 deletions
@@ -0,0 +1,116 @@
# req-044: kill-switch day-scoped 제외 store + 테이블 + 마이그레이션
- Status: Approved
- Type: Data
- Priority: High
- Owner: project maintainers
## Intent
kill-switch 발동 시 대상 범위(portfolio/전역)를 **당일(day-scoped) 전략 실행에서 제외**하는 상태를 데몬 재시작 후에도 유지하기 위해 영속화한다. 기존 `snapshot_pause`(portfolio_id PK, resume 전까지 영구, 날짜 없음)와 의미가 다르므로(당일만, `trading_date` 키), **별도 테이블 + 전용 store 어댑터를 신설**한다(dcy-008 OQ-2 Answered). 다음 거래일 부팅 시 자동 무효된다.
## Requirement
- 신규 테이블(예: `killswitch_exclusion`)을 추가하는 additive 마이그레이션을 작성한다. 최소 컬럼: `portfolio_id`(전역 제외 표현 포함), `trading_date`, `actor`, `created_at`.
- 전역(global) 제외 표현 방식(예: `portfolio_id = '*'` sentinel 또는 별도 scope 컬럼)은 구현 시 결정한다(Notes).
- PK 또는 unique 제약은 `(portfolio_id, trading_date)` 로 동일 거래일 중복 제외를 멱등 처리한다.
- 전용 store 어댑터(예: `PostgreSQLKillSwitchStore`)가 아래를 제공한다: `exclude(portfolio_id|global, trading_date, actor)`, `clear(portfolio_id|global, trading_date)`(수동 해제, REQ-046), `list_excluded(trading_date) -> set`.
- `list_excluded(trading_date)` 는 **해당 거래일** 의 제외 항목만 반환한다. 다른 날짜 row 는 자동으로 결과에서 제외된다(day-scoped). 과거 row 정리(삭제)는 선택이며 조회가 trading_date 로 필터링되므로 정합에 영향 없다.
- 기존 `snapshot_pause` / `PostgreSQLPauseStore` 는 변경하지 않는다(관심사 분리).
## Acceptance Criteria
1. Given 마이그레이션 적용, When 스키마를 확인하면, Then `killswitch_exclusion` 테이블이 `(portfolio_id, trading_date, actor, created_at)` 컬럼과 `(portfolio_id, trading_date)` 멱등 제약으로 존재한다.
2. Given 마이그레이션을 2회 적용, When 재적용하면, Then `IF NOT EXISTS` 패턴으로 오류 없이 멱등하다(기존 데이터 보존).
3. Given `exclude("pf-A", D)`, When `list_excluded(D)`, Then `{"pf-A"}` 를 포함한다.
4. Given `exclude("pf-A", D)`, When `list_excluded(D+1)`(다음 거래일), Then `pf-A` 가 포함되지 않는다(day-scoped 자동 무효).
5. Given 같은 `(pf-A, D)` 로 `exclude` 2회, When 호출하면, Then 멱등(중복 row 없음, 오류 없음).
6. Given `exclude("pf-A", D)` 후 `clear("pf-A", D)`, When `list_excluded(D)`, Then `pf-A` 가 더 이상 포함되지 않는다(수동 해제, REQ-046).
7. Given 전역 제외, When `exclude` 후 `list_excluded(D)`, Then 전역 sentinel 이 결과에 포함되어 호출자가 전체 제외로 해석할 수 있다.
## Impacted Area
- Docs:
- `docs/project-structure.md` — 신규 테이블/store 모듈 반영 (REQ-047 처리)
- Modules:
- `trex_core/adapters/persistence/sql/005_create_killswitch_exclusion.sql` (신규, additive)
- `trex_core/adapters/portfolio/killswitch_store.py` 또는 동등 위치 — `PostgreSQLKillSwitchStore`
- Tests:
- store CRUD + day-scoped 조회 + 멱등 + 전역 sentinel 단위/통합 테스트(PG 게이트)
## Notes
- dcy-008 OQ-2 Answered: 별도 테이블/store 신설(snapshot_pause 와 분리).
- 전역 제외 표현(`portfolio_id='*'` vs scope enum 컬럼)은 구현 결정 — masking 소비처(REQ-046)와 계약 일치만 보장하면 됨.
- `trading_date` 기준: dcy-008 의 day-scoped 의미 = "발동 거래일". 거래일 경계(UTC vs KST)는 데몬의 기존 trading_date 관례(UTC date)를 따르되 REQ-045/046 와 일치시킨다.
- BAT-010 R-2(마이그레이션 실 PG round-trip) 선례에 따라 verification 에서 실 PG 적용 확인.
## Change Log
### CHG-20260607-01
- Date: 2026-06-07
- Author: Justin Ko
#### Change Summary
- dcy-008(confirmed) → REQ-044 초안 생성.
#### Intent
- 당일 제외 영속(OQ-2 Answered: 별도 테이블)을 Data REQ 로 정규화.
#### Acceptance Criteria Delta
- Added: AC-1~7 전체
#### Impacted Area Delta
- Docs: project-structure.md (REQ-047)
- Modules: sql/005_create_killswitch_exclusion.sql, killswitch_store.py
- Tests: store CRUD + day-scoped + 멱등
#### Delivery Trace Delta
- Batches: none (미할당)
- Releases: none
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: confirm-req 로 승인.
### CHG-20260607-02
- Date: 2026-06-07
- Author: Justin Ko
#### Change Summary
- Proposed → Approved (confirm-req).
#### Intent
- 승인 게이트 통과: 필수 필드·구체 AC·Impacted Area·Change Log 완비. dcy-008(confirmed) OQ-2 결정(별도 테이블) 반영. 전역 sentinel 표현은 구현 결정으로 승인 blocker 아님.
#### Acceptance Criteria Delta
- (변경 없음)
#### Impacted Area Delta
- (변경 없음)
#### Delivery Trace Delta
- Batches: none (미할당)
- Releases: none
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: suggest-batch-reqs / draft-batch 로 delivery 편성.