docs(backtest): SDD 문서와 마일스톤을 업데이트하고 USER_REVIEW 정리한다
backtest-multi-timeframe-coverage와 scheduled-market-data-refresh의 SDD 및 마일스톤 문서 수정 USER_REVIEW 파일 삭제 (검증 완료로 간주)
This commit is contained in:
parent
ac5dbc0c71
commit
91602a66c7
6 changed files with 71 additions and 147 deletions
|
|
@ -19,25 +19,26 @@
|
||||||
|
|
||||||
## 구현 잠금
|
## 구현 잠금
|
||||||
|
|
||||||
- 상태: 잠금
|
- 상태: 해제
|
||||||
- SDD: 필요
|
- SDD: 필요
|
||||||
- SDD 문서: `agent-roadmap/sdd/backtest-loop/backtest-multi-timeframe-coverage/SDD.md`
|
- SDD 문서: `agent-roadmap/sdd/backtest-loop/backtest-multi-timeframe-coverage/SDD.md`
|
||||||
- SDD 사유: timeframe contract/proto, provider capability, DB 저장 key, aggregation provenance, backtest fill policy와 field smoke가 함께 바뀐다.
|
- SDD 사유: timeframe contract/proto, provider capability, DB 저장 key, aggregation provenance, backtest fill policy와 field smoke가 함께 바뀐다.
|
||||||
- 잠금 해제 조건: 아래 체크리스트
|
- 잠금 해제 조건: 아래 체크리스트
|
||||||
- [ ] SDD 잠금이 해제되어 있다.
|
- [x] SDD 잠금이 해제되어 있다.
|
||||||
- [ ] SDD 사용자 리뷰가 없거나 승인/해결되었다.
|
- [x] SDD 사용자 리뷰가 없거나 승인/해결되었다.
|
||||||
- [ ] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다.
|
- [x] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다.
|
||||||
- [ ] Evidence Map이 plan의 `Spec Targets`와 완료 시 `Spec Completion`으로 검증 가능하게 연결되어 있다.
|
- [x] Evidence Map이 plan의 `Spec Targets`와 완료 시 `Spec Completion`으로 검증 가능하게 연결되어 있다.
|
||||||
- 결정 필요: 아래 체크리스트
|
- 결정 필요: 없음
|
||||||
- [ ] 분봉 1차 import/backtest 검증 baseline을 `1m`만으로 시작할지, 기존 vocabulary처럼 `1m`/`5m`를 함께 포함할지 결정한다.
|
- 결정 반영:
|
||||||
- [ ] 월봉을 provider 원천 데이터로 우선 받을지, 일봉에서 deterministic aggregation으로 생성할지 기본 우선순위를 결정한다.
|
- D01: 분봉 1차 import/backtest 검증 baseline은 `1m`/`5m`를 함께 포함한다.
|
||||||
|
- D02: 월봉 source of truth는 provider 월봉과 병행하지 않고 일봉 기반 deterministic aggregation 하나로 둔다.
|
||||||
|
|
||||||
## 범위
|
## 범위
|
||||||
|
|
||||||
- contracts/proto, Go domain, CLI scenario vocabulary에서 월봉, 일봉, 분봉 timeframe을 백테스트 기본 분석 단위로 정리
|
- contracts/proto, Go domain, CLI scenario vocabulary에서 월봉, 일봉, 분봉 timeframe을 백테스트 기본 분석 단위로 정리
|
||||||
- provider capability matrix가 timeframe별 지원 여부와 거부 사유를 표현하도록 보강
|
- provider capability matrix가 timeframe별 지원 여부와 거부 사유를 표현하도록 보강
|
||||||
- 분봉 provider import 또는 명시적 미지원 거부 경계
|
- 분봉 provider import 또는 명시적 미지원 거부 경계
|
||||||
- 월봉 provider import 또는 일봉 기반 deterministic aggregation 경계와 provenance 기록
|
- 월봉 일봉 기반 deterministic aggregation 경계와 provenance 기록
|
||||||
- `bars` 저장/조회, freshness/gap/duplicate/readiness 확인이 월/일/분 timeframe을 구분해 동작하도록 검증
|
- `bars` 저장/조회, freshness/gap/duplicate/readiness 확인이 월/일/분 timeframe을 구분해 동작하도록 검증
|
||||||
- backtest run selector, engine input, result handoff가 월/일/분봉 시나리오를 headless로 검증할 수 있게 하는 흐름
|
- backtest run selector, engine input, result handoff가 월/일/분봉 시나리오를 headless로 검증할 수 있게 하는 흐름
|
||||||
|
|
||||||
|
|
@ -55,7 +56,7 @@
|
||||||
백테스트 입력 데이터가 월/일/분 timeframe별로 수집 또는 생성되고 저장될 수 있게 한다.
|
백테스트 입력 데이터가 월/일/분 timeframe별로 수집 또는 생성되고 저장될 수 있게 한다.
|
||||||
|
|
||||||
- [ ] [minute-ingest] 분봉 provider import 경계를 추가하거나, provider 미지원 조합을 typed error로 거부한다. 검증: minute import success 또는 rejected fixture가 stable text/JSONL로 남는다.
|
- [ ] [minute-ingest] 분봉 provider import 경계를 추가하거나, provider 미지원 조합을 typed error로 거부한다. 검증: minute import success 또는 rejected fixture가 stable text/JSONL로 남는다.
|
||||||
- [ ] [monthly-bars] 월봉을 provider 원천 데이터 또는 일봉 aggregation으로 생성하고, 생성 기준과 provenance를 저장/출력한다. 검증: 동일 daily fixture에서 deterministic monthly OHLCV가 생성된다.
|
- [ ] [monthly-bars] 월봉을 일봉 aggregation으로 생성하고, 생성 기준과 provenance를 저장/출력한다. 검증: 동일 daily fixture에서 deterministic monthly OHLCV가 생성된다.
|
||||||
- [ ] [store-query] `bars` 저장/조회와 backtest bar source가 timeframe별 key를 유지하고 월/일/분 데이터를 섞지 않는다. 검증: 동일 instrument의 monthly/daily/minute bars가 독립 조회된다.
|
- [ ] [store-query] `bars` 저장/조회와 backtest bar source가 timeframe별 key를 유지하고 월/일/분 데이터를 섞지 않는다. 검증: 동일 instrument의 monthly/daily/minute bars가 독립 조회된다.
|
||||||
|
|
||||||
### Epic: [backtest-semantics] Backtest semantics
|
### Epic: [backtest-semantics] Backtest semantics
|
||||||
|
|
@ -92,4 +93,4 @@
|
||||||
- 표준선(선택): 백테스트는 먼저 단일 timeframe run을 확실히 닫고, 여러 timeframe을 동시에 참조하는 전략은 후속 Milestone으로 미룬다.
|
- 표준선(선택): 백테스트는 먼저 단일 timeframe run을 확실히 닫고, 여러 timeframe을 동시에 참조하는 전략은 후속 Milestone으로 미룬다.
|
||||||
- 선행 작업: Backtest Data Collection Infrastructure, Backtest Scenario Automation
|
- 선행 작업: Backtest Data Collection Infrastructure, Backtest Scenario Automation
|
||||||
- 후속 작업: Scheduled Market Data Refresh의 multi-timeframe cadence 보강, Multi-Timeframe Strategy Composition 후보
|
- 후속 작업: Scheduled Market Data Refresh의 multi-timeframe cadence 보강, Multi-Timeframe Strategy Composition 후보
|
||||||
- 확인 필요: 분봉 1차 import/backtest 검증 baseline과 월봉 source-of-truth 우선순위는 SDD에서 사용자 결정으로 확정한다.
|
- 결정: 분봉 1차 import/backtest 검증 baseline은 `1m`/`5m`를 함께 포함하고, 월봉 source of truth는 일봉 기반 deterministic aggregation 하나로 둔다.
|
||||||
|
|
|
||||||
|
|
@ -19,23 +19,27 @@
|
||||||
|
|
||||||
## 구현 잠금
|
## 구현 잠금
|
||||||
|
|
||||||
- 상태: 잠금
|
- 상태: 해제
|
||||||
- SDD: 필요
|
- SDD: 필요
|
||||||
- SDD 문서: `agent-roadmap/sdd/backtest-loop/scheduled-market-data-refresh/SDD.md`
|
- SDD 문서: `agent-roadmap/sdd/backtest-loop/scheduled-market-data-refresh/SDD.md`
|
||||||
- SDD 사유: 원격 scheduler가 외부 provider 호출, DB write, retry/idempotency, config/env, field smoke에 영향을 준다.
|
- SDD 사유: 원격 scheduler가 외부 provider 호출, DB write, retry/idempotency, config/env, field smoke에 영향을 준다.
|
||||||
- 잠금 해제 조건: 아래 체크리스트
|
- 잠금 해제 조건: 아래 체크리스트
|
||||||
- [ ] SDD 잠금이 해제되어 있다.
|
- [x] SDD 잠금이 해제되어 있다.
|
||||||
- [ ] SDD 사용자 리뷰가 없거나 승인/해결되었다.
|
- [x] SDD 사용자 리뷰가 없거나 승인/해결되었다.
|
||||||
- [ ] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다.
|
- [x] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다.
|
||||||
- [ ] Evidence Map이 plan의 `Spec Targets`와 완료 시 `Spec Completion`으로 검증 가능하게 연결되어 있다.
|
- [x] Evidence Map이 plan의 `Spec Targets`와 완료 시 `Spec Completion`으로 검증 가능하게 연결되어 있다.
|
||||||
- 결정 필요: 아래 체크리스트
|
- 결정 필요: 없음
|
||||||
- [ ] scheduler를 worker 내장 loop, OS/systemd timer, external cron 중 어디까지 1차 구현으로 둘지 확정한다.
|
- 결정 반영:
|
||||||
|
- D01: scheduler는 `services/worker` 내장 loop가 1차 실행 주체다.
|
||||||
|
- OS/systemd는 worker process supervision만 맡고, external cron은 사용하지 않는다.
|
||||||
|
- worker scheduler는 설정된 한도 안에서 병렬 수집을 지원해야 한다.
|
||||||
|
|
||||||
## 범위
|
## 범위
|
||||||
|
|
||||||
- 원격 worker/API runtime 위에서 실행할 scheduled market data refresh 경계
|
- 원격 worker/API runtime 위에서 실행할 scheduled market data refresh 경계. 일정 판단과 상태 관리는 worker 내부에 둔다.
|
||||||
- named universe별 provider, selector, timeframe, cadence, timezone, backfill window 설정
|
- named universe별 provider, selector, timeframe, cadence, timezone, backfill window, parallelism limit 설정
|
||||||
- 스케줄 tick마다 `import_daily_bars` 또는 후속 import action을 실행하고 DB upsert idempotency를 유지하는 흐름
|
- 스케줄 tick마다 `import_daily_bars` 또는 후속 import action을 실행하고 DB upsert idempotency를 유지하는 흐름
|
||||||
|
- tick 안에서 여러 수집 작업을 설정된 한도 안에서 병렬 실행하는 흐름
|
||||||
- provider 지연, 결측, gap, duplicate 상태를 freshness/readiness 결과로 남기는 확인 표면
|
- provider 지연, 결측, gap, duplicate 상태를 freshness/readiness 결과로 남기는 확인 표면
|
||||||
- remote runner에서 migration, runtime startup, scheduler tick, freshness query, backtest input selector를 검증하는 headless smoke
|
- remote runner에서 migration, runtime startup, scheduler tick, freshness query, backtest input selector를 검증하는 headless smoke
|
||||||
|
|
||||||
|
|
@ -45,8 +49,8 @@
|
||||||
|
|
||||||
원격 서버에서 선택 universe import를 주기 실행하고, 재시작/중복 실행에도 DB 상태가 안정적으로 유지되게 한다.
|
원격 서버에서 선택 universe import를 주기 실행하고, 재시작/중복 실행에도 DB 상태가 안정적으로 유지되게 한다.
|
||||||
|
|
||||||
- [ ] [schedule-config] named universe별 provider, selector, timeframe, cadence, timezone, backfill window를 선언하고 validate/dry-run에서 지원하지 않는 provider/timeframe 조합을 거부한다. 검증: schedule config validate가 next window와 rejected combination을 text/JSONL로 출력한다.
|
- [ ] [schedule-config] named universe별 provider, selector, timeframe, cadence, timezone, backfill window, parallelism limit를 선언하고 validate/dry-run에서 지원하지 않는 provider/timeframe 조합을 거부한다. 검증: schedule config validate가 next window와 rejected combination을 text/JSONL로 출력한다.
|
||||||
- [ ] [scheduled-runner] 원격 runtime에서 scheduler tick이 market data import job을 실행하고, 재시작 또는 tick 중복에도 같은 bar key를 중복 저장하지 않는다. 검증: scheduler tick 2회 실행 후 `bars` key 중복 없이 freshness/readiness 출력이 남는다.
|
- [ ] [scheduled-runner] 원격 worker runtime에서 내장 scheduler tick이 market data import job을 실행하고, 병렬 수집과 재시작 또는 tick 중복에도 같은 bar key를 중복 저장하지 않는다. 검증: worker scheduler tick 2회 실행 후 병렬 item별 result와 `bars` key 중복 없는 freshness/readiness 출력이 남는다.
|
||||||
- [ ] [retry-backfill] provider 지연, 결측, gap 결과에 따라 retry와 backfill window를 계산하고 실패를 stale/error 상태로 남긴다. 검증: fixture 또는 local smoke에서 missing/gap/provider delay 케이스가 stable text/JSONL로 구분된다.
|
- [ ] [retry-backfill] provider 지연, 결측, gap 결과에 따라 retry와 backfill window를 계산하고 실패를 stale/error 상태로 남긴다. 검증: fixture 또는 local smoke에서 missing/gap/provider delay 케이스가 stable text/JSONL로 구분된다.
|
||||||
|
|
||||||
### Epic: [handoff] Headless readiness handoff
|
### Epic: [handoff] Headless readiness handoff
|
||||||
|
|
@ -82,4 +86,4 @@
|
||||||
- 표준선(선택): scheduler config에는 secret 값을 넣지 않고, 원격 runtime env/SOPS 주입 경계를 따른다.
|
- 표준선(선택): scheduler config에는 secret 값을 넣지 않고, 원격 runtime env/SOPS 주입 경계를 따른다.
|
||||||
- 선행 작업: Backtest Data Collection Infrastructure, Backtest Scenario Automation
|
- 선행 작업: Backtest Data Collection Infrastructure, Backtest Scenario Automation
|
||||||
- 후속 작업: Backtest Multi-Timeframe Coverage, Data Quality Monitoring 후보
|
- 후속 작업: Backtest Multi-Timeframe Coverage, Data Quality Monitoring 후보
|
||||||
- 확인 필요: SDD 작성 시 scheduler를 worker 내장 loop, OS/systemd timer, external cron 중 어디까지 1차 구현으로 둘지 확정한다.
|
- 결정: scheduler는 `services/worker` 내장 loop가 1차 실행 주체다. OS/systemd는 worker process supervision만 맡고 external cron은 사용하지 않는다. worker scheduler는 설정된 한도 안에서 병렬 수집을 지원해야 한다.
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,13 @@
|
||||||
|
|
||||||
## 상태
|
## 상태
|
||||||
|
|
||||||
[검토중]
|
[승인됨]
|
||||||
|
|
||||||
## SDD 잠금
|
## SDD 잠금
|
||||||
|
|
||||||
- 상태: 잠금
|
- 상태: 해제
|
||||||
- 사용자 리뷰: `USER_REVIEW.md`
|
- 사용자 리뷰: 없음
|
||||||
- 잠금 항목:
|
- 잠금 항목: 없음
|
||||||
- [ ] [D01] 분봉 1차 import/backtest 검증 baseline을 `1m`만으로 시작할지, 기존 vocabulary처럼 `1m`/`5m`를 함께 포함할지 결정한다.
|
|
||||||
- [ ] [D02] 월봉의 기본 source of truth를 provider 원천 데이터 우선으로 둘지, 일봉 기반 deterministic aggregation 우선으로 둘지 결정한다.
|
|
||||||
|
|
||||||
## 문제 / 비목표
|
## 문제 / 비목표
|
||||||
|
|
||||||
|
|
@ -29,18 +27,18 @@
|
||||||
|
|
||||||
## Source of Truth
|
## Source of Truth
|
||||||
|
|
||||||
| 영역 | 기준 | 메모 |
|
| 영역 | 기준 | 메모 |
|
||||||
|------|------|------|
|
| -------------------| --------------------------------------------------------------------------------------------------| ---------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| Roadmap | `agent-roadmap/phase/backtest-loop/milestones/backtest-multi-timeframe-coverage.md` | Milestone 목표, 기능 Task, 범위 제외, 완료 후보 반영 기준 |
|
| Roadmap | `agent-roadmap/phase/backtest-loop/milestones/backtest-multi-timeframe-coverage.md` | Milestone 목표, 기능 Task, 범위 제외, 완료 후보 반영 기준 |
|
||||||
| Code | `packages/contracts/proto/alt/v1/common.proto` | `Timeframe` enum 원천. 현재 `DAILY`, `MINUTE_1`, `MINUTE_5`가 있으며 월봉 추가가 필요하다. |
|
| Code | `packages/contracts/proto/alt/v1/common.proto` | `Timeframe` enum 원천. 현재 `DAILY`, `MINUTE_1`, `MINUTE_5`가 있으며 월봉 추가가 필요하다. |
|
||||||
| Code | `packages/domain/market/types.go` | domain `market.Timeframe` 원천. 현재 `1d`, `1m`, `5m`가 있다. |
|
| Code | `packages/domain/market/types.go` | domain `market.Timeframe` 원천. 현재 `1d`, `1m`, `5m`가 있다. |
|
||||||
| Code | `packages/contracts/proto/alt/v1/market.proto`, `packages/contracts/proto/alt/v1/backtest.proto` | `Bar`, `ListBarsRequest`, `BacktestRunSpec`의 timeframe 전달 계약 |
|
| Code | `packages/contracts/proto/alt/v1/market.proto`, `packages/contracts/proto/alt/v1/backtest.proto` | `Bar`, `ListBarsRequest`, `BacktestRunSpec`의 timeframe 전달 계약 |
|
||||||
| Code | `apps/cli/internal/operator/scenario.go` | scenario string vocabulary와 matrix validation 기준 |
|
| Code | `apps/cli/internal/operator/scenario.go` | scenario string vocabulary와 matrix validation 기준 |
|
||||||
| Code | `services/worker/internal/storage/postgres/queries/queries.sql` | `bars` key는 `(instrument_id, timeframe, timestamp)`이며 timeframe별 독립 저장 기준이다. |
|
| Code | `services/worker/internal/storage/postgres/queries/queries.sql` | `bars` key는 `(instrument_id, timeframe, timestamp)`이며 timeframe별 독립 저장 기준이다. |
|
||||||
| Code | `services/worker/internal/storage/postgres/migrate_test.go` | `bars` table은 normalized OHLCV 저장 계약을 유지하며 provider raw payload를 섞지 않는다. |
|
| Code | `services/worker/internal/storage/postgres/migrate_test.go` | `bars` table은 normalized OHLCV 저장 계약을 유지하며 provider raw payload를 섞지 않는다. |
|
||||||
| Code | `services/worker/internal/backtest/bar_source.go` | backtest run selector가 storage에서 timeframe별 bars를 읽는 기준이다. |
|
| Code | `services/worker/internal/backtest/bar_source.go` | backtest run selector가 storage에서 timeframe별 bars를 읽는 기준이다. |
|
||||||
| External Provider | KIS | provider capability와 실제 지원 timeframe을 명시적으로 accepted/rejected로 판정해야 한다. |
|
| External Provider | KIS | provider capability와 실제 지원 timeframe을 명시적으로 accepted/rejected로 판정해야 한다. |
|
||||||
| User Decision | D01, D02 | 분봉 1차 import/backtest 검증 baseline과 월봉 source of truth 우선순위가 구현 잠금 해제 조건이다. |
|
| User Decision | `user_review_0.log` | D01: 분봉 1차 import/backtest 검증 baseline은 `1m`/`5m`를 함께 포함한다. D02: 월봉 source of truth는 일봉 기반 deterministic aggregation 하나로 정한다. |
|
||||||
|
|
||||||
## State Machine
|
## State Machine
|
||||||
|
|
||||||
|
|
@ -60,14 +58,14 @@
|
||||||
|
|
||||||
- 계약 원문: 없음
|
- 계약 원문: 없음
|
||||||
- 입력:
|
- 입력:
|
||||||
- `Timeframe`: proto enum과 domain value, CLI string의 동일 의미 매핑. `daily`, `minute_1`, `minute_5` 기존 vocabulary는 호환 유지하고 `monthly`를 추가한다. D01은 기존 vocabulary 제거 여부가 아니라 1차 import/backtest 검증 baseline에 `minute_5`까지 포함할지 결정한다.
|
- `Timeframe`: proto enum과 domain value, CLI string의 동일 의미 매핑. `daily`, `minute_1`, `minute_5` 기존 vocabulary는 호환 유지하고 `monthly`를 추가한다. 분봉 1차 import/backtest 검증 baseline에는 `minute_1`과 `minute_5`를 함께 포함한다.
|
||||||
- `provider_capability`: provider, market, venue, asset type, timeframe별 accepted/rejected와 거부 사유.
|
- `provider_capability`: provider, market, venue, asset type, timeframe별 accepted/rejected와 거부 사유.
|
||||||
- `bar_source`: provider 원천 bars 또는 deterministic aggregation 결과.
|
- `bar_source`: daily/minute provider 원천 bars 또는 월봉 deterministic aggregation 결과. 월봉 source of truth는 일봉 기반 deterministic aggregation 하나로 둔다.
|
||||||
- `BacktestRunSpec.timeframe`: backtest matrix와 run selector가 사용할 단일 timeframe.
|
- `BacktestRunSpec.timeframe`: backtest matrix와 run selector가 사용할 단일 timeframe.
|
||||||
- `freshness_request`: universe, timeframe, from/to window, expected dates.
|
- `freshness_request`: universe, timeframe, from/to window, expected dates.
|
||||||
- 출력:
|
- 출력:
|
||||||
- `Bar`: instrument id, timeframe, timestamp, normalized OHLCV.
|
- `Bar`: instrument id, timeframe, timestamp, normalized OHLCV.
|
||||||
- `provenance`: 월봉이 provider 원천인지 daily aggregation인지 확인 가능한 근거. 1차 완료 근거는 stable CLI/JSONL 또는 fixture output에 남기고, durable metadata가 필요하면 normalized `bars` key를 깨지 않는 별도 metadata 경계를 둔다.
|
- `provenance`: 월봉이 어떤 일봉 입력 범위와 aggregation 규칙에서 생성되었는지 확인 가능한 근거. 1차 완료 근거는 stable CLI/JSONL 또는 fixture output에 남기고, durable metadata가 필요하면 normalized `bars` key를 깨지 않는 별도 metadata 경계를 둔다.
|
||||||
- `readiness`: timeframe별 latest, missing, gap, duplicate, provider delay 상태.
|
- `readiness`: timeframe별 latest, missing, gap, duplicate, provider delay 상태.
|
||||||
- `backtest_result`: timeframe별 deterministic run id, status, result summary.
|
- `backtest_result`: timeframe별 deterministic run id, status, result summary.
|
||||||
- 금지:
|
- 금지:
|
||||||
|
|
@ -83,7 +81,7 @@
|
||||||
| S01 | `timeframe-vocab` | 기존 `daily`, `minute_1`, `minute_5` vocabulary와 신규 monthly 요구가 있다. | proto/domain/CLI mapping을 검증한다. | monthly가 추가되고 기존 daily/minute compatibility가 유지된다. |
|
| S01 | `timeframe-vocab` | 기존 `daily`, `minute_1`, `minute_5` vocabulary와 신규 monthly 요구가 있다. | proto/domain/CLI mapping을 검증한다. | monthly가 추가되고 기존 daily/minute compatibility가 유지된다. |
|
||||||
| S02 | `capability-matrix` | KIS KR/US venue와 monthly/daily/minute 후보가 있다. | capability matrix validation을 실행한다. | accepted/rejected case와 거부 사유가 명시적으로 나온다. |
|
| S02 | `capability-matrix` | KIS KR/US venue와 monthly/daily/minute 후보가 있다. | capability matrix validation을 실행한다. | accepted/rejected case와 거부 사유가 명시적으로 나온다. |
|
||||||
| S03 | `minute-ingest` | 분봉 import 요청 또는 미지원 조합 fixture가 있다. | provider import 또는 reject path를 실행한다. | success 또는 typed rejection이 stable text/JSONL로 남는다. |
|
| S03 | `minute-ingest` | 분봉 import 요청 또는 미지원 조합 fixture가 있다. | provider import 또는 reject path를 실행한다. | success 또는 typed rejection이 stable text/JSONL로 남는다. |
|
||||||
| S04 | `monthly-bars` | 동일 daily fixture와 D02 source-of-truth 결정이 있다. | 월봉 provider import 또는 deterministic aggregation을 실행한다. | deterministic monthly OHLCV와 provenance가 남는다. |
|
| S04 | `monthly-bars` | 동일 daily fixture가 있다. | 월봉 deterministic aggregation을 실행한다. | deterministic monthly OHLCV와 provenance가 남는다. |
|
||||||
| S05 | `store-query` | 동일 instrument의 monthly/daily/minute bars가 있다. | 저장 후 timeframe별 조회를 실행한다. | 각 timeframe이 독립 조회되고 서로 섞이지 않는다. |
|
| S05 | `store-query` | 동일 instrument의 monthly/daily/minute bars가 있다. | 저장 후 timeframe별 조회를 실행한다. | 각 timeframe이 독립 조회되고 서로 섞이지 않는다. |
|
||||||
| S06 | `run-selector` | monthly/daily/minute scenario matrix가 있다. | dry-run validation과 matrix expand를 실행한다. | timeframe별 run id와 기간 검증 결과가 생성된다. |
|
| S06 | `run-selector` | monthly/daily/minute scenario matrix가 있다. | dry-run validation과 matrix expand를 실행한다. | timeframe별 run id와 기간 검증 결과가 생성된다. |
|
||||||
| S07 | `fill-policy` | monthly/daily/minute fixture bars와 동일 전략이 있다. | backtest engine fixture를 실행한다. | timeframe별 deterministic result가 나온다. |
|
| S07 | `fill-policy` | monthly/daily/minute fixture bars와 동일 전략이 있다. | backtest engine fixture를 실행한다. | timeframe별 deterministic result가 나온다. |
|
||||||
|
|
@ -111,11 +109,11 @@
|
||||||
- [x] Milestone 기능 Task와 Acceptance Scenario가 일치한다.
|
- [x] Milestone 기능 Task와 Acceptance Scenario가 일치한다.
|
||||||
- [x] Evidence Map이 plan/code-review/complete.log에서 검증 가능하다.
|
- [x] Evidence Map이 plan/code-review/complete.log에서 검증 가능하다.
|
||||||
- [x] agent-contract를 쓰는 경우 SDD에 계약 원문을 복제하지 않았다.
|
- [x] agent-contract를 쓰는 경우 SDD에 계약 원문을 복제하지 않았다.
|
||||||
- [x] 사용자 리뷰가 필요한 항목은 `USER_REVIEW.md`에만 남겼다.
|
- [x] 사용자 리뷰 항목은 `user_review_0.log`로 해결 기록을 남겼다.
|
||||||
|
|
||||||
## 사용자 리뷰 이력
|
## 사용자 리뷰 이력
|
||||||
|
|
||||||
- 없음
|
- `user_review_0.log`: D01은 `1m`/`5m` 1차 baseline 포함으로 결정했고, D02는 월봉 source of truth를 일봉 기반 deterministic aggregation 하나로 결정했다.
|
||||||
|
|
||||||
## 작업 컨텍스트
|
## 작업 컨텍스트
|
||||||
|
|
||||||
|
|
@ -123,5 +121,6 @@
|
||||||
- 표준선: proto-socket과 `packages/contracts/proto`가 ALT runtime 사이의 통신 기준이다.
|
- 표준선: proto-socket과 `packages/contracts/proto`가 ALT runtime 사이의 통신 기준이다.
|
||||||
- 표준선: `services/api`는 얇은 control plane으로 유지하고 provider import, aggregation, backtest execution은 worker 경계에 둔다.
|
- 표준선: `services/api`는 얇은 control plane으로 유지하고 provider import, aggregation, backtest execution은 worker 경계에 둔다.
|
||||||
- 표준선: provider가 직접 제공하지 않는 timeframe은 deterministic aggregation 또는 typed rejection 중 하나로만 처리한다.
|
- 표준선: provider가 직접 제공하지 않는 timeframe은 deterministic aggregation 또는 typed rejection 중 하나로만 처리한다.
|
||||||
|
- 표준선: 월봉 source of truth는 provider 월봉 원천 데이터와 병행하지 않고 일봉 기반 deterministic aggregation 하나로 둔다.
|
||||||
- 표준선: 백테스트는 먼저 단일 timeframe run을 확실히 닫고 multi-timeframe composition은 후속 Milestone으로 미룬다.
|
- 표준선: 백테스트는 먼저 단일 timeframe run을 확실히 닫고 multi-timeframe composition은 후속 Milestone으로 미룬다.
|
||||||
- 후속 SDD: `agent-roadmap/sdd/backtest-loop/scheduled-market-data-refresh/SDD.md`
|
- 후속 SDD: `agent-roadmap/sdd/backtest-loop/scheduled-market-data-refresh/SDD.md`
|
||||||
|
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
# SDD User Review
|
|
||||||
|
|
||||||
## 상태
|
|
||||||
|
|
||||||
요청됨
|
|
||||||
|
|
||||||
## 검토 대상
|
|
||||||
|
|
||||||
- SDD: `agent-roadmap/sdd/backtest-loop/backtest-multi-timeframe-coverage/SDD.md`
|
|
||||||
- Milestone: `agent-roadmap/phase/backtest-loop/milestones/backtest-multi-timeframe-coverage.md`
|
|
||||||
|
|
||||||
## 사용자 결정 항목
|
|
||||||
|
|
||||||
### [D01] 분봉 1차 검증 baseline
|
|
||||||
|
|
||||||
- 결정 필요: 분봉 1차 import/backtest 검증 baseline을 `1m`만으로 시작할지, 기존 vocabulary처럼 `1m`/`5m`를 함께 포함할지 결정한다.
|
|
||||||
- 추천안: 기존 proto/domain/CLI vocabulary의 `minute_5`는 호환 유지하고, 1차 import/backtest 검증 baseline에는 `1m`/`5m`를 함께 포함한다. provider capability가 실제 지원 여부를 accepted/rejected로 판정하게 한다.
|
|
||||||
- 대안: 기존 `minute_5` vocabulary는 유지하되, 1차 import/backtest 검증 baseline은 `1m`만 닫고 `5m` provider/backtest fixture는 후속으로 미룬다.
|
|
||||||
- 영향: scope와 fixture 수가 달라진다. `1m`/`5m`를 함께 검증하면 기존 vocabulary와 더 잘 맞지만 provider별 reject case를 더 명시해야 한다. `1m`만 닫아도 기존 `minute_5` mapping은 제거하지 않는다.
|
|
||||||
- 적용 위치:
|
|
||||||
- SDD: `SDD 잠금`, `Interface Contract`, `Acceptance Scenarios`
|
|
||||||
- Milestone: `구현 잠금`, `timeframe-vocab`, `minute-ingest`
|
|
||||||
|
|
||||||
### [D02] 월봉 source of truth 우선순위
|
|
||||||
|
|
||||||
- 결정 필요: 월봉을 provider 원천 데이터로 우선 받을지, 일봉에서 deterministic aggregation으로 생성할지 기본 우선순위를 결정한다.
|
|
||||||
- 추천안: 1차 구현은 일봉 기반 deterministic aggregation을 기본 source of truth로 두고, provider 월봉은 capability가 확인될 때 후속 또는 provider-specific path로 추가한다.
|
|
||||||
- 대안: provider 월봉 원천 데이터를 우선하고 일봉 aggregation은 fallback으로 둔다.
|
|
||||||
- 영향: provider 의존도와 검증 방식이 달라진다. deterministic aggregation 우선은 현재 daily MVP와 fixture를 재사용하기 쉬운 대신 provenance를 반드시 남겨야 한다.
|
|
||||||
- 적용 위치:
|
|
||||||
- SDD: `Source of Truth`, `State Machine`, `Interface Contract`, `Acceptance Scenarios`
|
|
||||||
- Milestone: `구현 잠금`, `monthly-bars`
|
|
||||||
|
|
||||||
## 승인 항목
|
|
||||||
|
|
||||||
- [ ] 위 결정 항목을 승인했다.
|
|
||||||
- [ ] SDD 잠금 해제를 승인했다.
|
|
||||||
|
|
||||||
## 답변 기록
|
|
||||||
|
|
||||||
- 없음
|
|
||||||
|
|
||||||
## 해결 조건
|
|
||||||
|
|
||||||
- 모든 사용자 결정 항목의 답변이 SDD에 반영되어 있다.
|
|
||||||
- `USER_REVIEW.md`가 `user_review_N.log`로 이동되어 있다.
|
|
||||||
- 남은 잠금 항목이 없으면 SDD 상태가 `[승인됨]`이고 `SDD 잠금` 상태가 `해제`다.
|
|
||||||
|
|
@ -7,14 +7,13 @@
|
||||||
|
|
||||||
## 상태
|
## 상태
|
||||||
|
|
||||||
[검토중]
|
[승인됨]
|
||||||
|
|
||||||
## SDD 잠금
|
## SDD 잠금
|
||||||
|
|
||||||
- 상태: 잠금
|
- 상태: 해제
|
||||||
- 사용자 리뷰: `USER_REVIEW.md`
|
- 사용자 리뷰: 없음
|
||||||
- 잠금 항목:
|
- 잠금 항목: 없음
|
||||||
- [ ] [D01] scheduler를 worker 내장 loop, OS/systemd timer, external cron 중 어디까지 1차 구현으로 둘지 확정한다.
|
|
||||||
|
|
||||||
## 문제 / 비목표
|
## 문제 / 비목표
|
||||||
|
|
||||||
|
|
@ -38,18 +37,19 @@
|
||||||
| Code | `apps/cli/internal/operator/scenario.go` | scenario validation, `collection_freshness`, matrix/readiness smoke 기준 |
|
| Code | `apps/cli/internal/operator/scenario.go` | scenario validation, `collection_freshness`, matrix/readiness smoke 기준 |
|
||||||
| Code | `apps/cli/testdata/operator/headless_validation.md` | operator-facing headless evidence key와 scenario handoff 기준 |
|
| Code | `apps/cli/testdata/operator/headless_validation.md` | operator-facing headless evidence key와 scenario handoff 기준 |
|
||||||
| External Provider | KIS | scheduled tick이 호출할 provider이며 delay, gap, missing, typed error를 상태로 남겨야 한다. |
|
| External Provider | KIS | scheduled tick이 호출할 provider이며 delay, gap, missing, typed error를 상태로 남겨야 한다. |
|
||||||
| User Decision | D01 | scheduler 실행 주체와 운영 책임 경계가 구현 잠금 해제 조건이다. |
|
| User Decision | `user_review_0.log` | D01: scheduler는 `services/worker` 내장 loop가 1차 실행 주체다. OS/systemd는 process supervision만 맡고 external cron은 사용하지 않는다. worker scheduler는 설정된 한도 안에서 병렬 수집을 지원해야 한다. |
|
||||||
|
|
||||||
## State Machine
|
## State Machine
|
||||||
|
|
||||||
| 상태 | 진입 조건 | 다음 상태 | 근거 |
|
| 상태 | 진입 조건 | 다음 상태 | 근거 |
|
||||||
|------|-----------|-----------|------|
|
|------|-----------|-----------|------|
|
||||||
| `config-candidate` | schedule config가 named universe, provider, selector, timeframe, cadence, timezone, backfill window를 선언한다. | `config-valid` 또는 `config-rejected` | validate/dry-run output |
|
| `config-candidate` | schedule config가 named universe, provider, selector, timeframe, cadence, timezone, backfill window, parallelism limit를 선언한다. | `config-valid` 또는 `config-rejected` | validate/dry-run output |
|
||||||
| `config-rejected` | 필수 필드 누락 또는 provider/timeframe 조합 미지원이다. | terminal | typed validation error, stable text/JSONL |
|
| `config-rejected` | 필수 필드 누락 또는 provider/timeframe 조합 미지원이다. | terminal | typed validation error, stable text/JSONL |
|
||||||
| `config-valid` | schedule config가 validation을 통과한다. | `scheduled` | next window calculation |
|
| `config-valid` | schedule config가 validation을 통과한다. | `scheduled` | next window calculation |
|
||||||
| `scheduled` | tick 시간이 도래하거나 manual tick smoke가 실행된다. | `running` 또는 `skipped` | scheduler log/status |
|
| `scheduled` | worker 내장 scheduler loop에서 tick 시간이 도래하거나 manual tick smoke가 실행된다. | `dispatching` 또는 `skipped` | scheduler log/status |
|
||||||
|
| `dispatching` | worker scheduler가 tick lock을 획득하고 universe를 수집 작업 단위로 펼친다. | `running` | bounded parallel dispatch log/status |
|
||||||
| `skipped` | 동일 tick이 이미 running이거나 lock/idempotency guard가 막는다. | terminal | duplicate tick evidence |
|
| `skipped` | 동일 tick이 이미 running이거나 lock/idempotency guard가 막는다. | terminal | duplicate tick evidence |
|
||||||
| `running` | import job이 provider와 DB upsert를 실행한다. | `succeeded`, `stale`, 또는 `failed` | job result, importer result, DB state |
|
| `running` | 하나 이상의 import job이 설정된 병렬 한도 안에서 provider 호출과 DB upsert를 실행한다. | `succeeded`, `stale`, 또는 `failed` | job result, importer result, DB state |
|
||||||
| `succeeded` | import와 freshness/readiness가 expected window를 만족한다. | `ready-for-backtest` | status JSONL, freshness output |
|
| `succeeded` | import와 freshness/readiness가 expected window를 만족한다. | `ready-for-backtest` | status JSONL, freshness output |
|
||||||
| `stale` | provider delay, missing, gap이 남아 backfill/retry가 필요하다. | `scheduled` 또는 terminal | retry/backfill calculation, stale status |
|
| `stale` | provider delay, missing, gap이 남아 backfill/retry가 필요하다. | `scheduled` 또는 terminal | retry/backfill calculation, stale status |
|
||||||
| `failed` | provider, config, DB, runtime 오류가 발생한다. | `scheduled` 또는 terminal | last_error, error status |
|
| `failed` | provider, config, DB, runtime 오류가 발생한다. | `scheduled` 또는 terminal | last_error, error status |
|
||||||
|
|
@ -59,17 +59,19 @@
|
||||||
|
|
||||||
- 계약 원문: 없음
|
- 계약 원문: 없음
|
||||||
- 입력:
|
- 입력:
|
||||||
- `schedule_config`: named universe별 provider, selector, timeframe, cadence, timezone, backfill window.
|
- `schedule_config`: named universe별 provider, selector, timeframe, cadence, timezone, backfill window, parallelism limit.
|
||||||
- `tick`: scheduled 또는 manual smoke로 실행되는 refresh trigger.
|
- `tick`: worker 내장 scheduler loop 또는 manual smoke로 실행되는 refresh trigger. 1차 구현에서 external cron은 사용하지 않는다.
|
||||||
- `provider_capability`: provider, market, venue, timeframe별 accepted/rejected 판정.
|
- `provider_capability`: provider, market, venue, timeframe별 accepted/rejected 판정.
|
||||||
- `runtime_env`: provider credential과 DB URL은 config 파일에 쓰지 않고 원격 runtime env/SOPS 주입 경계에서 제공한다.
|
- `runtime_env`: provider credential과 DB URL은 config 파일에 쓰지 않고 원격 runtime env/SOPS 주입 경계에서 제공한다.
|
||||||
- `freshness_window`: latest, expected dates, missing/gap/duplicate/provider delay를 계산할 기간.
|
- `freshness_window`: latest, expected dates, missing/gap/duplicate/provider delay를 계산할 기간.
|
||||||
- 출력:
|
- 출력:
|
||||||
- `refresh_status`: last_success, last_error, next_run, imported bar count, missing/gap/duplicate/provider_delay.
|
- `refresh_status`: last_success, last_error, next_run, imported bar count, missing/gap/duplicate/provider_delay.
|
||||||
- `job_result`: import job success/stale/error와 retry/backfill decision.
|
- `job_result`: import job success/stale/error와 retry/backfill decision, parallel dispatch item별 result.
|
||||||
- `readiness`: backtest selector가 scheduled import 결과를 사용할 수 있는지에 대한 headless result.
|
- `readiness`: backtest selector가 scheduled import 결과를 사용할 수 있는지에 대한 headless result.
|
||||||
- `remote_smoke`: migration, runtime startup, tick, freshness query, backtest selector/result scenario exit code.
|
- `remote_smoke`: migration, runtime startup, tick, freshness query, backtest selector/result scenario exit code.
|
||||||
- 금지:
|
- 금지:
|
||||||
|
- external cron을 1차 scheduler 실행 주체로 사용하지 않는다.
|
||||||
|
- OS/systemd timer가 schedule state나 tick 판단을 소유하지 않는다. OS/systemd는 worker process supervision까지만 맡는다.
|
||||||
- schedule config에 secret 값을 저장하지 않는다.
|
- schedule config에 secret 값을 저장하지 않는다.
|
||||||
- 동일 tick 재실행이 duplicate `bars` row를 만들지 않는다.
|
- 동일 tick 재실행이 duplicate `bars` row를 만들지 않는다.
|
||||||
- provider delay나 gap을 성공으로 조용히 숨기지 않는다.
|
- provider delay나 gap을 성공으로 조용히 숨기지 않는다.
|
||||||
|
|
@ -81,7 +83,7 @@
|
||||||
| ID | Milestone Task | Given | When | Then |
|
| ID | Milestone Task | Given | When | Then |
|
||||||
|----|----------------|-------|------|------|
|
|----|----------------|-------|------|------|
|
||||||
| S01 | `schedule-config` | named universe별 provider, selector, timeframe, cadence, timezone, backfill window가 있다. | validate/dry-run을 실행한다. | next window와 rejected combination이 text/JSONL로 출력된다. |
|
| S01 | `schedule-config` | named universe별 provider, selector, timeframe, cadence, timezone, backfill window가 있다. | validate/dry-run을 실행한다. | next window와 rejected combination이 text/JSONL로 출력된다. |
|
||||||
| S02 | `scheduled-runner` | 원격 runtime과 idempotent `bars` upsert가 있다. | scheduler tick을 2회 실행한다. | duplicate row 없이 freshness/readiness output이 남는다. |
|
| S02 | `scheduled-runner` | 원격 worker runtime, idempotent `bars` upsert, 병렬 수집 대상이 있다. | worker 내장 scheduler tick을 2회 실행하고 병렬 수집을 수행한다. | external cron 없이 duplicate row 없이 item별 job result와 freshness/readiness output이 남는다. |
|
||||||
| S03 | `retry-backfill` | provider delay, missing, gap fixture가 있다. | retry/backfill calculation을 실행한다. | stale/error 상태와 backfill window가 stable text/JSONL로 구분된다. |
|
| S03 | `retry-backfill` | provider delay, missing, gap fixture가 있다. | retry/backfill calculation을 실행한다. | stale/error 상태와 backfill window가 stable text/JSONL로 구분된다. |
|
||||||
| S04 | `refresh-status` | success, stale, error 상태가 있다. | status scenario를 실행한다. | last_success, last_error, next_run, bar count, missing/gap/duplicate/provider_delay가 구분된다. |
|
| S04 | `refresh-status` | success, stale, error 상태가 있다. | status scenario를 실행한다. | last_success, last_error, next_run, bar count, missing/gap/duplicate/provider_delay가 구분된다. |
|
||||||
| S05 | `backtest-readiness` | scheduler tick이 bars를 적재했다. | remote runner에서 backtest matrix 또는 result summary scenario를 실행한다. | exit code `0`과 result/readiness evidence가 남는다. |
|
| S05 | `backtest-readiness` | scheduler tick이 bars를 적재했다. | remote runner에서 backtest matrix 또는 result summary scenario를 실행한다. | exit code `0`과 result/readiness evidence가 남는다. |
|
||||||
|
|
@ -91,7 +93,7 @@
|
||||||
| Scenario | Required Evidence | `agent-task` 연결 | `Spec Completion` 기대 |
|
| Scenario | Required Evidence | `agent-task` 연결 | `Spec Completion` 기대 |
|
||||||
|----------|-------------------|------------------|---------------------------|
|
|----------|-------------------|------------------|---------------------------|
|
||||||
| S01 | schedule config validate test와 dry-run text/JSONL | `agent-task/m-scheduled-market-data-refresh/...` | `schedule-config` task와 next window/rejected combination evidence |
|
| S01 | schedule config validate test와 dry-run text/JSONL | `agent-task/m-scheduled-market-data-refresh/...` | `schedule-config` task와 next window/rejected combination evidence |
|
||||||
| S02 | duplicate tick smoke, `bars` key 중복 없음, freshness/readiness output | `agent-task/m-scheduled-market-data-refresh/...` | `scheduled-runner` task와 2회 tick idempotency evidence |
|
| S02 | worker 내장 scheduler tick smoke, bounded parallel dispatch output, `bars` key 중복 없음, freshness/readiness output | `agent-task/m-scheduled-market-data-refresh/...` | `scheduled-runner` task와 2회 tick idempotency 및 병렬 수집 evidence |
|
||||||
| S03 | missing/gap/provider delay fixture 또는 local smoke | `agent-task/m-scheduled-market-data-refresh/...` | `retry-backfill` task와 stale/error/backfill evidence |
|
| S03 | missing/gap/provider delay fixture 또는 local smoke | `agent-task/m-scheduled-market-data-refresh/...` | `retry-backfill` task와 stale/error/backfill evidence |
|
||||||
| S04 | success/stale/error status scenario expected JSONL | `agent-task/m-scheduled-market-data-refresh/...` | `refresh-status` task와 status field evidence |
|
| S04 | success/stale/error status scenario expected JSONL | `agent-task/m-scheduled-market-data-refresh/...` | `refresh-status` task와 status field evidence |
|
||||||
| S05 | remote runner smoke after scheduler tick | `agent-task/m-scheduled-market-data-refresh/...` | `backtest-readiness` task와 exit code `0` evidence |
|
| S05 | remote runner smoke after scheduler tick | `agent-task/m-scheduled-market-data-refresh/...` | `backtest-readiness` task와 exit code `0` evidence |
|
||||||
|
|
@ -105,17 +107,19 @@
|
||||||
- [x] Milestone 기능 Task와 Acceptance Scenario가 일치한다.
|
- [x] Milestone 기능 Task와 Acceptance Scenario가 일치한다.
|
||||||
- [x] Evidence Map이 plan/code-review/complete.log에서 검증 가능하다.
|
- [x] Evidence Map이 plan/code-review/complete.log에서 검증 가능하다.
|
||||||
- [x] agent-contract를 쓰는 경우 SDD에 계약 원문을 복제하지 않았다.
|
- [x] agent-contract를 쓰는 경우 SDD에 계약 원문을 복제하지 않았다.
|
||||||
- [x] 사용자 리뷰가 필요한 항목은 `USER_REVIEW.md`에만 남겼다.
|
- [x] 사용자 리뷰 항목은 `user_review_0.log`로 해결 기록을 남겼다.
|
||||||
|
|
||||||
## 사용자 리뷰 이력
|
## 사용자 리뷰 이력
|
||||||
|
|
||||||
- 없음
|
- `user_review_0.log`: D01은 `services/worker` 내장 scheduler loop를 1차 실행 주체로 결정했고, external cron은 사용하지 않으며, worker scheduler는 설정된 한도 안에서 병렬 수집을 지원해야 한다.
|
||||||
|
|
||||||
## 작업 컨텍스트
|
## 작업 컨텍스트
|
||||||
|
|
||||||
- 표준선: 운영 기능은 먼저 화면 없이 CLI, YAML scenario, JSONL/text output, fixture, remote smoke로 검증한다.
|
- 표준선: 운영 기능은 먼저 화면 없이 CLI, YAML scenario, JSONL/text output, fixture, remote smoke로 검증한다.
|
||||||
- 표준선: scheduled import는 provider 호출과 DB upsert를 idempotent하게 유지하고 동일 tick 재실행이 중복 row를 만들지 않아야 한다.
|
- 표준선: scheduled import는 provider 호출과 DB upsert를 idempotent하게 유지하고 동일 tick 재실행이 중복 row를 만들지 않아야 한다.
|
||||||
- 표준선: `services/worker`가 데이터 수집, 정규화, backtest, scheduled job처럼 오래 걸리거나 비동기적인 일을 담당한다.
|
- 표준선: `services/worker`가 데이터 수집, 정규화, backtest, scheduled job처럼 오래 걸리거나 비동기적인 일을 담당한다.
|
||||||
|
- 표준선: scheduler의 일정 판단과 상태 관리는 worker 내부에 둔다. OS/systemd는 worker process supervision만 맡고 external cron은 쓰지 않는다.
|
||||||
|
- 표준선: worker scheduler는 provider/API 부하를 제어할 수 있는 bounded parallelism으로 여러 수집 작업을 병렬 실행할 수 있어야 한다.
|
||||||
- 표준선: scheduler config에는 secret 값을 넣지 않고 원격 runtime env/SOPS 주입 경계를 따른다.
|
- 표준선: scheduler config에는 secret 값을 넣지 않고 원격 runtime env/SOPS 주입 경계를 따른다.
|
||||||
- 표준선: `services/api`는 client-facing 요청을 worker 실행/조회 경계로 중계하는 control plane으로 남긴다.
|
- 표준선: `services/api`는 client-facing 요청을 worker 실행/조회 경계로 중계하는 control plane으로 남긴다.
|
||||||
- 후속 SDD: 없음
|
- 후속 SDD: 없음
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
# SDD User Review
|
|
||||||
|
|
||||||
## 상태
|
|
||||||
|
|
||||||
요청됨
|
|
||||||
|
|
||||||
## 검토 대상
|
|
||||||
|
|
||||||
- SDD: `agent-roadmap/sdd/backtest-loop/scheduled-market-data-refresh/SDD.md`
|
|
||||||
- Milestone: `agent-roadmap/phase/backtest-loop/milestones/scheduled-market-data-refresh.md`
|
|
||||||
|
|
||||||
## 사용자 결정 항목
|
|
||||||
|
|
||||||
### [D01] scheduler 실행 주체
|
|
||||||
|
|
||||||
- 결정 필요: scheduler를 worker 내장 loop, OS/systemd timer, external cron 중 어디까지 1차 구현으로 둘지 확정한다.
|
|
||||||
- 추천안: 1차 구현은 `services/worker` 내장 scheduler loop로 두고, OS/systemd는 worker process supervision까지만 맡긴다. external cron은 후속 운영 옵션으로 남긴다.
|
|
||||||
- 대안: systemd timer 또는 external cron이 CLI/manual tick을 호출하고 worker는 import/readiness action만 수행한다.
|
|
||||||
- 영향: 운영 책임 경계와 failure surface가 달라진다. worker 내장 loop는 ALT runtime 내부에서 status, retry, idempotency를 한곳에 모으기 쉽고, cron 방식은 process lifecycle과 schedule state가 외부로 분산된다.
|
|
||||||
- 적용 위치:
|
|
||||||
- SDD: `SDD 잠금`, `State Machine`, `Interface Contract`
|
|
||||||
- Milestone: `구현 잠금`, `schedule-config`, `scheduled-runner`
|
|
||||||
|
|
||||||
## 승인 항목
|
|
||||||
|
|
||||||
- [ ] 위 결정 항목을 승인했다.
|
|
||||||
- [ ] SDD 잠금 해제를 승인했다.
|
|
||||||
|
|
||||||
## 답변 기록
|
|
||||||
|
|
||||||
- 없음
|
|
||||||
|
|
||||||
## 해결 조건
|
|
||||||
|
|
||||||
- 모든 사용자 결정 항목의 답변이 SDD에 반영되어 있다.
|
|
||||||
- `USER_REVIEW.md`가 `user_review_N.log`로 이동되어 있다.
|
|
||||||
- 남은 잠금 항목이 없으면 SDD 상태가 `[승인됨]`이고 `SDD 잠금` 상태가 `해제`다.
|
|
||||||
Loading…
Reference in a new issue