blackout: persist session_id across queued intent lifecycle (#375) #385

Merged
jihoson merged 2 commits from feature/issue-375-queued-intent-session-id into feature/v3-session-policy-stream 2026-03-02 03:20:18 +09:00
Collaborator

Summary

  • QueuedOrderIntentsession_id 필드를 추가해 큐잉 시점 세션 식별자를 저장하도록 변경했습니다.
  • _maybe_queue_order_intent()session_id를 인자로 받아 intent 생성 시 함께 기록하도록 반영했습니다.
  • trading_cycle/run_daily_session에서 이미 계산한 runtime_session_id를 큐잉 경로로 전달하도록 연결했습니다.
  • 복구 실행(process_blackout_recovery_orders) 시 intent.session_id를 우선 사용해 DB 로그의 session_id가 큐잉 시점과 일치하도록 보장했습니다.
  • 회귀 테스트를 추가/보강해 큐 overflow 및 recovery 경로에서 session_id가 유지되는지 검증했습니다.

Scope Mapping

  • REQ: REQ-V3-001
  • TASK: TASK-CODE-008
  • TEST: TEST-ACC-015

Validation

  • ruff check src/core/blackout_manager.py src/main.py tests/test_blackout_manager.py tests/test_main.py
  • pytest -q tests/test_blackout_manager.py
  • pytest -q tests/test_main.py -k "blackout_queue_overflow_keeps_latest_intent or blackout_queues_order_and_skips_submission or process_blackout_recovery_executes_valid_intents or process_blackout_recovery"
  • python3 scripts/validate_governance_assets.py origin/feature/v3-session-policy-stream...HEAD
  • python3 scripts/validate_ouroboros_docs.py
## Summary - `QueuedOrderIntent`에 `session_id` 필드를 추가해 큐잉 시점 세션 식별자를 저장하도록 변경했습니다. - `_maybe_queue_order_intent()`가 `session_id`를 인자로 받아 intent 생성 시 함께 기록하도록 반영했습니다. - `trading_cycle`/`run_daily_session`에서 이미 계산한 `runtime_session_id`를 큐잉 경로로 전달하도록 연결했습니다. - 복구 실행(`process_blackout_recovery_orders`) 시 `intent.session_id`를 우선 사용해 DB 로그의 session_id가 큐잉 시점과 일치하도록 보장했습니다. - 회귀 테스트를 추가/보강해 큐 overflow 및 recovery 경로에서 `session_id`가 유지되는지 검증했습니다. ## Scope Mapping - REQ: `REQ-V3-001` - TASK: `TASK-CODE-008` - TEST: `TEST-ACC-015` ## Validation - `ruff check src/core/blackout_manager.py src/main.py tests/test_blackout_manager.py tests/test_main.py` - `pytest -q tests/test_blackout_manager.py` - `pytest -q tests/test_main.py -k "blackout_queue_overflow_keeps_latest_intent or blackout_queues_order_and_skips_submission or process_blackout_recovery_executes_valid_intents or process_blackout_recovery"` - `python3 scripts/validate_governance_assets.py origin/feature/v3-session-policy-stream...HEAD` - `python3 scripts/validate_ouroboros_docs.py`
agentson added 1 commit 2026-03-02 03:09:45 +09:00
blackout: persist session_id across queued intent lifecycle (#375)
All checks were successful
Gitea CI / test (push) Successful in 32s
Gitea CI / test (pull_request) Successful in 33s
8e02b1ea4f
Author
Collaborator

PR #385 코드 리뷰 — feature/issue-375-queued-intent-session-id

범위: QueuedOrderIntentsession_id 필드 추가 및 blackout 복구 경로에서 원래 session_id 보존


통과 항목

1. 데이터 모델 변경
QueuedOrderIntentsession_id: str 필드가 3번째 위치(market_code → exchange_code → session_id)에 추가됨.
필수 필드(default 없음)로 선언되어 컴파일 타임에 미전달 감지 가능.

2. 호출 경로 완전성
_maybe_queue_order_intent() 호출 4곳 모두 session_id=runtime_session_id 전달 확인:

  • trading_cycle 2061, 2109번 라인 (BUY/SELL 경로)
  • run_daily_session 3270, 3308번 라인 (BUY/SELL 경로)

3. 복구 경로 session_id 보존
process_blackout_recovery_orders()에서 복구 시 intent에 저장된 session_id를 재사용하는 의도가 명확함.

4. 테스트 커버리지

  • test_blackout_queue_stores_session_id: batch[0].session_id == "KRX_REG" 검증
  • test_blackout_recovery_logs_session_id: recovery DB에 "NXT_AFTER" session_id 저장 검증
  • 로컬 실행 결과: 167 passed in 8.05s

5. overflow_drop_count 통합
이 PR이 동시에 #371 overflow 카운터(_overflow_drop_count, overflow_drop_count 프로퍼티)를 포함한 것은
#384 머지 이후 충돌 없이 병합된 것으로 확인. 중복 기여 없음.


⚠️ 소견 (Non-blocking)

getattr 방어 접근 불필요

# src/main.py:1225
session_id=getattr(intent, "session_id", get_session_info(market).session_id),

session_idQueuedOrderIntent필수 dataclass 필드이므로, 필드 없이 인스턴스화 자체가 불가합니다.
getattr 폴백은 실제로 도달할 수 없는 브랜치입니다.
PR #384에서도 동일한 패턴(_coerce_nonnegative_int + getattr)을 소견으로 지적했으며,
그때와 마찬가지로 직접 접근으로 단순화를 권장합니다:

# 권장
session_id=intent.session_id,

단, 이 소견은 Non-blocking이며, 현재 구현도 정확히 동작합니다.


결론

LGTM — 핵심 기능(session_id 보존) 완전히 구현됨, 테스트 통과.
getattr 단순화는 후속 PR 또는 리팩터링 기회에 처리 가능.

## PR #385 코드 리뷰 — feature/issue-375-queued-intent-session-id **범위**: `QueuedOrderIntent`에 `session_id` 필드 추가 및 blackout 복구 경로에서 원래 session_id 보존 --- ### ✅ 통과 항목 **1. 데이터 모델 변경** `QueuedOrderIntent`에 `session_id: str` 필드가 3번째 위치(market_code → exchange_code → session_id)에 추가됨. 필수 필드(default 없음)로 선언되어 컴파일 타임에 미전달 감지 가능. **2. 호출 경로 완전성** `_maybe_queue_order_intent()` 호출 4곳 모두 `session_id=runtime_session_id` 전달 확인: - `trading_cycle` 2061, 2109번 라인 (BUY/SELL 경로) - `run_daily_session` 3270, 3308번 라인 (BUY/SELL 경로) **3. 복구 경로 session_id 보존** `process_blackout_recovery_orders()`에서 복구 시 intent에 저장된 session_id를 재사용하는 의도가 명확함. **4. 테스트 커버리지** - `test_blackout_queue_stores_session_id`: `batch[0].session_id == "KRX_REG"` 검증 - `test_blackout_recovery_logs_session_id`: recovery DB에 `"NXT_AFTER"` session_id 저장 검증 - 로컬 실행 결과: 167 passed in 8.05s ✅ **5. overflow_drop_count 통합** 이 PR이 동시에 #371 overflow 카운터(`_overflow_drop_count`, `overflow_drop_count` 프로퍼티)를 포함한 것은 #384 머지 이후 충돌 없이 병합된 것으로 확인. 중복 기여 없음. --- ### ⚠️ 소견 (Non-blocking) **getattr 방어 접근 불필요** ```python # src/main.py:1225 session_id=getattr(intent, "session_id", get_session_info(market).session_id), ``` `session_id`는 `QueuedOrderIntent`의 **필수 dataclass 필드**이므로, 필드 없이 인스턴스화 자체가 불가합니다. 이 `getattr` 폴백은 실제로 도달할 수 없는 브랜치입니다. PR #384에서도 동일한 패턴(`_coerce_nonnegative_int + getattr`)을 소견으로 지적했으며, 그때와 마찬가지로 직접 접근으로 단순화를 권장합니다: ```python # 권장 session_id=intent.session_id, ``` 단, 이 소견은 Non-blocking이며, 현재 구현도 정확히 동작합니다. --- ### 결론 **LGTM** — 핵심 기능(session_id 보존) 완전히 구현됨, 테스트 통과. getattr 단순화는 후속 PR 또는 리팩터링 기회에 처리 가능.
agentson added 1 commit 2026-03-02 03:17:42 +09:00
blackout: simplify recovery session_id binding to queued value
All checks were successful
Gitea CI / test (push) Successful in 33s
Gitea CI / test (pull_request) Successful in 35s
4f21117eca
Author
Collaborator

추가 리뷰 — getattr 단순화 업데이트 확인

커밋: 4f21117 blackout: simplify recovery session_id binding to queued value

소견 반영 확인

# 변경 전 (src/main.py:1223)
session_id=getattr(intent, "session_id", get_session_info(market).session_id),

# 변경 후
session_id=intent.session_id,

getattr 폴백 제거 완료. session_id가 필수 dataclass 필드임을 코드가 명확히 반영.

  • 테스트: 167 passed in 8.87s
  • 변경 범위: 단일 라인, 사이드 이펙트 없음

LGTM — 추가 소견 없음. 머지 준비 완료.

## 추가 리뷰 — getattr 단순화 업데이트 확인 **커밋**: `4f21117 blackout: simplify recovery session_id binding to queued value` ### ✅ 소견 반영 확인 ```python # 변경 전 (src/main.py:1223) session_id=getattr(intent, "session_id", get_session_info(market).session_id), # 변경 후 session_id=intent.session_id, ``` `getattr` 폴백 제거 완료. `session_id`가 필수 dataclass 필드임을 코드가 명확히 반영. - 테스트: 167 passed in 8.87s ✅ - 변경 범위: 단일 라인, 사이드 이펙트 없음 **LGTM** — 추가 소견 없음. 머지 준비 완료.
jihoson merged commit 16ddc22d14 into feature/v3-session-policy-stream 2026-03-02 03:20:18 +09:00
jihoson deleted branch feature/issue-375-queued-intent-session-id 2026-03-02 03:20:18 +09:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jihoson/The-Ouroboros#385