@operato/twin-kernel
v0.0.4
Published
Twin Domain Kernel — framework-agnostic, zero-dep (domain + sim + 3-channel contract). WMS/YMS/MES, EPCIS 2.0 · ISA-95.
Keywords
Readme
@operato-twin/kernel — 비즈니스레이어 디지털트윈 커널
물류창고·야드·스마트팩토리의 비즈니스 실행을 시뮬레이션·모니터링하는 헤드리스·프레임워크 무관·zero-dep TS 커널. UI/3D/DOM 없이 순수 Node 에서 도는 것이 목적(sim=능동 생산, live=수동 미러, 계약 동일).
- 실행:
node --test test/*.test.ts(Node 25 네이티브 TS, 무의존) - 상태: 38 tests green, 3 버티컬(WMS/YMS/MES)
계층 (아래로만 의존, 무방언)
contract.ts 3채널 계약(State/Command/Scenario) + 운영 델타 + TwinKernel ← 도메인/표준 무관
epcis.ts GS1 EPCIS 2.0 이벤트 machinery(타입·빌더·검증기·URI·CBV disp) ← 표준(도메인 무관)
flow-engine.ts FlowEngine base — mechanics(RNG·clock·tick·자원배정·태스크진행·emit·snapshot)
allocation-policy.ts AllocationPolicy 확장 시임(selectPlacement/selectStock)
state-projector.ts 이벤트 스트림 → State 투영(모니터링 미러) ← 도메인 무관
runtime.ts TwinRuntime — host-facing facade + 구독 프로토콜 ← 도메인/전송 무관
face2-adapter.ts 레거시 레코드 → 정규 EPCIS(선언적 매핑 + 검증) ← ACL
{wms,yms,mes}-profile.ts 도메인 어휘(bizStep/btt)만
{wms,yms,mes}-kernel.ts 도메인 flow 동사(4 hook) — FlowEngine 확장무방언 원칙: 코어(contract/epcis/flow-engine/policy/projector/runtime)에 특정 도메인 용어를 넣지 않는다. EPCIS 는 표준이라
epcis.ts(≠wms). order.kind·task.resourceType 등은 도메인이 소유. 정책 인터페이스는selectPlacement/selectStock(≠putaway/pallets).
FlowEngine — 단일 base, 도메인은 4 hook 만
abstract FlowEngine implements TwinKernel 이 모든 mechanics 를 소유. 도메인 kernel 은 flow 동사만 구현:
| hook | 역할 |
|---|---|
| onArrival(spec) | 입고/도착 자극 → 아이템 생성 + EPCIS + 반입 태스크 |
| onOrder(spec) | 오더/작업지시 자극 → 오더 생성 |
| allocate(order) | created 오더 할당 → 재고 선택(정책) + 태스크. 시간창 게이트도 여기(스케줄링) |
| onTaskComplete(task) | 완료의 의미 — 이동(WMS/YMS) 또는 변환(MES). occupancy·EPCIS·오더 이행 전부 도메인 |
base 는 task 생명주기(자원 배정·진행·완료·해제·델타)만 소유 → 이동-중립. 새 버티컬 = 프로파일(어휘) + kernel(4 hook), ~100줄.
3 버티컬 — base 가 4 flow 성격을 담음을 실증
| 버티컬 | flow 성격 | base 대응 |
|---|---|---|
| WMS | 이동 (putaway/pick/pack/ship) + 백오더 | 기본 |
| YMS | 이동 (spot/pull) + 시간창 스케줄링(어포인트먼트↔도크도어 예약) | 스케줄링=도메인 게이팅으로 base 흡수 |
| MES | 변환(TransformationEvent) + 다단계 라우팅 + 이종 자원(cutter/welder) | 자원 매칭=FlowTask.resourceType base 확장(load-bearing 검증) |
두 진화 축: 시간창 스케줄링=흡수, 자원-타입 매칭=최소 확장. 둘 다 backward-compatible(기존 도메인 무영향, 예제 바이트 동일로 검증).
3채널 계약 (Face 1) + 구독
- State:
getSnapshot()(스냅샷) + 델타 이벤트 스트림. 델타 = EPCIS(재고/위치/조립/변환) + 운영 델타(task/equipment/order.status, EPCIS 로 재구성 불가한 절반). - Command (행위/act):
dispatch(cmd)가 실제로 sim 을 변이 → State 델타 유발(폐루프). 코어 공통order.hold/resume(할당 보류/재개) + 도메인order.release(즉시 투입) 등은handleCommand시임으로 확장. - Scenario:
scenario.load/start/pause/setSpeed(시뮬 자극). - TwinRuntime:
subscribe(snapshot→delta, revision 연속) ·resync·tick. sparse 스트리밍(전이·move-start 만, 매 tick 아님).
State 이원 모델
- EPCIS 저널(이산): 재고·위치·조립·변환.
epcis.ts로 정규 방출,validateEpcisEvent검증. - 운영·키네마틱(연속): 무버 motion(from/to/progress)·태스크·오더 진척. 운영 델타로 미러.
- StateProjector 가 둘을 접어 재구성 → sim 이벤트든 live 이벤트든 같은 State(데이터원 스왑).
트윈 본연 — 현재로부터 예측 + 정합 (mirror+sim 과 구별짓는 기능)
관측·예측·행위가 따로 있는 건 mirror+simulator. 트윈의 본질은 그 커플링:
kernel.fork()— 현재 상태(in-flight 포함)를 정확히 복제한 격리 엔진. 원본(live/sim)은 계속 가고, fork 는 현재로부터 앞으로 굴려 forecast(완료 시각·처리량)·대안 what-if 탐색.compareStates(predicted, actual)— fork 예측 vs 실제 관측을 같은 시점에 대조 → 드리프트(모델↔현실 이탈) 탐지·국소화(item/node/order 필드별). 발산 = 이상/개입 신호.- 루프: 관측(현재) → fork 예측(미래) → 관측(실제) → 정합(발산) → 행위(개입).
EventJournal+replay(board, events)— 트윈의 기억: 이벤트열이 곧 상태(이벤트-소싱).journal.until(revision)/untilSimTime(iso)을 projector 로 재생 → 임의 과거 시점 상태 재구성(시간여행). 감사·리플레이·발산 비교의 기반. things-factory 에선 append 를 DB 이벤트 테이블로 교체.
본질 심화
- fork = 완전한 결정적 분기 — 상태 + 시나리오(gens) + RNG state 까지 복제 → 미래 생성까지 원본과 동일하게 이어가는 진짜 continuation(what-if 는 fork 후 scenario 교체).
TwinObserver— 자동 정합 루프: 주기적으로 fork-예측 후 실제가 그 시점 도달 시 대조 → 드리프트를 알림 이벤트로. 트윈이 자기 모델↔현실 이탈을 능동 감지(방해 없으면 발산 0).monteCarloForecast— 확률적 예측: seed 변주 N개 fork → 지표를 분포로(min/mean/p50/p90/max). "언제 끝나?"가 아니라 "P90 완료시각·소진 확률". 원본 무간섭.TwinHistory+counterfactualAt— 반사실(기억+분기): 주기 checkpoint(전체 커널 fork 저장) → 과거 시점 T로 되돌아가(사이 시점은 결정적 재구동) 대안 결정을 fork → 앞으로 굴려 baseline 과 대조 → "그때 X 했다면?"의 효과. 사후분석·의사결정 평가.
확장 지점
- 버티컬 추가:
{x}-profile.ts(어휘) +{x}-kernel.ts(4 hook). - 할당 정책:
AllocationPolicy교체(firstFit/partialFit 내장, FEFO/nearest/zone 추가 가능). - Face2 어댑터: 실 시스템 페이로드 → 선언적 매핑 → 정규 EPCIS.
- host 결합:
TwinRuntime를 GraphQL sub·서비스로 래핑(전송은 얇은 host 계층).
미구현(범위 밖)
host 결합(things-factory 전송/퍼시스턴스/커넥터) · 보드 바인딩(컴포넌트↔SGLN) · 도메인 깊이(WMS 멀티라인, YMS 상하차 AggregationEvent, MES BOM/수율). 설계 SoT: operato-twin/design/.
