Files
trex-core/docs/batches/bat-025_20260609_slot-entry-count-and-closed-reallocation/verification.md
T
genichinandClaude Opus 4.8 6e8e79660c feat(slot): slot entry_count + closed-slot reallocation (dcy-019, BAT-025) + REL-005
dcy-019/issue #18: slot 자원을 진입 횟수 기준으로 고르게 재사용하고 idle 소진 시
closed 슬롯을 직접 재할당한다. 거버넌스는 전부 change-req(신규 REQ 없음).

- 도메인(REQ-002): Slot.entry_count(기본 0) + EXPECTED_SLOT_FIELDS, 상태 머신
  closed→pending_buy 신규 전이(base 8→9, ALLOWED_TRANSITIONS 14→15),
  _apply_transition_fields closed→pending_buy clean-slate + →pending_buy 시 +1
- 영속화(REQ-006): 멱등 마이그레이션 008(entry_count), flat 매핑,
  find_allocatable_slot(idle∪closed, entry_count→updated_at→slot_id) + in-memory 동등
- admission(REQ-007): _admit_buy find_idle_slot→find_allocatable_slot + from_state=slot.status
- 테스트(REQ-003): 전이 카운트/계약 가드 정합 + test_slot_entry_count.py / test_buy_admission_reallocation.py
- 문서(REQ-009): data-model.md / runtime-flows.md 정합
- 기존 daily_symbol_entries(symbol-scoped) 분리·미변경

BAT-025(release-candidate) delivery + change-req REQ-002/003/006/007/009(CHG-20260609-01).
REL-005(confirmed, app-service): BAT-024+BAT-025 묶음. operator-facing run-the-app
스모크로 enter --forced-close-at(BAT-024)·closed 재할당(BAT-025) 실 데몬 검증
(실 PG 마이그레이션 008 round-trip 포함).

검증: 단위 366 passed / 35 skipped(KIS sandbox 1건 deselect — live .env 환경 의존), ruff clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 14:49:22 +09:00

4.8 KiB
Raw Blame History

BAT-025 Verification

  • Status: verified
  • Batch: BAT-025

Acceptance Mapping

REQ-002 (entry_count 필드 + closed→pending_buy 전이 + 전이 로직, change-req)

AC Evidence
Slot.entry_count 가 EXPECTED_SLOT_FIELDS 에 포함 tests/domain/slot/test_contract.py::test_slot_fields_match_expected_contract
6 상태 / 9 base 전이(closed→pending_buy) tests/domain/slot/test_state.py::test_allowed_transition[CLOSED-PENDING_BUY] / ::test_allowed_transitions_set_size(15)
→pending_buy 시 entry_count +1(idle→/closed→), 그 외 보존 tests/domain/slot/test_slot_entry_count.py::TestEntryCount(증분/non-buy/closed→idle 보존)
closed→pending_buy clean-slate 점유 초기화 ::TestClosedReallocation::test_closed_to_pending_buy_clean_slate_and_bumps_count / ::test_closed_to_pending_buy_clears_prior_position_when_not_supplied

REQ-003 (테스트 계약 정합, change-req)

AC Evidence
전이 집합 테스트 closed→pending_buy allowed + 크기 15 tests/domain/slot/test_state.py
컬럼 계약 가드 entry_count 포함 tests/domain/slot/test_contract.py
entry_count/reallocation 신규 단위 tests/domain/slot/test_slot_entry_count.py, tests/application/test_buy_admission_reallocation.py

REQ-006 (마이그레이션 + persistence + selector, change-req)

AC Evidence
daily_slot entry_count 컬럼(마이그레이션 008, 멱등) sql/008_add_slot_entry_count.sql + tests/adapters/persistence/test_migration_and_drift.py(test DSN 게이트, EXPECTED_SLOT_FIELDS↔information_schema 자동)
find_allocatable_slot(idle∪closed, entry_count→updated_at→slot_id) tests/domain/slot/test_slot_entry_count.py::TestAllocatableSelector(none/idle-only/closed 포함/오름차순)
flat slot 매핑(+entry_count) round-trip tests/adapters/persistence/test_migration_and_drift.py(test DSN) + in-memory selector 단위

REQ-007 (_admit_buy 일반화, change-req)

AC Evidence
idle 소진 시 closed 슬롯으로 admit tests/application/test_buy_admission_reallocation.py::test_admits_into_closed_slot_when_no_idle_remains
idle 우선(closed 보다) ::test_prefers_idle_over_closed
idle·closed 모두 소진 → no_idle_slot 거부 ::test_rejects_when_no_idle_and_no_closed
마지막 슬롯 경합 동시성 회귀 tests/application/test_intent_concurrency.py 전체

REQ-009 (baseline 문서 정합, change-req)

AC Evidence
runtime-flows admission selector/transit entry_count step docs/runtime-flows.md(코드-문서 diff 대조)
data-model daily_slot entry_count/lifecycle/state rules docs/data-model.md(코드-문서 diff 대조)

Evidence

  • Test:
    • 단위 전체 회귀: 366 passed / 35 skipped / 1 deselected(신규 entry_count 12 + reallocation 3 포함; ::test_sandbox_token_and_submit deselect — LIVE .env KIS URL 환경 의존, 본 batch 무관).
    • ruff check trex_core tests → All checks passed.
  • Logs: 366 passed, 35 skipped, 1 deselected in 1.13s.

성공 기준(dcy-019) 대응

  • S-1(idle 없고 closed 있을 때 closed 로 admit, 이전엔 no_idle_slot 거부): test_admits_into_closed_slot_when_no_idle_remains.
  • S-2(entry_count 최소 선택 + tie-break 결정적): TestAllocatableSelector::test_orders_by_entry_count_ascending + test_prefers_idle_over_closed.
  • S-3(할당 전이 시 정확히 +1, 동시 경합 중복 없음, daily_symbol_entries 회귀 green): TestEntryCount::test_increments_on_each_pending_buy + test_intent_concurrency.py + test_service.py::TestClosedToIdleRecovery(daily_symbol_entries 보존).

Carried-Over / 비차단

  • PG 게이트(마이그레이션 008 round-trip + 드리프트)는 라이브 runtime DSN 미사용(파괴적 truncate 회피) → test DSN 환경에서 자동 검증. 마이그레이션은 004 의 검증된 additive·멱등 패턴과 동일하고, 드리프트 가드는 EXPECTED_SLOT_FIELDS(entry_count 포함)↔information_schema 로 강제되어 코드 단위로 동등 보장.
  • 실 데몬 + 실 PG full-stack 의 closed 재할당 e2e 는 운영 배포 검증(후속 REL)에서 확인 — 단위(in-memory repo + IntentService)로 admission/전이/카운트 커버.
  • snapshot available_slots(=idle_count) 는 dcy-019 범위 밖(§5 제외)이라 closed 가용분을 보수적으로 under-report — admission 자체는 closed 재할당을 수행. 필요 시 후속 change-req 후보.

Result

  • Ready for Release: true
  • Blocking Issues:
    • 없음. entry_count 필드/closed→pending_buy 전이/selector/admission 일반화 전부 단위 green(366 passed 회귀, flat 매핑·계약 가드 무누락, 동시성 경합 회귀 보존). PG 게이트는 test DSN 자동 검증(라이브 DSN 비파괴 정책). LIVE full-stack 은 운영 배포 검증 비차단.