Skip to content

Commit 06c17b4

Browse files
committed
추가: DataHub 통합 계약과 분산 실행 제어면 구현
1 parent 5367119 commit 06c17b4

166 files changed

Lines changed: 3761 additions & 1027 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

mainPlan/dartlab-universe/04-capability-simulator-execution.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# 04. Capability, 엔진 실행, 시뮬레이터 격리
22

33
> 2026-07-22 정정: `simulate.mirror`는 제거됐다. L1, L1.5, L2 capability 실행의 현재 정본은
4-
> `dartlab.data("catalog")`, `dartlab.data("query")`다. Universe는 이 작업대를 소비하는 상위 제품이며
4+
> `dartlab.dataHub("catalog")`, `dartlab.dataHub("query")`다. Universe는 이 작업대를 소비하는 상위 제품이며
55
> Data Workbench가 Universe를 역참조하지 않는 의존 규칙은 유지한다.
66
77
## 1. 전체의 의미

mainPlan/unified-data-workbench/00-product-charter.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ DartLab에는 데이터와 계산이 부족한 것이 아니다. L1의 gather와
66

77
현재 소비자는 각 엔진의 반환형, target 위치, period 표현, 오류, 캐시, 계보를 따로 알아야 한다. simulator의 Mirror는 일부 축을 정규화하지만 전체 데이터 플랫폼이 아니라 6개 엔진용 내부 물질화 도구다. Universe attempts는 더 넓은 control plane을 증명했지만 simulator가 사용할 수 없는 상위 제품으로 설계됐다.
88

9-
Data Workbench는 이 두 장점을 합치되 둘의 잘못된 경계를 승계하지 않는다.
9+
DataHub는 이 두 장점을 합치되 둘의 잘못된 경계를 승계하지 않는다.
1010

1111
## 2. 범위
1212

@@ -22,7 +22,7 @@ Data Workbench는 이 두 장점을 합치되 둘의 잘못된 경계를 승계
2222

2323
### 3.1 외부 Python 사용자
2424

25-
`dartlab.data` 하나로 자산을 찾고, 여러 owner의 자산을 한 query에 묶고, factor 또는 native 형태로 받는다. 각 엔진의 내부 import 경로나 parquet 위치를 알 필요가 없다.
25+
`dartlab.dataHub` 하나로 자산을 찾고, 여러 owner의 자산을 한 query에 묶고, factor 또는 native 형태로 받는다. 각 엔진의 내부 import 경로나 parquet 위치를 알 필요가 없다.
2626

2727
### 3.2 simulator
2828

@@ -40,7 +40,7 @@ Universe, story, AI, UI가 서로 다른 내부 reader를 만들지 않고 같
4040

4141
### D01. owner truth
4242

43-
원천 수집은 gather, provider 변환과 load는 providers, 횡단 가공은 scan, 도메인 계산은 각 L2 owner가 정본이다. data에서 이를 재구현하지 않는다.
43+
원천 수집은 gather, provider 변환과 load는 providers, 횡단 가공은 scan, 도메인 계산은 각 L2 owner가 정본이다. dataHub에서 이를 재구현하지 않는다.
4444

4545
### D02. 한 catalog, 분산 소유
4646

mainPlan/unified-data-workbench/02-contract-and-architecture.md

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# 02. 계약과 아키텍처
22

3+
분산·원격·비동기 실행면은 [07-datahub-distributed-runtime.md](07-datahub-distributed-runtime.md)를 정본으로 한다.
4+
35
## 1. 공개 facade
46

57
```python
6-
dartlab.data("catalog", query=CatalogQuery(...))
7-
dartlab.data("query", assets=(...), query=DataQuery(...))
8+
dartlab.dataHub("catalog", query=CatalogQuery(...))
9+
dartlab.dataHub("query", assets=(...), query=DataQuery(...))
810
```
911

1012
no-arg 호출은 두 axis와 사용 예를 담은 guide DataFrame을 반환한다. 알 수 없는 axis는 fail-fast한다. accessor chain과 detail helper를 공개하지 않는다.
@@ -22,7 +24,7 @@ assetId는 안정 논리 ID다. schema나 구현 변경을 ID rename으로 숨
2224

2325
## 3. descriptor
2426

25-
각 owner는 metadata-only `dataProduct` provider를 소유한다. data는 top-level package를 열거하고 provider가 선언한 descriptor만 실행 후보로 받는다.
27+
각 owner는 metadata-only `dataProduct` provider를 소유한다. dataHub는 top-level package를 열거하고 provider가 선언한 descriptor만 실행 후보로 받는다.
2628

2729
필수 필드:
2830

@@ -40,7 +42,7 @@ licenseRef
4042
costClass
4143
```
4244

43-
새 axis는 owner registry에 등록되면 provider가 자동 projection한다. 새 engine은 자기 package에 provider 하나를 선언한다. data 중앙 파일에 engine 이름을 추가하지 않는다. descriptor가 없는 새 package도 catalog에서 `UNCLASSIFIED_OWNER`로 나타나 조용히 누락되지 않는다.
45+
새 axis는 owner registry에 등록되면 provider가 자동 projection한다. 새 engine은 자기 package에 provider 하나를 선언한다. dataHub 중앙 파일에 engine 이름을 추가하지 않는다. descriptor가 없는 새 package도 catalog에서 `UNCLASSIFIED_OWNER`로 나타나 조용히 누락되지 않는다.
4446

4547
catalog discovery는 네트워크나 값 실행을 하지 않는다. metadata import에 side effect가 있으면 provider가 실패다.
4648

@@ -142,9 +144,9 @@ DataFrame은 Arrow IPC 또는 Polars partition으로 전달하고, 큰 결과는
142144

143145
### 7.1 DART와 EDGAR 계산 feature runtime paging
144146

145-
`analysis.dartFinancialFeatures``analysis.edgarFinancialFeatures``FactorProjection`, 각 시장의 현재 `listed` universe, 부분 성공 정책 조합에서 owner 계산을 continuation page로 실행한다. 호출자는 종목별 반복문을 만들지 않고 한 `data("query", ...)`에 KR과 US universe를 함께 등록할 수 있다. 명시한 `subjects`는 이 paging 경로로 바꾸지 않고 기존 eager `subjectFanout`으로 실행한다.
147+
`analysis.dartFinancialFeatures``analysis.edgarFinancialFeatures``FactorProjection`, 각 시장의 현재 `listed` universe, 부분 성공 정책 조합에서 owner 계산을 continuation page로 실행한다. 호출자는 종목별 반복문을 만들지 않고 한 `dataHub("query", ...)`에 KR과 US universe를 함께 등록할 수 있다. 명시한 `subjects`는 이 paging 경로로 바꾸지 않고 기존 eager `subjectFanout`으로 실행한다.
146148

147-
owner lane 한 page는 종목 시도 8개를 넘지 않으며 row, byte, time 예산이 더 작은 경계를 만들 수 있다. 종목별 계산 실패는 machine-readable gap으로 남고 cursor는 실패 종목을 지나 다음 종목으로 전진한다. `requireComplete`와 historical universe는 owner 호출 전에 거부한다.
149+
owner lane 한 page는 종목 시도 64개를 넘지 않으며 row, byte, time 예산이 더 작은 경계를 만들 수 있다. 종목별 계산 실패는 machine-readable gap으로 남고 cursor는 실패 종목을 지나 다음 종목으로 전진한다. `requireComplete`와 historical universe는 owner 호출 전에 거부한다.
148150

149151
continuation private state는 원 query, contract, 외부 Arrow schema, source manifest, 상장 membership, entity와 source ID mapping, DART 결산월 같은 entity parameter를 digest로 고정한다. 미완료 token을 재개할 때 source, universe, 요청 measure, owner code가 달라지면 실패한다. commit된 page replay는 source와 owner를 다시 접촉하지 않는다. token의 임시 보존 기한은 24시간이다.
150152

@@ -199,10 +201,10 @@ systemic outage, policy denial, invalid query는 result-level failure다. 개별
199201

200202
## 9. 의존 방향
201203

202-
data package 내부 후보:
204+
dataHub package 구조:
203205

204206
```text
205-
data/
207+
dataHub/
206208
__init__.py
207209
entry.py
208210
contracts.py
@@ -212,7 +214,12 @@ data/
212214
execution.py
213215
projections.py
214216
lineage.py
215-
result.py
217+
materialization/
218+
continuation/
219+
controlPlane/
220+
remote/
221+
transport/
222+
workerPlane/
216223
```
217224

218-
data가 허용하는 import는 core, gather, providers, scan, frame, synth, reference, L2 owner뿐이다. simulate, story, Universe, AI, server, UI를 import하지 않는다.
225+
dataHub가 허용하는 import는 core, gather, providers, scan, frame, synth, reference, L2 owner뿐이다. simulate, story, Universe, AI, server, UI를 import하지 않는다. server는 반대로 dataHub의 versioned router를 호스팅한다.

mainPlan/unified-data-workbench/04-verification-progress-ledger.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,31 @@ uv run python -X utf8 tests/audit/dartlabGuard.py strict --scope l0-l15 --provid
254254
- materialization CAS page payload read는 public page당 정확히 1회
255255
- page read 중 GC race, crash recovery, concurrent builder, corruption, private path, bounded GC를 포함한 19개 집중 회귀 통과
256256
- cold build는 전체 6시간과 page별 timeout 상한, warm replay는 목표 page 하나 적재
257+
258+
### 2026-07-26 W14
259+
260+
- immutable generation의 warm page 재생을 전체 page ledger scan에서 ordinal 직접 조회로 변경해 page 수 증가에 따른 반복 scan 제거
261+
- production materialization store를 root와 timeout 조합별로 재사용하고 immutable terminal manifest를 process당 제한된 16개 root까지 검증 cache
262+
- CAS가 이미 수행한 SHA-256 검증을 replay와 publication 계층에서 중복 수행하지 않도록 정리
263+
- reader lease 최종 검증과 release를 한 SQLite transaction으로 합쳐 page 재생의 ledger 연결을 5회에서 2회로 축소
264+
- 8 page, page당 100행, 60회 warm replay 실측에서 p50 93.278ms에서 51.501ms로 44.8%, p95 116.479ms에서 57.471ms로 50.7% 단축
265+
- fresh owner process fixture에서 종목 8개 대비 64개 batch의 p50 처리량이 초당 3.794개에서 18.276개로 4.82배 증가했고 최대 payload는 411,008 bytes로 8MiB 상한의 4.9%
266+
- DART와 EDGAR 계산 owner page 상한을 8개에서 64개로 확대
267+
- 실제 local-only 첫 page 단일 실측에서 KR은 8개 3.737초에서 64개 9.242초, US는 8개 3.910초에서 64개 5.644초
268+
- 완료 종목 처리량은 KR 2.14개/초에서 6.92개/초로 3.24배, US 2.05개/초에서 11.34개/초로 5.53배 증가
269+
- 64개 page도 30초 기본 예산의 31% 이하였으며 row, byte, time budget과 continuation이 더 작은 실제 경계를 계속 강제
270+
271+
### 2026-07-26 W15
272+
273+
- canonical 엔진 폴더와 공개 진입점을 `src/dartlab/dataHub/`, `dartlab.dataHub(...)`로 전환
274+
- `dartlab.data`는 기존 소비자를 위한 callable compatibility alias로 유지
275+
- capability key를 `dataHub.catalog`, `dataHub.query`로 승격하고 Skill OS 정본을 `engines.dataHub`로 이동
276+
- `/api/dataHub/v1` versioned catalog, job, result, cancel, worker lease API 추가
277+
- request와 result를 private SHA-256 CAS에 저장하고 SQLite에는 digest, 상태, 우선순위, 시도 수, lease epoch만 보존
278+
- idempotency key, 원자 claim, heartbeat, lease 만료 재queue, bounded retry, stale completion 차단 구현
279+
- client와 worker bearer token을 역할별로 분리하고 서로 대체할 수 없게 고정
280+
- `DataHubClient`, `AsyncDataHubClient`에 local과 같은 catalog와 query 의미, submit, wait, cancel, result 계약 추가
281+
- pull 기반 `DataHubWorker``python -m dartlab.dataHub.workerPlane` 실행 진입점 추가
282+
- remote wire에서 bounded Arrow materialization page, continuation, immutable receipt를 digest 검증 후 복원
283+
- control plane, remote, public surface 집중 회귀 13건 통과
284+
- 이동된 DataHub 전수 회귀는 504개를 분할 실행해 501개 통과와 환경 의존 3개 skip 확인

mainPlan/unified-data-workbench/05-signature-data-prism.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## 1. 제품 판정
44

5-
Data Workbench의 최종 정체성은 factor store가 아니다. DartLab이 소유하거나 발견한 모든 데이터 자산을 하나의 진입점에서 목적별 view로 바꾸는 `Data Prism`이다.
5+
DataHub의 최종 정체성은 factor store가 아니다. DartLab이 소유하거나 발견한 모든 데이터 자산을 하나의 진입점에서 목적별 view로 바꾸는 `Data Prism`이다.
66

77
```text
88
factor view quant, technical, ML
@@ -12,7 +12,7 @@ catalog + query -> graph view relation, transmission, causality
1212
resource view external locator, bulk handoff
1313
```
1414

15-
외부 사용자는 `dartlab.data("query", ...)` 한 번만 호출한다. 내부 simulator도 같은 계약을 쓴다. 계산은 quant, scan, analysis 등 원래 owner가 수행하고 data는 발견, 실행, view 변환, 시간 진실성, 계보, 품질, transport를 담당한다.
15+
외부 사용자는 `dartlab.dataHub("query", ...)` 한 번만 호출한다. 내부 simulator도 같은 계약을 쓴다. 계산은 quant, scan, analysis 등 원래 owner가 수행하고 dataHub는 발견, 실행, view 변환, 시간 진실성, 계보, 품질, transport를 담당한다.
1616

1717
## 2. 공식 설계 조사와 흡수한 개념
1818

@@ -60,14 +60,14 @@ catalog + query -> graph view relation, transmission, causality
6060

6161
```python
6262
import dartlab
63-
from dartlab.data import (
63+
from dartlab.dataHub import (
6464
DataQuery,
6565
DataRequest,
6666
FactorProjection,
6767
NarrativeProjection,
6868
)
6969

70-
result = dartlab.data(
70+
result = dartlab.dataHub(
7171
"query",
7272
query=DataQuery(
7373
requests=(

mainPlan/unified-data-workbench/06-full-certification-and-hardening.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ quant.entry와 quant.style은 `dipBuy`가 등록하지 않은 camelCase Signal k
105105
- runtime `timeoutMs`는 owner Python 호출을 강제 종료하지 못하는 협력적 제한이다. 전수 인증 runner는 프로세스 격리로 이 한계를 보완했다.
106106
- row와 byte budget은 owner 결과를 받은 뒤 projection에서 적용된다. owner별 predicate, projection, slice pushdown은 별도 최적화가 필요하다.
107107
- `analysis.edgarFinancialFeatures`가 실제 filing cutoff를 쓰는 knownAt feature를 제공하지만, retained companyfacts가 historical admission snapshot 전체를 보존하지 않아 exact가 아니라 conditional이다.
108-
- raw DART와 EDGAR resource 및 두 시장의 계산 feature는 opaque continuation을 지원한다. pageable, eager 혼합 query는 outer continuation 하나를 사용한다. 네트워크 Arrow Flight server와 원격 다중 노드 storage는 아직 확장 범위다.
108+
- raw DART와 EDGAR resource 및 두 시장의 계산 feature는 opaque continuation을 지원한다. pageable, eager 혼합 query는 outer continuation 하나를 사용한다. versioned HTTP API와 원격 분산 worker는 지원하며, Arrow Flight 전용 server와 control plane multi-primary storage는 확장 범위다.
109109
- cold materialization은 현재 요청 process에서 terminal generation을 동기적으로 구축한다. 별도 scheduler와 distributed worker는 없다.
110110
- fresh child의 write guard는 Python과 알려진 데이터 writer를 차단하지만 임의 native syscall을 막는 적대적 OS sandbox는 아니다. 설치된 trusted owner 실행 격리로 사용한다.
111111
- receipt 재생은 같은 `DARTLAB_HOME` 또는 같은 private storage를 보는 process 범위다. 원격 인증과 권한 분리는 별도 service plane이 필요하다.
@@ -163,3 +163,13 @@ fresh spawned process가 structured receipt만 받아 page 0과 continuation pag
163163
같은 실행에서 중복 테스트 모듈명도 발견했다. `tests/data/test_contracts.py`와 continuation 하위의 동명 파일 때문에 `tests/data` 전체 수집이 불가능했고, data와 resourceStream을 함께 수집할 때 provider 하위의 동명 파일도 충돌했다. 두 계약 테스트를 고유 이름으로 옮겨 통합 수집 사각지대를 제거했다. 최종 집중 검증은 data, local-only core, DART와 EDGAR provider, resourceStream, 외부 HTTP master API, simulator 계약을 합쳐 637개를 수집해 634개 통과와 환경 의존 3개 skip이다. Guard quick은 architecture와 provider 규칙을 모두 통과했고 workbench purity는 계층 역전과 원천 직독 0건을 확인했다.
164164

165165
별도 장시간 격리 감사 21개도 통과했다. owner child 50회 연속 실행에서 성공 50회, zero-live 50회, artifact residue 0개였고 준비 시간은 p50 1.568초, p95 4.539초, 최대 7.989초였다. eager와 owner 혼합 초기 실행 20회도 매회 artifact residue 0개였다.
166+
167+
## 13. 2026-07-26 W14 속도와 효율
168+
169+
warm materialization replay는 ordinal page 하나만 SQLite에서 직접 읽고, immutable terminal manifest는 검증 후 process 안의 16개 root 제한 cache에서 재사용한다. store 초기화도 같은 root와 timeout 조합에서 재사용한다. CAS가 이미 digest를 검증한 payload를 상위 계층에서 다시 SHA-256 계산하지 않고, reader lease의 마지막 검증과 release는 한 transaction으로 끝낸다.
170+
171+
8 page와 page당 100행을 둔 60회 재생 실측에서 SQLite 연결은 호출당 5회에서 2회로 줄었다. p50은 93.278ms에서 51.501ms로 44.8%, p95는 116.479ms에서 57.471ms로 50.7% 단축됐다. terminal manifest는 같은 process의 60회 요청에서 한 번만 읽었다. cache는 최대 16개 manifest로 제한해 속도를 위해 메모리를 무제한 점유하지 않는다.
172+
173+
계산 owner의 page 상한은 8개에서 64개로 높였다. fresh process fixture p50 처리량은 8개 batch의 초당 3.794개에서 64개 batch의 초당 18.276개로 4.82배 증가했고, 64개 payload는 최대 411,008 bytes로 8MiB 상한의 약 4.9%였다.
174+
175+
실제 local-only 첫 page 단일 실측에서 KR은 8개 3.737초에서 64개 9.242초, US는 8개 3.910초에서 64개 5.644초였다. 완료 종목 기준 처리량은 각각 3.24배와 5.53배 증가했다. 두 시장 모두 64개 page가 30초 기본 예산의 31% 이하였고 row, byte, time budget이 먼저 닿으면 더 작은 page를 반환하는 fail-closed 경계는 유지한다. 이 수치는 첫 page 실측이며 전시장 전체 완주 시간 보증으로 확대하지 않는다.

0 commit comments

Comments
 (0)