docs(dcy-036): draft-req + confirm-req — REQ-112~115 Approved (그날-시작 KIS fetch + fail-safe 로드)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
This commit is contained in:
2026-06-28 10:12:18 +09:00
co-authored by Claude Opus 4.8
parent 9312ac4401
commit f9c4fb4eba
6 changed files with 374 additions and 19 deletions
@@ -0,0 +1,88 @@
# req-113: KISConfig 소스 우선순위 — portfolio-hub fetch 1차 + env break-glass + opt-in
- Status: Approved
- Type: Configuration
- Priority: High
- Owner: trex-core-dev
## Intent
- 현재 `DaemonConfig.from_env()`는 KIS 인증정보를 `TREX_KIS_BROKER_*` 환경변수에서만 읽는다. dcy-036 C1/FR-4/NFR-1에 따라 "fetch 1차, env는 명시적 break-glass 오버라이드"로 소스 우선순위를 변경하되, 기존 단기 인스턴스(M1/M2)의 회귀를 막기 위해 fetch는 **opt-in**(명시적 활성화 없으면 기존 env-only 경로 보존)으로 도입한다.
- 이 REQ는 설정 계층(TOML/env/fetch 우선순위)과 `DaemonInstanceConfig`/`DaemonConfig` 로더의 변경만 다루며, 실제 fetch I/O는 REQ-112 어댑터에 위임한다.
## Requirement
- `DaemonInstanceConfig`(per-instance TOML 로더)에 `credential_fetch_enabled: bool = False` 필드를 추가한다. TOML에 `credential_fetch_enabled = true`가 명시된 경우에만 활성화된다(opt-in, 부재 시 False = env-only 기존 경로 보존).
- `credential_fetch_enabled = true`일 때 `DaemonConfig` 구성 단계에서 KISConfig 소스 우선순위는 다음과 같다:
1. **portfolio-hub fetch** (`PortfolioHubReadAdapter.fetch_broker_credential()` 호출) — 성공 시 반환된 `BrokerCredentialPayload`로 `KISConfig` 구성.
2. **env break-glass** (`TREX_KIS_BROKER_BREAK_GLASS=true` 환경변수가 명시적으로 설정된 경우) — portfolio-hub fetch를 시도하지 않고 기존 `TREX_KIS_BROKER_*` env로 KISConfig 구성. 운영자가 의도적으로 break-glass 경로를 활성화한 것으로 간주.
- fetch와 break-glass가 모두 부재/비활성이면 env-only 기존 경로(`TREX_KIS_BROKER_*`) 유지.
- `credential_fetch_enabled = false`(기본값)일 때: 기존 `TREX_KIS_BROKER_*` env-only 경로를 byte-for-byte 보존한다. portfolio-hub를 호출하지 않는다.
- break-glass 활성화 여부를 기동 시 INFO 로그로 출력한다(운영자 인지). 단, app_secret은 마스킹(NFR-2).
- KISConfig 구성에 사용된 소스(fetch / break-glass / env-only)를 기동 시 INFO 로그로 기록한다.
## Acceptance Criteria
1. Given TOML에 `credential_fetch_enabled = false`(부재 포함)이고 `TREX_KIS_BROKER_*` env 설정, When 데몬 기동, Then `KISConfig`가 `TREX_KIS_BROKER_*` env-only로 구성되고 portfolio-hub fetch 호출이 발생하지 않는다 (기존 회귀 없음).
2. Given TOML에 `credential_fetch_enabled = true`이고 portfolio-hub fetch가 유효한 `BrokerCredentialPayload`를 반환, When 데몬 기동, Then `KISConfig.app_key`, `KISConfig.app_secret`, `KISConfig.account_ref`가 fetch 결과로 구성된다.
3. Given TOML에 `credential_fetch_enabled = true`이고 `TREX_KIS_BROKER_BREAK_GLASS=true` 환경변수 설정, When 데몬 기동, Then portfolio-hub fetch를 시도하지 않고 `TREX_KIS_BROKER_*` env로 KISConfig가 구성된다 (break-glass 경로).
4. Given break-glass 활성화 상태, When 데몬 기동 로그 확인, Then break-glass 활성화 사실이 INFO로 기록된다.
5. Given 어떤 KISConfig 구성 경로든, When 기동 로그 확인, Then `app_secret` 값이 평문으로 출력되지 않는다 (마스킹).
6. Given `credential_fetch_enabled = true` TOML이고 `TREX_KIS_BROKER_BREAK_GLASS` 미설정, When 기동 로그 확인, Then KISConfig 소스가 "fetch" 임을 INFO로 기록한다.
7. Given `DaemonInstanceConfig.from_toml`에서 `credential_fetch_enabled` 파싱, When TOML에 해당 키 부재, Then `False`로 파싱된다 (opt-in 기본값).
## Impacted Area
- Docs: 없음 (baseline 문서 갱신은 별도 scope)
- Modules:
- `trex_core/runtime/config.py` — `DaemonInstanceConfig`에 `credential_fetch_enabled: bool = False` 필드 추가; `from_toml()` 로더에서 파싱; `from_config()` 또는 `DaemonConfig` 조립 단계에서 fetch/break-glass/env-only 우선순위 로직 추가; `TREX_KIS_BROKER_BREAK_GLASS` 환경변수 인식
- `trex_core/runtime/daemon.py` (또는 조립 지점) — 기동 시 소스 INFO 로그 출력
- Tests:
- `tests/runtime/test_config.py` — AC-1~7 케이스 추가: fetch opt-in off/on, break-glass, 마스킹, TOML 파싱 기본값
## Notes
- `TREX_KIS_BROKER_BASE_URL`은 fetch 경로에서도 여전히 env로 제공한다. portfolio-hub `/v1/user_info`는 `app_key`/`app_secret`/`account_ref`만 전달하며 `base_url`과 기타 KIS 설정(timeout, allow_live 등)은 env에서 읽는다.
- `TREX_KIS_BROKER_BREAK_GLASS` 환경변수명은 의도적으로 명시적이다 — 운영자가 비상 경로임을 인지하고 설정해야 한다.
- portfolio-hub fetch 실패(네트워크 오류 등) 시 처리는 REQ-114(그날-시작 로드 게이트)가 담당한다. 이 REQ는 설정 우선순위 계층만 다룬다.
- OQ-4(알람 trex-notifier 연동): Deferred — REQ-114 Notes 참조.
- Source: dcy-036 C1, FR-4, NFR-1, OQ-3 Answered (fetch 1차, env 명시적 break-glass).
## Change Log
### CHG-20260628-01
- Date: 2026-06-28
- Author: trex-core-dev
#### Change Summary
- 신규 생성 (Proposed) — dcy-036 C1/FR-4/NFR-1/OQ-3 산출물.
#### Intent
- dcy-036 FR-4(KISConfig 소스 우선순위 확장: fetch 1차 + env break-glass + opt-in)를 Configuration REQ로 정규화한다. REQ-112 어댑터의 소비자 배선 계층.
#### Acceptance Criteria Delta
- Added:
- AC-1~7 전체 (신규 초안)
- Updated: 없음
- Removed: 없음
#### Impacted Area Delta
- Docs: 없음
- Modules:
- `config.py` `DaemonInstanceConfig` 확장 (`credential_fetch_enabled`), `from_toml` 파싱, 조립 우선순위 로직
- `daemon.py` 기동 로그
- Tests:
- `tests/runtime/test_config.py` 케이스 추가
#### Delivery Trace Delta
- Batches: 미정 (suggest-batch-reqs 대기)
- Releases: 미정
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: confirm-req 후 REQ-112~115 일괄 batch 배정 검토.
#### Validation Plan
- pytest로 AC-1~7 각 케이스 확인. AC-1(opt-in off → env-only, fetch 미호출)가 회귀 방지의 핵심 케이스.
### CHG-20260628-02
- Date: 2026-06-28
- Author: 팀장(Claude)
- confirm-req: `Proposed` → `Approved`. dcy-036 FR-4/OQ-3 추적. credential_fetch_enabled opt-in 기본 false로 M1/M2 byte-for-byte 보존(AC-1·NFR-1) 적절. fetch 1차→env break-glass(명시적 TREX_KIS_BROKER_BREAK_GLASS) 우선순위 정합. base_url 등은 env 유지 합리. blocker 없음.