Resolve scope/toolchain CONFIRM items (operator-confirmed), check off remaining handoff items, and flip Freeze flags (Handoff 승인, Ready true, Confirmed By Justin). Update discovery index row to confirmed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
21 KiB
0. 문서 상태
이 문서의 현재 상태와 식별 정보를 기록한다. 문서 추적과 승인 흐름에 필요한 최소 메타데이터를 적는다.
- 상태: confirmed
- 문서 ID: dcy-001_20260603_slot-pure-domain-migration
- 이슈명: trex-core 베이스 수립 및 slot 순수 도메인 이식
- 작성 시각(KST): 2026-06-03
- 마지막 갱신 시각(KST): 2026-06-03
- 대체됨: 없음
- 후속 Discovery 참조: 없음
- 생성된 REQ 참조: 없음
1. 계획 상태 요약
현재 Discovery가 어떤 배경에서 작성되고 있는지, 연계 문서가 있는지, 지금 시점의 해석이 무엇인지 짧게 요약한다.
- 연계 문서 현황:
- 관련 점수 파일: 미생성
- 관련 TODO/메모: 없음 (검토 초안 내용은 본 Discovery 본문과 부록 A 에 통합)
- 해석:
- bootstrap-baseline 초기화가 끝난 빈 베이스(trex-core)에서 시작하는 첫 real Discovery이며, 입력은 trex-orbit slot 도메인 코드 분석과 운영자 확정 결정(신규 베이스 + 순수 도메인만)이다.
- 이번 Discovery는 "코어 베이스 부트스트랩 + slot 순수 도메인 이식 + 단위테스트 green"의 범위와 성공 기준을 확정하고, 잔여 미결 결정(컬럼 계약 박제, OQ-2)을 드러내는 것이 핵심이다. 패키지 네임스페이스는
trex_core.domain.slot으로 확정됨(OQ-1).
2. 요구사항 판정 결과
이번 요청이 기존 요구사항과 비교해 신규인지, 유사한지, 중복인지 판단하고 그 근거를 남긴다.
- 판정: 신규
- 근거
- docs/discovery/ 아래 기존 Discovery 문서가 없고(첫 반복), 후보로 비교할 주기가 존재하지 않는다.
- 주제(코어 베이스 수립 + slot 순수 도메인 이식)가 기존 어떤 REQ/Batch/Release 와도 겹치지 않는 신규 문제 정의다.
3. 문제점의 요약
문제의 현재 상태, 기대 상태, 관련 이해관계자, 제약사항을 정리한다. Discovery의 핵심 맥락을 가장 먼저 이해할 수 있어야 한다.
- 현재 상태
- trex-core 는 Python 코드 스캐폴딩이 전혀 없다 —
CLAUDE.md,docs/(baseline 4종 + active index),.stage-pilot/(도구·템플릿·baseline.yaml) 만 존재하고app/·pyproject.toml·tests/가 없다. - 이식 대상인 slot 도메인은 trex-orbit
app/domain/slot/(총 ~1,150 LOC)에 있고, 그중 순수 6개 모듈(state.py/models.py/errors.py/repository.py/service.py/in_memory_repository.py)은 import 스윕 결과 외부 의존이 0(stdlib + 패키지 내부 참조만)으로 확인됐다. - trex-core 의 baseline(
docs/project-structure.md,docs/runtime-flows.md,docs/interface-contract.md,docs/data-model.md)은 이미 slot 도메인을 planned 구조로 반영해 둔 상태이며, 실제 코드는 아직 없어 planned 와 실제 사이에 갭이 있다.
- trex-core 는 Python 코드 스캐폴딩이 전혀 없다 —
- 기대 상태
- trex-core 가 자체 Python 프로젝트(pyproject + 패키지 레이아웃 + pytest/ruff)로 부트스트랩되어 빌드/테스트가 가능하다.
- slot 순수 도메인이 trex-core 안에 storage-agnostic 코어로 이식되고, 이식한 단위테스트가 trex-core 에서 통과한다.
- baseline 문서의 planned 구조가 실제 코드와 일치하도록 갱신된다.
- 이해관계자
- 문서 작성자/구현자(AI agent)
- 리뷰어/승인자(운영자, genichin@gmail.com)
- trex-core 를 베이스로 사용할 후속 제품/도메인 개발자
- 제약사항
- 운영자 확정: 신규 베이스로 시작(trex-orbit 은 병행, 이번에 수정하지 않음) + 순수 도메인만 이식.
- 순수 도메인 경계 유지: 브로커/DB 드라이버/CLI 등 인프라에 직접 의존하지 않는다.
- 6 상태 / 8 전이 / advisory-lock 직렬화 / append-only 전이 로그 / closed→idle 재진입 +1 같은 도메인 불변식을 보존한다.
주요 사용자 시나리오
사용자 또는 운영자가 실제로 어떤 상황에서 이 변경을 필요로 하는지 대표 시나리오를 적는다.
- 개발자가 trex-core 를 clone 한 뒤
pip install -e .[dev]와pytest로 slot 도메인 테스트가 통과하는 깨끗한 베이스를 확보한다. - 후속 도메인 작성자가 slot 도메인을 trex-core 의 "표준 도메인 작성 패턴(storage-agnostic + Protocol 저장소 경계)" 참조로 삼는다.
- 다음 반복에서 영속화(PostgreSQL) 구현자가 이식된
SlotRepositoryProtocol 과 보존된 컬럼 계약(본 문서 부록 A)을 기준으로 저장소 구현을 붙인다.
4. 이번에 정의할 변경
이번 Discovery에서 다루는 핵심 변경 항목을 목록으로 적는다. 기능, 구조, 규칙 변경을 함께 포함해도 된다.
- trex-core Python 프로젝트 부트스트랩:
pyproject.toml(배포명trex-core) + 패키지 레이아웃(trex_core/,trex_core/domain/) + pytest/ruff 설정. - slot 순수 도메인 이식: 6개 모듈 +
__init__.py복사, 공개 API 확정(__init__docstring 을 순수 도메인 기준으로 정리, 인프라 export 없음 확인). - 도메인 단위테스트 이식 및 green:
test_state.py,test_service.py(InMemorySlotRepository 기반)을 trex-core 에서 통과. - 컬럼 계약 가드 신설(OQ-2 결정): 도메인에 표준 필드 집합 선언(
EXPECTED_SLOT_FIELDS)을 두고, 순수 계약 테스트(test_contract.py)가dataclasses.fields(Slot)의 필드 집합과 일치함을 단언한다. DB-side 드리프트 검사는 영속화 반복으로 인계. - baseline 문서 정합: 이식 후
docs/project-structure.md·docs/runtime-flows.md의 planned 표기를 실제 구조와 일치하도록 갱신.
영향 범위
변경이 미칠 코드/문서/운영 범위를 명시해 REQ 정제와 batch planning에서 추정 누락을 줄인다.
- 코드 영향:
- 신규 생성:
pyproject.toml,trex_core/__init__.py,trex_core/domain/__init__.py,trex_core/domain/slot/*(6 모듈 +__init__+EXPECTED_SLOT_FIELDS선언),tests/domain/slot/*(이식 2종 + 신규test_contract.py). - trex-orbit 코드: 무수정(병행).
- 신규 생성:
- 문서 영향:
docs/project-structure.md,docs/runtime-flows.md의 planned→실제 갱신.docs/srs/index.md(REQ 등록),docs/batches/index.md(Batch 등록) 갱신은 후속 단계에서 발생.
- 운영 영향:
- 배포/운영 절차 변경 없음(라이브러리 시드, 런타임 데몬/CLI 없음).
- slot 도메인이 trex-orbit·trex-core 두 곳에 병존하는 임시 이중 진실 발생(동기화 부담은 리스크로 추적).
5. 요구사항 목록
실제로 구현과 검증으로 이어질 요구사항을 기능/비기능으로 나누어 정리하고, 범위 경계를 명확히 적는다.
기능 요구사항
- FR-1: trex-core 를 설치/테스트 가능한 Python 패키지로 부트스트랩한다(
pyproject.toml+ 패키지 레이아웃 + pytest/ruff 설정).pip install -e .[dev]후pytest가 실행 가능해야 한다. - FR-2: slot 순수 도메인 6개 모듈(
state/models/errors/repository/service/in_memory_repository)과__init__.py를trex_core.domain.slot네임스페이스(OQ-1 결정)로 이식하고, 모듈 간 import 경로를trex_core.domain.slot.*로 통일한다. 공개 API(SlotState/Slot/SlotCapacity/SlotTransitionRecord/SlotRepository/SlotService/예외/is_allowed_transition/SLOT_ADVISORY_LOCK_ID/ALLOWED_TRANSITIONS)를 인프라 심볼 없이 노출한다. - FR-3: 이식된 도메인 단위테스트(
tests/domain/slot/test_state.py,test_service.py)가 trex-core 에서 통과한다. - FR-4: 이식 완료 후
docs/project-structure.md와docs/runtime-flows.md의 planned 표기를 실제 코드 구조와 일치하도록 갱신한다. - FR-5: 컬럼 계약 가드(OQ-2 결정) — 도메인 패키지에 표준 필드 집합
EXPECTED_SLOT_FIELDS(부록 A 를 가리키는 주석 포함)를 선언하고, 순수 계약 테스트tests/domain/slot/test_contract.py가{f.name for f in dataclasses.fields(Slot)} == EXPECTED_SLOT_FIELDS를 단언해 필드 추가/삭제 시 실패하도록 한다. 타입 단언은 하지 않고(이름/존재 중심) 타입 매핑은 부록 A 문서에 둔다. DB-side(information_schema) 드리프트 검사는 영속화 REQ 로 인계한다.
비기능 요구사항
성능, 운영성, 일관성, 자동화 안정성 등 기능 외 요구사항을 적는다.
- NFR-1: 순수 도메인 경계 유지 — 이식된 도메인 코드는 stdlib 와 패키지 내부 참조 외 외부 의존(psycopg/네트워크/CLI/config)을 import 하지 않는다(정적 import 스윕으로 검증 가능).
- NFR-2: 도메인 불변식 보존 — 6 상태/8 전이, advisory-lock 직렬화, append-only 전이 로그, closed→idle 재진입 +1, lock 보유 중 외부 I/O 금지가 이식 후에도 동일하게 성립한다.
- NFR-3: 컬럼 계약 보존 —
Slot데이터클래스 필드 계약(본 문서 부록 A)이 변형 없이 유지되어, 다음 반복의 영속화 구현이 동일 계약을 기준으로 삼을 수 있다. 보존은 선언(문서: 부록 A +docs/data-model.md)이 아니라 자동 가드(FR-5 계약 테스트)로 강제한다.
범위 경계
이번 반복에서 반드시 포함할 범위와 명시적으로 제외할 범위를 구분한다.
- In Scope
- trex-core 부트스트랩(pyproject/레이아웃/pytest/ruff).
- slot 순수 도메인 6개 모듈 +
__init__이식 및 공개 API 확정. - 도메인 단위테스트(
test_state.py,test_service.py) 이식 및 green. - baseline 문서(project-structure, runtime-flows) planned→실제 갱신.
- Out of Scope
- PostgreSQL 구현체(
postgresql_repository.py), SQL DDL/마이그레이션,db init러너, schema drift 감지(schema.py). trex slotCLI(resolve/status/provision/archive), config 해석, coordinator 연동, daily_slot_archive/retention prune.- trex-orbit 수정 및 trex-orbit↔trex-core 코드 수렴.
- PostgreSQL 구현체(
6. 리스크/가정 목록
불확실성과 전제 조건을 분리해서 적는다. 리스크는 영향과 완화 방안을, 가정은 현재 판단의 전제를 기록한다.
리스크
- R-1 (Medium): 영속화 부재로 trex-core 의
SlotService는 in-memory repo 로만 구동되어, 단일 writer/advisory lock 의 실제 가치가 다음 반복(Postgres 재구성)까지 미실현된다.- 완화 방안: 이번 반복 목표를 "도메인 코어 시드 + 테스트 green"으로 한정하고, 영속화는 별도 후속 Discovery 로 명시 인계한다.
- R-2 (Medium): DDL 을 함께 가져오지 않으므로 향후 영속화 구현 시
Slot필드와 스키마가 어긋나는 컬럼 계약 드리프트 위험이 있다.- 완화 방안: 이번 반복은 계약 테스트(FR-5)로
Slot필드↔EXPECTED_SLOT_FIELDS일치를 자동 강제하고, 부록 A·docs/data-model.md를 문서 계약으로 둔다. DB-side(information_schema) 드리프트 검사는 영속화 REQ 로 인계한다.
- 완화 방안: 이번 반복은 계약 테스트(FR-5)로
- R-3 (Low): slot 도메인이 trex-orbit·trex-core 두 곳에 병존(이중 진실)해 로직 변경 시 동기화 부담이 생긴다.
- 완화 방안: 신규 베이스 결정의 의도된 비용으로 수용하고, 수렴 시점은 별도 Discovery(OQ 처리)로 추적한다.
가정
아직 확정되지 않았지만 현재 문서 작성의 기반이 되는 전제를 적는다.
- A-1: trex-orbit 의 순수 6개 모듈은 외부 의존이 0이라 코드 수정 없이 복사 가능하다(import 스윕으로 확인됨).
- A-2: 이식 시 유일한 코드 수정은
__init__.pydocstring 정리 수준이며, 로직 변경은 없다. - A-3: trex-core 의 툴체인은 trex-orbit 과 동등(Python >=3.12, setuptools, pytest, ruff)을 기본 채택한다.
오픈 질문
답을 아직 모르는 항목을 적는다. 추정으로 덮지 말고 REQ 초안 작성 이전에 확인할 질문으로 남긴다.
- OQ-1: 패키지 네임스페이스를 trex-orbit 과 동일한
app.domain.slot으로 유지할지, trex-core 전용trex_core.domain.slot으로 출발할지.- 상태: Answered (2026-06-03)
- 결정:
trex_core.domain.slot으로 출발(독립 베이스 네임스페이스). 근거: 재사용 코어 정체성·apptop-level 패키지 충돌 회피·OQ-3(향후 수렴) 시 자연스러운 import 경로. 이식 시 import 라인 1회 기계적 치환 비용만 발생. - 반영 위치:
# 4(코드 영향 신규 생성 경로),# 5FR-1(레이아웃)·FR-2(import 경로 통일). baseline 구조 표기(docs/project-structure.md·docs/runtime-flows.md등)의app/planned 표기는 FR-4 갱신 시trex_core/로 정정한다.
- OQ-2:
Slot컬럼 계약(본 문서 부록 A)을 영속화 미구현 상태에서 어떻게 드리프트 없이 박제할지(문서 고정 vs 계약 테스트 vs 스키마 placeholder).- 상태: Answered (2026-06-03)
- 결정: 계약 테스트를 주 수단으로 채택(2층 구조). ① 코드 가드 = 도메인의
EXPECTED_SLOT_FIELDS↔dataclasses.fields(Slot)일치 단언(FR-5). ② 문서 거울 = 부록 A +docs/data-model.md. DB-side(information_schema) 드리프트 검사는 영속화 반복으로 인계. 근거: 문서 고정은 강제력이 없어 R-2 미완화, 스키마 placeholder 는 제외한 영속화 인프라의 조기 유입이라 범위 위반. 계약 테스트만 순수 도메인 범위 안에서 NFR-3 을 자동 강제. - 반영 위치:
# 4(계약 가드 신설 항목·신규 파일),# 5FR-5, NFR-3,# 6R-2 완화,# 7S-4.
- OQ-3: trex-orbit↔trex-core slot 도메인의 향후 수렴(역참조/단일화) 여부.
- 상태: Deferred
- 처리 방안: 이번 반복 비범위. 영속화 재구성 이후 별도 Discovery 에서 다룬다. OQ-1 결과(
trex_core.domain.slot)를 인계 — 수렴 시 trex-orbit 이trex_core.domain.slot을 역참조하는 경로가 자연스럽다. - 종료 조건: 영속화 반복 종료 후 수렴 Discovery 가 생성되면 그 문서로 이관.
오픈 질문 처리 기준
Open: 아직 답이 없고 다음 단계 진행에 영향이 있는 상태다. 문서에 유지한다.Answered: 답이 확정된 상태다. 관련 본문/요구사항에 반영한 뒤 오픈 질문 목록에서는 제거하거나 resolved 기록으로 이동한다.Deferred: 지금 단계에서 결정하지 않고 다음 단계 또는 후속 이슈로 넘기는 상태다. 넘길 대상과 이유를 반드시 적는다.Dropped: 더 이상 유효하지 않은 질문이다. 삭제 사유를 짧게 남기고 목록에서 제거한다.- 처리 원칙 1: 질문만 남기지 말고 반드시
상태,처리 방안,종료 조건을 함께 적는다. - 처리 원칙 2: 답이 나온 질문은 본문 반영 없이 단순 삭제하지 않는다. 반영 위치를 먼저 갱신한다.
- 처리 원칙 3: High 영향 질문은
Deferred처리 후 처리 방안에 REQ 인계 추적 방식을 명시한다.
7. 초기 성공 기준
이 변경이 성공했다고 판단할 기준을 측정 가능하게 정의한다. 가능하면 데이터 출처까지 연결한다.
- S-1: trex-core 가 부트스트랩되어
pip install -e .[dev]후pytest가 정상 수집/실행된다. - S-2: 이식한 slot 도메인 단위테스트 2개 파일이 모두 통과한다.
- S-3: 이식된 도메인 코드의 import 스윕에서 외부(인프라) 의존이 0으로 확인되고, baseline 문서(project-structure/runtime-flows)가 실제 구조와 일치한다.
- S-4: 계약 테스트(
test_contract.py)가Slot필드 집합과EXPECTED_SLOT_FIELDS일치를 단언하고 통과한다(필드 변경 시 실패하는 것을 음성 케이스로 확인).
측정 방식 및 데이터 출처
각 성공 기준을 어떻게 측정할지와 어떤 데이터나 문서를 근거로 쓸지 적는다.
- S-1 측정 방식: 클린 환경에서 설치 후
pytest실행 로그 확인 / 데이터 출처: CI 또는 로컬pytest출력,pyproject.toml. - S-2 측정 방식:
pytest tests/domain/slot통과 여부 / 데이터 출처: 테스트 실행 결과(green count). - S-3 측정 방식:
grep/정적 import 스윕으로 외부 모듈 import 0 확인 + baseline 문서와 실제 트리 비교 / 데이터 출처: 소스 import 목록,docs/project-structure.md·docs/runtime-flows.md. - S-4 측정 방식:
pytest tests/domain/slot/test_contract.py통과 + 임시 필드 추가/삭제 시 실패 재현 / 데이터 출처: 계약 테스트 실행 결과,EXPECTED_SLOT_FIELDS선언.
8. REQ로 넘기기 전 확인 체크
REQ 초안 작성 단계로 넘기기 전에 무엇이 확정되어야 하는지 확인한다. 미완료 항목은 후속 결정이 필요함을 뜻한다.
- 범위(In Scope/Out of Scope) 확정
- 기준: 운영자가 In/Out 경계(특히 영속화·CLI 제외)를 확인했다. → confirm-discovery 에서 문서대로 확정(2026-06-03).
- 성공 지표의 측정 방식/데이터 출처 확정
- 기준: S-1~S-3 각각 측정 방식과 데이터 출처가 명시됨(본 문서 # 7).
- High 영향 리스크 우선순위 및 해소 책임자 지정
- 기준: High 등급 리스크 없음(R-1/R-2 Medium, R-3 Low) — 별도 책임자 지정 불요, 완화 방안 명시됨.
- 모든 오픈 질문(OQ)
Open상태 없음 확인- 기준: OQ 목록에
Open상태 항목이 0개이거나, 잔여 항목 전부Deferred처리 완료 (OQ-1·OQ-2 Answered, OQ-3 Deferred →Open0개)
- 기준: OQ 목록에
- Freeze 확정 담당자(CONFIRMED_BY) 지정
- 기준: 운영자가 confirm-discovery 시점에 CONFIRMED_BY 를 지정한다. → Confirmed By: Justin.
9. 파일 처리 결과
이 Discovery 문서 생성/갱신 결과와 참조 문서를 기록한다. 이후 추적과 리뷰 시 근거로 사용한다.
- 처리 결과: 생성
- 생성 경로: docs/discovery/dcy-001_20260603_slot-pure-domain-migration.md
- 참조 문서:
- docs/project-structure.md, docs/runtime-flows.md (구조/런타임 baseline — 본 Discovery 가 갱신 요구)
- docs/interface-contract.md, docs/data-model.md (인터페이스/데이터 baseline — 컬럼 계약 기준)
- stage-pilot/templates/project-structure.md, stage-pilot/templates/runtime-flows.md (baseline 갱신 시 논리 템플릿 참조)
10. 사용자 결정 필요 항목 요약
사용자나 승인자가 결정해야 하는 항목만 모아 정리한다. 결정, 확인, 데이터 요청을 구분해서 적는다.
DECIDE
패키지 네임스페이스→ 결정됨:trex_core.domain.slot(OQ-1, 2026-06-03)컬럼 계약 박제 수단→ 결정됨: 계약 테스트 주 수단 + 문서 거울, DB-side 드리프트는 영속화 반복 인계 (OQ-2, 2026-06-03)
CONFIRM
범위 경계→ 확정됨: 문서 §5 범위 경계대로(영속화·SQL·CLI·config·coordinator·trex-orbit 수정 = Out of Scope) (confirm-discovery, 2026-06-03)툴체인→ 확정됨: trex-orbit 동등(Python >=3.12 + setuptools + pytest + ruff) 채택 (confirm-discovery, 2026-06-03)
DATA
- 없음 (별도 외부 데이터 요청 없음)
11. Discovery Freeze
REQ 초안 작성 인계 시점의 확정 플래그와 섹션 참조만 기록한다. 내용 재작성 없이 원본 섹션을 링크로 대신한다.
섹션 참조
- 범위: # 5. 요구사항 목록 > 범위 경계
- 리스크/오픈 질문: # 6. 리스크/가정 목록
- 성공 기준: # 7. 초기 성공 기준
- 인계 전 확인: # 8. REQ로 넘기기 전 확인 체크
- 사용자 결정 필요: # 10. 사용자 결정 필요 항목 요약
Freeze 플래그
- Handoff Decision: 승인
- Handoff Rationale: 모든 오픈 질문 해소(OQ-1
trex_core.domain.slot·OQ-2 계약 테스트 Answered, OQ-3 Deferred). 범위·툴체인 CONFIRM(§10)을 confirm-discovery 에서 확정하고 CONFIRMED_BY 지정 완료. REQ Drafting(FR-1~FR-5) 으로 인계 가능. - Ready for REQ Drafting: true
- Confirmed By: Justin
- Confirmed At (KST): 2026-06-03
부록 A. Slot 데이터클래스 ↔ daily_slot 컬럼 계약 (이식 보존 대상)
NFR-3 과 OQ-2 가 참조하는 컬럼 계약이다. 순수 도메인의 Slot 데이터클래스는 trex-orbit daily_slot 스키마 컬럼 계약을 암묵 전제하므로, trex-core 가 다음 반복에서 영속화 계층을 새로 구성할 때 이 계약을 반드시 만족시켜야 도메인이 정상 동작한다. (docs/data-model.md 와 동일 기준)
| 필드 | 타입(도메인) | 원본 DDL 타입 | 비고 |
|---|---|---|---|
slot_id |
UUID | UUID PK | |
trading_date |
date | DATE NOT NULL | |
status |
SlotState | TEXT CHECK(6값) | idle/pending_buy/holding/pending_sell/closed/error |
symbol |
str? | TEXT | |
qty |
float? | NUMERIC(18,4) | |
avg_price |
float? | NUMERIC(18,4) | |
entry_price |
float? | NUMERIC(18,4) | 가격 잠금 |
allocated_capital |
float? | NUMERIC(18,2) | |
order_id |
str? | TEXT | 자유 주석 |
strategy_id |
str? | TEXT | 진입 전략 |
broker_order_id |
str? | TEXT | 브로커 식별자 |
portfolio_id |
str? | TEXT | |
sell_strategy_id |
str? | TEXT | 청산 전략 |
forced_close_at |
datetime? | TIMESTAMPTZ | 강제청산 마감선 |
created_at / updated_at |
datetime? | TIMESTAMPTZ |
부속 테이블 계약(영속화 재구성 시 함께 필요): daily_symbol_entries(재진입 카운터 — PK (trading_date, symbol)), slot_transition_log(append-only 감사 로그). 본 이관(순수 도메인)에서는 계약만 보존하고 DDL 은 가져오지 않는다.