@things-factory/headless-twin 10.0.5 → 10.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist-server/engine/kpi-fold.js +24 -49
  2. package/dist-server/engine/kpi-fold.js.map +1 -1
  3. package/dist-server/engine/kpi-query.d.ts +7 -0
  4. package/dist-server/engine/kpi-query.js +11 -0
  5. package/dist-server/engine/kpi-query.js.map +1 -1
  6. package/dist-server/engine/twin-engine.d.ts +29 -2
  7. package/dist-server/engine/twin-engine.js +78 -21
  8. package/dist-server/engine/twin-engine.js.map +1 -1
  9. package/dist-server/engine/warm-start.d.ts +39 -0
  10. package/dist-server/engine/warm-start.js +37 -0
  11. package/dist-server/engine/warm-start.js.map +1 -0
  12. package/dist-server/index.js +8 -0
  13. package/dist-server/index.js.map +1 -1
  14. package/dist-server/service/twin-event/backfill-keys.d.ts +11 -0
  15. package/dist-server/service/twin-event/backfill-keys.js +63 -0
  16. package/dist-server/service/twin-event/backfill-keys.js.map +1 -0
  17. package/dist-server/service/twin-event/twin-event-keys.d.ts +35 -0
  18. package/dist-server/service/twin-event/twin-event-keys.js +95 -0
  19. package/dist-server/service/twin-event/twin-event-keys.js.map +1 -0
  20. package/dist-server/service/twin-event/twin-event-type.d.ts +6 -0
  21. package/dist-server/service/twin-event/twin-event-type.js +32 -0
  22. package/dist-server/service/twin-event/twin-event-type.js.map +1 -0
  23. package/dist-server/service/twin-event/twin-event.d.ts +5 -0
  24. package/dist-server/service/twin-event/twin-event.js +45 -0
  25. package/dist-server/service/twin-event/twin-event.js.map +1 -1
  26. package/dist-server/service/twin-journal/twin-journal-query.d.ts +19 -0
  27. package/dist-server/service/twin-journal/twin-journal-query.js +74 -0
  28. package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
  29. package/dist-server/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +6 -6
  31. package/server/engine/kpi-fold.ts +23 -52
  32. package/server/engine/kpi-query.ts +11 -0
  33. package/server/engine/twin-engine.ts +95 -28
  34. package/server/engine/warm-start.ts +53 -0
  35. package/server/index.ts +9 -0
  36. package/server/service/twin-event/backfill-keys.ts +72 -0
  37. package/server/service/twin-event/twin-event-keys.ts +102 -0
  38. package/server/service/twin-event/twin-event-type.ts +27 -0
  39. package/server/service/twin-event/twin-event.ts +48 -0
  40. package/server/service/twin-journal/twin-journal-query.ts +79 -3
  41. package/test/kpi-fold.test.ts +22 -0
  42. package/test/twin-event-keys.test.ts +108 -0
  43. package/test/warm-start.test.ts +78 -0
@@ -12,6 +12,8 @@ exports.TwinEngine = exports.DEFAULT_REALITY_MODE = void 0;
12
12
  const shell_1 = require("@things-factory/shell");
13
13
  const cache_service_1 = require("@things-factory/cache-service");
14
14
  const twin_event_js_1 = require("../service/twin-event/twin-event.js");
15
+ const twin_event_keys_js_1 = require("../service/twin-event/twin-event-keys.js");
16
+ const warm_start_js_1 = require("./warm-start.js");
15
17
  const twin_instance_js_1 = require("../service/twin-instance/twin-instance.js");
16
18
  const twin_space_js_1 = require("../service/twin-space/twin-space.js");
17
19
  const twin_space_representation_js_1 = require("../service/twin-space/twin-space-representation.js");
@@ -122,18 +124,55 @@ class TwinEngine {
122
124
  console.error('[twin-engine] recovery scan failed', err);
123
125
  }
124
126
  }
125
- /** 트윈 인스턴스 시작 — 커널 생성 + 보드 로드 + State 스트림 브리지 + 워커 tick + 레지스트리 영속. */
126
- static start(id, domainId, kind, board, realityMode) {
127
+ /**
128
+ * 웜스타트 기동하는 커널에 **직전 관측 상태**를 심는다.
129
+ *
130
+ * ── 왜 필요한가 ─────────────────────────────────────────────────────────────
131
+ * `loadBoard` 는 **구조만** 싣는다(노드·무버). 상태(무엇이 어디에 얼마나)는 없다. 그래서 재기동한
132
+ * 트윈은 저널에 입고 540건이 남아 있어도 재고가 0 이었고, 화면은 "보유 중인 것이 없습니다" 라고
133
+ * 말했다 — 있는 재고를 없다고 하는 셈이다(2026-07-31 hatiolab-wms 실측으로 확인).
134
+ * `bootstrap()` 이 이미 체크포인트 캐시(없으면 저널 replay)로 상태를 복구해 `recovered` 에 담아 두는데,
135
+ * 기동 순간 그걸 **버리고** 있었다. 반만 연결돼 있던 장치를 잇는다.
136
+ *
137
+ * ── 정직한 한계 ─────────────────────────────────────────────────────────────
138
+ * · **오더는 복원하지 않는다.** `hydrateObserved` 의 오더 인자는 requested/fulfilled/lines 를 요구하는데
139
+ * 스냅샷의 `OrderState` 에는 `progress` 밖에 없다. progress 에서 역산하면 없는 숫자를 지어내는 것이라
140
+ * 넘기지 않는다 — 재고·노드·무버만 복원되고 진행 중 오더는 비어서 시작한다.
141
+ * · 진행 중 개별 task 의 내부 상태도 관측만으로는 복원되지 않는다(커널이 명시한 한계, 재계획에 맡김).
142
+ * · 근본 해법(상태 영속 계약·revision 이어붙임)은 별도 과제.
143
+ *
144
+ * ── 벤치는 시드하지 않는다 ──────────────────────────────────────────────────
145
+ * 부하 벤치는 **새 시작에서 용량을 재는 것**이 목적이라 현재 상태를 심으면 측정이 오염된다.
146
+ */
147
+ static warmStart(id, kernel, purpose) {
148
+ const hydrate = kernel.hydrateObserved;
149
+ const plan = (0, warm_start_js_1.planWarmStart)(this.recovered[id]?.state, purpose, typeof hydrate === 'function');
150
+ if (plan.action === 'skip') {
151
+ if (plan.reason === 'bench') {
152
+ console.log(`[twin-engine] "${id}" is a bench twin — starting empty on purpose (seeding would skew the measurement).`);
153
+ }
154
+ else if (plan.reason === 'unsupported') {
155
+ console.warn(`[twin-engine] kernel for "${id}" cannot be warm-started (no hydrateObserved) — it starts with structure only, so held stock will read as zero.`);
156
+ }
157
+ return;
158
+ }
159
+ hydrate.call(kernel, plan.seed);
160
+ console.log(`[twin-engine] warm-started "${id}" — ${plan.itemCount} item(s), ${plan.moverCount} mover(s) restored. ` +
161
+ 'Open orders are not restored (the snapshot carries no requested/fulfilled counts).');
162
+ }
163
+ /** 트윈 인스턴스 시작 — 커널 생성 + 보드 로드 + 직전 상태 웜스타트 + State 스트림 브리지 + 워커 tick + 레지스트리 영속. */
164
+ static start(id, domainId, kind, board, realityMode, purpose) {
127
165
  if (this.instances[id])
128
166
  return this.instances[id];
129
167
  const Kernel = KERNELS[kind] ?? WmsKernel;
130
168
  const kernel = new Kernel(domainId);
131
- kernel.loadBoard(board);
169
+ kernel.loadBoard(board); // 구조만. 상태는 아래 웜스타트가 심는다.
170
+ this.warmStart(id, kernel, purpose);
132
171
  const runtime = new TwinRuntime(kernel);
133
172
  /* subscribe 는 RuntimeSubscription({ unsubscribe() }) 반환 → () => void 로 감쌈. */
134
173
  const inst = { id, domainId, runtime, kernel, realityMode: realityMode ?? exports.DEFAULT_REALITY_MODE, unsub: () => { } };
135
174
  this.instances[id] = inst;
136
- delete this.recovered[id]; // 라이브가 우선
175
+ delete this.recovered[id]; // 웜스타트로 커널에 옮겨 심었다 — 이제 라이브가 진실이다.
137
176
  /* 라이브 바인딩(P3): data 채널 필터가 subdomain 을 보므로 Domain 객체를 1회 해석해 둔다. */
138
177
  (0, shell_1.getRepository)(shell_1.Domain).findOne({ where: { id: domainId } }).then(d => (inst.domain = d)).catch(() => { });
139
178
  /* State 채널: runtime.subscribe(snapshot→delta→clock) → pubsub 방송(구독 리졸버가 instanceId 필터). */
@@ -271,18 +310,27 @@ class TwinEngine {
271
310
  this.broadcastTimer = undefined;
272
311
  } // live 없으면 tick 정지
273
312
  }
274
- /** live 저널 배치 기록 — 모아둔 CanonicalEnvelope 들에 startRevision+1.. 을 부여해 벌크 저장(coalescer tick 당 1회). */
275
- static async persistBatch(domainId, instanceId, envelopes, startRevision) {
276
- const repo = (0, shell_1.getRepository)(twin_event_js_1.TwinEvent);
277
- const rows = envelopes.map((e, i) => repo.create({
313
+ /**
314
+ * 저널 행 한 줄 — **기록 경로가 둘이라(라이브 벌크·심 단건) 행 모양은 반드시 한 곳에서 만든다.**
315
+ * 곳에 각자 적으면 승격 검색 키가 한쪽에만 채워지고, 반쯤 빈 색인은 "저널에는 있는데
316
+ * 검색으로는 나오는 이벤트" 만든다 — 저널에서 가장 나쁜 종류의 결함이다.
317
+ */
318
+ static journalRow(repo, domainId, instanceId, e, revision) {
319
+ return repo.create({
278
320
  domain: { id: domainId },
279
321
  instanceId,
280
322
  tenantId: e?.tenantId,
281
323
  eventType: e?.eventType,
282
- revision: startRevision + i + 1,
324
+ revision,
283
325
  eventTime: e?.eventTime,
326
+ ...(0, twin_event_keys_js_1.twinEventKeys)(e),
284
327
  payload: e
285
- }));
328
+ });
329
+ }
330
+ /** live 저널 배치 기록 — 모아둔 CanonicalEnvelope 들에 startRevision+1.. 을 부여해 벌크 저장(coalescer tick 당 1회). */
331
+ static async persistBatch(domainId, instanceId, envelopes, startRevision) {
332
+ const repo = (0, shell_1.getRepository)(twin_event_js_1.TwinEvent);
333
+ const rows = envelopes.map((e, i) => this.journalRow(repo, domainId, instanceId, e, startRevision + i + 1));
286
334
  await repo.save(rows, { chunk: 500 });
287
335
  }
288
336
  /** 레지스트리 upsert(도메인+instanceId 유니크). status 인자로 provision(stopped)/start(running) 공용. */
@@ -365,7 +413,25 @@ class TwinEngine {
365
413
  const reg = await (0, shell_1.getRepository)(twin_instance_js_1.TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } });
366
414
  if (!reg?.board)
367
415
  throw new Error(`instance "${instanceId}" not provisioned (no board)`);
368
- return this.start(instanceId, domainId, reg.kind ?? 'wms', reg.board, realityMode ?? reg.realityMode ?? undefined);
416
+ /*
417
+ * 웜스타트 재료를 **여기서 확실히 확보한다.**
418
+ * `start()` 는 동기라 스스로 캐시를 읽을 수 없어서 `recovered` 에 미리 담겨 있기를 기대하는데,
419
+ * 그건 `bootstrap()` 이 먼저 돌았을 때만 참이다. 부팅 순서에 기대면 어떤 날은 재고가 살아나고
420
+ * 어떤 날은 조용히 빈 채로 뜬다 — 재현되지 않는 결함이 가장 나쁘다.
421
+ * 체크포인트 캐시 우선(O(1) + 라이브 파생상태 보존), 없으면 저널 replay 폴백(부팅과 같은 순서).
422
+ */
423
+ if (!this.recovered[instanceId] && reg.purpose !== 'bench') {
424
+ const cached = await this.loadSnapshot(domainId, instanceId).catch(() => null);
425
+ if (cached?.state) {
426
+ this.recovered[instanceId] = { revision: cached.revision, state: cached.state };
427
+ }
428
+ else {
429
+ const state = await this.recover(domainId, instanceId).catch(() => null);
430
+ if (state)
431
+ this.recovered[instanceId] = { revision: state.revision, state };
432
+ }
433
+ }
434
+ return this.start(instanceId, domainId, reg.kind ?? 'wms', reg.board, realityMode ?? reg.realityMode ?? undefined, reg.purpose ?? undefined);
369
435
  }
370
436
  /**
371
437
  * 선언 기반 부팅(§0 프레임 ① → 부팅 거동 매핑) — 트윈이 선언한 realityMode 에 따라 재기동 방식을 가른다.
@@ -624,16 +690,7 @@ class TwinEngine {
624
690
  }
625
691
  static async persist(domainId, instanceId, msg) {
626
692
  const repo = (0, shell_1.getRepository)(twin_event_js_1.TwinEvent);
627
- const e = msg.event;
628
- await repo.save(repo.create({
629
- domain: { id: domainId },
630
- instanceId,
631
- tenantId: e?.tenantId,
632
- eventType: e?.eventType,
633
- revision: msg.revision,
634
- eventTime: e?.eventTime,
635
- payload: e
636
- }));
693
+ await repo.save(this.journalRow(repo, domainId, instanceId, msg.event, msg.revision));
637
694
  }
638
695
  /**
639
696
  * 재부팅 복구 / 시간여행 — DB 저널을 replay 해 상태 재구성.
@@ -1 +1 @@
1
- {"version":3,"file":"twin-engine.js","sourceRoot":"","sources":["../../server/engine/twin-engine.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * TwinEngine — operato-twin 커널 인스턴스를 things-factory 위에서 호스팅.\n * integration-base 의 ScenarioEngine 패턴 미러: 메모리 인스턴스 맵 + 백그라운드 tick + pubsub 상태 발행.\n *\n * 커널(zero-dep, ESM+CJS 이중배포)은 CJS require 로 로드(Node 20 CommonJS 소비 — require(ESM) 회피).\n * 커널은 결정적 논리 연산 코어 — 이 host 가 전송(pubsub)·영속(TypeORM)·스케줄(tick)·복구(replay)만 얇게 래핑.\n * (설계 SoT: operato-twin/design/integration/things-factory-host.md)\n */\n\nimport { pubsub, getRepository, Domain } from '@things-factory/shell'\nimport { cacheService } from '@things-factory/cache-service'\n\nimport { TwinEvent } from '../service/twin-event/twin-event.js'\nimport { TwinInstance } from '../service/twin-instance/twin-instance.js'\nimport { TwinSpace } from '../service/twin-space/twin-space.js'\nimport { TwinSpaceRepresentation } from '../service/twin-space/twin-space-representation.js'\nimport { TwinSpaceArea } from '../service/twin-space/twin-space-area.js'\nimport { TwinArea } from '../service/twin-space/twin-area.js'\nimport { masterToTwin, type ReferenceMaster } from '../service/reference/reference-master.js'\nimport { buildEntityDeltas } from './entity-delta.js'\nimport { OeeAccumulator, withLiveOee } from './oee-accumulator.js'\nimport { withLiveAttentions } from './live-attentions.js'\n\nimport type { TwinKernel, BoardDef, SubscriptionMessage, TwinRuntime as TwinRuntimeType, CanonicalEnvelope } from '@operato/twin-kernel'\n\n/* 커널 런타임 로드 — CJS 번들(dist-cjs). 타입은 위 import type 로. replay = 이벤트열→상태 재구성(복구·시간여행). */\nconst { WmsKernel, YmsKernel, MesKernel, TwinRuntime, StateProjector, replay, DOMAIN_CATALOG, OP_EVENT } = require('@operato/twin-kernel')\n\nconst KERNELS: Record<string, any> = { wms: WmsKernel, yms: YmsKernel, mes: MesKernel }\n\n/* 라이브 처리량 계측(모니터) — 유입/방송/저널률·백로그. 실 동기 인터페이스 부하를 읽는 일급 지표. */\ninterface TwinMetrics {\n ingestedTotal: number // 누적 유입 이벤트\n broadcastTotal: number // 누적 방송 횟수\n journaledTotal: number // 누적 저널 기록 이벤트\n ingestRate: number // 최근 유입률(ev/s)\n broadcastRate: number // 최근 방송률(회/s)\n journalRate: number // 최근 저널률(ev/s)\n backlog: number // 마지막 flush 시 대기 저널 크기(백프레셔 신호)\n // 창(window) 집계용 내부 누적\n _accIngest: number\n _accBroadcast: number\n _accJournal: number\n _windowStartMs: number\n}\n\n/*\n * realityMode — 이 트윈의 \"현실이 어디서 오나\"(runtime-state-model §0·§1 프레임의 ① 선언).\n * 부팅 거동을 결정하는 1급 선언: mirror=외부 실물 재동기 / sim-world=생성 타임라인 지속(resume) / sim-experiment=seed 재현(reset).\n * 미선언 = 'sim-experiment'(가장 보수적 — 기존 데모 거동 보존).\n */\nexport type RealityMode = 'mirror' | 'sim-world' | 'sim-experiment'\nexport const DEFAULT_REALITY_MODE: RealityMode = 'sim-experiment'\n\n/* 인메모리 라이브 런타임 홀더(영속 엔티티 TwinInstance 와 구분). */\ninterface InstanceRuntime {\n /** 현실 출처 선언(§0 프레임 ①). 부팅 거동(reset/resume/resync)의 근거. */\n realityMode?: RealityMode\n id: string\n domainId: string\n domain?: any // 라이브 바인딩(data 채널)용 Domain 객체(subdomain 필터). start 시 비동기 해석.\n runtime?: TwinRuntimeType // sim: 커널 런타임(tick/subscribe/dispatch). live 는 projector 사용.\n kernel?: any // sim: ForecastTwin(fork/getSnapshot/tick/scenario). live 미사용.\n mode?: 'sim' | 'live' // 상태 드라이버 — sim=커널 tick / live=projector 미러(face2-inbound-live). 미지정=sim.\n projector?: any // live: StateProjector(이벤트→State 재구성). sim 미사용.\n oee?: OeeAccumulator // live: OEE 계산 층(이벤트 누적 → mover payload 보강). sim 은 커널이 계산.\n unsub: () => void\n timer?: any\n /** 엔티티별 마지막 발행 시그니처 — 값이 바뀐 엔티티만 재발행(무변화 반복 push 방지). */\n entitySigs?: Map<string, string>\n /** live 방송 병합(ingest-scale §4.4) — ingest 마다 방송하지 않고 dirty 표시 → coalescer tick 이 주기 방송. */\n dirty?: boolean\n /** live 저널 결선 — ingest 이벤트를 모았다가 coalescer tick 에서 배치 기록(이벤트마다 DB write 금지). */\n pendingJournal?: any[]\n /** live 저널 revision 카운터(sim 의 delta revision 대응 — 시간여행·히스토리 노브 앵커). */\n revision?: number\n /** live 처리량 계측(모니터, ④-1). */\n metrics?: TwinMetrics\n}\n\nexport class TwinEngine {\n static instances: Record<string, InstanceRuntime> = {}\n /** 라이브 런타임이 없을 때(복구 후 미기동) 저널에서 재구성한 상태 캐시. */\n static recovered: Record<string, any> = {}\n static TICK_MS = 1000\n\n /* 최신 스냅샷 영속(warm-start) — 재기동 시 저널 fold-from-0 replay 대신 마지막 라이브 스냅샷으로 복원.\n * 프레임워크 공통 cache-service(@things-factory/cache-service) 재사용(재발명 금지, framework-leverage §4).\n * 저널은 그대로 진실(시간여행/history replay 무변경) — 캐시는 display-only 웜스타트 최적화. */\n static SNAPSHOT_CACHE_ID = 'twin-snapshot'\n static SNAPSHOT_TTL_S = 7 * 24 * 3600 // 7일 — 정상 다운타임 생존, 만료 시 저널 replay 폴백\n static CHECKPOINT_MS = 20000 // 체크포인트 주기(핫 브로드캐스트 경로와 분리, O(state) 스로틀)\n private static checkpointTimer?: any\n\n /** 최신 스냅샷을 cache-service 에 체크포인트(도메인+instanceId 키). display-only·비차단·오류흡수. */\n static async persistSnapshot(domainId: string, instanceId: string): Promise<void> {\n const inst = this.instances[instanceId]\n if (!inst) return\n const state = this.snapshot(instanceId)\n if (!state) return\n const revision = inst.revision ?? state.revision ?? 0\n await cacheService.setInCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId }, { revision, state }, this.SNAPSHOT_TTL_S)\n }\n\n /** 체크포인트된 최신 스냅샷 로드(없으면 null). getFromCache 는 CacheStore 엔티티를 반환 → 페이로드는 .value. */\n static async loadSnapshot(domainId: string, instanceId: string): Promise<{ revision: number; state: any } | null> {\n const entry = await cacheService.getFromCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId })\n return (entry as any)?.value ?? null\n }\n\n /** 체크포인트 루프 기동(1회) — 라이브 인스턴스들의 최신 스냅샷을 주기 영속. */\n static startCheckpointLoop(): void {\n if (this.checkpointTimer) return\n this.checkpointTimer = setInterval(() => {\n for (const [instanceId, inst] of Object.entries(this.instances)) {\n this.persistSnapshot(inst.domainId, instanceId).catch(err =>\n console.error(`[twin-engine] snapshot checkpoint fail \"${instanceId}\"`, err?.message ?? err)\n )\n }\n }, this.CHECKPOINT_MS)\n if (typeof this.checkpointTimer?.unref === 'function') this.checkpointTimer.unref()\n }\n\n /**\n * 부팅 훅 — DB 에 status='running' 으로 남은 인스턴스를 저널에서 상태 재구성(DB→replay).\n * 라이브 tick 재개(sim 결정적 re-run / live 인제스트 지속)는 후속. 여기선 상태 복원 + 노출.\n */\n static async bootstrap(): Promise<void> {\n try {\n // 백필(space #3) — spaceId 컬럼 없는 기존 인스턴스를 board.spaceId 로 채움(1회, 마이그레이션 안전).\n const repo = getRepository(TwinInstance)\n const missing = (await repo.find()).filter(r => !r.spaceId && (r.board as any)?.spaceId)\n for (const r of missing) {\n r.spaceId = (r.board as any).spaceId\n r.areaId = (r.board as any).areaId ?? r.areaId\n await repo.save(r)\n }\n if (missing.length) console.log(`[twin-engine] backfilled spaceId for ${missing.length} instance(s).`)\n\n // 백필(area 단일화 P3) — deprecated content.areas → TwinArea 이관(폴백 제거 전 완전성 보장, 1회).\n const spaceRepo = getRepository(TwinSpace)\n const twinAreaRepo = getRepository(TwinArea)\n for (const sp of await spaceRepo.find()) {\n const cAreas = ((sp.content as any)?.areas ?? []) as any[]\n for (const a of cAreas) {\n if (!a?.id) continue\n const ex = await twinAreaRepo.findOne({ where: { domain: { id: sp.domainId } as any, space: { id: sp.id } as any, areaId: a.id } })\n if (ex) continue\n await twinAreaRepo.save(twinAreaRepo.create({\n domain: { id: sp.domainId } as any, space: { id: sp.id } as any, areaId: a.id,\n name: a.name ?? a.id, type: a.type, parentId: a.parentId ?? null,\n layout: a.x != null ? { x: a.x, y: a.y, w: a.w, h: a.h } : null\n }))\n }\n }\n\n const rows = await repo.find({ where: { status: 'running' } })\n for (const row of rows) {\n if (!row.domainId || !row.instanceId) continue\n // 웜스타트: 캐시된 최신 스냅샷 우선(O(1) + attentions/OEE 등 라이브 파생상태 보존).\n // 없으면 저널 fold-from-0 replay(진실 폴백 — replay 는 라이브 파생상태를 못 담으므로 캐시가 더 충실).\n const cached = await this.loadSnapshot(row.domainId, row.instanceId).catch(() => null)\n if (cached?.state) {\n this.recovered[row.instanceId] = { revision: cached.revision, state: cached.state }\n console.log(`[twin-engine] warm-started \"${row.instanceId}\" from snapshot cache → revision ${cached.revision}.`)\n continue\n }\n const state = await this.recover(row.domainId, row.instanceId).catch(() => null)\n if (state) {\n this.recovered[row.instanceId] = { revision: state.revision, state }\n console.log(`[twin-engine] recovered \"${row.instanceId}\" from journal → revision ${state.revision}.`)\n }\n }\n this.startCheckpointLoop() // 이후 기동되는 라이브 인스턴스의 최신 스냅샷을 주기 영속\n } catch (err) {\n console.error('[twin-engine] recovery scan failed', err)\n }\n }\n\n /** 트윈 인스턴스 시작 — 커널 생성 + 보드 로드 + State 스트림 브리지 + 워커 tick + 레지스트리 영속. */\n static start(id: string, domainId: string, kind: string, board: BoardDef, realityMode?: RealityMode): InstanceRuntime {\n if (this.instances[id]) return this.instances[id]\n\n const Kernel = KERNELS[kind] ?? WmsKernel\n const kernel: TwinKernel = new Kernel(domainId)\n kernel.loadBoard(board)\n const runtime: TwinRuntimeType = new TwinRuntime(kernel)\n\n /* subscribe 는 RuntimeSubscription({ unsubscribe() }) 반환 → () => void 로 감쌈. */\n const inst: InstanceRuntime = { id, domainId, runtime, kernel, realityMode: realityMode ?? DEFAULT_REALITY_MODE, unsub: () => {} }\n this.instances[id] = inst\n delete this.recovered[id] // 라이브가 우선\n\n /* 라이브 바인딩(P3): data 채널 필터가 subdomain 을 보므로 Domain 객체를 1회 해석해 둔다. */\n getRepository(Domain).findOne({ where: { id: domainId } }).then(d => (inst.domain = d)).catch(() => {})\n\n /* State 채널: runtime.subscribe(snapshot→delta→clock) → pubsub 방송(구독 리졸버가 instanceId 필터). */\n const sub = runtime.subscribe((msg: SubscriptionMessage) => {\n pubsub.publish('twin-state', {\n twinState: { instanceId: id, kind: msg.kind, revision: (msg as any).revision, payload: msg }\n })\n /* 영속 + 라이브 바인딩 브리지: delta 마다 저널 저장 + 엔티티별 data(tag:) publish → 보드 컴포넌트 라이브. */\n if (msg.kind === 'delta') {\n this.persist(domainId, id, msg).catch(err => console.error('twin persist fail', err))\n this.publishEntityData(inst)\n }\n })\n inst.unsub = () => sub.unsubscribe()\n\n /* 복구 앵커: 레지스트리에 board/kind/status/realityMode 영속(재부팅 시 이게 있어야 replay·선언 거동 가능). */\n this.register(domainId, id, kind, board, 'running', inst.realityMode).catch(err => console.error('twin register fail', err))\n\n /* 워커 tick — 스켈레톤은 setInterval(메인 루프). 긴 시뮬 오프-루프(worker thread)는 스케일 하드닝(향후, §host 경계). */\n inst.timer = setInterval(() => runtime.tick(this.TICK_MS), this.TICK_MS)\n return inst\n }\n\n /**\n * live-모드 기동(face2-inbound-live §1.1) — 커널 tick 대신 StateProjector 로 실 이벤트를 미러.\n * 관측 상태(점유·위치·아이템)는 projector 가 재구성 → sim 과 동일 data(tag) payload → **보드 컴포넌트 동일 렌더**\n * (live-mirror-parity 로 payload 층 검증됨). 계산 층(attentions·OEE)은 이벤트에 없어 부재 — derive 층은 후속.\n * 실 이벤트원 = reference 어댑터 openLiveFeed → face2-adapter.ingest → CanonicalEnvelope → ingestLive().\n */\n static startLive(id: string, domainId: string, kind: string, board: BoardDef): InstanceRuntime {\n if (this.instances[id]) return this.instances[id]\n const projector = new StateProjector(board)\n const inst: InstanceRuntime = { id, domainId, mode: 'live', realityMode: 'mirror', projector, oee: new OeeAccumulator(), unsub: () => {} }\n inst.metrics = { ingestedTotal: 0, broadcastTotal: 0, journaledTotal: 0, ingestRate: 0, broadcastRate: 0, journalRate: 0, backlog: 0, _accIngest: 0, _accBroadcast: 0, _accJournal: 0, _windowStartMs: Date.now() }\n this.instances[id] = inst\n delete this.recovered[id]\n /* 라이브 바인딩(data 채널) subdomain 필터용 Domain 1회 해석(sim 과 동일). */\n getRepository(Domain).findOne({ where: { id: domainId } }).then(d => (inst.domain = d)).catch(() => {})\n /* 저널 revision 카운터 시드 — 기존 저널 최대치에서 이어붙임(재기동 시 revision 충돌 방지). 이후 인메모리 증가. */\n getRepository(TwinEvent)\n .findOne({ where: { domain: { id: domainId }, instanceId: id }, order: { revision: 'DESC' } })\n .then(top => (inst.revision = top?.revision ?? 0))\n .catch(() => (inst.revision = 0))\n this.register(domainId, id, kind, board, 'running', 'mirror').catch(err => console.error('twin register fail', err))\n return inst\n }\n\n /**\n * live 이벤트 인제스트 — projector 구동 + data(tag) 방송(폐루프의 인바운드 도착 지점, command-routing §8.2).\n * reference 어댑터가 낸 records → 커널 face2-adapter.ingest → CanonicalEnvelope 를 여기로 밀어넣는다.\n * (State 채널 델타/저널 결선은 후속 — 스켈레톤은 data(tag) 미러 중심.)\n */\n static ingestLive(id: string, envelopes: CanonicalEnvelope[]): void {\n const inst = this.instances[id]\n if (inst?.mode !== 'live' || !inst.projector) return\n for (const e of envelopes) { inst.projector.apply(e); inst.oee?.apply(e) } // 관측(projector) + 계산(OEE 누적)\n // 저널 결선(라이브도 sim 처럼 이벤트 영속) — 단 이벤트마다 DB write 하면 부하폭발이라 모아뒀다가\n // coalescer tick 에서 배치 기록(방송과 동일 주기). 히스토리 노브·타임라인·비즈니스 원장이 이 저널을 읽는다.\n ;(inst.pendingJournal ?? (inst.pendingJournal = [])).push(...envelopes)\n if (inst.metrics) { inst.metrics.ingestedTotal += envelopes.length; inst.metrics._accIngest += envelopes.length } // 계측(④-1)\n // 방송 병합(ingest-scale §1.1/§4.4) — apply 는 O(1)·싸다. 그러나 방송(snapshot O(state))은 비싸(대규모 5ms+)\n // 이벤트마다 방송하면 폭발 → dirty 만 찍고 coalescer tick 이 주기 방송(방송률 ≠ 인제스트률).\n inst.dirty = true\n this.ensureBroadcastCoalescer()\n }\n\n /** 방송 병합 주기(ms) — 방송률 상한. 인제스트가 아무리 빨라도 이 주기로만 방송. */\n static BROADCAST_COALESCE_MS = 200\n private static broadcastTimer?: any\n\n /** live 방송 coalescer — dirty 인 live 인스턴스만 주기적으로 1회 방송(entitySigs 로 변경 엔티티만). */\n private static ensureBroadcastCoalescer(): void {\n if (this.broadcastTimer) return\n this.broadcastTimer = setInterval(() => this.flushLiveBroadcasts(), this.BROADCAST_COALESCE_MS)\n if (typeof this.broadcastTimer.unref === 'function') this.broadcastTimer.unref() // 종료 비차단\n }\n\n /** dirty live 인스턴스 방송 flush(주기 tick 또는 명시 호출). 테스트/즉시 방송용으로 public. */\n static flushLiveBroadcasts(): void {\n let anyLive = false\n const now = Date.now()\n for (const inst of Object.values(this.instances)) {\n if (inst.mode !== 'live') continue\n anyLive = true\n // 처리량 계측(④-1) — 창(≥1s)마다 유입/방송/저널률 갱신. dirty 무관(유휴면 0으로 수렴). 부하를 읽는 신호.\n const m = inst.metrics\n if (m) {\n const dt = (now - m._windowStartMs) / 1000\n if (dt >= 1) {\n m.ingestRate = Math.round(m._accIngest / dt)\n m.broadcastRate = Math.round((m._accBroadcast / dt) * 10) / 10\n m.journalRate = Math.round(m._accJournal / dt)\n m._accIngest = 0; m._accBroadcast = 0; m._accJournal = 0; m._windowStartMs = now\n }\n }\n if (!inst.dirty) continue\n inst.dirty = false\n // ① 엔티티 data(tag) 방송 — 보드 컴포넌트 라이브 렌더.\n this.publishEntityData(inst)\n if (m) { m.broadcastTotal++; m._accBroadcast++ }\n // ③ 저널 배치 기록 — 모아둔 이벤트에 revision 부여해 벌크 저장(이벤트마다 write 아님).\n // revision 카운터는 인메모리(startLive 에서 저널 high-water 로 1회 시드) → tick 마다 DB 질의 없음.\n const batch = inst.pendingJournal\n if (batch?.length && inst.revision != null) {\n inst.pendingJournal = []\n const start = inst.revision\n inst.revision = start + batch.length\n if (m) { m.journaledTotal += batch.length; m._accJournal += batch.length; m.backlog = batch.length }\n this.persistBatch(inst.domainId, inst.id, batch, start).catch(err => console.error('twin live journal fail', err))\n }\n // ② State 채널 방송 — \"바뀌었다\"는 가벼운 신호만(kind+revision). 맵 구독(subscribeTwinState)은 이 신호에\n // scheduleRefresh(250ms 디바운스)→pollLive 로 되물어봄. 스냅샷(O(state))은 보는 사람이 물을 때만 1회 계산.\n // (여기서 payload 로 스냅샷을 실으면 아무도 안 읽는데 tick 마다 통째로 떠서 순수 낭비 — 신호만 보낸다.)\n pubsub.publish('twin-state', {\n twinState: { instanceId: inst.id, kind: 'delta', revision: inst.revision ?? 0 }\n })\n }\n if (!anyLive && this.broadcastTimer) { clearInterval(this.broadcastTimer); this.broadcastTimer = undefined } // live 없으면 tick 정지\n }\n\n /** live 저널 배치 기록 — 모아둔 CanonicalEnvelope 들에 startRevision+1.. 을 부여해 벌크 저장(coalescer tick 당 1회). */\n static async persistBatch(domainId: string, instanceId: string, envelopes: any[], startRevision: number): Promise<void> {\n const repo = getRepository(TwinEvent)\n const rows = envelopes.map((e, i) =>\n repo.create({\n domain: { id: domainId } as any,\n instanceId,\n tenantId: e?.tenantId,\n eventType: e?.eventType,\n revision: startRevision + i + 1,\n eventTime: e?.eventTime,\n payload: e\n })\n )\n await repo.save(rows, { chunk: 500 })\n }\n\n /** 레지스트리 upsert(도메인+instanceId 유니크). status 인자로 provision(stopped)/start(running) 공용. */\n static async register(\n domainId: string,\n instanceId: string,\n kind: string,\n board: BoardDef,\n status: 'running' | 'stopped' = 'running',\n realityMode?: RealityMode\n ): Promise<void> {\n const repo = getRepository(TwinInstance)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n await repo.save(\n repo.create({\n ...(existing ?? {}),\n domain: { id: domainId } as any,\n instanceId,\n kind,\n board,\n // 인스턴스↔공간 1급 링크(space #3) — board.spaceId/areaId 를 컬럼으로 승격(dual-write). board JSON 도 유지(커널·복구용).\n spaceId: (board as any)?.spaceId ?? existing?.spaceId,\n areaId: (board as any)?.areaId ?? existing?.areaId,\n // 현실 출처 선언(§0 ①) — 명시값 우선, 없으면 기존값 보존(재프로비전이 선언을 지우지 않게).\n realityMode: realityMode ?? existing?.realityMode ?? undefined,\n status\n })\n )\n }\n\n /**\n * 라이브 구조 변이(resource.add 등)를 저장된 board 에 반영 — 런타임 커널의 무버를 registry board.movers 에 동기.\n * 이게 없으면 런타임엔 추가돼도(상태·저널엔 반영) 저장 board 는 원본이라 프로비저닝 편집기·재기동(loadBoard)이\n * 추가분을 잃는다. 기존 board.movers 항목은 보존(homeNode 유지)하고 새 id 만 append(추가 시점 location=homeNode).\n * 좌표(layout)만 다루는 register 와 달리 movers 집합을 갱신하나, 재프로비전(purge)이 아니라 in-place 갱신이라\n * 저널은 보존된다(추가는 이미 equipment 델타로 저널됨 → replay 는 id-keyed upsert 라 이중계산 없음).\n */\n static async syncBoardMovers(domainId: string, instanceId: string): Promise<void> {\n const inst = this.instances[instanceId]\n const snap = inst?.kernel?.getSnapshot?.()\n if (!snap?.movers) return\n const repo = getRepository(TwinInstance)\n const reg = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) return\n const board = reg.board as BoardDef\n const known = new Set((board.movers ?? []).map(m => m.id))\n const added = snap.movers\n .filter((m: any) => !known.has(m.id))\n .map((m: any) => ({ id: m.id, kind: m.kind, homeNode: m.location }))\n if (!added.length) return\n board.movers = [...(board.movers ?? []), ...added]\n reg.board = board\n await repo.save(reg)\n }\n\n /**\n * 프로비저닝 — 레지스트리에 구조(board)를 등록만 하고 기동하지 않음(status='stopped').\n * 재프로비전 시 구조 시그니처가 바뀌면(노드·무버 집합/속성 변경) 기존 저널을 purge 한다(ADR-0015):\n * board 는 replay 의 마스터라 구조가 바뀌면 과거 이벤트의 전제가 깨진다. 좌표(layout)만 바뀌면 저널 보존.\n */\n static async provision(domainId: string, instanceId: string, kind: string, board: BoardDef): Promise<void> {\n if (this.instances[instanceId]) throw new Error(`instance \"${instanceId}\" is running — stop before re-provisioning`)\n const repo = getRepository(TwinInstance)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n\n if (existing?.board && this.structureSignature(existing.board as BoardDef) !== this.structureSignature(board)) {\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n delete this.recovered[instanceId]\n }\n await this.register(domainId, instanceId, kind, board, existing?.status === 'running' ? 'stopped' : (existing?.status as any) ?? 'stopped')\n }\n\n /** 구조 동일성 지문 — 좌표(layout) 등 뷰 관심사는 제외하고 커널이 보는 위상·용량·무버만. */\n private static structureSignature(board: BoardDef): string {\n const nodes = [...(board.nodes ?? [])]\n .map(n => `${n.id}:${n.type}:${n.capacity}`)\n .sort()\n .join('|')\n const movers = [...(board.movers ?? [])]\n .map(m => `${m.id}:${m.kind}:${m.homeNode}`)\n .sort()\n .join('|')\n return `N[${nodes}]M[${movers}]`\n }\n\n /** 레지스트리 board 로 기동(프로비전된 인스턴스 start). board 인자 없이 저장된 구조로 재기동. */\n static async startFromRegistry(domainId: string, instanceId: string, realityMode?: RealityMode): Promise<InstanceRuntime> {\n if (this.instances[instanceId]) return this.instances[instanceId]\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) throw new Error(`instance \"${instanceId}\" not provisioned (no board)`)\n return this.start(instanceId, domainId, reg.kind ?? 'wms', reg.board as BoardDef, realityMode ?? (reg.realityMode as RealityMode) ?? undefined)\n }\n\n /**\n * 선언 기반 부팅(§0 프레임 ① → 부팅 거동 매핑) — 트윈이 선언한 realityMode 에 따라 재기동 방식을 가른다.\n * 부팅 경로를 한 곳에 모아 \"런타임 ≠ 현실\" 범주오류를 코드로 강제한다.\n * - 'mirror' : 현실=외부 실물 → startLive(재동기). 이벤트는 어댑터 ingest 로 유입, 커널 tick 없음.\n * - 'sim-world' : 생성 타임라인 지속 → 저널 보존 + resume(현실 이어감).\n * ⚠ GATE(§8 ②③): 커널 상태 직렬화/재개가 아직 없어 진짜 resume 불가 → 실 필요·실부하 시 구현.\n * 그때까지는 저널을 보존하되 revision 충돌을 피하려 fresh 로 기동하고, 선언과 구현의 간극을 크게 경고한다.\n * - 'sim-experiment' : seed 재현 → resetJournal + fresh 기동(백지 시작이 버그가 아니라 선언된 거동).\n * 반환: 기동된 InstanceRuntime.\n */\n static async bootDeclared(domainId: string, instanceId: string, mode: RealityMode = DEFAULT_REALITY_MODE): Promise<InstanceRuntime> {\n if (mode === 'mirror') {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) throw new Error(`instance \"${instanceId}\" not provisioned (no board)`)\n return this.startLive(instanceId, domainId, reg.kind ?? 'wms', reg.board as BoardDef)\n }\n if (mode === 'sim-world') {\n // 선언은 world(지속)지만 resume 기계장치(커널 상태 복원)가 아직 없다 → 정직하게 큰 경고 후 fresh 기동.\n console.warn(\n `[twin-engine] \"${instanceId}\" declared sim-world but resume is not yet implemented (runtime-state-model §8 gate ②③) — booting FRESH (journal reset). Persisted continuity will attach here once kernel-state resume lands.`\n )\n await this.resetJournal(domainId, instanceId)\n return this.startFromRegistry(domainId, instanceId, 'sim-world')\n }\n // sim-experiment(기본): seed 재현 — 저널 초기화 후 revision 0 부터 재실행.\n await this.resetJournal(domainId, instanceId)\n return this.startFromRegistry(domainId, instanceId, 'sim-experiment')\n }\n\n /**\n * 저널 초기화 — 인스턴스 이벤트 저널 purge(레지스트리·상태는 유지).\n * 데모 fresh-start 용: 매 부팅 seed 부터 새로 실행하는 데모에서, 복구본 폐기 후 revision 0 부터 재실행하면\n * 옛 런과 revision 이 겹쳐 저널이 오염된다 → start 전에 호출해 현재 런만 남긴다.\n */\n static async resetJournal(domainId: string, instanceId: string): Promise<void> {\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n delete this.recovered[instanceId]\n }\n\n /** 삭제 — 정지 + 레지스트리 삭제 + 저널 purge(domain 스코프). */\n static async remove(domainId: string, instanceId: string): Promise<void> {\n await this.stop(instanceId)\n delete this.recovered[instanceId]\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n await getRepository(TwinInstance).delete({ domain: { id: domainId } as any, instanceId })\n }\n\n /** 관리 목록 — domain 의 등록 인스턴스 전체(라이브 여부·최신 저널 revision·노드/무버 수 포함). */\n static async list(domainId: string): Promise<any[]> {\n const rows = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const out: any[] = []\n for (const r of rows) {\n const board = (r.board as BoardDef) ?? { nodes: [], movers: [] }\n const last = await getRepository(TwinEvent).findOne({\n where: { domain: { id: domainId } as any, instanceId: r.instanceId },\n order: { revision: 'DESC' }\n })\n out.push({\n instanceId: r.instanceId,\n kind: r.kind,\n status: r.status,\n spaceId: r.spaceId, // co-location: 같은 spaceId 인스턴스들이 한 공간(공장) 공유 — 공간뷰 집약 키(G7)\n realityMode: r.realityMode ?? DEFAULT_REALITY_MODE, // 현실 출처 선언(§0 ①) — mirror/sim-world/sim-experiment\n purpose: r.purpose ?? 'operational', // 운영 vs 벤치 사본(1급 구별 — 이름 접두사 아님)\n copyOf: r.copyOf ?? undefined,\n running: !!this.instances[r.instanceId],\n revision: last?.revision ?? 0,\n nodeCount: board.nodes?.length ?? 0,\n moverCount: board.movers?.length ?? 0\n })\n }\n return out\n }\n\n /** 레거시 벤치 잔재 가드 — purpose 도입 전 만들어진 벤치/부하 공간(이름 규약)까지 걸러낸다. */\n static isBenchSpace(spaceId?: string): boolean {\n return !!spaceId && (/^bench-/.test(spaceId) || spaceId === 'rosarito-load' || /^loadtest/.test(spaceId))\n }\n\n /** 운영 공간 목록(벤치 소스 선택기) — 이름·규모 포함, 벤치 사본·잔재 제외. */\n static async listSpaces(domainId: string): Promise<{ spaceId: string; name: string; instances: number; nodes: number; movers: number }[]> {\n const nameOf = new Map((await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })).map(s => [s.spaceId, s.name]))\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const agg = new Map<string, { spaceId: string; name: string; instances: number; nodes: number; movers: number }>()\n for (const r of insts) {\n if (!r.spaceId || r.purpose === 'bench' || this.isBenchSpace(r.spaceId)) continue // 벤치·잔재 제외\n const board: any = r.board ?? {}\n const a = agg.get(r.spaceId) ?? { spaceId: r.spaceId, name: nameOf.get(r.spaceId) ?? r.spaceId, instances: 0, nodes: 0, movers: 0 }\n a.instances++\n a.nodes += board.nodes?.length ?? 0\n a.movers += board.movers?.length ?? 0\n agg.set(r.spaceId, a)\n }\n return [...agg.values()]\n }\n\n /** 인스턴스 목적 표식(운영/벤치) 설정 — 벤치 사본을 1급 속성으로 구별(이름 접두사 아님). */\n static async setPurpose(domainId: string, instanceId: string, purpose: 'operational' | 'bench', copyOf?: string): Promise<void> {\n await getRepository(TwinInstance).update({ domain: { id: domainId } as any, instanceId }, { purpose, copyOf: copyOf ?? null } as any)\n }\n\n /**\n * 공간 구조 판독 — 완전복제(벤치 사본)의 소스. 저장물이 board(위상)·TwinSpace.content(치수·geo·표현)·TwinArea(영역)로\n * 분산돼 있으므로 셋을 모아 돌려준다. 호출측이 ReferenceMaster 로 재구성 → 재식별 → ingestMaster.\n */\n static async spaceStructure(domainId: string, spaceId: string): Promise<{ name?: string; content: any; areas: any[]; instances: { instanceId: string; kind?: string; board: any }[] } | null> {\n const sp = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n const areas = sp\n ? (await getRepository(TwinArea).find({ where: { domain: { id: domainId } as any, space: { id: sp.id } as any } })).map(a => ({ id: a.areaId, type: a.type, name: a.name, parentId: a.parentId, layout: a.layout }))\n : []\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n if (!insts.length) return null\n return { name: sp?.name, content: sp?.content ?? {}, areas, instances: insts.map(i => ({ instanceId: i.instanceId, kind: i.kind, board: i.board })) }\n }\n\n /** 공간(+표현·영역) 삭제 — 벤치 정리 등. 호출측이 바인딩 인스턴스를 먼저 제거하는 전제(가드 없음). deleteTwinSpace 리졸버와 동형. */\n static async deleteSpace(domainId: string, spaceId: string): Promise<void> {\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n if (space) {\n const reps = await getRepository(TwinSpaceRepresentation).find({ where: { domain: { id: domainId }, space: { id: space.id } } })\n for (const rep of reps) await getRepository(TwinSpaceArea).delete({ domain: { id: domainId } as any, representation: { id: rep.id } as any })\n await getRepository(TwinSpaceRepresentation).delete({ domain: { id: domainId } as any, space: { id: space.id } as any })\n await getRepository(TwinArea).delete({ domain: { id: domainId } as any, space: { id: space.id } as any })\n }\n await getRepository(TwinSpace).delete({ domain: { id: domainId } as any, spaceId })\n }\n\n /**\n * Face2 마스터 인제스트(ADR-0018) — 레퍼런스 시스템(실 또는 가상)의 마스터를 읽어 트윈을 생성.\n * 엔티티를 손배선/발명하지 않고 마스터에서 반영: 공간(Space) upsert + 인스턴스 provision(미기동).\n * 노드타입은 커널 카탈로그로 검증(warning). start 는 호출측(bootstrap/mutation)이 결정.\n */\n static async ingestMaster(domainId: string, master: ReferenceMaster): Promise<{ instanceId: string; spaceId: string; warnings: string[] }> {\n const { board, spaceContent, warnings } = masterToTwin(master, DOMAIN_CATALOG)\n const spaceId: string = board.spaceId\n const repo = getRepository(TwinSpace)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, spaceId } })\n /*\n * 공유 공간(여러 트윈이 한 spaceId, N:1) content 병합 — 마지막 인제스트가 통째로 덮어써 area(그룹)·표현이\n * 유실되던 문제 보정. area·landmark 는 id 합집합, representations 는 비어있지 않은 쪽 보존, 나머지는 first-wins.\n */\n const prev: any = existing?.content ?? {}\n const cur: any = spaceContent\n const unionById = (a: any[] = [], b: any[] = []) => {\n const m = new Map<string, any>()\n for (const x of [...a, ...b]) if (x?.id) m.set(x.id, x)\n return [...m.values()]\n }\n const mergedContent = {\n width: prev.width ?? cur.width,\n depth: prev.depth ?? cur.depth,\n unit: prev.unit ?? cur.unit,\n geo: prev.geo ?? cur.geo,\n primaryId: prev.primaryId ?? cur.primaryId,\n representations: (cur.representations?.length ? cur.representations : prev.representations) ?? [],\n // areas 는 content 에 더 이상 쓰지 않는다(area 단일화 P3) — 권위=TwinArea. 아래 TwinArea 로만 기록.\n landmarks: unionById(prev.landmarks, cur.landmarks)\n }\n const savedSpace = await repo.save(repo.create({ ...(existing ?? {}), domain: { id: domainId } as any, spaceId, name: existing?.name || master.siteName, content: mergedContent }))\n /*\n * 표현을 twin_space_representations 테이블에 저장한다 — 뷰(twin-map-page 등)는 content 가 아니라 테이블 표현을 소싱하므로,\n * 저장하지 않으면 인제스트 사이트에 \"대표 표현\" 이 없어 지도로 시작하지 못한다. rep.areas 가 있으면 TwinSpaceArea 도 함께 저장.\n * 최초 인제스트만(기존 표현 있으면 사용자 편집 보존).\n */\n const repRepo = getRepository(TwinSpaceRepresentation)\n const areaRepo = getRepository(TwinSpaceArea)\n if ((await repRepo.count({ where: { space: { id: savedSpace.id } } })) === 0) {\n const reps: any[] = (spaceContent as any).representations ?? []\n for (let i = 0; i < reps.length; i++) {\n const rep = reps[i]\n const config =\n rep.type === 'map' ? { center: rep.center, zoom: rep.zoom }\n : rep.type === 'board' ? { boardId: rep.boardId }\n : rep.type === 'image' ? { imageUrl: rep.imageUrl, width: rep.width, height: rep.height }\n : {}\n const savedRep = await repRepo.save(repRepo.create({ domain: { id: domainId } as any, space: { id: savedSpace.id } as any, type: rep.type, name: rep.name, seq: i, isPrimary: !!rep.primary || rep.id === (spaceContent as any).primaryId, config }))\n for (const area of (rep.areas ?? []) as any[]) {\n await areaRepo.save(areaRepo.create({ domain: { id: domainId } as any, representation: { id: savedRep.id } as any, name: area.name, type: area.type, geometry: area.geometry, drillTo: area.drillTo ?? null, binding: area.binding ?? null, style: area.style ?? null }))\n }\n }\n }\n /*\n * area 단일화(space #2, P1) — 논리 구역을 TwinArea(정규·표현무관·공유)에 dual-write(upsert by areaId).\n * P3: content.areas 저장 폐기 → TwinArea 가 유일 권위. 소스 = masterToTwin 산출 spaceContent.areas(cur).\n * (원천 diff 제거[master 에서 빠진 area 삭제]는 사용자저작 area 보호 위해 per-area provenance 필요 → 후속.)\n */\n const twinAreaRepo = getRepository(TwinArea)\n for (const a of ((spaceContent as any).areas ?? []) as any[]) {\n if (!a?.id) continue\n const existingArea = await twinAreaRepo.findOne({ where: { domain: { id: domainId }, space: { id: savedSpace.id }, areaId: a.id } })\n await twinAreaRepo.save(\n twinAreaRepo.create({\n ...(existingArea ?? {}),\n domain: { id: domainId } as any,\n space: { id: savedSpace.id } as any,\n areaId: a.id,\n name: a.name ?? a.id,\n type: a.type,\n parentId: a.parentId ?? null,\n layout: a.x != null || a.w != null ? { x: a.x, y: a.y, w: a.w, h: a.h } : null\n })\n )\n }\n\n await this.provision(domainId, master.source, master.system, board)\n if (warnings.length) console.warn(`[twin-engine] ingest \"${master.source}\" warnings:`, warnings)\n return { instanceId: master.source, spaceId, warnings }\n }\n\n /** 단건 상세 — 프로비저닝 에디터가 편집할 board(구조+layout) 포함. */\n static async detail(domainId: string, instanceId: string): Promise<any | null> {\n const r = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!r) return null\n return {\n instanceId: r.instanceId,\n kind: r.kind,\n status: r.status,\n running: !!this.instances[r.instanceId],\n realityMode: r.realityMode, // 현실 선언 — what-if 적용 가드용(mirror=예측 전용, 자극 주입 불가)\n board: r.board\n }\n }\n\n /**\n * 라이브 바인딩 브리지(P3, ADR-0018) — 트윈 엔티티 상태를 `data(tag=엔티티id)` 채널로 publish.\n * 보드 컴포넌트가 tag 로 구독(board-ui provider)해 `component.data` 로 라이브 갱신. delta 시에만(희소).\n * tag=엔티티 id(데모=단일 인스턴스). 멀티 인스턴스/보드 재사용 시 tag 네임스페이스는 후속.\n */\n static publishEntityData(inst: InstanceRuntime): void {\n const domain = inst.domain\n if (!domain) return\n /* 상태 출처 스왑 — sim: 커널 runtime, live: projector 미러(+OEE 계산 층 보강). 계약·payload 동일, 드라이버만 다름. */\n const st: any =\n inst.mode === 'live'\n ? inst.oee\n ? withLiveOee(inst.projector?.snapshot?.(), inst.oee) // 관측 미러 + 계산(OEE) → mover payload 에 oee 포함(sim 동형)\n : inst.projector?.snapshot?.()\n : inst.runtime?.resync?.()?.state\n if (!st) return\n /*\n * 변화한 엔티티만 발행 — 이전엔 delta 마다 전 엔티티(노드+무버+오더)를 값 변화와 무관하게 전량 재발행해\n * 같은 데이터를 매초 반복 push 하고 있었다(오용). 최신-상태 채널이므로 무변화 재방송은 무의미하다.\n * 엔티티별 시그니처를 비교해 바뀐 것만 push.\n */\n const sigs = inst.entitySigs ?? (inst.entitySigs = new Map())\n const seen = new Set<string>()\n /* payload 매핑은 순수 함수(buildEntityDeltas)로 분리 — 여기선 시그니처 dedup + 발행만.\n * 변화한 엔티티만 발행(최신-상태 채널이라 무변화 재방송 무의미). */\n for (const { tag, data } of buildEntityDeltas(st)) {\n seen.add(tag)\n const sig = JSON.stringify(data)\n if (sigs.get(tag) === sig) continue // 무변화 → 발행 생략\n sigs.set(tag, sig)\n pubsub.publish('data', { data: { domain, tag, data } })\n }\n /* 사라진 엔티티의 시그니처 정리(맵 무한 성장 방지). */\n if (sigs.size > seen.size) for (const tag of sigs.keys()) if (!seen.has(tag)) sigs.delete(tag)\n }\n\n static async persist(domainId: string, instanceId: string, msg: any): Promise<void> {\n const repo = getRepository(TwinEvent)\n const e = msg.event\n await repo.save(\n repo.create({\n domain: { id: domainId } as any,\n instanceId,\n tenantId: e?.tenantId,\n eventType: e?.eventType,\n revision: msg.revision,\n eventTime: e?.eventTime,\n payload: e\n })\n )\n }\n\n /**\n * 재부팅 복구 / 시간여행 — DB 저널을 replay 해 상태 재구성.\n * board 는 레지스트리(TwinInstance)에서, 이벤트는 TwinEvent(revision ASC)에서.\n * 커서 두 축(runtime-state-model §4): **시각(untilTime, 사용자 모국어·공간 공통축)** 우선, 없으면 리비전(untilRevision, 렌즈 내부).\n * - untilTime 주면 `eventTime ≤ T` 인 이벤트만(그 시점 watermark) — 공동배치 여러 트윈을 하나의 시각 T로 통일 해소.\n * - 둘 다 없으면 최신(라이브 인메모리 진실).\n * 이벤트는 항상 revision ASC(인과 순서)로 적용 — 시각 필터는 컷오프 집합만 정한다.\n */\n static async recover(domainId: string, instanceId: string, untilRevision?: number, untilTime?: string): Promise<any> {\n // 라이브 최신(시간여행 아님) + 인메모리 인스턴스 → 라이브 커널 스냅샷을 직접 사용.\n // replay(StateProjector)는 attentions·ack 등 라이브 전용 파생 상태를 담지 못하므로, 최신은 커널 진실을 쓴다.\n if (untilRevision == null && untilTime == null) {\n const live = this.instances[instanceId]\n if (live?.kernel?.getSnapshot) return live.kernel.getSnapshot()\n // live 모드는 kernel 이 없고 projector 미러 → 인메모리 최신 스냅샷(projector+OEE+attentions) 직접 사용.\n // (저널이 있어도 최신은 인메모리가 진실 — replay 는 시간여행/복구 전용.)\n if (live?.mode === 'live' && live.projector) return this.snapshot(instanceId)\n }\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) throw new Error(`twin instance \"${instanceId}\" not registered (no board to replay)`)\n\n const rows = await getRepository(TwinEvent).find({\n where: { domain: { id: domainId }, instanceId },\n order: { revision: 'ASC' }\n })\n const cutoffMs = untilTime != null ? Date.parse(untilTime) : NaN\n const events = rows\n .filter(r => {\n if (untilTime != null && !Number.isNaN(cutoffMs)) {\n const t = r.eventTime != null ? Date.parse(String(r.eventTime)) : NaN\n return Number.isNaN(t) ? true : t <= cutoffMs // eventTime 없는 레거시 행은 포함(보수적)\n }\n return untilRevision == null || (r.revision ?? 0) <= untilRevision\n })\n .map(r => r.payload)\n .filter(Boolean)\n\n return replay(reg.board as BoardDef, events)\n }\n\n /**\n * 공간(공동배치) 시각 범위 — 스크러버 앵커(runtime-state-model §4·§6). 그 공간 전 인스턴스 저널의 min/max eventTime.\n * 반환 {minTime, maxTime}(ISO) — 이벤트/시각 없으면 null. 클라 히스토리 스크러버가 이 범위를 시각축으로 그린다.\n */\n static async timeRange(domainId: string, spaceId: string): Promise<{ minTime: string | null; maxTime: string | null }> {\n const regs = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n const ids = regs.map(r => r.instanceId)\n if (!ids.length) return { minTime: null, maxTime: null }\n let min = Infinity\n let max = -Infinity\n for (const instanceId of ids) {\n const rows = await getRepository(TwinEvent).find({ where: { domain: { id: domainId }, instanceId } })\n for (const r of rows) {\n const t = r.eventTime != null ? Date.parse(String(r.eventTime)) : NaN\n if (Number.isNaN(t)) continue\n if (t < min) min = t\n if (t > max) max = t\n }\n }\n if (min === Infinity) return { minTime: null, maxTime: null }\n return { minTime: new Date(min).toISOString(), maxTime: new Date(max).toISOString() }\n }\n\n /** 정지 훅 — 인스턴스 정지 시 부수자원 정리(예: reference-live 피드 unsubscribe). 순환 임포트 없이 결선. */\n static stopHooks: ((id: string) => void)[] = []\n static onStop(fn: (id: string) => void): void {\n this.stopHooks.push(fn)\n }\n\n static async stop(id: string): Promise<void> {\n const i = this.instances[id]\n if (i) {\n clearInterval(i.timer)\n i.unsub()\n delete this.instances[id]\n await getRepository(TwinInstance)\n .update({ domain: { id: i.domainId }, instanceId: id }, { status: 'stopped' })\n .catch(err => console.error('twin deregister fail', err))\n }\n for (const hook of this.stopHooks) { try { hook(id) } catch { /* 훅 격리 */ } }\n }\n\n static runtime(id: string): TwinRuntimeType | undefined {\n return this.instances[id]?.runtime\n }\n\n /**\n * 도메인 소유 게이트 — 인스턴스가 이 도메인 소유일 때만 true(테넌트 격리).\n * 없거나 다른 도메인이면 false. 노출 리졸버(per-id metrics/attentions/state/stop/forecast)가\n * this.instances[id] 를 만지기 전에 반드시 이걸로 확인해야 한다. 인스턴스 id 는 추측 가능하므로\n * 검증 없이 접근하면 크로스테넌트 읽기/정지가 가능해진다.\n */\n static owns(domainId: string, id: string): boolean {\n return this.instances[id]?.domainId === domainId\n }\n\n /** 라이브 커널(ForecastTwin) — forecast/divergence 예측 연산용. */\n static kernel(id: string): any {\n return this.instances[id]?.kernel\n }\n\n /** 라이브 처리량 계측 스냅샷(모니터, ④-1) — 내부 누적(_acc*) 제외한 공개 지표. live 아니면 null. */\n static metrics(id: string): any {\n const m = this.instances[id]?.metrics\n if (!m) return null\n return {\n instanceId: id,\n ingestedTotal: m.ingestedTotal, broadcastTotal: m.broadcastTotal, journaledTotal: m.journaledTotal,\n ingestRate: m.ingestRate, broadcastRate: m.broadcastRate, journalRate: m.journalRate,\n backlog: m.backlog, broadcastCoalesceMs: this.BROADCAST_COALESCE_MS\n }\n }\n\n /** 전체 라이브 인스턴스 계측(모니터 대시보드용). */\n static async allMetrics(domainId?: string): Promise<any[]> {\n const rows = Object.keys(this.instances)\n .filter(id => !domainId || this.instances[id].domainId === domainId)\n .map(id => this.metrics(id))\n .filter(Boolean)\n if (!rows.length || !domainId) return rows\n // 표시 이름 부여 — 실행중 카드가 id 만 보이지 않도록 공간명을 실어준다(공간 카드와 동일). name=공간명 폴백 spaceId 폴백 instanceId.\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const spaceOf = new Map(insts.map(i => [i.instanceId, i.spaceId]))\n const nameOf = new Map((await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })).map(s => [s.spaceId, s.name]))\n for (const r of rows) {\n const sp = spaceOf.get(r.instanceId)\n r.spaceId = sp\n r.name = (sp && nameOf.get(sp)) || sp || r.instanceId\n }\n return rows\n }\n\n /**\n * 라이브 예측용 임시 커널(kernel-unification P1) — 라이브는 projector 미러라 커널이 없어 예측을 못 한다.\n * 관측 스냅샷(재고·무버·노드) + 저널의 오더 원값·라인을 hydrate 해 예측 가능한 임시 커널을 만든다.\n * 라이브 런타임은 무간섭(이 커널은 fork 대상 임시본, instances 에 넣지 않음). sim 인스턴스면 null(그쪽은 kernel() 사용).\n */\n static async buildForecastKernel(domainId: string, instanceId: string): Promise<any | null> {\n const inst = this.instances[instanceId]\n if (inst?.mode !== 'live' || !inst.projector) return null\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) return null\n const Kernel = KERNELS[reg.kind ?? 'wms'] ?? WmsKernel\n const k = new Kernel(domainId)\n k.loadBoard(reg.board as BoardDef)\n // 저널에서 오더별 최신 관측(원값+라인) 수집 — projector 스냅샷은 오더에 손실적(progress 만)이라 저널을 쓴다.\n const rows = await getRepository(TwinEvent).find({ where: { domain: { id: domainId }, instanceId, eventType: OP_EVENT.order }, order: { revision: 'ASC' } })\n const latest = new Map<string, any>()\n for (const r of rows) { const d = (r.payload as any)?.data; if (d?.orderId) latest.set(d.orderId, d) }\n k.hydrateObserved(this.snapshot(instanceId), [...latest.values()])\n return k\n }\n\n /**\n * 예측용 커널을 **임의 시각 T 기준**으로 재구성 — 과거-vantage 예측(백테스트)·\"그때 서서 본 미래\".\n * recover(untilTime)로 T 시점 상태를, T 이하 오더 관측을 모아 hydrate → monteCarloForecast 가 T 에서 앞으로 굴린다.\n * sim/live 무관(저널 기반 재구성). untilTime 생략 시 최신. 도메인 스코프(reg·journal 조회가 domainId).\n */\n static async buildForecastKernelAt(domainId: string, instanceId: string, untilTime?: string): Promise<any | null> {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) return null\n const Kernel = KERNELS[reg.kind ?? 'wms'] ?? WmsKernel\n const k = new Kernel(domainId)\n k.loadBoard(reg.board as BoardDef)\n const state = await this.recover(domainId, instanceId, undefined, untilTime).catch(() => null)\n if (!state) return null\n const cutoff = untilTime != null ? Date.parse(untilTime) : Infinity\n const rows = await getRepository(TwinEvent).find({ where: { domain: { id: domainId }, instanceId, eventType: OP_EVENT.order }, order: { revision: 'ASC' } })\n const latest = new Map<string, any>()\n for (const r of rows) {\n if (Number.isFinite(cutoff) && Date.parse(r.eventTime) > cutoff) continue\n const d = (r.payload as any)?.data\n if (d?.orderId) latest.set(d.orderId, d)\n }\n k.hydrateObserved(state, [...latest.values()])\n return k\n }\n\n /** 현재 전체 스냅샷 — 라이브 우선, 없으면 저널 복구 캐시. */\n static snapshot(id: string): any {\n const inst = this.instances[id]\n if (inst?.mode === 'live' && inst.projector) {\n // live: projector 미러 + 계산 층(OEE·attentions) 보강 → 질의(attention 등)가 sim 동형 스냅샷을 봄.\n const st = inst.oee ? withLiveOee(inst.projector.snapshot(), inst.oee) : inst.projector.snapshot()\n return withLiveAttentions(st)\n }\n return inst?.runtime?.resync() ?? this.recovered[id]\n }\n}\n"]}
1
+ {"version":3,"file":"twin-engine.js","sourceRoot":"","sources":["../../server/engine/twin-engine.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * TwinEngine — operato-twin 커널 인스턴스를 things-factory 위에서 호스팅.\n * integration-base 의 ScenarioEngine 패턴 미러: 메모리 인스턴스 맵 + 백그라운드 tick + pubsub 상태 발행.\n *\n * 커널(zero-dep, ESM+CJS 이중배포)은 CJS require 로 로드(Node 20 CommonJS 소비 — require(ESM) 회피).\n * 커널은 결정적 논리 연산 코어 — 이 host 가 전송(pubsub)·영속(TypeORM)·스케줄(tick)·복구(replay)만 얇게 래핑.\n * (설계 SoT: operato-twin/design/integration/things-factory-host.md)\n */\n\nimport { pubsub, getRepository, Domain } from '@things-factory/shell'\nimport { cacheService } from '@things-factory/cache-service'\n\nimport { TwinEvent } from '../service/twin-event/twin-event.js'\nimport { twinEventKeys } from '../service/twin-event/twin-event-keys.js'\nimport { planWarmStart } from './warm-start.js'\nimport { TwinInstance } from '../service/twin-instance/twin-instance.js'\nimport { TwinSpace } from '../service/twin-space/twin-space.js'\nimport { TwinSpaceRepresentation } from '../service/twin-space/twin-space-representation.js'\nimport { TwinSpaceArea } from '../service/twin-space/twin-space-area.js'\nimport { TwinArea } from '../service/twin-space/twin-area.js'\nimport { masterToTwin, type ReferenceMaster } from '../service/reference/reference-master.js'\nimport { buildEntityDeltas } from './entity-delta.js'\nimport { OeeAccumulator, withLiveOee } from './oee-accumulator.js'\nimport { withLiveAttentions } from './live-attentions.js'\n\nimport type { TwinKernel, BoardDef, SubscriptionMessage, TwinRuntime as TwinRuntimeType, CanonicalEnvelope } from '@operato/twin-kernel'\n\n/* 커널 런타임 로드 — CJS 번들(dist-cjs). 타입은 위 import type 로. replay = 이벤트열→상태 재구성(복구·시간여행). */\nconst { WmsKernel, YmsKernel, MesKernel, TwinRuntime, StateProjector, replay, DOMAIN_CATALOG, OP_EVENT } = require('@operato/twin-kernel')\n\nconst KERNELS: Record<string, any> = { wms: WmsKernel, yms: YmsKernel, mes: MesKernel }\n\n/* 라이브 처리량 계측(모니터) — 유입/방송/저널률·백로그. 실 동기 인터페이스 부하를 읽는 일급 지표. */\ninterface TwinMetrics {\n ingestedTotal: number // 누적 유입 이벤트\n broadcastTotal: number // 누적 방송 횟수\n journaledTotal: number // 누적 저널 기록 이벤트\n ingestRate: number // 최근 유입률(ev/s)\n broadcastRate: number // 최근 방송률(회/s)\n journalRate: number // 최근 저널률(ev/s)\n backlog: number // 마지막 flush 시 대기 저널 크기(백프레셔 신호)\n // 창(window) 집계용 내부 누적\n _accIngest: number\n _accBroadcast: number\n _accJournal: number\n _windowStartMs: number\n}\n\n/*\n * realityMode — 이 트윈의 \"현실이 어디서 오나\"(runtime-state-model §0·§1 프레임의 ① 선언).\n * 부팅 거동을 결정하는 1급 선언: mirror=외부 실물 재동기 / sim-world=생성 타임라인 지속(resume) / sim-experiment=seed 재현(reset).\n * 미선언 = 'sim-experiment'(가장 보수적 — 기존 데모 거동 보존).\n */\nexport type RealityMode = 'mirror' | 'sim-world' | 'sim-experiment'\nexport const DEFAULT_REALITY_MODE: RealityMode = 'sim-experiment'\n\n/* 인메모리 라이브 런타임 홀더(영속 엔티티 TwinInstance 와 구분). */\ninterface InstanceRuntime {\n /** 현실 출처 선언(§0 프레임 ①). 부팅 거동(reset/resume/resync)의 근거. */\n realityMode?: RealityMode\n id: string\n domainId: string\n domain?: any // 라이브 바인딩(data 채널)용 Domain 객체(subdomain 필터). start 시 비동기 해석.\n runtime?: TwinRuntimeType // sim: 커널 런타임(tick/subscribe/dispatch). live 는 projector 사용.\n kernel?: any // sim: ForecastTwin(fork/getSnapshot/tick/scenario). live 미사용.\n mode?: 'sim' | 'live' // 상태 드라이버 — sim=커널 tick / live=projector 미러(face2-inbound-live). 미지정=sim.\n projector?: any // live: StateProjector(이벤트→State 재구성). sim 미사용.\n oee?: OeeAccumulator // live: OEE 계산 층(이벤트 누적 → mover payload 보강). sim 은 커널이 계산.\n unsub: () => void\n timer?: any\n /** 엔티티별 마지막 발행 시그니처 — 값이 바뀐 엔티티만 재발행(무변화 반복 push 방지). */\n entitySigs?: Map<string, string>\n /** live 방송 병합(ingest-scale §4.4) — ingest 마다 방송하지 않고 dirty 표시 → coalescer tick 이 주기 방송. */\n dirty?: boolean\n /** live 저널 결선 — ingest 이벤트를 모았다가 coalescer tick 에서 배치 기록(이벤트마다 DB write 금지). */\n pendingJournal?: any[]\n /** live 저널 revision 카운터(sim 의 delta revision 대응 — 시간여행·히스토리 노브 앵커). */\n revision?: number\n /** live 처리량 계측(모니터, ④-1). */\n metrics?: TwinMetrics\n}\n\nexport class TwinEngine {\n static instances: Record<string, InstanceRuntime> = {}\n /** 라이브 런타임이 없을 때(복구 후 미기동) 저널에서 재구성한 상태 캐시. */\n static recovered: Record<string, any> = {}\n static TICK_MS = 1000\n\n /* 최신 스냅샷 영속(warm-start) — 재기동 시 저널 fold-from-0 replay 대신 마지막 라이브 스냅샷으로 복원.\n * 프레임워크 공통 cache-service(@things-factory/cache-service) 재사용(재발명 금지, framework-leverage §4).\n * 저널은 그대로 진실(시간여행/history replay 무변경) — 캐시는 display-only 웜스타트 최적화. */\n static SNAPSHOT_CACHE_ID = 'twin-snapshot'\n static SNAPSHOT_TTL_S = 7 * 24 * 3600 // 7일 — 정상 다운타임 생존, 만료 시 저널 replay 폴백\n static CHECKPOINT_MS = 20000 // 체크포인트 주기(핫 브로드캐스트 경로와 분리, O(state) 스로틀)\n private static checkpointTimer?: any\n\n /** 최신 스냅샷을 cache-service 에 체크포인트(도메인+instanceId 키). display-only·비차단·오류흡수. */\n static async persistSnapshot(domainId: string, instanceId: string): Promise<void> {\n const inst = this.instances[instanceId]\n if (!inst) return\n const state = this.snapshot(instanceId)\n if (!state) return\n const revision = inst.revision ?? state.revision ?? 0\n await cacheService.setInCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId }, { revision, state }, this.SNAPSHOT_TTL_S)\n }\n\n /** 체크포인트된 최신 스냅샷 로드(없으면 null). getFromCache 는 CacheStore 엔티티를 반환 → 페이로드는 .value. */\n static async loadSnapshot(domainId: string, instanceId: string): Promise<{ revision: number; state: any } | null> {\n const entry = await cacheService.getFromCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId })\n return (entry as any)?.value ?? null\n }\n\n /** 체크포인트 루프 기동(1회) — 라이브 인스턴스들의 최신 스냅샷을 주기 영속. */\n static startCheckpointLoop(): void {\n if (this.checkpointTimer) return\n this.checkpointTimer = setInterval(() => {\n for (const [instanceId, inst] of Object.entries(this.instances)) {\n this.persistSnapshot(inst.domainId, instanceId).catch(err =>\n console.error(`[twin-engine] snapshot checkpoint fail \"${instanceId}\"`, err?.message ?? err)\n )\n }\n }, this.CHECKPOINT_MS)\n if (typeof this.checkpointTimer?.unref === 'function') this.checkpointTimer.unref()\n }\n\n /**\n * 부팅 훅 — DB 에 status='running' 으로 남은 인스턴스를 저널에서 상태 재구성(DB→replay).\n * 라이브 tick 재개(sim 결정적 re-run / live 인제스트 지속)는 후속. 여기선 상태 복원 + 노출.\n */\n static async bootstrap(): Promise<void> {\n try {\n // 백필(space #3) — spaceId 컬럼 없는 기존 인스턴스를 board.spaceId 로 채움(1회, 마이그레이션 안전).\n const repo = getRepository(TwinInstance)\n const missing = (await repo.find()).filter(r => !r.spaceId && (r.board as any)?.spaceId)\n for (const r of missing) {\n r.spaceId = (r.board as any).spaceId\n r.areaId = (r.board as any).areaId ?? r.areaId\n await repo.save(r)\n }\n if (missing.length) console.log(`[twin-engine] backfilled spaceId for ${missing.length} instance(s).`)\n\n // 백필(area 단일화 P3) — deprecated content.areas → TwinArea 이관(폴백 제거 전 완전성 보장, 1회).\n const spaceRepo = getRepository(TwinSpace)\n const twinAreaRepo = getRepository(TwinArea)\n for (const sp of await spaceRepo.find()) {\n const cAreas = ((sp.content as any)?.areas ?? []) as any[]\n for (const a of cAreas) {\n if (!a?.id) continue\n const ex = await twinAreaRepo.findOne({ where: { domain: { id: sp.domainId } as any, space: { id: sp.id } as any, areaId: a.id } })\n if (ex) continue\n await twinAreaRepo.save(twinAreaRepo.create({\n domain: { id: sp.domainId } as any, space: { id: sp.id } as any, areaId: a.id,\n name: a.name ?? a.id, type: a.type, parentId: a.parentId ?? null,\n layout: a.x != null ? { x: a.x, y: a.y, w: a.w, h: a.h } : null\n }))\n }\n }\n\n const rows = await repo.find({ where: { status: 'running' } })\n for (const row of rows) {\n if (!row.domainId || !row.instanceId) continue\n // 웜스타트: 캐시된 최신 스냅샷 우선(O(1) + attentions/OEE 등 라이브 파생상태 보존).\n // 없으면 저널 fold-from-0 replay(진실 폴백 — replay 는 라이브 파생상태를 못 담으므로 캐시가 더 충실).\n const cached = await this.loadSnapshot(row.domainId, row.instanceId).catch(() => null)\n if (cached?.state) {\n this.recovered[row.instanceId] = { revision: cached.revision, state: cached.state }\n console.log(`[twin-engine] warm-started \"${row.instanceId}\" from snapshot cache → revision ${cached.revision}.`)\n continue\n }\n const state = await this.recover(row.domainId, row.instanceId).catch(() => null)\n if (state) {\n this.recovered[row.instanceId] = { revision: state.revision, state }\n console.log(`[twin-engine] recovered \"${row.instanceId}\" from journal → revision ${state.revision}.`)\n }\n }\n this.startCheckpointLoop() // 이후 기동되는 라이브 인스턴스의 최신 스냅샷을 주기 영속\n } catch (err) {\n console.error('[twin-engine] recovery scan failed', err)\n }\n }\n\n /**\n * 웜스타트 — 기동하는 커널에 **직전 관측 상태**를 심는다.\n *\n * ── 왜 필요한가 ─────────────────────────────────────────────────────────────\n * `loadBoard` 는 **구조만** 싣는다(노드·무버). 상태(무엇이 어디에 얼마나)는 없다. 그래서 재기동한\n * 트윈은 저널에 입고 540건이 남아 있어도 재고가 0 이었고, 화면은 \"보유 중인 것이 없습니다\" 라고\n * 말했다 — 있는 재고를 없다고 하는 셈이다(2026-07-31 hatiolab-wms 실측으로 확인).\n * `bootstrap()` 이 이미 체크포인트 캐시(없으면 저널 replay)로 상태를 복구해 `recovered` 에 담아 두는데,\n * 기동 순간 그걸 **버리고** 있었다. 반만 연결돼 있던 장치를 잇는다.\n *\n * ── 정직한 한계 ─────────────────────────────────────────────────────────────\n * · **오더는 복원하지 않는다.** `hydrateObserved` 의 오더 인자는 requested/fulfilled/lines 를 요구하는데\n * 스냅샷의 `OrderState` 에는 `progress` 밖에 없다. progress 에서 역산하면 없는 숫자를 지어내는 것이라\n * 넘기지 않는다 — 재고·노드·무버만 복원되고 진행 중 오더는 비어서 시작한다.\n * · 진행 중 개별 task 의 내부 상태도 관측만으로는 복원되지 않는다(커널이 명시한 한계, 재계획에 맡김).\n * · 근본 해법(상태 영속 계약·revision 이어붙임)은 별도 과제.\n *\n * ── 벤치는 시드하지 않는다 ──────────────────────────────────────────────────\n * 부하 벤치는 **새 시작에서 용량을 재는 것**이 목적이라 현재 상태를 심으면 측정이 오염된다.\n */\n private static warmStart(id: string, kernel: TwinKernel, purpose?: string): void {\n const hydrate = (kernel as any).hydrateObserved\n const plan = planWarmStart(this.recovered[id]?.state, purpose, typeof hydrate === 'function')\n\n if (plan.action === 'skip') {\n if (plan.reason === 'bench') {\n console.log(`[twin-engine] \"${id}\" is a bench twin — starting empty on purpose (seeding would skew the measurement).`)\n } else if (plan.reason === 'unsupported') {\n console.warn(\n `[twin-engine] kernel for \"${id}\" cannot be warm-started (no hydrateObserved) — it starts with structure only, so held stock will read as zero.`\n )\n }\n return\n }\n\n hydrate.call(kernel, plan.seed)\n console.log(\n `[twin-engine] warm-started \"${id}\" — ${plan.itemCount} item(s), ${plan.moverCount} mover(s) restored. ` +\n 'Open orders are not restored (the snapshot carries no requested/fulfilled counts).'\n )\n }\n\n /** 트윈 인스턴스 시작 — 커널 생성 + 보드 로드 + 직전 상태 웜스타트 + State 스트림 브리지 + 워커 tick + 레지스트리 영속. */\n static start(id: string, domainId: string, kind: string, board: BoardDef, realityMode?: RealityMode, purpose?: string): InstanceRuntime {\n if (this.instances[id]) return this.instances[id]\n\n const Kernel = KERNELS[kind] ?? WmsKernel\n const kernel: TwinKernel = new Kernel(domainId)\n kernel.loadBoard(board) // 구조만. 상태는 아래 웜스타트가 심는다.\n this.warmStart(id, kernel, purpose)\n const runtime: TwinRuntimeType = new TwinRuntime(kernel)\n\n /* subscribe 는 RuntimeSubscription({ unsubscribe() }) 반환 → () => void 로 감쌈. */\n const inst: InstanceRuntime = { id, domainId, runtime, kernel, realityMode: realityMode ?? DEFAULT_REALITY_MODE, unsub: () => {} }\n this.instances[id] = inst\n delete this.recovered[id] // 웜스타트로 커널에 옮겨 심었다 — 이제 라이브가 진실이다.\n\n /* 라이브 바인딩(P3): data 채널 필터가 subdomain 을 보므로 Domain 객체를 1회 해석해 둔다. */\n getRepository(Domain).findOne({ where: { id: domainId } }).then(d => (inst.domain = d)).catch(() => {})\n\n /* State 채널: runtime.subscribe(snapshot→delta→clock) → pubsub 방송(구독 리졸버가 instanceId 필터). */\n const sub = runtime.subscribe((msg: SubscriptionMessage) => {\n pubsub.publish('twin-state', {\n twinState: { instanceId: id, kind: msg.kind, revision: (msg as any).revision, payload: msg }\n })\n /* 영속 + 라이브 바인딩 브리지: delta 마다 저널 저장 + 엔티티별 data(tag:) publish → 보드 컴포넌트 라이브. */\n if (msg.kind === 'delta') {\n this.persist(domainId, id, msg).catch(err => console.error('twin persist fail', err))\n this.publishEntityData(inst)\n }\n })\n inst.unsub = () => sub.unsubscribe()\n\n /* 복구 앵커: 레지스트리에 board/kind/status/realityMode 영속(재부팅 시 이게 있어야 replay·선언 거동 가능). */\n this.register(domainId, id, kind, board, 'running', inst.realityMode).catch(err => console.error('twin register fail', err))\n\n /* 워커 tick — 스켈레톤은 setInterval(메인 루프). 긴 시뮬 오프-루프(worker thread)는 스케일 하드닝(향후, §host 경계). */\n inst.timer = setInterval(() => runtime.tick(this.TICK_MS), this.TICK_MS)\n return inst\n }\n\n /**\n * live-모드 기동(face2-inbound-live §1.1) — 커널 tick 대신 StateProjector 로 실 이벤트를 미러.\n * 관측 상태(점유·위치·아이템)는 projector 가 재구성 → sim 과 동일 data(tag) payload → **보드 컴포넌트 동일 렌더**\n * (live-mirror-parity 로 payload 층 검증됨). 계산 층(attentions·OEE)은 이벤트에 없어 부재 — derive 층은 후속.\n * 실 이벤트원 = reference 어댑터 openLiveFeed → face2-adapter.ingest → CanonicalEnvelope → ingestLive().\n */\n static startLive(id: string, domainId: string, kind: string, board: BoardDef): InstanceRuntime {\n if (this.instances[id]) return this.instances[id]\n const projector = new StateProjector(board)\n const inst: InstanceRuntime = { id, domainId, mode: 'live', realityMode: 'mirror', projector, oee: new OeeAccumulator(), unsub: () => {} }\n inst.metrics = { ingestedTotal: 0, broadcastTotal: 0, journaledTotal: 0, ingestRate: 0, broadcastRate: 0, journalRate: 0, backlog: 0, _accIngest: 0, _accBroadcast: 0, _accJournal: 0, _windowStartMs: Date.now() }\n this.instances[id] = inst\n delete this.recovered[id]\n /* 라이브 바인딩(data 채널) subdomain 필터용 Domain 1회 해석(sim 과 동일). */\n getRepository(Domain).findOne({ where: { id: domainId } }).then(d => (inst.domain = d)).catch(() => {})\n /* 저널 revision 카운터 시드 — 기존 저널 최대치에서 이어붙임(재기동 시 revision 충돌 방지). 이후 인메모리 증가. */\n getRepository(TwinEvent)\n .findOne({ where: { domain: { id: domainId }, instanceId: id }, order: { revision: 'DESC' } })\n .then(top => (inst.revision = top?.revision ?? 0))\n .catch(() => (inst.revision = 0))\n this.register(domainId, id, kind, board, 'running', 'mirror').catch(err => console.error('twin register fail', err))\n return inst\n }\n\n /**\n * live 이벤트 인제스트 — projector 구동 + data(tag) 방송(폐루프의 인바운드 도착 지점, command-routing §8.2).\n * reference 어댑터가 낸 records → 커널 face2-adapter.ingest → CanonicalEnvelope 를 여기로 밀어넣는다.\n * (State 채널 델타/저널 결선은 후속 — 스켈레톤은 data(tag) 미러 중심.)\n */\n static ingestLive(id: string, envelopes: CanonicalEnvelope[]): void {\n const inst = this.instances[id]\n if (inst?.mode !== 'live' || !inst.projector) return\n for (const e of envelopes) { inst.projector.apply(e); inst.oee?.apply(e) } // 관측(projector) + 계산(OEE 누적)\n // 저널 결선(라이브도 sim 처럼 이벤트 영속) — 단 이벤트마다 DB write 하면 부하폭발이라 모아뒀다가\n // coalescer tick 에서 배치 기록(방송과 동일 주기). 히스토리 노브·타임라인·비즈니스 원장이 이 저널을 읽는다.\n ;(inst.pendingJournal ?? (inst.pendingJournal = [])).push(...envelopes)\n if (inst.metrics) { inst.metrics.ingestedTotal += envelopes.length; inst.metrics._accIngest += envelopes.length } // 계측(④-1)\n // 방송 병합(ingest-scale §1.1/§4.4) — apply 는 O(1)·싸다. 그러나 방송(snapshot O(state))은 비싸(대규모 5ms+)\n // 이벤트마다 방송하면 폭발 → dirty 만 찍고 coalescer tick 이 주기 방송(방송률 ≠ 인제스트률).\n inst.dirty = true\n this.ensureBroadcastCoalescer()\n }\n\n /** 방송 병합 주기(ms) — 방송률 상한. 인제스트가 아무리 빨라도 이 주기로만 방송. */\n static BROADCAST_COALESCE_MS = 200\n private static broadcastTimer?: any\n\n /** live 방송 coalescer — dirty 인 live 인스턴스만 주기적으로 1회 방송(entitySigs 로 변경 엔티티만). */\n private static ensureBroadcastCoalescer(): void {\n if (this.broadcastTimer) return\n this.broadcastTimer = setInterval(() => this.flushLiveBroadcasts(), this.BROADCAST_COALESCE_MS)\n if (typeof this.broadcastTimer.unref === 'function') this.broadcastTimer.unref() // 종료 비차단\n }\n\n /** dirty live 인스턴스 방송 flush(주기 tick 또는 명시 호출). 테스트/즉시 방송용으로 public. */\n static flushLiveBroadcasts(): void {\n let anyLive = false\n const now = Date.now()\n for (const inst of Object.values(this.instances)) {\n if (inst.mode !== 'live') continue\n anyLive = true\n // 처리량 계측(④-1) — 창(≥1s)마다 유입/방송/저널률 갱신. dirty 무관(유휴면 0으로 수렴). 부하를 읽는 신호.\n const m = inst.metrics\n if (m) {\n const dt = (now - m._windowStartMs) / 1000\n if (dt >= 1) {\n m.ingestRate = Math.round(m._accIngest / dt)\n m.broadcastRate = Math.round((m._accBroadcast / dt) * 10) / 10\n m.journalRate = Math.round(m._accJournal / dt)\n m._accIngest = 0; m._accBroadcast = 0; m._accJournal = 0; m._windowStartMs = now\n }\n }\n if (!inst.dirty) continue\n inst.dirty = false\n // ① 엔티티 data(tag) 방송 — 보드 컴포넌트 라이브 렌더.\n this.publishEntityData(inst)\n if (m) { m.broadcastTotal++; m._accBroadcast++ }\n // ③ 저널 배치 기록 — 모아둔 이벤트에 revision 부여해 벌크 저장(이벤트마다 write 아님).\n // revision 카운터는 인메모리(startLive 에서 저널 high-water 로 1회 시드) → tick 마다 DB 질의 없음.\n const batch = inst.pendingJournal\n if (batch?.length && inst.revision != null) {\n inst.pendingJournal = []\n const start = inst.revision\n inst.revision = start + batch.length\n if (m) { m.journaledTotal += batch.length; m._accJournal += batch.length; m.backlog = batch.length }\n this.persistBatch(inst.domainId, inst.id, batch, start).catch(err => console.error('twin live journal fail', err))\n }\n // ② State 채널 방송 — \"바뀌었다\"는 가벼운 신호만(kind+revision). 맵 구독(subscribeTwinState)은 이 신호에\n // scheduleRefresh(250ms 디바운스)→pollLive 로 되물어봄. 스냅샷(O(state))은 보는 사람이 물을 때만 1회 계산.\n // (여기서 payload 로 스냅샷을 실으면 아무도 안 읽는데 tick 마다 통째로 떠서 순수 낭비 — 신호만 보낸다.)\n pubsub.publish('twin-state', {\n twinState: { instanceId: inst.id, kind: 'delta', revision: inst.revision ?? 0 }\n })\n }\n if (!anyLive && this.broadcastTimer) { clearInterval(this.broadcastTimer); this.broadcastTimer = undefined } // live 없으면 tick 정지\n }\n\n /**\n * 저널 행 한 줄 — **기록 경로가 둘이라(라이브 벌크·심 단건) 행 모양은 반드시 한 곳에서 만든다.**\n * 두 곳에 각자 적으면 승격 검색 키가 한쪽에만 채워지고, 반쯤 빈 색인은 \"저널에는 있는데\n * 검색으로는 안 나오는 이벤트\" 를 만든다 — 저널에서 가장 나쁜 종류의 결함이다.\n */\n private static journalRow(repo: any, domainId: string, instanceId: string, e: any, revision: number) {\n return repo.create({\n domain: { id: domainId } as any,\n instanceId,\n tenantId: e?.tenantId,\n eventType: e?.eventType,\n revision,\n eventTime: e?.eventTime,\n ...twinEventKeys(e),\n payload: e\n })\n }\n\n /** live 저널 배치 기록 — 모아둔 CanonicalEnvelope 들에 startRevision+1.. 을 부여해 벌크 저장(coalescer tick 당 1회). */\n static async persistBatch(domainId: string, instanceId: string, envelopes: any[], startRevision: number): Promise<void> {\n const repo = getRepository(TwinEvent)\n const rows = envelopes.map((e, i) => this.journalRow(repo, domainId, instanceId, e, startRevision + i + 1))\n await repo.save(rows, { chunk: 500 })\n }\n\n /** 레지스트리 upsert(도메인+instanceId 유니크). status 인자로 provision(stopped)/start(running) 공용. */\n static async register(\n domainId: string,\n instanceId: string,\n kind: string,\n board: BoardDef,\n status: 'running' | 'stopped' = 'running',\n realityMode?: RealityMode\n ): Promise<void> {\n const repo = getRepository(TwinInstance)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n await repo.save(\n repo.create({\n ...(existing ?? {}),\n domain: { id: domainId } as any,\n instanceId,\n kind,\n board,\n // 인스턴스↔공간 1급 링크(space #3) — board.spaceId/areaId 를 컬럼으로 승격(dual-write). board JSON 도 유지(커널·복구용).\n spaceId: (board as any)?.spaceId ?? existing?.spaceId,\n areaId: (board as any)?.areaId ?? existing?.areaId,\n // 현실 출처 선언(§0 ①) — 명시값 우선, 없으면 기존값 보존(재프로비전이 선언을 지우지 않게).\n realityMode: realityMode ?? existing?.realityMode ?? undefined,\n status\n })\n )\n }\n\n /**\n * 라이브 구조 변이(resource.add 등)를 저장된 board 에 반영 — 런타임 커널의 무버를 registry board.movers 에 동기.\n * 이게 없으면 런타임엔 추가돼도(상태·저널엔 반영) 저장 board 는 원본이라 프로비저닝 편집기·재기동(loadBoard)이\n * 추가분을 잃는다. 기존 board.movers 항목은 보존(homeNode 유지)하고 새 id 만 append(추가 시점 location=homeNode).\n * 좌표(layout)만 다루는 register 와 달리 movers 집합을 갱신하나, 재프로비전(purge)이 아니라 in-place 갱신이라\n * 저널은 보존된다(추가는 이미 equipment 델타로 저널됨 → replay 는 id-keyed upsert 라 이중계산 없음).\n */\n static async syncBoardMovers(domainId: string, instanceId: string): Promise<void> {\n const inst = this.instances[instanceId]\n const snap = inst?.kernel?.getSnapshot?.()\n if (!snap?.movers) return\n const repo = getRepository(TwinInstance)\n const reg = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) return\n const board = reg.board as BoardDef\n const known = new Set((board.movers ?? []).map(m => m.id))\n const added = snap.movers\n .filter((m: any) => !known.has(m.id))\n .map((m: any) => ({ id: m.id, kind: m.kind, homeNode: m.location }))\n if (!added.length) return\n board.movers = [...(board.movers ?? []), ...added]\n reg.board = board\n await repo.save(reg)\n }\n\n /**\n * 프로비저닝 — 레지스트리에 구조(board)를 등록만 하고 기동하지 않음(status='stopped').\n * 재프로비전 시 구조 시그니처가 바뀌면(노드·무버 집합/속성 변경) 기존 저널을 purge 한다(ADR-0015):\n * board 는 replay 의 마스터라 구조가 바뀌면 과거 이벤트의 전제가 깨진다. 좌표(layout)만 바뀌면 저널 보존.\n */\n static async provision(domainId: string, instanceId: string, kind: string, board: BoardDef): Promise<void> {\n if (this.instances[instanceId]) throw new Error(`instance \"${instanceId}\" is running — stop before re-provisioning`)\n const repo = getRepository(TwinInstance)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n\n if (existing?.board && this.structureSignature(existing.board as BoardDef) !== this.structureSignature(board)) {\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n delete this.recovered[instanceId]\n }\n await this.register(domainId, instanceId, kind, board, existing?.status === 'running' ? 'stopped' : (existing?.status as any) ?? 'stopped')\n }\n\n /** 구조 동일성 지문 — 좌표(layout) 등 뷰 관심사는 제외하고 커널이 보는 위상·용량·무버만. */\n private static structureSignature(board: BoardDef): string {\n const nodes = [...(board.nodes ?? [])]\n .map(n => `${n.id}:${n.type}:${n.capacity}`)\n .sort()\n .join('|')\n const movers = [...(board.movers ?? [])]\n .map(m => `${m.id}:${m.kind}:${m.homeNode}`)\n .sort()\n .join('|')\n return `N[${nodes}]M[${movers}]`\n }\n\n /** 레지스트리 board 로 기동(프로비전된 인스턴스 start). board 인자 없이 저장된 구조로 재기동. */\n static async startFromRegistry(domainId: string, instanceId: string, realityMode?: RealityMode): Promise<InstanceRuntime> {\n if (this.instances[instanceId]) return this.instances[instanceId]\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) throw new Error(`instance \"${instanceId}\" not provisioned (no board)`)\n\n /*\n * 웜스타트 재료를 **여기서 확실히 확보한다.**\n * `start()` 는 동기라 스스로 캐시를 읽을 수 없어서 `recovered` 에 미리 담겨 있기를 기대하는데,\n * 그건 `bootstrap()` 이 먼저 돌았을 때만 참이다. 부팅 순서에 기대면 어떤 날은 재고가 살아나고\n * 어떤 날은 조용히 빈 채로 뜬다 — 재현되지 않는 결함이 가장 나쁘다.\n * 체크포인트 캐시 우선(O(1) + 라이브 파생상태 보존), 없으면 저널 replay 폴백(부팅과 같은 순서).\n */\n if (!this.recovered[instanceId] && reg.purpose !== 'bench') {\n const cached = await this.loadSnapshot(domainId, instanceId).catch(() => null)\n if (cached?.state) {\n this.recovered[instanceId] = { revision: cached.revision, state: cached.state }\n } else {\n const state = await this.recover(domainId, instanceId).catch(() => null)\n if (state) this.recovered[instanceId] = { revision: state.revision, state }\n }\n }\n\n return this.start(\n instanceId,\n domainId,\n reg.kind ?? 'wms',\n reg.board as BoardDef,\n realityMode ?? (reg.realityMode as RealityMode) ?? undefined,\n reg.purpose ?? undefined\n )\n }\n\n /**\n * 선언 기반 부팅(§0 프레임 ① → 부팅 거동 매핑) — 트윈이 선언한 realityMode 에 따라 재기동 방식을 가른다.\n * 부팅 경로를 한 곳에 모아 \"런타임 ≠ 현실\" 범주오류를 코드로 강제한다.\n * - 'mirror' : 현실=외부 실물 → startLive(재동기). 이벤트는 어댑터 ingest 로 유입, 커널 tick 없음.\n * - 'sim-world' : 생성 타임라인 지속 → 저널 보존 + resume(현실 이어감).\n * ⚠ GATE(§8 ②③): 커널 상태 직렬화/재개가 아직 없어 진짜 resume 불가 → 실 필요·실부하 시 구현.\n * 그때까지는 저널을 보존하되 revision 충돌을 피하려 fresh 로 기동하고, 선언과 구현의 간극을 크게 경고한다.\n * - 'sim-experiment' : seed 재현 → resetJournal + fresh 기동(백지 시작이 버그가 아니라 선언된 거동).\n * 반환: 기동된 InstanceRuntime.\n */\n static async bootDeclared(domainId: string, instanceId: string, mode: RealityMode = DEFAULT_REALITY_MODE): Promise<InstanceRuntime> {\n if (mode === 'mirror') {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) throw new Error(`instance \"${instanceId}\" not provisioned (no board)`)\n return this.startLive(instanceId, domainId, reg.kind ?? 'wms', reg.board as BoardDef)\n }\n if (mode === 'sim-world') {\n // 선언은 world(지속)지만 resume 기계장치(커널 상태 복원)가 아직 없다 → 정직하게 큰 경고 후 fresh 기동.\n console.warn(\n `[twin-engine] \"${instanceId}\" declared sim-world but resume is not yet implemented (runtime-state-model §8 gate ②③) — booting FRESH (journal reset). Persisted continuity will attach here once kernel-state resume lands.`\n )\n await this.resetJournal(domainId, instanceId)\n return this.startFromRegistry(domainId, instanceId, 'sim-world')\n }\n // sim-experiment(기본): seed 재현 — 저널 초기화 후 revision 0 부터 재실행.\n await this.resetJournal(domainId, instanceId)\n return this.startFromRegistry(domainId, instanceId, 'sim-experiment')\n }\n\n /**\n * 저널 초기화 — 인스턴스 이벤트 저널 purge(레지스트리·상태는 유지).\n * 데모 fresh-start 용: 매 부팅 seed 부터 새로 실행하는 데모에서, 복구본 폐기 후 revision 0 부터 재실행하면\n * 옛 런과 revision 이 겹쳐 저널이 오염된다 → start 전에 호출해 현재 런만 남긴다.\n */\n static async resetJournal(domainId: string, instanceId: string): Promise<void> {\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n delete this.recovered[instanceId]\n }\n\n /** 삭제 — 정지 + 레지스트리 삭제 + 저널 purge(domain 스코프). */\n static async remove(domainId: string, instanceId: string): Promise<void> {\n await this.stop(instanceId)\n delete this.recovered[instanceId]\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n await getRepository(TwinInstance).delete({ domain: { id: domainId } as any, instanceId })\n }\n\n /** 관리 목록 — domain 의 등록 인스턴스 전체(라이브 여부·최신 저널 revision·노드/무버 수 포함). */\n static async list(domainId: string): Promise<any[]> {\n const rows = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const out: any[] = []\n for (const r of rows) {\n const board = (r.board as BoardDef) ?? { nodes: [], movers: [] }\n const last = await getRepository(TwinEvent).findOne({\n where: { domain: { id: domainId } as any, instanceId: r.instanceId },\n order: { revision: 'DESC' }\n })\n out.push({\n instanceId: r.instanceId,\n kind: r.kind,\n status: r.status,\n spaceId: r.spaceId, // co-location: 같은 spaceId 인스턴스들이 한 공간(공장) 공유 — 공간뷰 집약 키(G7)\n realityMode: r.realityMode ?? DEFAULT_REALITY_MODE, // 현실 출처 선언(§0 ①) — mirror/sim-world/sim-experiment\n purpose: r.purpose ?? 'operational', // 운영 vs 벤치 사본(1급 구별 — 이름 접두사 아님)\n copyOf: r.copyOf ?? undefined,\n running: !!this.instances[r.instanceId],\n revision: last?.revision ?? 0,\n nodeCount: board.nodes?.length ?? 0,\n moverCount: board.movers?.length ?? 0\n })\n }\n return out\n }\n\n /** 레거시 벤치 잔재 가드 — purpose 도입 전 만들어진 벤치/부하 공간(이름 규약)까지 걸러낸다. */\n static isBenchSpace(spaceId?: string): boolean {\n return !!spaceId && (/^bench-/.test(spaceId) || spaceId === 'rosarito-load' || /^loadtest/.test(spaceId))\n }\n\n /** 운영 공간 목록(벤치 소스 선택기) — 이름·규모 포함, 벤치 사본·잔재 제외. */\n static async listSpaces(domainId: string): Promise<{ spaceId: string; name: string; instances: number; nodes: number; movers: number }[]> {\n const nameOf = new Map((await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })).map(s => [s.spaceId, s.name]))\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const agg = new Map<string, { spaceId: string; name: string; instances: number; nodes: number; movers: number }>()\n for (const r of insts) {\n if (!r.spaceId || r.purpose === 'bench' || this.isBenchSpace(r.spaceId)) continue // 벤치·잔재 제외\n const board: any = r.board ?? {}\n const a = agg.get(r.spaceId) ?? { spaceId: r.spaceId, name: nameOf.get(r.spaceId) ?? r.spaceId, instances: 0, nodes: 0, movers: 0 }\n a.instances++\n a.nodes += board.nodes?.length ?? 0\n a.movers += board.movers?.length ?? 0\n agg.set(r.spaceId, a)\n }\n return [...agg.values()]\n }\n\n /** 인스턴스 목적 표식(운영/벤치) 설정 — 벤치 사본을 1급 속성으로 구별(이름 접두사 아님). */\n static async setPurpose(domainId: string, instanceId: string, purpose: 'operational' | 'bench', copyOf?: string): Promise<void> {\n await getRepository(TwinInstance).update({ domain: { id: domainId } as any, instanceId }, { purpose, copyOf: copyOf ?? null } as any)\n }\n\n /**\n * 공간 구조 판독 — 완전복제(벤치 사본)의 소스. 저장물이 board(위상)·TwinSpace.content(치수·geo·표현)·TwinArea(영역)로\n * 분산돼 있으므로 셋을 모아 돌려준다. 호출측이 ReferenceMaster 로 재구성 → 재식별 → ingestMaster.\n */\n static async spaceStructure(domainId: string, spaceId: string): Promise<{ name?: string; content: any; areas: any[]; instances: { instanceId: string; kind?: string; board: any }[] } | null> {\n const sp = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n const areas = sp\n ? (await getRepository(TwinArea).find({ where: { domain: { id: domainId } as any, space: { id: sp.id } as any } })).map(a => ({ id: a.areaId, type: a.type, name: a.name, parentId: a.parentId, layout: a.layout }))\n : []\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n if (!insts.length) return null\n return { name: sp?.name, content: sp?.content ?? {}, areas, instances: insts.map(i => ({ instanceId: i.instanceId, kind: i.kind, board: i.board })) }\n }\n\n /** 공간(+표현·영역) 삭제 — 벤치 정리 등. 호출측이 바인딩 인스턴스를 먼저 제거하는 전제(가드 없음). deleteTwinSpace 리졸버와 동형. */\n static async deleteSpace(domainId: string, spaceId: string): Promise<void> {\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n if (space) {\n const reps = await getRepository(TwinSpaceRepresentation).find({ where: { domain: { id: domainId }, space: { id: space.id } } })\n for (const rep of reps) await getRepository(TwinSpaceArea).delete({ domain: { id: domainId } as any, representation: { id: rep.id } as any })\n await getRepository(TwinSpaceRepresentation).delete({ domain: { id: domainId } as any, space: { id: space.id } as any })\n await getRepository(TwinArea).delete({ domain: { id: domainId } as any, space: { id: space.id } as any })\n }\n await getRepository(TwinSpace).delete({ domain: { id: domainId } as any, spaceId })\n }\n\n /**\n * Face2 마스터 인제스트(ADR-0018) — 레퍼런스 시스템(실 또는 가상)의 마스터를 읽어 트윈을 생성.\n * 엔티티를 손배선/발명하지 않고 마스터에서 반영: 공간(Space) upsert + 인스턴스 provision(미기동).\n * 노드타입은 커널 카탈로그로 검증(warning). start 는 호출측(bootstrap/mutation)이 결정.\n */\n static async ingestMaster(domainId: string, master: ReferenceMaster): Promise<{ instanceId: string; spaceId: string; warnings: string[] }> {\n const { board, spaceContent, warnings } = masterToTwin(master, DOMAIN_CATALOG)\n const spaceId: string = board.spaceId\n const repo = getRepository(TwinSpace)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, spaceId } })\n /*\n * 공유 공간(여러 트윈이 한 spaceId, N:1) content 병합 — 마지막 인제스트가 통째로 덮어써 area(그룹)·표현이\n * 유실되던 문제 보정. area·landmark 는 id 합집합, representations 는 비어있지 않은 쪽 보존, 나머지는 first-wins.\n */\n const prev: any = existing?.content ?? {}\n const cur: any = spaceContent\n const unionById = (a: any[] = [], b: any[] = []) => {\n const m = new Map<string, any>()\n for (const x of [...a, ...b]) if (x?.id) m.set(x.id, x)\n return [...m.values()]\n }\n const mergedContent = {\n width: prev.width ?? cur.width,\n depth: prev.depth ?? cur.depth,\n unit: prev.unit ?? cur.unit,\n geo: prev.geo ?? cur.geo,\n primaryId: prev.primaryId ?? cur.primaryId,\n representations: (cur.representations?.length ? cur.representations : prev.representations) ?? [],\n // areas 는 content 에 더 이상 쓰지 않는다(area 단일화 P3) — 권위=TwinArea. 아래 TwinArea 로만 기록.\n landmarks: unionById(prev.landmarks, cur.landmarks)\n }\n const savedSpace = await repo.save(repo.create({ ...(existing ?? {}), domain: { id: domainId } as any, spaceId, name: existing?.name || master.siteName, content: mergedContent }))\n /*\n * 표현을 twin_space_representations 테이블에 저장한다 — 뷰(twin-map-page 등)는 content 가 아니라 테이블 표현을 소싱하므로,\n * 저장하지 않으면 인제스트 사이트에 \"대표 표현\" 이 없어 지도로 시작하지 못한다. rep.areas 가 있으면 TwinSpaceArea 도 함께 저장.\n * 최초 인제스트만(기존 표현 있으면 사용자 편집 보존).\n */\n const repRepo = getRepository(TwinSpaceRepresentation)\n const areaRepo = getRepository(TwinSpaceArea)\n if ((await repRepo.count({ where: { space: { id: savedSpace.id } } })) === 0) {\n const reps: any[] = (spaceContent as any).representations ?? []\n for (let i = 0; i < reps.length; i++) {\n const rep = reps[i]\n const config =\n rep.type === 'map' ? { center: rep.center, zoom: rep.zoom }\n : rep.type === 'board' ? { boardId: rep.boardId }\n : rep.type === 'image' ? { imageUrl: rep.imageUrl, width: rep.width, height: rep.height }\n : {}\n const savedRep = await repRepo.save(repRepo.create({ domain: { id: domainId } as any, space: { id: savedSpace.id } as any, type: rep.type, name: rep.name, seq: i, isPrimary: !!rep.primary || rep.id === (spaceContent as any).primaryId, config }))\n for (const area of (rep.areas ?? []) as any[]) {\n await areaRepo.save(areaRepo.create({ domain: { id: domainId } as any, representation: { id: savedRep.id } as any, name: area.name, type: area.type, geometry: area.geometry, drillTo: area.drillTo ?? null, binding: area.binding ?? null, style: area.style ?? null }))\n }\n }\n }\n /*\n * area 단일화(space #2, P1) — 논리 구역을 TwinArea(정규·표현무관·공유)에 dual-write(upsert by areaId).\n * P3: content.areas 저장 폐기 → TwinArea 가 유일 권위. 소스 = masterToTwin 산출 spaceContent.areas(cur).\n * (원천 diff 제거[master 에서 빠진 area 삭제]는 사용자저작 area 보호 위해 per-area provenance 필요 → 후속.)\n */\n const twinAreaRepo = getRepository(TwinArea)\n for (const a of ((spaceContent as any).areas ?? []) as any[]) {\n if (!a?.id) continue\n const existingArea = await twinAreaRepo.findOne({ where: { domain: { id: domainId }, space: { id: savedSpace.id }, areaId: a.id } })\n await twinAreaRepo.save(\n twinAreaRepo.create({\n ...(existingArea ?? {}),\n domain: { id: domainId } as any,\n space: { id: savedSpace.id } as any,\n areaId: a.id,\n name: a.name ?? a.id,\n type: a.type,\n parentId: a.parentId ?? null,\n layout: a.x != null || a.w != null ? { x: a.x, y: a.y, w: a.w, h: a.h } : null\n })\n )\n }\n\n await this.provision(domainId, master.source, master.system, board)\n if (warnings.length) console.warn(`[twin-engine] ingest \"${master.source}\" warnings:`, warnings)\n return { instanceId: master.source, spaceId, warnings }\n }\n\n /** 단건 상세 — 프로비저닝 에디터가 편집할 board(구조+layout) 포함. */\n static async detail(domainId: string, instanceId: string): Promise<any | null> {\n const r = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!r) return null\n return {\n instanceId: r.instanceId,\n kind: r.kind,\n status: r.status,\n running: !!this.instances[r.instanceId],\n realityMode: r.realityMode, // 현실 선언 — what-if 적용 가드용(mirror=예측 전용, 자극 주입 불가)\n board: r.board\n }\n }\n\n /**\n * 라이브 바인딩 브리지(P3, ADR-0018) — 트윈 엔티티 상태를 `data(tag=엔티티id)` 채널로 publish.\n * 보드 컴포넌트가 tag 로 구독(board-ui provider)해 `component.data` 로 라이브 갱신. delta 시에만(희소).\n * tag=엔티티 id(데모=단일 인스턴스). 멀티 인스턴스/보드 재사용 시 tag 네임스페이스는 후속.\n */\n static publishEntityData(inst: InstanceRuntime): void {\n const domain = inst.domain\n if (!domain) return\n /* 상태 출처 스왑 — sim: 커널 runtime, live: projector 미러(+OEE 계산 층 보강). 계약·payload 동일, 드라이버만 다름. */\n const st: any =\n inst.mode === 'live'\n ? inst.oee\n ? withLiveOee(inst.projector?.snapshot?.(), inst.oee) // 관측 미러 + 계산(OEE) → mover payload 에 oee 포함(sim 동형)\n : inst.projector?.snapshot?.()\n : inst.runtime?.resync?.()?.state\n if (!st) return\n /*\n * 변화한 엔티티만 발행 — 이전엔 delta 마다 전 엔티티(노드+무버+오더)를 값 변화와 무관하게 전량 재발행해\n * 같은 데이터를 매초 반복 push 하고 있었다(오용). 최신-상태 채널이므로 무변화 재방송은 무의미하다.\n * 엔티티별 시그니처를 비교해 바뀐 것만 push.\n */\n const sigs = inst.entitySigs ?? (inst.entitySigs = new Map())\n const seen = new Set<string>()\n /* payload 매핑은 순수 함수(buildEntityDeltas)로 분리 — 여기선 시그니처 dedup + 발행만.\n * 변화한 엔티티만 발행(최신-상태 채널이라 무변화 재방송 무의미). */\n for (const { tag, data } of buildEntityDeltas(st)) {\n seen.add(tag)\n const sig = JSON.stringify(data)\n if (sigs.get(tag) === sig) continue // 무변화 → 발행 생략\n sigs.set(tag, sig)\n pubsub.publish('data', { data: { domain, tag, data } })\n }\n /* 사라진 엔티티의 시그니처 정리(맵 무한 성장 방지). */\n if (sigs.size > seen.size) for (const tag of sigs.keys()) if (!seen.has(tag)) sigs.delete(tag)\n }\n\n static async persist(domainId: string, instanceId: string, msg: any): Promise<void> {\n const repo = getRepository(TwinEvent)\n await repo.save(this.journalRow(repo, domainId, instanceId, msg.event, msg.revision))\n }\n\n /**\n * 재부팅 복구 / 시간여행 — DB 저널을 replay 해 상태 재구성.\n * board 는 레지스트리(TwinInstance)에서, 이벤트는 TwinEvent(revision ASC)에서.\n * 커서 두 축(runtime-state-model §4): **시각(untilTime, 사용자 모국어·공간 공통축)** 우선, 없으면 리비전(untilRevision, 렌즈 내부).\n * - untilTime 주면 `eventTime ≤ T` 인 이벤트만(그 시점 watermark) — 공동배치 여러 트윈을 하나의 시각 T로 통일 해소.\n * - 둘 다 없으면 최신(라이브 인메모리 진실).\n * 이벤트는 항상 revision ASC(인과 순서)로 적용 — 시각 필터는 컷오프 집합만 정한다.\n */\n static async recover(domainId: string, instanceId: string, untilRevision?: number, untilTime?: string): Promise<any> {\n // 라이브 최신(시간여행 아님) + 인메모리 인스턴스 → 라이브 커널 스냅샷을 직접 사용.\n // replay(StateProjector)는 attentions·ack 등 라이브 전용 파생 상태를 담지 못하므로, 최신은 커널 진실을 쓴다.\n if (untilRevision == null && untilTime == null) {\n const live = this.instances[instanceId]\n if (live?.kernel?.getSnapshot) return live.kernel.getSnapshot()\n // live 모드는 kernel 이 없고 projector 미러 → 인메모리 최신 스냅샷(projector+OEE+attentions) 직접 사용.\n // (저널이 있어도 최신은 인메모리가 진실 — replay 는 시간여행/복구 전용.)\n if (live?.mode === 'live' && live.projector) return this.snapshot(instanceId)\n }\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) throw new Error(`twin instance \"${instanceId}\" not registered (no board to replay)`)\n\n const rows = await getRepository(TwinEvent).find({\n where: { domain: { id: domainId }, instanceId },\n order: { revision: 'ASC' }\n })\n const cutoffMs = untilTime != null ? Date.parse(untilTime) : NaN\n const events = rows\n .filter(r => {\n if (untilTime != null && !Number.isNaN(cutoffMs)) {\n const t = r.eventTime != null ? Date.parse(String(r.eventTime)) : NaN\n return Number.isNaN(t) ? true : t <= cutoffMs // eventTime 없는 레거시 행은 포함(보수적)\n }\n return untilRevision == null || (r.revision ?? 0) <= untilRevision\n })\n .map(r => r.payload)\n .filter(Boolean)\n\n return replay(reg.board as BoardDef, events)\n }\n\n /**\n * 공간(공동배치) 시각 범위 — 스크러버 앵커(runtime-state-model §4·§6). 그 공간 전 인스턴스 저널의 min/max eventTime.\n * 반환 {minTime, maxTime}(ISO) — 이벤트/시각 없으면 null. 클라 히스토리 스크러버가 이 범위를 시각축으로 그린다.\n */\n static async timeRange(domainId: string, spaceId: string): Promise<{ minTime: string | null; maxTime: string | null }> {\n const regs = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n const ids = regs.map(r => r.instanceId)\n if (!ids.length) return { minTime: null, maxTime: null }\n let min = Infinity\n let max = -Infinity\n for (const instanceId of ids) {\n const rows = await getRepository(TwinEvent).find({ where: { domain: { id: domainId }, instanceId } })\n for (const r of rows) {\n const t = r.eventTime != null ? Date.parse(String(r.eventTime)) : NaN\n if (Number.isNaN(t)) continue\n if (t < min) min = t\n if (t > max) max = t\n }\n }\n if (min === Infinity) return { minTime: null, maxTime: null }\n return { minTime: new Date(min).toISOString(), maxTime: new Date(max).toISOString() }\n }\n\n /** 정지 훅 — 인스턴스 정지 시 부수자원 정리(예: reference-live 피드 unsubscribe). 순환 임포트 없이 결선. */\n static stopHooks: ((id: string) => void)[] = []\n static onStop(fn: (id: string) => void): void {\n this.stopHooks.push(fn)\n }\n\n static async stop(id: string): Promise<void> {\n const i = this.instances[id]\n if (i) {\n clearInterval(i.timer)\n i.unsub()\n delete this.instances[id]\n await getRepository(TwinInstance)\n .update({ domain: { id: i.domainId }, instanceId: id }, { status: 'stopped' })\n .catch(err => console.error('twin deregister fail', err))\n }\n for (const hook of this.stopHooks) { try { hook(id) } catch { /* 훅 격리 */ } }\n }\n\n static runtime(id: string): TwinRuntimeType | undefined {\n return this.instances[id]?.runtime\n }\n\n /**\n * 도메인 소유 게이트 — 인스턴스가 이 도메인 소유일 때만 true(테넌트 격리).\n * 없거나 다른 도메인이면 false. 노출 리졸버(per-id metrics/attentions/state/stop/forecast)가\n * this.instances[id] 를 만지기 전에 반드시 이걸로 확인해야 한다. 인스턴스 id 는 추측 가능하므로\n * 검증 없이 접근하면 크로스테넌트 읽기/정지가 가능해진다.\n */\n static owns(domainId: string, id: string): boolean {\n return this.instances[id]?.domainId === domainId\n }\n\n /** 라이브 커널(ForecastTwin) — forecast/divergence 예측 연산용. */\n static kernel(id: string): any {\n return this.instances[id]?.kernel\n }\n\n /** 라이브 처리량 계측 스냅샷(모니터, ④-1) — 내부 누적(_acc*) 제외한 공개 지표. live 아니면 null. */\n static metrics(id: string): any {\n const m = this.instances[id]?.metrics\n if (!m) return null\n return {\n instanceId: id,\n ingestedTotal: m.ingestedTotal, broadcastTotal: m.broadcastTotal, journaledTotal: m.journaledTotal,\n ingestRate: m.ingestRate, broadcastRate: m.broadcastRate, journalRate: m.journalRate,\n backlog: m.backlog, broadcastCoalesceMs: this.BROADCAST_COALESCE_MS\n }\n }\n\n /** 전체 라이브 인스턴스 계측(모니터 대시보드용). */\n static async allMetrics(domainId?: string): Promise<any[]> {\n const rows = Object.keys(this.instances)\n .filter(id => !domainId || this.instances[id].domainId === domainId)\n .map(id => this.metrics(id))\n .filter(Boolean)\n if (!rows.length || !domainId) return rows\n // 표시 이름 부여 — 실행중 카드가 id 만 보이지 않도록 공간명을 실어준다(공간 카드와 동일). name=공간명 폴백 spaceId 폴백 instanceId.\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const spaceOf = new Map(insts.map(i => [i.instanceId, i.spaceId]))\n const nameOf = new Map((await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })).map(s => [s.spaceId, s.name]))\n for (const r of rows) {\n const sp = spaceOf.get(r.instanceId)\n r.spaceId = sp\n r.name = (sp && nameOf.get(sp)) || sp || r.instanceId\n }\n return rows\n }\n\n /**\n * 라이브 예측용 임시 커널(kernel-unification P1) — 라이브는 projector 미러라 커널이 없어 예측을 못 한다.\n * 관측 스냅샷(재고·무버·노드) + 저널의 오더 원값·라인을 hydrate 해 예측 가능한 임시 커널을 만든다.\n * 라이브 런타임은 무간섭(이 커널은 fork 대상 임시본, instances 에 넣지 않음). sim 인스턴스면 null(그쪽은 kernel() 사용).\n */\n static async buildForecastKernel(domainId: string, instanceId: string): Promise<any | null> {\n const inst = this.instances[instanceId]\n if (inst?.mode !== 'live' || !inst.projector) return null\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) return null\n const Kernel = KERNELS[reg.kind ?? 'wms'] ?? WmsKernel\n const k = new Kernel(domainId)\n k.loadBoard(reg.board as BoardDef)\n // 저널에서 오더별 최신 관측(원값+라인) 수집 — projector 스냅샷은 오더에 손실적(progress 만)이라 저널을 쓴다.\n const rows = await getRepository(TwinEvent).find({ where: { domain: { id: domainId }, instanceId, eventType: OP_EVENT.order }, order: { revision: 'ASC' } })\n const latest = new Map<string, any>()\n for (const r of rows) { const d = (r.payload as any)?.data; if (d?.orderId) latest.set(d.orderId, d) }\n k.hydrateObserved(this.snapshot(instanceId), [...latest.values()])\n return k\n }\n\n /**\n * 예측용 커널을 **임의 시각 T 기준**으로 재구성 — 과거-vantage 예측(백테스트)·\"그때 서서 본 미래\".\n * recover(untilTime)로 T 시점 상태를, T 이하 오더 관측을 모아 hydrate → monteCarloForecast 가 T 에서 앞으로 굴린다.\n * sim/live 무관(저널 기반 재구성). untilTime 생략 시 최신. 도메인 스코프(reg·journal 조회가 domainId).\n */\n static async buildForecastKernelAt(domainId: string, instanceId: string, untilTime?: string): Promise<any | null> {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) return null\n const Kernel = KERNELS[reg.kind ?? 'wms'] ?? WmsKernel\n const k = new Kernel(domainId)\n k.loadBoard(reg.board as BoardDef)\n const state = await this.recover(domainId, instanceId, undefined, untilTime).catch(() => null)\n if (!state) return null\n const cutoff = untilTime != null ? Date.parse(untilTime) : Infinity\n const rows = await getRepository(TwinEvent).find({ where: { domain: { id: domainId }, instanceId, eventType: OP_EVENT.order }, order: { revision: 'ASC' } })\n const latest = new Map<string, any>()\n for (const r of rows) {\n if (Number.isFinite(cutoff) && Date.parse(r.eventTime) > cutoff) continue\n const d = (r.payload as any)?.data\n if (d?.orderId) latest.set(d.orderId, d)\n }\n k.hydrateObserved(state, [...latest.values()])\n return k\n }\n\n /** 현재 전체 스냅샷 — 라이브 우선, 없으면 저널 복구 캐시. */\n static snapshot(id: string): any {\n const inst = this.instances[id]\n if (inst?.mode === 'live' && inst.projector) {\n // live: projector 미러 + 계산 층(OEE·attentions) 보강 → 질의(attention 등)가 sim 동형 스냅샷을 봄.\n const st = inst.oee ? withLiveOee(inst.projector.snapshot(), inst.oee) : inst.projector.snapshot()\n return withLiveAttentions(st)\n }\n return inst?.runtime?.resync() ?? this.recovered[id]\n }\n}\n"]}