From 0c29a32487554a1fcf99b26dd4051422ff274693 Mon Sep 17 00:00:00 2001 From: Justin Ko Date: Wed, 3 Jun 2026 12:42:41 +0000 Subject: [PATCH] Add dcy-001 Discovery: trex-core base + slot pure-domain migration First real Discovery after baseline bootstrap. Defines scope, FR/NFR, risks, and success criteria for bootstrapping the trex-core Python project and migrating the slot pure domain (no persistence/CLI). Open questions OQ-1 (package namespace) and OQ-2 (column-contract anchoring) left for confirm-discovery; handoff held. Co-Authored-By: Claude Opus 4.8 (1M context) --- ...001_20260603_slot-pure-domain-migration.md | 219 ++++++++++++++++++ docs/discovery/index.md | 3 +- 2 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 docs/discovery/dcy-001_20260603_slot-pure-domain-migration.md diff --git a/docs/discovery/dcy-001_20260603_slot-pure-domain-migration.md b/docs/discovery/dcy-001_20260603_slot-pure-domain-migration.md new file mode 100644 index 0000000..4e91885 --- /dev/null +++ b/docs/discovery/dcy-001_20260603_slot-pure-domain-migration.md @@ -0,0 +1,219 @@ +# 0. 문서 상태 +이 문서의 현재 상태와 식별 정보를 기록한다. 문서 추적과 승인 흐름에 필요한 최소 메타데이터를 적는다. + +- 상태: draft +- 문서 ID: dcy-001_20260603_slot-pure-domain-migration +- 이슈명: trex-core 베이스 수립 및 slot 순수 도메인 이식 +- 작성 시각(KST): 2026-06-03 +- 마지막 갱신 시각(KST): 2026-06-03 +- 대체됨: 없음 +- 후속 Discovery 참조: 없음 +- 생성된 REQ 참조: 없음 + +# 1. 계획 상태 요약 +현재 Discovery가 어떤 배경에서 작성되고 있는지, 연계 문서가 있는지, 지금 시점의 해석이 무엇인지 짧게 요약한다. + +- 연계 문서 현황: + - 관련 점수 파일: 미생성 + - 관련 TODO/메모: temp/plan.md (slot 순수 도메인 이관 계획서, gitignored 초안) +- 해석: + - bootstrap-baseline 초기화가 끝난 빈 베이스(trex-core)에서 시작하는 첫 real Discovery이며, 입력은 temp/plan.md 와 운영자 확정 결정(신규 베이스 + 순수 도메인만)이다. + - 이번 Discovery는 "코어 베이스 부트스트랩 + slot 순수 도메인 이식 + 단위테스트 green"의 범위와 성공 기준을 확정하고, 네임스페이스/컬럼 계약 박제 같은 미결 결정을 드러내는 것이 핵심이다. + +# 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 프로젝트(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) 구현자가 이식된 `SlotRepository` Protocol 과 보존된 컬럼 계약(plan.md 부록 A)을 기준으로 저장소 구현을 붙인다. + +# 4. 이번에 정의할 변경 +이번 Discovery에서 다루는 핵심 변경 항목을 목록으로 적는다. 기능, 구조, 규칙 변경을 함께 포함해도 된다. + +- trex-core Python 프로젝트 부트스트랩: `pyproject.toml` + 패키지 레이아웃(`app/`, `app/domain/`) + pytest/ruff 설정. +- slot 순수 도메인 이식: 6개 모듈 + `__init__.py` 복사, 공개 API 확정(`__init__` docstring 을 순수 도메인 기준으로 정리, 인프라 export 없음 확인). +- 도메인 단위테스트 이식 및 green: `test_state.py`, `test_service.py`(InMemorySlotRepository 기반)을 trex-core 에서 통과. +- baseline 문서 정합: 이식 후 `docs/project-structure.md`·`docs/runtime-flows.md` 의 planned 표기를 실제 구조와 일치하도록 갱신. + +## 영향 범위 +변경이 미칠 코드/문서/운영 범위를 명시해 REQ 정제와 batch planning에서 추정 누락을 줄인다. + +- 코드 영향: + - 신규 생성: `pyproject.toml`, `app/__init__.py`, `app/domain/__init__.py`, `app/domain/slot/*`(6 모듈 + `__init__`), `tests/domain/slot/*`. + - 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 에 이식하고, 공개 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 표기를 실제 코드 구조와 일치하도록 갱신한다. + +## 비기능 요구사항 +성능, 운영성, 일관성, 자동화 안정성 등 기능 외 요구사항을 적는다. + +- 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` 데이터클래스 필드 계약(plan.md 부록 A)이 변형 없이 유지되어, 다음 반복의 영속화 구현이 동일 계약을 기준으로 삼을 수 있다. + +## 범위 경계 +이번 반복에서 반드시 포함할 범위와 명시적으로 제외할 범위를 구분한다. + +- 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 slot` CLI(resolve/status/provision/archive), config 해석, coordinator 연동, daily_slot_archive/retention prune. + - trex-orbit 수정 및 trex-orbit↔trex-core 코드 수렴. + +# 6. 리스크/가정 목록 +불확실성과 전제 조건을 분리해서 적는다. 리스크는 영향과 완화 방안을, 가정은 현재 판단의 전제를 기록한다. + +## 리스크 +- R-1 (Medium): 영속화 부재로 trex-core 의 `SlotService` 는 in-memory repo 로만 구동되어, 단일 writer/advisory lock 의 실제 가치가 다음 반복(Postgres 재구성)까지 미실현된다. + - 완화 방안: 이번 반복 목표를 "도메인 코어 시드 + 테스트 green"으로 한정하고, 영속화는 별도 후속 Discovery 로 명시 인계한다. +- R-2 (Medium): DDL 을 함께 가져오지 않으므로 향후 영속화 구현 시 `Slot` 필드와 스키마가 어긋나는 컬럼 계약 드리프트 위험이 있다. + - 완화 방안: plan.md 부록 A 와 `docs/data-model.md` 를 계약 기준으로 고정(NFR-3)하고, 영속화 REQ 에서 드리프트 테스트를 동반하도록 인계한다. +- R-3 (Low): slot 도메인이 trex-orbit·trex-core 두 곳에 병존(이중 진실)해 로직 변경 시 동기화 부담이 생긴다. + - 완화 방안: 신규 베이스 결정의 의도된 비용으로 수용하고, 수렴 시점은 별도 Discovery(OQ 처리)로 추적한다. + +## 가정 +아직 확정되지 않았지만 현재 문서 작성의 기반이 되는 전제를 적는다. + +- A-1: trex-orbit 의 순수 6개 모듈은 외부 의존이 0이라 코드 수정 없이 복사 가능하다(import 스윕으로 확인됨). +- A-2: 이식 시 유일한 코드 수정은 `__init__.py` docstring 정리 수준이며, 로직 변경은 없다. +- 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` 으로 출발할지. + - 상태: Open + - 처리 방안: 운영자가 신규 베이스 정체성(독립 패키지명) vs 향후 대조 용이성(파리티) 사이에서 결정. AskUser 로 확인 후 본문 FR-2/구조 표기에 반영. + - 종료 조건: 네임스페이스가 확정되어 `# 5` FR-2 와 baseline 구조 표기의 import 경로가 단일 값으로 고정되면 Answered. +- OQ-2: `Slot` 컬럼 계약(plan.md 부록 A)을 영속화 미구현 상태에서 어떻게 드리프트 없이 박제할지(문서 고정 vs 계약 테스트 vs 스키마 placeholder). + - 상태: Open + - 처리 방안: NFR-3 의 구체 수단을 운영자 확인 후 결정. 최소안은 `docs/data-model.md` + 부록 A 를 단일 계약 기준으로 선언하고 영속화 REQ 로 드리프트 테스트를 인계. + - 종료 조건: 계약 박제 수단이 정해져 NFR-3 의 검증 방식으로 연결되면 Answered. +- OQ-3: trex-orbit↔trex-core slot 도메인의 향후 수렴(역참조/단일화) 여부. + - 상태: Deferred + - 처리 방안: 이번 반복 비범위. 영속화 재구성 이후 별도 Discovery 에서 다룬다. OQ-1 네임스페이스 결정이 이 질문의 선택지를 제약하므로 OQ-1 결과를 기록해 인계한다. + - 종료 조건: 영속화 반복 종료 후 수렴 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-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`. + +# 8. REQ로 넘기기 전 확인 체크 +REQ 초안 작성 단계로 넘기기 전에 무엇이 확정되어야 하는지 확인한다. 미완료 항목은 후속 결정이 필요함을 뜻한다. + +- [ ] 범위(In Scope/Out of Scope) 확정 + - 기준: 운영자가 In/Out 경계(특히 영속화·CLI 제외)를 확인했다. +- [x] 성공 지표의 측정 방식/데이터 출처 확정 + - 기준: S-1~S-3 각각 측정 방식과 데이터 출처가 명시됨(본 문서 # 7). +- [x] High 영향 리스크 우선순위 및 해소 책임자 지정 + - 기준: High 등급 리스크 없음(R-1/R-2 Medium, R-3 Low) — 별도 책임자 지정 불요, 완화 방안 명시됨. +- [ ] 모든 오픈 질문(OQ) `Open` 상태 없음 확인 + - 기준: OQ 목록에 `Open` 상태 항목이 0개이거나, 잔여 항목 전부 `Deferred` 처리 완료 (현재 OQ-1, OQ-2 가 Open) +- [ ] Freeze 확정 담당자(CONFIRMED_BY) 지정 + - 기준: 운영자가 confirm-discovery 시점에 CONFIRMED_BY 를 지정한다. + +# 9. 파일 처리 결과 +이 Discovery 문서 생성/갱신 결과와 참조 문서를 기록한다. 이후 추적과 리뷰 시 근거로 사용한다. + +- 처리 결과: 생성 +- 생성 경로: docs/discovery/dcy-001_20260603_slot-pure-domain-migration.md +- 참조 문서: + - temp/plan.md (slot 순수 도메인 이관 계획서) + - 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 +- {{DECIDE_PACKAGE_NAMESPACE}} — `app.domain.slot`(파리티) vs `trex_core.domain.slot`(독립 베이스) (OQ-1) +- {{DECIDE_COLUMN_CONTRACT_ANCHOR}} — `Slot` 컬럼 계약 박제 수단: 문서 고정 / 계약 테스트 / 스키마 placeholder 중 택 (OQ-2) + +## CONFIRM +- {{CONFIRM_SCOPE_BOUNDARY}} — 영속화·CLI·config·coordinator 연동을 이번 반복에서 제외하는 범위 경계 확정 +- {{CONFIRM_TOOLCHAIN_PARITY}} — Python >=3.12 + setuptools + pytest + ruff(trex-orbit 동등) 채택 확정 + +## DATA +- {{DATA_NONE}} — 별도 외부 데이터 요청 없음 + +# 11. Discovery Freeze +REQ 초안 작성 인계 시점의 확정 플래그와 섹션 참조만 기록한다. 내용 재작성 없이 원본 섹션을 링크로 대신한다. + +## 섹션 참조 +- 범위: [# 5. 요구사항 목록 > 범위 경계](#5-요구사항-목록) +- 리스크/오픈 질문: [# 6. 리스크/가정 목록](#6-리스크가정-목록) +- 성공 기준: [# 7. 초기 성공 기준](#7-초기-성공-기준) +- 인계 전 확인: [# 8. REQ로 넘기기 전 확인 체크](#8-req로-넘기기-전-확인-체크) +- 사용자 결정 필요: [# 10. 사용자 결정 필요 항목 요약](#10-사용자-결정-필요-항목-요약) + +## Freeze 플래그 +- Handoff Decision: 보류 +- Handoff Rationale: 초기 Discovery 초안 생성 완료. OQ-1(네임스페이스)·OQ-2(컬럼 계약 박제)가 Open 상태이며, confirm-discovery 에서 사용자 결정 후 REQ Drafting 으로 인계한다. +- Ready for REQ Drafting: false +- Confirmed By: TBD +- Confirmed At (KST): TBD diff --git a/docs/discovery/index.md b/docs/discovery/index.md index 8c9f028..3ae86a4 100644 --- a/docs/discovery/index.md +++ b/docs/discovery/index.md @@ -5,4 +5,5 @@ ## Discovery 목록 | ID | 날짜 | 이슈명 | 문서 | 상태 | -|---|---|---|---|---| \ No newline at end of file +|---|---|---|---|---| +| dcy-001_20260603_slot-pure-domain-migration | 20260603 | trex-core 베이스 수립 및 slot 순수 도메인 이식 | [Discovery](./dcy-001_20260603_slot-pure-domain-migration.md) | draft | \ No newline at end of file