@things-factory/headless-twin 10.0.7 → 10.0.9
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.
- package/dist-server/engine/attention-digest.d.ts +52 -0
- package/dist-server/engine/attention-digest.js +76 -0
- package/dist-server/engine/attention-digest.js.map +1 -0
- package/dist-server/engine/board-vocabulary.d.ts +17 -0
- package/dist-server/engine/board-vocabulary.js +63 -0
- package/dist-server/engine/board-vocabulary.js.map +1 -0
- package/dist-server/engine/command-routing.d.ts +33 -0
- package/dist-server/engine/command-routing.js +53 -0
- package/dist-server/engine/command-routing.js.map +1 -0
- package/dist-server/engine/entity-delta.d.ts +13 -6
- package/dist-server/engine/entity-delta.js +38 -12
- package/dist-server/engine/entity-delta.js.map +1 -1
- package/dist-server/engine/index.d.ts +6 -0
- package/dist-server/engine/index.js +10 -0
- package/dist-server/engine/index.js.map +1 -1
- package/dist-server/engine/kpi-baseline.d.ts +78 -0
- package/dist-server/engine/kpi-baseline.js +123 -0
- package/dist-server/engine/kpi-baseline.js.map +1 -0
- package/dist-server/engine/kpi-broadcast.d.ts +4 -0
- package/dist-server/engine/kpi-broadcast.js +16 -0
- package/dist-server/engine/kpi-broadcast.js.map +1 -0
- package/dist-server/engine/kpi-query.d.ts +31 -0
- package/dist-server/engine/kpi-query.js +50 -2
- package/dist-server/engine/kpi-query.js.map +1 -1
- package/dist-server/engine/live-attentions.d.ts +1 -0
- package/dist-server/engine/live-attentions.js +7 -1
- package/dist-server/engine/live-attentions.js.map +1 -1
- package/dist-server/engine/runtime-key.d.ts +15 -0
- package/dist-server/engine/runtime-key.js +64 -0
- package/dist-server/engine/runtime-key.js.map +1 -0
- package/dist-server/engine/state-axes.d.ts +16 -0
- package/dist-server/engine/state-axes.js +54 -0
- package/dist-server/engine/state-axes.js.map +1 -0
- package/dist-server/engine/twin-engine.d.ts +92 -16
- package/dist-server/engine/twin-engine.js +335 -77
- package/dist-server/engine/twin-engine.js.map +1 -1
- package/dist-server/engine/twin-level.d.ts +23 -0
- package/dist-server/engine/twin-level.js +52 -0
- package/dist-server/engine/twin-level.js.map +1 -0
- package/dist-server/engine/warm-start.d.ts +58 -12
- package/dist-server/engine/warm-start.js +80 -9
- package/dist-server/engine/warm-start.js.map +1 -1
- package/dist-server/service/reference/discovery-result.d.ts +34 -0
- package/dist-server/service/reference/discovery-result.js +84 -0
- package/dist-server/service/reference/discovery-result.js.map +1 -0
- package/dist-server/service/reference/ingest-space.d.ts +30 -0
- package/dist-server/service/reference/ingest-space.js +63 -0
- package/dist-server/service/reference/ingest-space.js.map +1 -0
- package/dist-server/service/reference/knob-defaults.d.ts +20 -0
- package/dist-server/service/reference/knob-defaults.js +59 -0
- package/dist-server/service/reference/knob-defaults.js.map +1 -0
- package/dist-server/service/reference/reference-live.js +2 -2
- package/dist-server/service/reference/reference-live.js.map +1 -1
- package/dist-server/service/reference/reference-master.d.ts +37 -2
- package/dist-server/service/reference/reference-master.js +55 -5
- package/dist-server/service/reference/reference-master.js.map +1 -1
- package/dist-server/service/reference/reference-resolver.d.ts +2 -2
- package/dist-server/service/reference/reference-resolver.js +71 -15
- package/dist-server/service/reference/reference-resolver.js.map +1 -1
- package/dist-server/service/twin-attention/twin-attention-query.d.ts +8 -1
- package/dist-server/service/twin-attention/twin-attention-query.js +39 -8
- package/dist-server/service/twin-attention/twin-attention-query.js.map +1 -1
- package/dist-server/service/twin-control/twin-control-mutation.d.ts +2 -0
- package/dist-server/service/twin-control/twin-control-mutation.js +29 -10
- package/dist-server/service/twin-control/twin-control-mutation.js.map +1 -1
- package/dist-server/service/twin-forecast/twin-forecast-query.js +2 -1
- package/dist-server/service/twin-forecast/twin-forecast-query.js.map +1 -1
- package/dist-server/service/twin-instance/twin-instance.js +4 -2
- package/dist-server/service/twin-instance/twin-instance.js.map +1 -1
- package/dist-server/service/twin-journal/twin-journal-query.d.ts +6 -2
- package/dist-server/service/twin-journal/twin-journal-query.js +25 -7
- package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.d.ts +8 -0
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js +23 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +1 -1
- package/dist-server/service/twin-metrics/twin-metrics-query.js +1 -1
- package/dist-server/service/twin-metrics/twin-metrics-query.js.map +1 -1
- package/dist-server/service/twin-space/twin-space-resolver.js +9 -0
- package/dist-server/service/twin-space/twin-space-resolver.js.map +1 -1
- package/dist-server/service/twin-state/twin-state-subscription.js +1 -1
- package/dist-server/service/twin-state/twin-state-subscription.js.map +1 -1
- package/dist-server/service/twin-structure/twin-structure.js +2 -1
- package/dist-server/service/twin-structure/twin-structure.js.map +1 -1
- package/dist-server/service/twin-target/twin-target-resolver.js +21 -4
- package/dist-server/service/twin-target/twin-target-resolver.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/server/engine/attention-digest.ts +102 -0
- package/server/engine/board-vocabulary.ts +61 -0
- package/server/engine/command-routing.ts +67 -0
- package/server/engine/entity-delta.ts +33 -11
- package/server/engine/index.ts +10 -0
- package/server/engine/kpi-baseline.ts +202 -0
- package/server/engine/kpi-broadcast.ts +13 -0
- package/server/engine/kpi-query.ts +81 -3
- package/server/engine/live-attentions.ts +7 -2
- package/server/engine/runtime-key.ts +58 -0
- package/server/engine/state-axes.ts +55 -0
- package/server/engine/twin-engine.ts +350 -77
- package/server/engine/twin-level.ts +48 -0
- package/server/engine/warm-start.ts +130 -16
- package/server/service/reference/discovery-result.ts +95 -0
- package/server/service/reference/ingest-space.ts +70 -0
- package/server/service/reference/knob-defaults.ts +59 -0
- package/server/service/reference/reference-live.ts +2 -2
- package/server/service/reference/reference-master.ts +94 -8
- package/server/service/reference/reference-resolver.ts +80 -16
- package/server/service/twin-attention/twin-attention-query.ts +43 -6
- package/server/service/twin-control/twin-control-mutation.ts +31 -12
- package/server/service/twin-forecast/twin-forecast-query.ts +3 -2
- package/server/service/twin-instance/twin-instance.ts +6 -2
- package/server/service/twin-journal/twin-journal-query.ts +35 -5
- package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +18 -2
- package/server/service/twin-metrics/twin-metrics-query.ts +1 -1
- package/server/service/twin-space/twin-space-resolver.ts +10 -1
- package/server/service/twin-state/twin-state-subscription.ts +1 -1
- package/server/service/twin-structure/twin-structure.ts +4 -1
- package/server/service/twin-target/twin-target-resolver.ts +22 -4
- package/test/attention-digest.test.ts +135 -0
- package/test/board-vocabulary.test.ts +114 -0
- package/test/capability-mapping.test.ts +4 -4
- package/test/command-routing.test.ts +61 -0
- package/test/discovery-result.test.ts +75 -0
- package/test/entity-delta.test.ts +25 -25
- package/test/ingest-bench.test.ts +3 -3
- package/test/ingest-space.test.ts +50 -0
- package/test/knob-defaults.test.ts +72 -0
- package/test/kpi-baseline-db.test.ts +214 -0
- package/test/kpi-baseline.test.ts +196 -0
- package/test/kpi-query-bench.test.ts +128 -0
- package/test/live-mirror-parity.test.ts +35 -2
- package/test/master-to-twin.test.ts +7 -3
- package/test/mutation-gate.test.ts +108 -0
- package/test/oee-accumulator.test.ts +65 -1
- package/test/registry-key-guard.test.ts +80 -0
- package/test/runtime-key.test.ts +66 -0
- package/test/scale-twin-bench.test.ts +2 -2
- package/test/state-axes.test.ts +74 -0
- package/test/streamline-e2e.test.ts +2 -2
- package/test/structure-revision-db.test.ts +5 -4
- package/test/tenant-registry-db.test.ts +149 -0
- package/test/warm-start-seam.test.ts +140 -0
- package/test/warm-start.test.ts +138 -4
|
@@ -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) 회피). (vocabulary-guard: allow — Node 런타임 버전 표기)\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 { TwinStructure } from '../service/twin-structure/twin-structure.js'\nimport { TwinSpace } from '../service/twin-space/twin-space.js'\nimport { utcOffsetOf } from '../service/reference/reference-master.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 { buildTravelEstimator, chainEstimators } from './travel-estimator.js'\nimport { buildMeasuredEstimator } from './measured-estimator.js'\nimport { describeModelBasis, type ModelBasis } from './model-basis.js'\nimport { computeTwinKpi } from './kpi-query.js'\nimport { createHash } from 'node:crypto'\n\nimport { buildEntityDeltas } from './entity-delta.js'\nimport { diffStructures, type StructureDiff } from './structure-diff.js'\nimport { OeeAccumulator, withLiveOee } from './oee-accumulator.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, replaySegments, 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 /**\n * live 의 상태 접근 어댑터 — 이제 **관측 모드 커널**을 가리킨다(`kernel` 과 같은 것).\n * 이름은 소비처 호환으로 남았고, P3 에서 커널 어휘로 정리하면 사라진다.\n */\n projector?: any\n oee?: OeeAccumulator // live: OEE 계산 층(이벤트 누적 → equipment 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.equipmentCount} equipment restored. ` +\n 'Open orders are not restored (the snapshot carries no requested/fulfilled counts).'\n )\n }\n\n /** 트윈 인스턴스 시작 — 커널 생성 + 보드 로드 + 직전 상태 웜스타트 + State 스트림 브리지 + 워커 tick + 레지스트리 영속. */\n /**\n * 공정 명세를 커널에 싣는다 — **시뮬레이션의 시간을 데이터가 말하게 하는 마지막 한 칸.**\n *\n * `board.operations`(마스터 인제스트가 통과시킨 ISA-95 OperationsSegment 명세)를 커널이 소비한다.\n * 없으면 커널 기본 상수로 굴러가고, 커널 `specCoverage()` 가 무엇을 기본값으로 썼는지 보고한다.\n *\n * 커널이 아직 이 API 를 갖지 않은 버전이면(발행 이전) **조용히 넘어가지 않고 경고한다** — 명세를\n * 선언했는데 반영되지 않는 상태를 모르고 지나가면, 예측이 상수로 돌아간 것을 아무도 알 수 없다.\n */\n private static applyOperations(kernel: any, board: any, id: string): void {\n const ops = board?.operations\n if (!ops?.length) return\n if (typeof kernel?.loadOperations !== 'function') {\n console.warn(`[twin-engine] \"${id}\": board declares ${ops.length} operation spec(s) but the kernel cannot consume them (loadOperations missing — kernel needs publishing). Simulation will use built-in default durations.`)\n return\n }\n kernel.loadOperations(ops)\n }\n\n /**\n * 소요시간 추정기 주입 — **상수를 데이터로 바꾸는 두 번째·세 번째 층.**\n *\n * 커널 `durationOf` 의 우선순위는 추정기 > 명세 > 상수다. 그 추정기 자리에 두 가지를 사슬로 넣는다:\n * ① **실측**(저널의 작업 종류별 작업시간 p50) — 그 현장에서 실제로 얼마 걸렸나. 가장 강한 근거.\n * ② **거리 × 속도**(board.layout + 설비 속도 속성) — 이동은 거리에 비례한다. 커널은 좌표를 모르므로\n * 호스트가 계산해 넣는다.\n * 둘 다 못 만들면 주입하지 않는다 — 커널이 명세·상수로 굴러가고 `specCoverage()` 가 그 사실을 남긴다.\n *\n * 실측은 DB 조회라 비동기다. 그래서 이 함수는 **await 하지 않는 쪽에서도 안전**하도록 실패를 삼키되,\n * 무엇을 왜 못 넣었는지는 로그로 남긴다(조용한 무효화 금지).\n */\n static async installEstimators(kernel: any, domainId: string, instanceId: string, board: any): Promise<void> {\n if (!kernel || typeof kernel !== 'object') return\n const travel = buildTravelEstimator({ layout: board?.layout, equipment: board?.equipment, unit: board?.unit })\n const measured = await this.measuredEstimator(domainId, instanceId)\n const chained = chainEstimators([measured?.estimator, travel.estimator])\n if (!chained) {\n /* 왜 못 넣었는지 한 번만 알린다 — 이동시간이 상수로 남은 이유를 모르고 지나가지 않게. */\n if (travel.reasons.length) console.warn(`[twin-engine] \"${instanceId}\": no duration estimator installed — ${travel.reasons.join('; ')}`)\n return\n }\n kernel.durationEstimator = chained\n const learned = Object.keys(measured?.learned ?? {})\n const spread = Object.keys(measured?.spreads ?? {})\n console.log(\n `[twin-engine] \"${instanceId}\": duration estimator installed — measured kinds: ${learned.length ? learned.join(',') : 'none'}` +\n ` (with observed spread: ${spread.length ? spread.join(',') : 'none'})` +\n `${travel.estimator ? `, travel from distance (speeds: ${Object.keys(travel.speedsByKind).join(',')})` : `, travel not derived (${travel.reasons.join('; ')})`}`\n )\n }\n\n /**\n * 실측 추정기 — **예측 요청마다 저널을 다시 접지 않는다.**\n *\n * 예측 커널은 요청마다 새로 세워지고(미러 예측·백테스트), 화면은 시각을 긁으면 계속 재예측한다.\n * 거기에 KPI 조회를 그대로 달면 요청당 저널 스캔이 하나씩 붙는다 — 실측은 분 단위로 바뀌지 않으므로\n * 짧은 TTL 로 재사용한다. 캐시는 인스턴스별이고, 만료 전에는 같은 값을 쓴다(예측 간 일관성도 얻는다).\n */\n private static measuredCache = new Map<string, { at: number; value: ReturnType<typeof buildMeasuredEstimator> | undefined }>()\n private static readonly MEASURED_TTL_MS = 60_000\n\n private static async measuredEstimator(domainId: string, instanceId: string) {\n const key = `${domainId}:${instanceId}`\n const hit = this.measuredCache.get(key)\n if (hit && Date.now() - hit.at < this.MEASURED_TTL_MS) return hit.value\n let value: ReturnType<typeof buildMeasuredEstimator> | undefined\n try {\n /* 작업 종류별 실측 — 창은 넉넉히(하루) 두고 표본이 모자란 종류는 추정기가 스스로 뺀다. */\n const kpi: any = await computeTwinKpi({ domainId, instanceId, windowMinutes: 24 * 60, groupBy: 'taskKind' })\n value = buildMeasuredEstimator(kpi?.groups?.items, {})\n } catch (err) {\n console.warn(`[twin-engine] \"${instanceId}\": measured duration lookup failed — falling back to declared/default durations.`, (err as any)?.message)\n }\n this.measuredCache.set(key, { at: Date.now(), value })\n return value\n }\n\n /**\n * 지금 이 트윈이 어떤 모델로 굴러가는가 — 예측 출력 보정이 **자기가 배운 모델**에만 적용되도록\n * 비교하는 지문. 재료는 호스트가 아는 것(실측·속도·선언 명세)이라 커널 발행 상태와 무관하다.\n * 실패하면 undefined — 그때는 비교를 하지 않는다(모르는 것을 근거로 보정을 끊지 않는다).\n */\n static async modelBasis(domainId: string, instanceId: string): Promise<ModelBasis | undefined> {\n try {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n const board: any = reg?.board\n const measured = await this.measuredEstimator(domainId, instanceId)\n const travel = buildTravelEstimator({ layout: board?.layout, equipment: board?.equipment, unit: board?.unit })\n return { measured: measured?.learned, speeds: travel.speedsByKind, declared: board?.operations }\n } catch {\n return undefined\n }\n }\n\n /**\n * **이 트윈이 하루 몇 대를 낼 수 있는가** — 굴려 보지 않고 답한다.\n *\n * 계산은 커널이 자기 상태에서 한다(`kernel.capacity`). 여기서 하는 일은 **기준 주를 정해 주는\n * 것**뿐이다: 공휴일이 없는 평상주여야 한다 — 공휴일은 연간 가용량을 따로 깎지, 이 공장의 평상시\n * 천장을 정하지 않는다. 커널이 임의로 고르게 두면 그 주에 공휴일이 끼었을 때 천장이 조용히 낮아진다.\n *\n * 트윈이 안 떠 있으면 `undefined` 다 — 0 이 아니다. 안 뜬 트윈의 천장을 0 이라고 답하면 화면은\n * \"이 공장은 아무것도 못 만든다\" 고 말한다.\n */\n static async capacity(\n domainId: string,\n target: { instanceId?: string; spaceId?: string },\n unitsPerDay: number,\n sampleWeekStartMs: number\n ): Promise<{ instanceId: string; kind?: string; analysis?: any; reason?: 'not-running' | 'no-operations' }[]> {\n /* 대상은 **등록부**가 정한다 — 떠 있는 런타임만 훑으면 \"안 떠 있어서 안 보이는 것\" 과 \"없는 것\" 이\n 구별되지 않는다. 화면은 그 둘을 다르게 말해야 한다. */\n const where: any = { domain: { id: domainId } }\n if (target.instanceId) where.instanceId = target.instanceId\n else where.spaceId = target.spaceId\n const registered = await getRepository(TwinInstance).find({ where })\n\n return registered.map(reg => {\n const rt = this.instances[reg.instanceId]\n const kernel: any = rt?.domainId === domainId ? rt.kernel : undefined\n if (typeof kernel?.capacity !== 'function') return { instanceId: reg.instanceId, kind: reg.kind, reason: 'not-running' as const }\n\n const analysis = kernel.capacity({ unitsPerDay, sampleWeekStartMs })\n /* 공정을 선언하지 않은 트윈(대개 YMS·WMS)은 **판정 대상이 아니다.** 0 으로 채워 넣으면\n \"야드가 병목\" 이라는 없는 사실이 생긴다 — 잴 것이 없다고 말한다. */\n if (!analysis?.operations?.length) return { instanceId: reg.instanceId, kind: reg.kind, reason: 'no-operations' as const }\n return { instanceId: reg.instanceId, kind: reg.kind, analysis }\n })\n }\n\n static start(id: string, domainId: string, kind: string, board: BoardDef, realityMode?: RealityMode, purpose?: string, resumeFrom?: number): InstanceRuntime {\n if (this.instances[id]) return this.instances[id]\n\n const Kernel = KERNELS[kind] ?? WmsKernel\n const kernel: TwinKernel = new Kernel(domainId, undefined, this.mesSpecOf(board))\n kernel.loadBoard(board) // 구조만. 상태는 아래 웜스타트가 심는다.\n this.applyOperations(kernel, board, id) // 시간·수율 명세(있으면) — 없으면 커널 기본값\n /* 추정기는 DB 조회를 포함해 비동기 — 기동을 막지 않고 붙는다(붙기 전 작업은 명세·상수로 산출). */\n this.installEstimators(kernel, domainId, id, board).catch(err => console.warn('[twin-engine] estimator install failed', err?.message))\n this.warmStart(id, kernel, purpose)\n /*\n * **번호를 이어 센다** — 저널에 이미 있는 번호와 겹치지 않게.\n *\n * 저널이 비어 있으면(0) 아무 일도 안 한다. 비어 있지 않은데 0부터 다시 세면 같은 트윈에 같은\n * 리비전이 둘 생기고, 재생 순서가 뒤섞이며, 시간여행이 엉뚱한 시점을 답한다 — 오류는 안 난다.\n */\n if (resumeFrom && typeof (kernel as any).resumeRevision === 'function') (kernel as any).resumeRevision(resumeFrom)\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-모드 기동 — **관측 모드 커널**로 실 이벤트를 미러한다(통합 P2).\n *\n * 예전에는 `StateProjector` 를 세웠다. 그래서 라이브에는 **커널이 없었고**, 그 하나 때문에 우회가\n * 줄줄이 생겼다: 예측하려면 임시 커널을 세워야 했고(`buildForecastKernel`), 주목 신호를 호스트가\n * 덧붙여야 했고(`withLiveAttentions`), AI 예측 도구는 미러에서 \"찾을 수 없다\" 로 끝났다.\n *\n * 이제 라이브 인스턴스도 **커널이다.** 같은 규칙(`ObservedReducer`)으로 이벤트를 접고, 주목 신호를\n * 스스로 내고, 그 자리에서 `fork` 해 예측한다. 구동만 다르다 — sim 은 `tick`, live 는 `apply`.\n *\n * 실 이벤트원 = reference 어댑터 openLiveFeed → face2-adapter.ingest → CanonicalEnvelope → ingestLive().\n */\n /**\n * 보드가 실은 **생산 정의**(레시피·라우트·바인딩)를 꺼낸다 — 커널의 정의-구동 모드 입구.\n *\n * ── 없을 때 무엇이 일어났나 ──────────────────────────────────────────────\n * 커널에는 정의-구동 MES 경로가 있는데 **호스트가 그것을 한 번도 넘기지 않았다.** 그래서 모든 MES\n * 트윈이 **하드코딩된 레거시 흐름**으로 돌았다 — 현장 레시피를 아무리 정성껏 적어도 커널은 그것을\n * 보지 못하고 토이 부품으로 토이 제품을 만들었다. 선언과 실행이 갈라져 있던 자리다.\n *\n * 보드에 없으면 `undefined` — 레거시 경로 그대로다(기존 트윈의 거동을 바꾸지 않는다).\n */\n private static mesSpecOf(board: BoardDef | undefined): any {\n return (board as any)?.mesSpec\n }\n\n /**\n * 현장(공간)의 **시각 기준**을 보드에 얹는다 — 커널이 교대의 `HH:MM` 을 읽을 기준.\n *\n * **테넌트가 아니라 공간이 권위다.** 한 테넌트가 Rosarito(태평양)와 한국 공장을 함께 가질 수 있고,\n * 테넌트 단위(`Domain.timezone`)로 두면 둘 중 하나는 반드시 틀린다. 그래서 인스턴스가 묶인 공간의\n * `timezone` 을 읽는다. 공간이 말하지 않으면 **테넌트로 내려가지 않는다** — 잘못된 입자로 답하는 것이\n * 모르는 것보다 나쁘다(그때는 커널이 UTC 로 읽고, 그 기본값은 계약에 밝혀져 있다).\n *\n * 커널은 zero-dep 이라 시간대 데이터베이스를 갖지 않으므로 **분 오프셋**으로 풀어 넘긴다. 그 값은\n * 지금 계절의 것이다(일광절약시간) — 계절을 넘는 긴 예측은 한 시간 어긋난다(계약에 명시).\n */\n static async withSpaceTimeBase(board: BoardDef, domainId: string, spaceId?: string): Promise<BoardDef> {\n const sid = spaceId ?? (board as any)?.spaceId\n if (!sid) return board\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId: sid } }).catch(() => null)\n const offset = utcOffsetOf(space?.timezone)\n if (offset === undefined) {\n if (space?.timezone) console.warn(`[twin-engine] space \"${sid}\" declares time zone \"${space.timezone}\" but it is not a known IANA zone — times will be read as UTC.`)\n return board\n }\n return { ...board, utcOffsetMinutes: offset }\n }\n\n static startLive(id: string, domainId: string, kind: string, board: BoardDef): InstanceRuntime {\n if (this.instances[id]) return this.instances[id]\n const Kernel = KERNELS[kind] ?? WmsKernel\n const kernel: any = new Kernel(domainId, undefined, this.mesSpecOf(board))\n kernel.loadBoard(board)\n this.applyOperations(kernel, board, id) // 명세는 라이브에도 실린다(예측 자격이 sim 과 같아진다)\n /* `projector` 필드는 옛 이름으로 남긴다 — 소비처가 `snapshot()` 을 부르므로 얇은 어댑터로 잇는다.\n * (P3 에서 소비처를 커널 어휘로 바꾸면 사라진다.) */\n const projector = { apply: (e: CanonicalEnvelope) => kernel.apply(e), snapshot: () => kernel.getSnapshot() }\n const inst: InstanceRuntime = { id, domainId, mode: 'live', realityMode: 'mirror', kernel, projector, oee: new OeeAccumulator(), unsub: () => {} }\n /* 추정기(실측·거리)도 라이브에 붙인다 — 예측이 상수로 돌지 않게. 기동을 막지 않는다. */\n this.installEstimators(kernel, domainId, id, board).catch(err => console.warn('[twin-engine] estimator install failed', err?.message))\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, structureRev?: number) {\n return repo.create({\n domain: { id: domainId } as any,\n instanceId,\n tenantId: e?.tenantId,\n eventType: e?.eventType,\n revision,\n /* **이 사실이 일어난 공장**을 함께 찍는다 — 이것이 없으면 나중에 구조가 바뀌었을 때 이 행을\n 새 공장에 대고 접게 되고, 그때 없던 설비에서 일이 있었던 것처럼 보인다. */\n ...(structureRev === undefined ? {} : { structureRev }),\n eventTime: e?.eventTime,\n ...twinEventKeys(e),\n payload: e\n })\n }\n\n /**\n * 이 트윈이 지금 어느 구조로 도는가 — 이벤트에 찍을 번호. 한 번 읽고 캐시한다(쓰기마다 조회 금지).\n *\n * 없으면 `undefined` 다 — 0 이 아니다. 구조 리비전이 생기기 전에 만들어진 트윈은 아직 리비전이\n * 없고, 그 사실을 0 이라는 **유효해 보이는 번호**로 위장하면 안 된다.\n */\n private static structureRevCache: Record<string, number> = {}\n static async structureRevOf(domainId: string, instanceId: string): Promise<number | undefined> {\n const key = `${domainId}:${instanceId}`\n const cached = this.structureRevCache[key]\n if (cached !== undefined) return cached\n const latest = await getRepository(TwinStructure).findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n if (latest) this.structureRevCache[key] = latest.rev\n return latest?.rev\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 structureRev = await this.structureRevOf(domainId, instanceId)\n const rows = envelopes.map((e, i) => this.journalRow(repo, domainId, instanceId, e, startRevision + i + 1, structureRev))\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.equipment 에 동기.\n * 이게 없으면 런타임엔 추가돼도(상태·저널엔 반영) 저장 board 는 원본이라 프로비저닝 편집기·재기동(loadBoard)이\n * 추가분을 잃는다. 기존 board.equipment 항목은 보존(homeLocation 유지)하고 새 id 만 append(추가 시점 location=homeLocation).\n * 좌표(layout)만 다루는 register 와 달리 equipment 집합을 갱신하나, 재프로비전(purge)이 아니라 in-place 갱신이라\n * 저널은 보존된다(추가는 이미 equipment 델타로 저널됨 → replay 는 id-keyed upsert 라 이중계산 없음).\n */\n static async syncBoardEquipment(domainId: string, instanceId: string): Promise<void> {\n const inst = this.instances[instanceId]\n const snap = inst?.kernel?.getSnapshot?.()\n if (!snap?.equipment) 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.equipment ?? []).map(m => m.id))\n const added = snap.equipment\n .filter((m: any) => !known.has(m.id))\n .map((m: any) => ({ id: m.id, kind: m.kind, homeLocation: m.location }))\n if (!added.length) return\n board.equipment = [...(board.equipment ?? []), ...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, comment?: string): 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 /*\n * **구조가 바뀌어도 역사를 지우지 않는다.**\n *\n * 예전에는 서명이 다르면 그 트윈의 저널을 통째로 지웠다. 안 지우면 옛 이벤트를 새 공장에 대고\n * 접게 되어 이력이 거짓말을 했기 때문이다 — 부스가 둘이던 시절의 사실을 여섯 개짜리 공장에\n * 접으면 그때 없던 부스에서 일이 있었던 것처럼 보인다. 선택지가 **역사를 잃거나 거짓말을\n * 하거나** 둘뿐이었고, 그래서 공장을 고칠 때마다 이력을 버려야 했다.\n *\n * 이제 셋째 길로 간다: 바뀐 구조를 **새 리비전**으로 남기고, 앞으로 쓰이는 이벤트가 그 번호를\n * 달고 다닌다. 재생은 구조가 바뀌는 지점에서 갈아탄 뒤 이어 접는다(`replaySegments`).\n */\n await this.recordStructure(domainId, instanceId, board, comment)\n await this.register(domainId, instanceId, kind, board, existing?.status === 'running' ? 'stopped' : (existing?.status as any) ?? 'stopped')\n }\n\n /**\n * 이 구조를 리비전으로 남기고 그 번호를 돌려준다 — **바뀌었을 때만** 새 번호가 생긴다.\n *\n * 프로비저닝은 부팅마다 다시 도는데, 그때마다 리비전이 늘면 이력이 뜻 없는 마디로 잘게 쪼개진다.\n * 그래서 **구조 서명이 같으면 있던 리비전을 그대로 쓴다.**\n */\n static async recordStructure(domainId: string, instanceId: string, board: BoardDef, comment?: string): Promise<number> {\n const repo = getRepository(TwinStructure)\n const signature = this.structureFingerprint(board)\n const latest = await repo.findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n\n /*\n * **저장된 지문이 아니라 저장된 공장과 비교한다.**\n *\n * 지문 계산 방식을 한 번이라도 바꾸면(원문 → 해시로 바꿨다) 저장된 문자열은 전부 옛 방식의\n * 것이라 무엇과도 안 맞는다. 그러면 **아무것도 안 바뀐 트윈들이 전부 \"구조가 바뀌었다\"** 로\n * 기록된다 — 실제로 그렇게 됐고, 재기동 한 번에 리비전이 통째로 하나씩 늘었다.\n *\n * 그래서 안 맞을 때 한 번 더 묻는다: 저장된 **보드**로 지문을 다시 계산하면 같은가? 같다면\n * 공장은 그대로이고 지문 표기만 낡은 것이니, 리비전을 만들지 않고 표기만 고친다.\n */\n if (latest && latest.signature !== signature && this.structureFingerprint(latest.board as BoardDef) === signature) {\n latest.signature = signature\n await repo.save(latest)\n }\n\n if (latest?.signature === signature) {\n this.structureRevCache[`${domainId}:${instanceId}`] = latest.rev\n return latest.rev\n }\n\n const rev = (latest?.rev ?? 0) + 1\n await repo.save(repo.create({ domain: { id: domainId } as any, instanceId, rev, signature, board: board as any, ...(comment ? { comment } : {}) }))\n this.structureRevCache[`${domainId}:${instanceId}`] = rev\n /* 구조가 바뀌면 재구성 캐시는 옛 공장의 것이다 — 버린다(지우는 건 캐시뿐, 사실은 남는다). */\n delete this.recovered[instanceId]\n if (latest) console.info(`[twin-engine] \"${instanceId}\" structure changed → revision ${rev} (history kept; older events stay under revision ${latest.rev}).`)\n return rev\n }\n\n /**\n * 이 트윈이 거쳐 온 구조들 — **무엇이 언제 달라졌나.**\n *\n * 리비전은 그 시절 공장을 통째로 담지만(재생에 필요하다), 사람이 보고 싶은 것은 통째가 아니라\n * 차이다. 보드는 빼고 **차이 요약만** 내보낸다 — 62KB 짜리 보드를 화면에 실어 보낼 이유가 없다.\n */\n static async structureHistory(\n domainId: string,\n instanceId: string\n ): Promise<{ rev: number; createdAt?: Date; comment?: string; events: number; diff: StructureDiff }[]> {\n const revs = await getRepository(TwinStructure).find({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'ASC' } })\n if (!revs.length) return []\n\n /* 리비전마다 그 아래에서 몇 건이 일어났나 — 이력의 무게를 보여준다(짧게 스쳐간 구조인지). */\n const counts = new Map<number | null, number>()\n for (const row of await getRepository(TwinEvent)\n .createQueryBuilder('e')\n .select('e.structureRev', 'rev')\n .addSelect('COUNT(1)', 'n')\n .where('e.domain = :domainId', { domainId })\n .andWhere('e.instanceId = :instanceId', { instanceId })\n .groupBy('e.structureRev')\n .getRawMany())\n counts.set(row.rev === null || row.rev === undefined ? null : Number(row.rev), Number(row.n))\n\n /* 번호 없는 옛 행은 **가장 오래된 리비전**의 몫이다 — 재생이 그렇게 접으므로 세는 것도 같아야 한다. */\n const oldest = revs[0].rev\n const legacy = counts.get(null) ?? 0\n\n return revs.map((r, i) => ({\n rev: r.rev,\n createdAt: r.createdAt,\n ...(r.comment ? { comment: r.comment } : {}),\n events: (counts.get(r.rev) ?? 0) + (r.rev === oldest ? legacy : 0),\n diff: diffStructures(i === 0 ? undefined : (revs[i - 1].board as any), r.board as any)\n }))\n }\n\n /** 지금 쓰이는 구조 리비전 — 이벤트에 찍을 번호. 아직 없으면 기록하며 만든다. */\n static async currentStructureRev(domainId: string, instanceId: string, board?: BoardDef): Promise<number | undefined> {\n const latest = await getRepository(TwinStructure).findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n if (latest) return latest.rev\n return board ? this.recordStructure(domainId, instanceId, board) : undefined\n }\n\n /** 구조 동일성 지문 — 좌표(layout) 등 뷰 관심사는 제외하고 커널이 보는 위상·용량·무버만. */\n /**\n * 지문을 **64자로 줄인다** — 컬럼이 varchar(64) 다.\n *\n * 원문 지문은 자리·설비를 전부 이어 붙인 문자열이라 큰 공장에서는 수만 자가 된다. sqlite 는\n * 길이를 강제하지 않아 그냥 들어가지만 **Postgres 는 거기서 터진다** — 개발에서는 멀쩡하고\n * 운영에서만 죽는 종류의 실패다. 비교에만 쓰는 값이므로 해시로 충분하다.\n */\n private static structureFingerprint(board: BoardDef): string {\n return createHash('sha256').update(this.structureSignature(board)).digest('hex')\n }\n\n private static structureSignature(board: BoardDef): string {\n const locations = [...(board.locations ?? [])]\n .map(n => `${n.id}:${n.type}:${n.capacity}`)\n .sort()\n .join('|')\n const equipment = [...(board.equipment ?? [])]\n .map(m => `${m.id}:${m.kind}:${m.homeLocation}`)\n .sort()\n .join('|')\n return `N[${locations}]M[${equipment}]`\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 /*\n * 저널에 남아 있는 마지막 번호 — **모드와 무관하게** 이것을 이어 센다.\n *\n * 저널을 초기화하고 기동하는 모드(sim-experiment)라면 이 값이 0이라 아무 영향이 없다. 규칙을\n * 모드별로 가르지 않는 이유: \"저널이 비어 있지 않으면 그 뒤부터\" 하나면 어느 모드에서도\n * 겹칠 수 없고, 모드가 늘어도 이 자리를 다시 손볼 일이 없다.\n */\n const last = await getRepository(TwinEvent)\n .createQueryBuilder('e')\n .select('MAX(e.revision)', 'max')\n .where('e.domain = :domainId', { domainId })\n .andWhere('e.instanceId = :instanceId', { instanceId })\n .getRawOne()\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 Number(last?.max ?? 0) || 0\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 /*\n * **이어지는 현실** — 저널을 지우지 않는다.\n *\n * 예전에는 여기서 저널을 지우고 fresh 로 띄웠다. resume 기계장치가 없다고 봤기 때문인데,\n * 실제로 없던 것은 **번호 이어 세기 하나**였다: 상태 복원은 이미 `startFromRegistry` 가\n * 저널 재생(또는 체크포인트)으로 하고 있었고, 막힌 것은 커널이 리비전을 0부터 다시 세어\n * 기존 행과 겹치는 문제였다. 그 하나를 `resumeRevision` 으로 풀었으므로 이제 이어 간다.\n *\n * 아직 이어지지 않는 것(정직하게): 시나리오 생성기의 난수 흐름은 재기동에 이어지지 않는다 —\n * 같은 씨앗에서 다시 시작하므로 자극의 패턴이 재기동 지점에서 한 번 끊긴다. 쌓인 사실과\n * 상태는 이어지고, 앞으로 일어날 일의 무작위 순서만 새로 시작한다.\n */\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) ?? { locations: [], equipment: [] }\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 locationCount: board.locations?.length ?? 0,\n equipmentCount: board.equipment?.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; locations: number; equipment: 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; locations: number; equipment: 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, locations: 0, equipment: 0 }\n a.instances++\n a.locations += board.locations?.length ?? 0\n a.equipment += board.equipment?.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 /*\n * **현장의 시각 기준을 공간에 남긴다** — 그러지 않으면 공간이 권위인데 그 값을 영원히 모른다.\n *\n * 마스터가 보드에 오프셋을 실어 주므로 갓 프로비저닝한 트윈은 맞게 돌지만, `withSpaceTimeBase` 가\n * 읽는 곳은 **공간**이다. 여기서 옮기지 않으면 공간의 시간대가 계속 비어 있고, 사용자가 화면에서\n * 그것을 보거나 고칠 수도 없다(만들고 잇지 않으면 없는 것이다).\n *\n * **사용자가 고친 값을 마스터가 덮지 않는다** — 이미 있으면 그대로 둔다(현장이 정본을 이긴다).\n */\n const timezone = existing?.timezone || master.space.timezone\n const savedSpace = await repo.save(repo.create({ ...(existing ?? {}), domain: { id: domainId } as any, spaceId, name: existing?.name || master.siteName, ...(timezone ? { timezone } : {}), 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) → equipment 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, await this.structureRevOf(domainId, instanceId)))\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 wanted = rows.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\n /*\n * **그때의 공장으로 접는다.**\n *\n * 예전에는 모든 이벤트를 지금 등록된 보드 하나로 접었다. 구조가 바뀐 적 없으면 맞지만, 바뀐\n * 뒤에는 옛 사실을 새 공장에 대고 접게 되어 — 그때 없던 설비에서 일이 있었던 것처럼 보인다.\n * (그래서 예전 프로비저닝은 구조가 바뀌면 저널을 아예 지웠다. 역사를 잃거나 거짓말을 하거나.)\n *\n * 이제 이벤트가 자기 구조를 달고 오므로, 리비전이 바뀌는 지점에서 구조를 갈아타며 이어 접는다.\n * 리비전이 하나뿐이거나(대다수) 아예 없으면(구조 이력 이전) 예전과 똑같이 한 번에 접는다.\n */\n const structures = await getRepository(TwinStructure).find({\n where: { domain: { id: domainId }, instanceId },\n order: { rev: 'ASC' }\n })\n const boardOf = new Map<number, BoardDef>(structures.map(x => [x.rev, x.board as BoardDef]))\n /* 컬럼이 생기기 전 행은 리비전이 비어 있다 — **가장 오래된 구조**에 속한다(0 으로 채우지 않는다). */\n const oldest = structures[0]?.rev\n const revOf = (r: { structureRev?: number }): number | undefined => r.structureRev ?? oldest\n\n const segments: { board: BoardDef; events: any[] }[] = []\n for (const r of wanted) {\n if (!r.payload) continue\n const rev = revOf(r)\n const board = (rev !== undefined && boardOf.get(rev)) || (reg.board as BoardDef)\n const last = segments[segments.length - 1]\n if (last && last.board === board) last.events.push(r.payload)\n else segments.push({ board, events: [r.payload] })\n }\n /*\n * **가장 새 구조가 지금의 공장이다** — 그 아래에서 아직 아무 일도 없었더라도.\n *\n * 재프로비저닝 직후가 정확히 그 상태다: 부스를 넷 늘렸는데 새 이벤트는 아직 하나도 없다. 이때\n * 마지막 이벤트의 구조로만 접으면 화면은 **옛 공장**을 보여준다 — 방금 늘린 것이 안 보인다.\n * 그래서 마디의 끝에 지금 구조를 한 번 더 얹는다(이벤트 없는 마디).\n *\n * **다만 \"지금\" 을 물었을 때만이다.** 과거 시점을 물었는데 최신 구조를 얹으면, 그 시점에 없던\n * 설비가 화면에 서고 — 이 작업이 막으려던 바로 그 거짓말이 된다.\n */\n const asOfNow = untilRevision == null && untilTime == null\n const newest = structures[structures.length - 1]?.board as BoardDef | undefined\n if (asOfNow && newest && segments[segments.length - 1]?.board !== newest) segments.push({ board: newest, events: [] })\n\n if (!segments.length) return replay(((asOfNow && newest) || reg.board) as BoardDef, [])\n if (segments.length === 1) return replay(segments[0].board, segments[0].events)\n\n const { state, shifts } = replaySegments(segments)\n /* 경계에서 사라진 것을 조용히 넘기지 않는다 — 수가 줄어든 이유를 어딘가에는 남겨야 한다. */\n for (const sh of shifts)\n if (sh.equipmentDropped || sh.locationsDropped || sh.personsDropped || sh.assetsDropped)\n console.info(`[twin-engine] \"${instanceId}\" replay crossed a structure change — dropped ${sh.equipmentDropped} equipment, ${sh.locationsDropped} locations, ${sh.personsDropped} persons, ${sh.assetsDropped} assets that no longer exist.`)\n return state\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 /**\n * 이 트윈이 이 테넌트 것인가 — **떠 있든 아니든.**\n *\n * `owns()` 는 **떠 있는** 런타임만 안다. 그것을 이력 조회의 관문으로 쓰면, 꺼진 트윈의 저널을\n * 읽으려 할 때 \"이 테넌트에 없다\" 는 답이 돌아온다 — 두 가지가 틀렸다. 첫째, 저널은 트윈이 꺼져\n * 있을 때 **가장 필요한 것**이다(그게 이력의 존재 이유다). 둘째, 그 문장은 남의 것이라는 뜻이라\n * 사용자가 권한 문제로 오해한다. 실제로는 그냥 안 돌고 있을 뿐이다.\n *\n * 소유는 **등록부**가 안다. 이력·집계처럼 런타임과 무관한 질문은 이쪽에 묻는다.\n */\n static async ownsRegistered(domainId: string, instanceId: string): Promise<boolean> {\n if (this.owns(domainId, instanceId)) return true\n return !!(await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } }))\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 * `buildForecastKernel` 은 **사라졌다**(통합 P3, 2026-08-01).\n *\n * 라이브가 `StateProjector` 였을 때는 커널이 없어서, 예측하려면 관측 스냅샷 + 저널의 오더 원값으로\n * **일회용 커널을 세워야** 했다. 이제 라이브 인스턴스가 곧 커널이므로(`startLive`) 그 자리에서\n * `fork` 하면 된다 — `TwinEngine.kernel(id)` 가 sim·live 둘 다 돌려준다.\n *\n * (오더 원값을 저널에서 되찾던 이유도 사라졌다 — 상태가 requested·fulfilled·lines 를 지킨다.)\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, undefined, this.mesSpecOf(reg.board as BoardDef))\n k.loadBoard(reg.board as BoardDef)\n this.applyOperations(k, reg.board, instanceId) // 예측도 같은 명세로 굴러야 한다(화면과 다른 숫자 금지)\n await this.installEstimators(k, domainId, instanceId, reg.board) // 예측은 기다린다 — 실측을 놓치면 예측이 상수로 돈다\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: **커널이 주목 신호를 스스로 낸다**(관측 모드) — 호스트가 덧붙이던 withLiveAttentions 는\n * 필요 없다. OEE 만 호스트가 채운다: 원 시스템이 시간 누적을 보내 주지 않아 상태 전이를 적분해\n * 만드는 값이라 커널이 대신할 수 없다(적합성 하네스의 유일한 예외). */\n const st = inst.projector.snapshot()\n return inst.oee ? withLiveOee(st, inst.oee) : 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) 회피). (vocabulary-guard: allow — Node 런타임 버전 표기)\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, unwrapState } from './warm-start.js'\nimport { isOfDomain, parseRuntimeKey, runtimeKey } from './runtime-key.js'\nimport { routeCommand } from './command-routing.js'\nimport { TwinInstance } from '../service/twin-instance/twin-instance.js'\nimport { TwinStructure } from '../service/twin-structure/twin-structure.js'\nimport { TwinSpace } from '../service/twin-space/twin-space.js'\nimport { utcOffsetOf } from '../service/reference/reference-master.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 { resolveIngestSpace, collidingIds } from '../service/reference/ingest-space.js'\nimport { type IngestWarning, landmarkIdsMerged, describeWarnings } from '../service/reference/reference-master.js'\nimport { buildTravelEstimator, chainEstimators } from './travel-estimator.js'\nimport { buildMeasuredEstimator } from './measured-estimator.js'\nimport { describeModelBasis, type ModelBasis } from './model-basis.js'\nimport { computeTwinKpi } from './kpi-query.js'\nimport { createHash } from 'node:crypto'\n\nimport { buildEntityDeltas } from './entity-delta.js'\nimport { diffStructures, type StructureDiff } from './structure-diff.js'\nimport { OeeAccumulator, withLiveOee } from './oee-accumulator.js'\nimport { withLiveAttentions } from './live-attentions.js'\nimport { digestAttentions, mergeLensAttentions } from './attention-digest.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, replaySegments, readBoardLocations, readBoardEquipment, 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 /**\n * live 의 상태 접근 어댑터 — 이제 **관측 모드 커널**을 가리킨다(`kernel` 과 같은 것).\n * 이름은 소비처 호환으로 남았고, P3 에서 커널 어휘로 정리하면 사라진다.\n */\n projector?: any\n oee?: OeeAccumulator // live: OEE 계산 층(이벤트 누적 → equipment 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 /*\n * 떠 있는 런타임 — **키는 `runtimeKey(domainId, instanceId)`** 다(`runtime-key.ts` 에 이유).\n *\n * 예전엔 `instanceId` 하나로 키를 잡았다. 그런데 정체성은 `(domain, instanceId)` 이고 DB 유일성도\n * 그쪽이라, 두 테넌트가 같은 id 를 쓰면(레퍼런스 경로가 소스 이름을 id 로 쓴다) 한 자리를 다퉜다.\n * **엔진 밖에서 이 맵을 직접 색인하지 않는다** — `owns`·`runtime`·`kernel` 같은 접근자를 쓴다.\n */\n static instances: Record<string, InstanceRuntime> = {}\n /** 라이브 런타임이 없을 때(복구 후 미기동) 저널에서 재구성한 상태 캐시. */\n /** 웜스타트 씨앗 — `instances` 와 **같은 키**(겹치면 남의 스냅샷으로 재고가 섞인다). */\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[runtimeKey(domainId, instanceId)]\n if (!inst) return\n /*\n * **봉투가 아니라 상태를 저장한다.** `snapshot()` 은 시뮬에서 `runtime.resync()` 봉투를 주는데,\n * 그것을 다시 `{revision, state}` 로 감싸 넣어 왔다 → 꺼낸 값에 축이 하나도 없어 웜스타트가\n * 조용히 넘어갔다(저널에 수천 건이 있어도 트윈이 빈 채로 떴다).\n */\n const state = unwrapState(this.snapshot(domainId, 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 [key, inst] of Object.entries(this.instances)) {\n const { instanceId } = parseRuntimeKey(key)\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 /* 예전에 겹포장으로 저장된 값이 남아 있을 수 있다 — 읽는 쪽에서도 벗긴다(한 번은 반드시 만난다). */\n this.recovered[runtimeKey(row.domainId, row.instanceId)] = { revision: cached.revision, state: unwrapState(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[runtimeKey(row.domainId, 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 * ── 반쪽이던 복구를 마무리한다 (2026-08-05) ─────────────────────────────────\n * 재고는 살아났는데 **진행 중 주문이 통째로 사라진** 화면이 남아 있었다. 씨앗이 자리·물품·설비\n * 셋만 넘겼기 때문이다. 그 근거는 \"스냅샷 오더에 progress 밖에 없다\" 였고, 그때는 맞았다 —\n * 그러나 커널 `OrderState` 가 원값(`requested`·`fulfilled`·`lines`)을 되찾은 뒤에도 이 자리만\n * 그대로 남았다. 오류를 내지 않는 종류라 오래 버텼다.\n *\n * 지금은 **관측 스냅샷 전체**를 넘긴다(오더·작업·사람·자산 포함). 시뮬은 커널 `snapshot()`,\n * 라이브는 `StateProjector` 가 그 일곱 축을 모두 담는다. 무엇을 심을 수 있는지 판정하는 규칙\n * (이행 완료 오더 제외·고아 작업 제외)은 커널에 있고, 호스트가 미리 골라내지 않는다.\n *\n * ── 남은 한계는 숨기지 않고 센다 ────────────────────────────────────────────\n * · 원값이 없는 오더(progress 만 있는 것)는 남은 수량을 알 수 없어 심지 않는다. **지어내지 않는\n * 대신 몇 건인지 말한다** — 세지 않으면 \"주문이 없다\" 와 \"주문을 못 심었다\" 가 화면에서 같아진다.\n * · 진행 중 개별 작업의 내부 상태는 관측만으로 완전히 복원되지 않는다(커널이 명시한 한계, 재계획에 맡김).\n *\n * ── 벤치는 시드하지 않는다 ──────────────────────────────────────────────────\n * 부하 벤치는 **새 시작에서 용량을 재는 것**이 목적이라 현재 상태를 심으면 측정이 오염된다.\n */\n private static warmStart(domainId: string, id: string, kernel: TwinKernel, purpose?: string): void {\n const hydrate = (kernel as any).hydrateObserved\n const plan = planWarmStart(this.recovered[runtimeKey(domainId, 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 const restored = [\n `${plan.itemCount} item(s)`,\n `${plan.equipmentCount} equipment`,\n `${plan.orderCount} open order(s)`,\n `${plan.taskCount} task(s)`,\n ...(plan.personCount ? [`${plan.personCount} person(s)`] : []),\n ...(plan.assetCount ? [`${plan.assetCount} asset(s)`] : []),\n /* 확인해 둔 신호를 이어받았다는 사실도 말한다 — 잃으면 확인 처리가 다시 빨개지는 것으로 보인다. */\n ...(plan.ackedCount ? [`${plan.ackedCount} acknowledged attention(s)`] : [])\n ].join(', ')\n console.log(`[twin-engine] warm-started \"${id}\" — restored ${restored}.`)\n /* 뺀 것은 조용히 넘기지 않는다 — 지어내지 않았다는 사실 자체를 말해야 화면의 빈칸이 읽힌다. */\n if (plan.ordersWithoutDemand > 0) {\n console.warn(\n `[twin-engine] \"${id}\": ${plan.ordersWithoutDemand} order(s) could not be restored — they carry progress only, ` +\n 'with no requested/fulfilled counts, so the remaining demand is unknown. They are left out rather than guessed.'\n )\n }\n }\n\n /** 트윈 인스턴스 시작 — 커널 생성 + 보드 로드 + 직전 상태 웜스타트 + State 스트림 브리지 + 워커 tick + 레지스트리 영속. */\n /**\n * 공정 명세를 커널에 싣는다 — **시뮬레이션의 시간을 데이터가 말하게 하는 마지막 한 칸.**\n *\n * `board.operations`(마스터 인제스트가 통과시킨 ISA-95 OperationsSegment 명세)를 커널이 소비한다.\n * 없으면 커널 기본 상수로 굴러가고, 커널 `specCoverage()` 가 무엇을 기본값으로 썼는지 보고한다.\n *\n * 커널이 아직 이 API 를 갖지 않은 버전이면(발행 이전) **조용히 넘어가지 않고 경고한다** — 명세를\n * 선언했는데 반영되지 않는 상태를 모르고 지나가면, 예측이 상수로 돌아간 것을 아무도 알 수 없다.\n */\n private static applyOperations(kernel: any, board: any, id: string): void {\n const ops = board?.operations\n if (!ops?.length) return\n if (typeof kernel?.loadOperations !== 'function') {\n console.warn(`[twin-engine] \"${id}\": board declares ${ops.length} operation spec(s) but the kernel cannot consume them (loadOperations missing — kernel needs publishing). Simulation will use built-in default durations.`)\n return\n }\n kernel.loadOperations(ops)\n }\n\n /**\n * 소요시간 추정기 주입 — **상수를 데이터로 바꾸는 두 번째·세 번째 층.**\n *\n * 커널 `durationOf` 의 우선순위는 추정기 > 명세 > 상수다. 그 추정기 자리에 두 가지를 사슬로 넣는다:\n * ① **실측**(저널의 작업 종류별 작업시간 p50) — 그 현장에서 실제로 얼마 걸렸나. 가장 강한 근거.\n * ② **거리 × 속도**(board.layout + 설비 속도 속성) — 이동은 거리에 비례한다. 커널은 좌표를 모르므로\n * 호스트가 계산해 넣는다.\n * 둘 다 못 만들면 주입하지 않는다 — 커널이 명세·상수로 굴러가고 `specCoverage()` 가 그 사실을 남긴다.\n *\n * 실측은 DB 조회라 비동기다. 그래서 이 함수는 **await 하지 않는 쪽에서도 안전**하도록 실패를 삼키되,\n * 무엇을 왜 못 넣었는지는 로그로 남긴다(조용한 무효화 금지).\n */\n static async installEstimators(kernel: any, domainId: string, instanceId: string, board: any): Promise<void> {\n if (!kernel || typeof kernel !== 'object') return\n const travel = buildTravelEstimator({ layout: board?.layout, equipment: board?.equipment, unit: board?.unit })\n const measured = await this.measuredEstimator(domainId, instanceId)\n const chained = chainEstimators([measured?.estimator, travel.estimator])\n if (!chained) {\n /* 왜 못 넣었는지 한 번만 알린다 — 이동시간이 상수로 남은 이유를 모르고 지나가지 않게. */\n if (travel.reasons.length) console.warn(`[twin-engine] \"${instanceId}\": no duration estimator installed — ${travel.reasons.join('; ')}`)\n return\n }\n kernel.durationEstimator = chained\n const learned = Object.keys(measured?.learned ?? {})\n const spread = Object.keys(measured?.spreads ?? {})\n console.log(\n `[twin-engine] \"${instanceId}\": duration estimator installed — measured kinds: ${learned.length ? learned.join(',') : 'none'}` +\n ` (with observed spread: ${spread.length ? spread.join(',') : 'none'})` +\n `${travel.estimator ? `, travel from distance (speeds: ${Object.keys(travel.speedsByKind).join(',')})` : `, travel not derived (${travel.reasons.join('; ')})`}`\n )\n }\n\n /**\n * 실측 추정기 — **예측 요청마다 저널을 다시 접지 않는다.**\n *\n * 예측 커널은 요청마다 새로 세워지고(미러 예측·백테스트), 화면은 시각을 긁으면 계속 재예측한다.\n * 거기에 KPI 조회를 그대로 달면 요청당 저널 스캔이 하나씩 붙는다 — 실측은 분 단위로 바뀌지 않으므로\n * 짧은 TTL 로 재사용한다. 캐시는 인스턴스별이고, 만료 전에는 같은 값을 쓴다(예측 간 일관성도 얻는다).\n */\n private static measuredCache = new Map<string, { at: number; value: ReturnType<typeof buildMeasuredEstimator> | undefined }>()\n private static readonly MEASURED_TTL_MS = 60_000\n\n private static async measuredEstimator(domainId: string, instanceId: string) {\n const key = `${domainId}:${instanceId}`\n const hit = this.measuredCache.get(key)\n if (hit && Date.now() - hit.at < this.MEASURED_TTL_MS) return hit.value\n let value: ReturnType<typeof buildMeasuredEstimator> | undefined\n try {\n /* 작업 종류별 실측 — 창은 넉넉히(하루) 두고 표본이 모자란 종류는 추정기가 스스로 뺀다. */\n const kpi: any = await computeTwinKpi({ domainId, instanceId, windowMinutes: 24 * 60, groupBy: 'taskKind' })\n value = buildMeasuredEstimator(kpi?.groups?.items, {})\n } catch (err) {\n console.warn(`[twin-engine] \"${instanceId}\": measured duration lookup failed — falling back to declared/default durations.`, (err as any)?.message)\n }\n this.measuredCache.set(key, { at: Date.now(), value })\n return value\n }\n\n /**\n * 지금 이 트윈이 어떤 모델로 굴러가는가 — 예측 출력 보정이 **자기가 배운 모델**에만 적용되도록\n * 비교하는 지문. 재료는 호스트가 아는 것(실측·속도·선언 명세)이라 커널 발행 상태와 무관하다.\n * 실패하면 undefined — 그때는 비교를 하지 않는다(모르는 것을 근거로 보정을 끊지 않는다).\n */\n static async modelBasis(domainId: string, instanceId: string): Promise<ModelBasis | undefined> {\n try {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n const board: any = reg?.board\n const measured = await this.measuredEstimator(domainId, instanceId)\n const travel = buildTravelEstimator({ layout: board?.layout, equipment: board?.equipment, unit: board?.unit })\n return { measured: measured?.learned, speeds: travel.speedsByKind, declared: board?.operations }\n } catch {\n return undefined\n }\n }\n\n /**\n * **이 트윈이 하루 몇 대를 낼 수 있는가** — 굴려 보지 않고 답한다.\n *\n * 계산은 커널이 자기 상태에서 한다(`kernel.capacity`). 여기서 하는 일은 **기준 주를 정해 주는\n * 것**뿐이다: 공휴일이 없는 평상주여야 한다 — 공휴일은 연간 가용량을 따로 깎지, 이 공장의 평상시\n * 천장을 정하지 않는다. 커널이 임의로 고르게 두면 그 주에 공휴일이 끼었을 때 천장이 조용히 낮아진다.\n *\n * 트윈이 안 떠 있으면 `undefined` 다 — 0 이 아니다. 안 뜬 트윈의 천장을 0 이라고 답하면 화면은\n * \"이 공장은 아무것도 못 만든다\" 고 말한다.\n */\n static async capacity(\n domainId: string,\n target: { instanceId?: string; spaceId?: string },\n unitsPerDay: number,\n sampleWeekStartMs: number\n ): Promise<{ instanceId: string; kind?: string; analysis?: any; reason?: 'not-running' | 'no-operations' }[]> {\n /* 대상은 **등록부**가 정한다 — 떠 있는 런타임만 훑으면 \"안 떠 있어서 안 보이는 것\" 과 \"없는 것\" 이\n 구별되지 않는다. 화면은 그 둘을 다르게 말해야 한다. */\n const where: any = { domain: { id: domainId } }\n if (target.instanceId) where.instanceId = target.instanceId\n else where.spaceId = target.spaceId\n const registered = await getRepository(TwinInstance).find({ where })\n\n return registered.map(reg => {\n const rt = this.instances[runtimeKey(domainId, reg.instanceId)]\n const kernel: any = rt?.kernel // 키에 도메인이 있으므로 남의 런타임을 집을 수 없다\n if (typeof kernel?.capacity !== 'function') return { instanceId: reg.instanceId, kind: reg.kind, reason: 'not-running' as const }\n\n const analysis = kernel.capacity({ unitsPerDay, sampleWeekStartMs })\n /* 공정을 선언하지 않은 트윈(대개 YMS·WMS)은 **판정 대상이 아니다.** 0 으로 채워 넣으면\n \"야드가 병목\" 이라는 없는 사실이 생긴다 — 잴 것이 없다고 말한다. */\n if (!analysis?.operations?.length) return { instanceId: reg.instanceId, kind: reg.kind, reason: 'no-operations' as const }\n return { instanceId: reg.instanceId, kind: reg.kind, analysis }\n })\n }\n\n static start(id: string, domainId: string, kind: string, board: BoardDef, realityMode?: RealityMode, purpose?: string, resumeFrom?: number): InstanceRuntime {\n const key = runtimeKey(domainId, id)\n if (this.instances[key]) return this.instances[key]\n\n const Kernel = KERNELS[kind] ?? WmsKernel\n const kernel: TwinKernel = new Kernel(domainId, undefined, this.productionSpecOf(board))\n kernel.loadBoard(board) // 구조만. 상태는 아래 웜스타트가 심는다.\n this.applyOperations(kernel, board, id) // 시간·수율 명세(있으면) — 없으면 커널 기본값\n /* 추정기는 DB 조회를 포함해 비동기 — 기동을 막지 않고 붙는다(붙기 전 작업은 명세·상수로 산출). */\n this.installEstimators(kernel, domainId, id, board).catch(err => console.warn('[twin-engine] estimator install failed', err?.message))\n this.warmStart(domainId, id, kernel, purpose)\n /*\n * **번호를 이어 센다** — 저널에 이미 있는 번호와 겹치지 않게.\n *\n * 저널이 비어 있으면(0) 아무 일도 안 한다. 비어 있지 않은데 0부터 다시 세면 같은 트윈에 같은\n * 리비전이 둘 생기고, 재생 순서가 뒤섞이며, 시간여행이 엉뚱한 시점을 답한다 — 오류는 안 난다.\n */\n if (resumeFrom && typeof (kernel as any).resumeRevision === 'function') (kernel as any).resumeRevision(resumeFrom)\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[key] = inst\n delete this.recovered[key] // 웜스타트로 커널에 옮겨 심었다 — 이제 라이브가 진실이다.\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(() => this.tickGuarded(domainId, id, runtime), this.TICK_MS)\n return inst\n }\n\n /**\n * live-모드 기동 — **관측 모드 커널**로 실 이벤트를 미러한다(통합 P2).\n *\n * 예전에는 `StateProjector` 를 세웠다. 그래서 라이브에는 **커널이 없었고**, 그 하나 때문에 우회가\n * 줄줄이 생겼다: 예측하려면 임시 커널을 세워야 했고(`buildForecastKernel`), 주목 신호를 호스트가\n * 덧붙여야 했고(`withLiveAttentions`), AI 예측 도구는 미러에서 \"찾을 수 없다\" 로 끝났다.\n *\n * 이제 라이브 인스턴스도 **커널이다.** 같은 규칙(`ObservedReducer`)으로 이벤트를 접고, 주목 신호를\n * 스스로 내고, 그 자리에서 `fork` 해 예측한다. 구동만 다르다 — sim 은 `tick`, live 는 `apply`.\n *\n * 실 이벤트원 = reference 어댑터 openLiveFeed → face2-adapter.ingest → CanonicalEnvelope → ingestLive().\n */\n /**\n * 보드가 실은 **생산 정의**(레시피·라우트·바인딩)를 꺼낸다 — 커널의 정의-구동 모드 입구.\n *\n * ── 없을 때 무엇이 일어났나 ──────────────────────────────────────────────\n * 커널에는 정의-구동 MES 경로가 있는데 **호스트가 그것을 한 번도 넘기지 않았다.** 그래서 모든 MES\n * 트윈이 **하드코딩된 레거시 흐름**으로 돌았다 — 현장 레시피를 아무리 정성껏 적어도 커널은 그것을\n * 보지 못하고 토이 부품으로 토이 제품을 만들었다. 선언과 실행이 갈라져 있던 자리다.\n *\n * 보드에 없으면 `undefined` — 레거시 경로 그대로다(기존 트윈의 거동을 바꾸지 않는다).\n */\n /**\n * 생산 선언을 꺼낸다 — 커널 생성자에 넘긴다.\n *\n * **옛 이름(`mesSpec`)은 읽지 않는다.** 그것은 계약에 선언조차 없던 필드였고(MES 커널 생성자 인자\n * 이름이 그대로 굳은 것), 일반 기제에 한 시스템 이름이 붙어 있었기 때문에 창고 트윈이 이 자리를\n * 쓰지 못했다. 별명으로 남겨 두면 그 혼동이 계속되므로 하나로 통일했다.\n *\n * 옛 이름만 가진 보드가 있으면 **조용히 생산 선언을 잃는 대신 분명히 멈춘다** — 그 트윈은 공정이\n * 없는 채로 돌게 되고(라인이 서 있는 창고), 원인을 찾기 어렵다.\n */\n private static productionSpecOf(board: BoardDef | undefined): any {\n const legacy = (board as any)?.mesSpec\n if (legacy && !(board as any)?.productionSpec) {\n throw new Error(\n 'board carries the retired `mesSpec` field — rename it to `productionSpec` ' +\n '(same shape; the name was tied to one kernel while the declaration is ISA-95 operations + BOM)'\n )\n }\n return (board as any)?.productionSpec\n }\n\n /**\n * 현장(공간)의 **시각 기준**을 보드에 얹는다 — 커널이 교대의 `HH:MM` 을 읽을 기준.\n *\n * **테넌트가 아니라 공간이 권위다.** 한 테넌트가 Rosarito(태평양)와 한국 공장을 함께 가질 수 있고,\n * 테넌트 단위(`Domain.timezone`)로 두면 둘 중 하나는 반드시 틀린다. 그래서 인스턴스가 묶인 공간의\n * `timezone` 을 읽는다. 공간이 말하지 않으면 **테넌트로 내려가지 않는다** — 잘못된 입자로 답하는 것이\n * 모르는 것보다 나쁘다(그때는 커널이 UTC 로 읽고, 그 기본값은 계약에 밝혀져 있다).\n *\n * 커널은 zero-dep 이라 시간대 데이터베이스를 갖지 않으므로 **분 오프셋**으로 풀어 넘긴다. 그 값은\n * 지금 계절의 것이다(일광절약시간) — 계절을 넘는 긴 예측은 한 시간 어긋난다(계약에 명시).\n */\n static async withSpaceTimeBase(board: BoardDef, domainId: string, spaceId?: string): Promise<BoardDef> {\n const sid = spaceId ?? (board as any)?.spaceId\n if (!sid) return board\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId: sid } }).catch(() => null)\n const offset = utcOffsetOf(space?.timezone)\n if (offset === undefined) {\n if (space?.timezone) console.warn(`[twin-engine] space \"${sid}\" declares time zone \"${space.timezone}\" but it is not a known IANA zone — times will be read as UTC.`)\n return board\n }\n return { ...board, utcOffsetMinutes: offset }\n }\n\n static startLive(id: string, domainId: string, kind: string, board: BoardDef): InstanceRuntime {\n const key = runtimeKey(domainId, id)\n if (this.instances[key]) return this.instances[key]\n const Kernel = KERNELS[kind] ?? WmsKernel\n const kernel: any = new Kernel(domainId, undefined, this.productionSpecOf(board))\n kernel.loadBoard(board)\n this.applyOperations(kernel, board, id) // 명세는 라이브에도 실린다(예측 자격이 sim 과 같아진다)\n /* `projector` 필드는 옛 이름으로 남긴다 — 소비처가 `snapshot()` 을 부르므로 얇은 어댑터로 잇는다.\n * (P3 에서 소비처를 커널 어휘로 바꾸면 사라진다.) */\n const projector = { apply: (e: CanonicalEnvelope) => kernel.apply(e), snapshot: () => kernel.getSnapshot() }\n const inst: InstanceRuntime = { id, domainId, mode: 'live', realityMode: 'mirror', kernel, projector, oee: new OeeAccumulator(), unsub: () => {} }\n /* 추정기(실측·거리)도 라이브에 붙인다 — 예측이 상수로 돌지 않게. 기동을 막지 않는다. */\n this.installEstimators(kernel, domainId, id, board).catch(err => console.warn('[twin-engine] estimator install failed', err?.message))\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[key] = inst\n delete this.recovered[key]\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(domainId: string, id: string, envelopes: CanonicalEnvelope[]): void {\n const inst = this.instances[runtimeKey(domainId, 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 /**\n * 구간 성과 방송은 **없앴다**(2026-08-06). 카드가 `twinKpi` 를 직접 묻는다.\n *\n * 왜: 카드를 여러 단계(공간·트윈·구역·자리·설비)에 붙이려면 방송으로는 태그가 트윈당 1,200개가 되고,\n * **보드에 카드를 하나도 안 놓아도** 30초마다 트윈마다 저널을 접었다. 질의로 바꾸니 보고 있는 카드\n * 수만큼만 들고, 같은 (대상·창·축) 은 클라이언트가 하나로 합친다.\n *\n * 덤으로 질의만 할 수 있는 것이 둘 생겼다 — **과거 시각**(`toTime`)과 **공간 단위 합산**(여러 트윈을\n * 한 번에 접기). 방송 루프는 트윈별이라 둘 다 못 했다.\n *\n * 축을 나눠도 폴드 비용이 같다는 실측이 근거다(`test/kpi-query-bench.test.ts`).\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, structureRev?: number) {\n return repo.create({\n domain: { id: domainId } as any,\n instanceId,\n tenantId: e?.tenantId,\n eventType: e?.eventType,\n revision,\n /* **이 사실이 일어난 공장**을 함께 찍는다 — 이것이 없으면 나중에 구조가 바뀌었을 때 이 행을\n 새 공장에 대고 접게 되고, 그때 없던 설비에서 일이 있었던 것처럼 보인다. */\n ...(structureRev === undefined ? {} : { structureRev }),\n eventTime: e?.eventTime,\n ...twinEventKeys(e),\n payload: e\n })\n }\n\n /**\n * 이 트윈이 지금 어느 구조로 도는가 — 이벤트에 찍을 번호. 한 번 읽고 캐시한다(쓰기마다 조회 금지).\n *\n * 없으면 `undefined` 다 — 0 이 아니다. 구조 리비전이 생기기 전에 만들어진 트윈은 아직 리비전이\n * 없고, 그 사실을 0 이라는 **유효해 보이는 번호**로 위장하면 안 된다.\n */\n private static structureRevCache: Record<string, number> = {}\n static async structureRevOf(domainId: string, instanceId: string): Promise<number | undefined> {\n const key = `${domainId}:${instanceId}`\n const cached = this.structureRevCache[key]\n if (cached !== undefined) return cached\n const latest = await getRepository(TwinStructure).findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n if (latest) this.structureRevCache[key] = latest.rev\n return latest?.rev\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 structureRev = await this.structureRevOf(domainId, instanceId)\n const rows = envelopes.map((e, i) => this.journalRow(repo, domainId, instanceId, e, startRevision + i + 1, structureRev))\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.equipment 에 동기.\n * 이게 없으면 런타임엔 추가돼도(상태·저널엔 반영) 저장 board 는 원본이라 프로비저닝 편집기·재기동(loadBoard)이\n * 추가분을 잃는다. 기존 board.equipment 항목은 보존(homeLocation 유지)하고 새 id 만 append(추가 시점 location=homeLocation).\n * 좌표(layout)만 다루는 register 와 달리 equipment 집합을 갱신하나, 재프로비전(purge)이 아니라 in-place 갱신이라\n * 저널은 보존된다(추가는 이미 equipment 델타로 저널됨 → replay 는 id-keyed upsert 라 이중계산 없음).\n */\n static async syncBoardEquipment(domainId: string, instanceId: string): Promise<void> {\n const inst = this.instances[runtimeKey(domainId, instanceId)]\n const snap = inst?.kernel?.getSnapshot?.()\n if (!snap?.equipment) 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.equipment ?? []).map(m => m.id))\n const added = snap.equipment\n .filter((m: any) => !known.has(m.id))\n .map((m: any) => ({ id: m.id, kind: m.kind, homeLocation: m.location }))\n if (!added.length) return\n board.equipment = [...(board.equipment ?? []), ...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, comment?: string): Promise<void> {\n if (this.instances[runtimeKey(domainId, 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 /*\n * **구조가 바뀌어도 역사를 지우지 않는다.**\n *\n * 예전에는 서명이 다르면 그 트윈의 저널을 통째로 지웠다. 안 지우면 옛 이벤트를 새 공장에 대고\n * 접게 되어 이력이 거짓말을 했기 때문이다 — 부스가 둘이던 시절의 사실을 여섯 개짜리 공장에\n * 접으면 그때 없던 부스에서 일이 있었던 것처럼 보인다. 선택지가 **역사를 잃거나 거짓말을\n * 하거나** 둘뿐이었고, 그래서 공장을 고칠 때마다 이력을 버려야 했다.\n *\n * 이제 셋째 길로 간다: 바뀐 구조를 **새 리비전**으로 남기고, 앞으로 쓰이는 이벤트가 그 번호를\n * 달고 다닌다. 재생은 구조가 바뀌는 지점에서 갈아탄 뒤 이어 접는다(`replaySegments`).\n */\n await this.recordStructure(domainId, instanceId, board, comment)\n await this.register(domainId, instanceId, kind, board, existing?.status === 'running' ? 'stopped' : (existing?.status as any) ?? 'stopped')\n }\n\n /**\n * 이 구조를 리비전으로 남기고 그 번호를 돌려준다 — **바뀌었을 때만** 새 번호가 생긴다.\n *\n * 프로비저닝은 부팅마다 다시 도는데, 그때마다 리비전이 늘면 이력이 뜻 없는 마디로 잘게 쪼개진다.\n * 그래서 **구조 서명이 같으면 있던 리비전을 그대로 쓴다.**\n */\n static async recordStructure(domainId: string, instanceId: string, board: BoardDef, comment?: string): Promise<number> {\n const repo = getRepository(TwinStructure)\n const signature = this.structureFingerprint(board)\n const latest = await repo.findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n\n /*\n * **저장된 지문이 아니라 저장된 공장과 비교한다.**\n *\n * 지문 계산 방식을 한 번이라도 바꾸면(원문 → 해시로 바꿨다) 저장된 문자열은 전부 옛 방식의\n * 것이라 무엇과도 안 맞는다. 그러면 **아무것도 안 바뀐 트윈들이 전부 \"구조가 바뀌었다\"** 로\n * 기록된다 — 실제로 그렇게 됐고, 재기동 한 번에 리비전이 통째로 하나씩 늘었다.\n *\n * 그래서 안 맞을 때 한 번 더 묻는다: 저장된 **보드**로 지문을 다시 계산하면 같은가? 같다면\n * 공장은 그대로이고 지문 표기만 낡은 것이니, 리비전을 만들지 않고 표기만 고친다.\n */\n if (latest && latest.signature !== signature && this.structureFingerprint(latest.board as BoardDef) === signature) {\n latest.signature = signature\n await repo.save(latest)\n }\n\n if (latest?.signature === signature) {\n this.structureRevCache[`${domainId}:${instanceId}`] = latest.rev\n return latest.rev\n }\n\n const rev = (latest?.rev ?? 0) + 1\n await repo.save(repo.create({ domain: { id: domainId } as any, instanceId, rev, signature, board: board as any, ...(comment ? { comment } : {}) }))\n this.structureRevCache[`${domainId}:${instanceId}`] = rev\n /* 구조가 바뀌면 재구성 캐시는 옛 공장의 것이다 — 버린다(지우는 건 캐시뿐, 사실은 남는다). */\n delete this.recovered[runtimeKey(domainId, instanceId)]\n if (latest) console.info(`[twin-engine] \"${instanceId}\" structure changed → revision ${rev} (history kept; older events stay under revision ${latest.rev}).`)\n return rev\n }\n\n /**\n * 이 트윈이 거쳐 온 구조들 — **무엇이 언제 달라졌나.**\n *\n * 리비전은 그 시절 공장을 통째로 담지만(재생에 필요하다), 사람이 보고 싶은 것은 통째가 아니라\n * 차이다. 보드는 빼고 **차이 요약만** 내보낸다 — 62KB 짜리 보드를 화면에 실어 보낼 이유가 없다.\n */\n static async structureHistory(\n domainId: string,\n instanceId: string\n ): Promise<{ rev: number; createdAt?: Date; comment?: string; events: number; diff: StructureDiff }[]> {\n const revs = await getRepository(TwinStructure).find({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'ASC' } })\n if (!revs.length) return []\n\n /* 리비전마다 그 아래에서 몇 건이 일어났나 — 이력의 무게를 보여준다(짧게 스쳐간 구조인지). */\n const counts = new Map<number | null, number>()\n for (const row of await getRepository(TwinEvent)\n .createQueryBuilder('e')\n .select('e.structureRev', 'rev')\n .addSelect('COUNT(1)', 'n')\n .where('e.domain = :domainId', { domainId })\n .andWhere('e.instanceId = :instanceId', { instanceId })\n .groupBy('e.structureRev')\n .getRawMany())\n counts.set(row.rev === null || row.rev === undefined ? null : Number(row.rev), Number(row.n))\n\n /* 번호 없는 옛 행은 **가장 오래된 리비전**의 몫이다 — 재생이 그렇게 접으므로 세는 것도 같아야 한다. */\n const oldest = revs[0].rev\n const legacy = counts.get(null) ?? 0\n\n return revs.map((r, i) => ({\n rev: r.rev,\n createdAt: r.createdAt,\n ...(r.comment ? { comment: r.comment } : {}),\n events: (counts.get(r.rev) ?? 0) + (r.rev === oldest ? legacy : 0),\n diff: diffStructures(i === 0 ? undefined : (revs[i - 1].board as any), r.board as any)\n }))\n }\n\n /** 지금 쓰이는 구조 리비전 — 이벤트에 찍을 번호. 아직 없으면 기록하며 만든다. */\n static async currentStructureRev(domainId: string, instanceId: string, board?: BoardDef): Promise<number | undefined> {\n const latest = await getRepository(TwinStructure).findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n if (latest) return latest.rev\n return board ? this.recordStructure(domainId, instanceId, board) : undefined\n }\n\n /** 구조 동일성 지문 — 좌표(layout) 등 뷰 관심사는 제외하고 커널이 보는 위상·용량·무버만. */\n /**\n * 지문을 **64자로 줄인다** — 컬럼이 varchar(64) 다.\n *\n * 원문 지문은 자리·설비를 전부 이어 붙인 문자열이라 큰 공장에서는 수만 자가 된다. sqlite 는\n * 길이를 강제하지 않아 그냥 들어가지만 **Postgres 는 거기서 터진다** — 개발에서는 멀쩡하고\n * 운영에서만 죽는 종류의 실패다. 비교에만 쓰는 값이므로 해시로 충분하다.\n */\n private static structureFingerprint(board: BoardDef): string {\n return createHash('sha256').update(this.structureSignature(board)).digest('hex')\n }\n\n private static structureSignature(board: BoardDef): string {\n const locations = [...(board.locations ?? [])]\n .map(n => `${n.id}:${n.type}:${n.capacity}`)\n .sort()\n .join('|')\n const equipment = [...(board.equipment ?? [])]\n .map(m => `${m.id}:${m.kind}:${m.homeLocation}`)\n .sort()\n .join('|')\n return `N[${locations}]M[${equipment}]`\n }\n\n /** 레지스트리 board 로 기동(프로비전된 인스턴스 start). board 인자 없이 저장된 구조로 재기동. */\n static async startFromRegistry(domainId: string, instanceId: string, realityMode?: RealityMode): Promise<InstanceRuntime> {\n const key = runtimeKey(domainId, instanceId)\n if (this.instances[key]) return this.instances[key]\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[key] && reg.purpose !== 'bench') {\n const cached = await this.loadSnapshot(domainId, instanceId).catch(() => null)\n if (cached?.state) {\n this.recovered[key] = { revision: cached.revision, state: cached.state }\n } else {\n const state = await this.recover(domainId, instanceId).catch(() => null)\n if (state) this.recovered[key] = { revision: state.revision, state }\n }\n }\n\n /*\n * 저널에 남아 있는 마지막 번호 — **모드와 무관하게** 이것을 이어 센다.\n *\n * 저널을 초기화하고 기동하는 모드(sim-experiment)라면 이 값이 0이라 아무 영향이 없다. 규칙을\n * 모드별로 가르지 않는 이유: \"저널이 비어 있지 않으면 그 뒤부터\" 하나면 어느 모드에서도\n * 겹칠 수 없고, 모드가 늘어도 이 자리를 다시 손볼 일이 없다.\n */\n const last = await getRepository(TwinEvent)\n .createQueryBuilder('e')\n .select('MAX(e.revision)', 'max')\n .where('e.domain = :domainId', { domainId })\n .andWhere('e.instanceId = :instanceId', { instanceId })\n .getRawOne()\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 Number(last?.max ?? 0) || 0\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 /*\n * **이어지는 현실** — 저널을 지우지 않는다.\n *\n * 예전에는 여기서 저널을 지우고 fresh 로 띄웠다. resume 기계장치가 없다고 봤기 때문인데,\n * 실제로 없던 것은 **번호 이어 세기 하나**였다: 상태 복원은 이미 `startFromRegistry` 가\n * 저널 재생(또는 체크포인트)으로 하고 있었고, 막힌 것은 커널이 리비전을 0부터 다시 세어\n * 기존 행과 겹치는 문제였다. 그 하나를 `resumeRevision` 으로 풀었으므로 이제 이어 간다.\n *\n * 아직 이어지지 않는 것(정직하게): 시나리오 생성기의 난수 흐름은 재기동에 이어지지 않는다 —\n * 같은 씨앗에서 다시 시작하므로 자극의 패턴이 재기동 지점에서 한 번 끊긴다. 쌓인 사실과\n * 상태는 이어지고, 앞으로 일어날 일의 무작위 순서만 새로 시작한다.\n */\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[runtimeKey(domainId, instanceId)]\n }\n\n /** 삭제 — 정지 + 레지스트리 삭제 + 저널 purge(domain 스코프). */\n static async remove(domainId: string, instanceId: string): Promise<void> {\n await this.stop(domainId, instanceId)\n delete this.recovered[runtimeKey(domainId, 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) ?? { locations: [], equipment: [] }\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[runtimeKey(domainId, r.instanceId)],\n revision: last?.revision ?? 0,\n /*\n * **리더를 거쳐 센다** — 보드 키를 직접 읽으면 옛 세대 보드가 0 으로 보인다.\n *\n * 커널은 자리·설비 배열의 **옛 세대 키까지 흡수해** 읽어 주는데, 이 목록은 새 이름만 직접\n * 세고 있었다. 그래서 옛 보드 12개가 화면에 **자리 0 · 설비 0**\n * 으로 떴다 — 오류 없이, 그냥 빈 공장처럼. 세는 규칙이 두 벌이면 이런 식으로 갈라진다.\n */\n locationCount: readBoardLocations(board).length,\n equipmentCount: readBoardEquipment(board).length\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; locations: number; equipment: 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; locations: number; equipment: 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, locations: 0, equipment: 0 }\n a.instances++\n /* 목록과 **같은 규칙**으로 센다 — 여기만 직접 세면 공간 요약과 인스턴스 목록이 다른 수를 말한다. */\n a.locations += readBoardLocations(board).length\n a.equipment += readBoardEquipment(board).length\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 * `into.spaceId` — **이 현장에 더한다.** 한 현실을 여러 렌즈(WMS·MES·YMS)가 비추므로 새 트윈이\n * 기존 공간으로 들어갈 수 있다. 아래 병합은 원래 그 경우를 위해 있었는데(N:1) 만드는 흐름에서\n * 공간을 고를 방법이 없었다 — 마스터가 파생한 id 만 쓰였다. 판정은 `resolveIngestSpace`(순수).\n */\n static async ingestMaster(\n domainId: string,\n master: ReferenceMaster,\n into?: { spaceId?: string }\n ): Promise<{ instanceId: string; spaceId: string; warnings: IngestWarning[] }> {\n const { board, spaceContent, warnings } = masterToTwin(master, DOMAIN_CATALOG)\n const repo = getRepository(TwinSpace)\n /* 합칠 공간을 골랐으면 **있는지 먼저 확인한다** — 없는 곳에 조용히 새 공간을 만들면 사용자는\n 합쳤다고 믿고 화면은 따로 논다. 판정 함수가 그 경우 거절한다. */\n const wanted = (into?.spaceId ?? '').trim()\n const wantedExists = wanted\n ? (await repo.count({ where: { domain: { id: domainId }, spaceId: wanted } })) > 0\n : false\n const choice = resolveIngestSpace(board.spaceId, wanted, wantedExists)\n const spaceId: string = choice.spaceId\n board.spaceId = spaceId // 보드(커널 소비)도 같은 공간을 가리켜야 한다\n const existing = await repo.findOne({ where: { domain: { id: domainId }, spaceId } })\n if (choice.joined) {\n /* 같은 id 의 구역·랜드마크는 합집합으로 접힌다 — 가릴 수 없는 것을 고르지 않고 무엇이\n 합쳐졌는지 말한다(정당한 경우가 많으므로 막지 않는다). */\n const prevContent: any = existing?.content ?? {}\n const lm = collidingIds(prevContent.landmarks, (spaceContent as any).landmarks)\n if (lm.length) warnings.push(landmarkIdsMerged(spaceId, lm))\n }\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 /*\n * **현장의 시각 기준을 공간에 남긴다** — 그러지 않으면 공간이 권위인데 그 값을 영원히 모른다.\n *\n * 마스터가 보드에 오프셋을 실어 주므로 갓 프로비저닝한 트윈은 맞게 돌지만, `withSpaceTimeBase` 가\n * 읽는 곳은 **공간**이다. 여기서 옮기지 않으면 공간의 시간대가 계속 비어 있고, 사용자가 화면에서\n * 그것을 보거나 고칠 수도 없다(만들고 잇지 않으면 없는 것이다).\n *\n * **사용자가 고친 값을 마스터가 덮지 않는다** — 이미 있으면 그대로 둔다(현장이 정본을 이긴다).\n */\n const timezone = existing?.timezone || master.space.timezone\n const savedSpace = await repo.save(repo.create({ ...(existing ?? {}), domain: { id: domainId } as any, spaceId, name: existing?.name || master.siteName, ...(timezone ? { timezone } : {}), 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: ${describeWarnings(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[runtimeKey(domainId, 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) → equipment 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, inst.id)) {\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, await this.structureRevOf(domainId, instanceId)))\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[runtimeKey(domainId, 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(domainId, 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 wanted = rows.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\n /*\n * **그때의 공장으로 접는다.**\n *\n * 예전에는 모든 이벤트를 지금 등록된 보드 하나로 접었다. 구조가 바뀐 적 없으면 맞지만, 바뀐\n * 뒤에는 옛 사실을 새 공장에 대고 접게 되어 — 그때 없던 설비에서 일이 있었던 것처럼 보인다.\n * (그래서 예전 프로비저닝은 구조가 바뀌면 저널을 아예 지웠다. 역사를 잃거나 거짓말을 하거나.)\n *\n * 이제 이벤트가 자기 구조를 달고 오므로, 리비전이 바뀌는 지점에서 구조를 갈아타며 이어 접는다.\n * 리비전이 하나뿐이거나(대다수) 아예 없으면(구조 이력 이전) 예전과 똑같이 한 번에 접는다.\n */\n const structures = await getRepository(TwinStructure).find({\n where: { domain: { id: domainId }, instanceId },\n order: { rev: 'ASC' }\n })\n const boardOf = new Map<number, BoardDef>(structures.map(x => [x.rev, x.board as BoardDef]))\n /* 컬럼이 생기기 전 행은 리비전이 비어 있다 — **가장 오래된 구조**에 속한다(0 으로 채우지 않는다). */\n const oldest = structures[0]?.rev\n const revOf = (r: { structureRev?: number }): number | undefined => r.structureRev ?? oldest\n\n const segments: { board: BoardDef; events: any[] }[] = []\n for (const r of wanted) {\n if (!r.payload) continue\n const rev = revOf(r)\n const board = (rev !== undefined && boardOf.get(rev)) || (reg.board as BoardDef)\n const last = segments[segments.length - 1]\n if (last && last.board === board) last.events.push(r.payload)\n else segments.push({ board, events: [r.payload] })\n }\n /*\n * **가장 새 구조가 지금의 공장이다** — 그 아래에서 아직 아무 일도 없었더라도.\n *\n * 재프로비저닝 직후가 정확히 그 상태다: 부스를 넷 늘렸는데 새 이벤트는 아직 하나도 없다. 이때\n * 마지막 이벤트의 구조로만 접으면 화면은 **옛 공장**을 보여준다 — 방금 늘린 것이 안 보인다.\n * 그래서 마디의 끝에 지금 구조를 한 번 더 얹는다(이벤트 없는 마디).\n *\n * **다만 \"지금\" 을 물었을 때만이다.** 과거 시점을 물었는데 최신 구조를 얹으면, 그 시점에 없던\n * 설비가 화면에 서고 — 이 작업이 막으려던 바로 그 거짓말이 된다.\n */\n const asOfNow = untilRevision == null && untilTime == null\n const newest = structures[structures.length - 1]?.board as BoardDef | undefined\n if (asOfNow && newest && segments[segments.length - 1]?.board !== newest) segments.push({ board: newest, events: [] })\n\n /*\n * 접은 상태에 **주의 신호와 시각을 채운다.**\n *\n * 라이브·시뮬은 커널이 신호를 스스로 내지만, 저널을 접는 이 경로는 프로젝터 상태만 낸다 — 신호도\n * `nowTime` 도 없다. 그래서 **과거를 되짚으면 주의 레일이 텅 비었고**(지도는 `snap.attentions` 를\n * 읽는다), 기동돼 있지 않은 트윈을 보는 화면도 같았다. 신호는 상태에서 계산되는 것이므로\n * 여기서 같은 공식(`deriveAttentions`)으로 채우면 된다 — 두 벌을 두지 않는다.\n *\n * `nowTime` 이 먼저다: \"늦었나\" 판정이 그 값을 본다. 되짚은 시점의 정직한 \"지금\" 은 물어본 시각\n * (`untilTime`)이고, 없으면 마지막으로 적용한 이벤트의 시각이다. 둘 다 없으면 채우지 않는다 —\n * 벽시계를 끼워 넣으면 과거 화면이 \"지금 기준으로 늦었다\" 고 말하게 된다.\n */\n const lastEventTime = rows.length ? String(rows[rows.length - 1]?.eventTime ?? '') : ''\n\n /*\n * **가동 이력도 되살린다** — 되짚은 화면에 설비 계측이 비어 있던 것.\n *\n * OEE 는 원 시스템이 누적을 보내 주지 않아 호스트가 상태 전이를 적분해 만든다(그래서 커널이 아니라\n * 여기 있다). 그런데 그 누적기는 **라이브에서만** 돌았고, 저널을 접는 경로는 그 계산을 하지 않았다 —\n * 과거를 되짚으면 모든 설비가 \"가동 이력이 전혀 없음\" 으로 보였다.\n *\n * 없는 것은 데이터가 아니라 계산이다: 입력(`equipment.status` 전이·`quality.output`)은 저널에 다\n * 있다. 그래서 **같은 누적기에 같은 이벤트를 태운다** — 규칙을 두 벌 만들지 않는다.\n *\n * 시간여행에서도 맞다: 여기 태우는 것은 이미 잘라 낸(`wanted`) 이벤트뿐이므로, 그 시점까지의\n * 가동 이력이 나온다(그 뒤에 일어난 고장이 과거 화면에 섞이지 않는다).\n */\n const oee = new OeeAccumulator()\n for (const r of wanted) {\n try {\n oee.apply(r.payload as any)\n } catch {\n /* 한 건이 이상해도 나머지 계측을 버리지 않는다 — 누적기는 모르는 이벤트를 무시하는 계약이다. */\n }\n }\n\n const withNow = (st: any): any => {\n if (!st || typeof st !== 'object') return st\n const nowTime = st.nowTime || untilTime || lastEventTime || undefined\n const based = nowTime ? { ...st, nowTime } : st\n /* 계측 시점은 그 화면의 \"지금\" 이다 — 벽시계로 재면 과거 화면의 가용률이 시간이 갈수록 떨어진다. */\n const nowMs = nowTime ? Date.parse(String(nowTime)) : Number.NaN\n const withMetrics = withLiveOee(based, oee, Number.isFinite(nowMs) ? nowMs : undefined)\n return withLiveAttentions(withMetrics)\n }\n\n if (!segments.length) return withNow(replay(((asOfNow && newest) || reg.board) as BoardDef, []))\n if (segments.length === 1) return withNow(replay(segments[0].board, segments[0].events))\n\n const { state, shifts } = replaySegments(segments)\n /* 경계에서 사라진 것을 조용히 넘기지 않는다 — 수가 줄어든 이유를 어딘가에는 남겨야 한다. */\n for (const sh of shifts)\n if (sh.equipmentDropped || sh.locationsDropped || sh.personsDropped || sh.assetsDropped)\n console.info(`[twin-engine] \"${instanceId}\" replay crossed a structure change — dropped ${sh.equipmentDropped} equipment, ${sh.locationsDropped} locations, ${sh.personsDropped} persons, ${sh.assetsDropped} assets that no longer exist.`)\n return withNow(state)\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(domainId: string, id: string): Promise<void> {\n const i = this.instances[runtimeKey(domainId, id)]\n if (i) {\n clearInterval(i.timer)\n i.unsub()\n delete this.instances[runtimeKey(domainId, 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 /*\n * tick 한 번 — **한 트윈의 예외가 서버를 내리지 못하게** 감싼다.\n *\n * 잘못된 시나리오가 실렸을 때 다음 tick 에서 `rate.meanPerHour` 를 읽다 터졌고, 타이머 콜백의\n * 예외는 아무도 받지 않아 **uncaught exception 으로 프로세스가 내려갔다.** 한 테넌트의 잘못된\n * 선언이 모든 테넌트를 멈춘 셈이다. 문 앞에서 막는 것이 1차 방벽이고(`validateScenario`),\n * 이것이 2차 방벽이다.\n *\n * **조용히 삼키지 않는다.** 굴리기를 멈추고 그 사실을 남긴다 — 예외를 무시하고 계속 tick 하면\n * 같은 오류가 매 주기 쏟아지고, 그 트윈은 \"도는 것처럼 보이면서\" 아무것도 진행하지 않는다.\n */\n private static tickGuarded(domainId: string, id: string, runtime: TwinRuntimeType): void {\n try {\n runtime.tick(this.TICK_MS)\n } catch (err: any) {\n const inst = this.instances[runtimeKey(domainId, id)]\n if (inst?.timer) {\n clearInterval(inst.timer)\n inst.timer = undefined\n }\n console.error(\n `[twin-engine] \"${id}\" tick failed — simulation stopped for this twin (other twins keep running). ` +\n `Fix the declaration and start it again. Reason: ${err?.message ?? err}`\n )\n }\n }\n\n static runtime(domainId: string, id: string): TwinRuntimeType | undefined {\n return this.instances[runtimeKey(domainId, id)]?.runtime\n }\n\n /*\n * 커맨드 실행 — **판정은 `routeCommand`(순수)가 하고 여기서는 실행만** 한다.\n * 판정을 코드 한가운데 두면 이 부류를 테스트로 못 잡는다(엔진은 DB 를 물고 있어 단위 테스트가\n * 불러올 수 없다). 예전에는 리졸버가 `inst.runtime.dispatch` 를 곧바로 불러 미러에서 터졌다.\n */\n static async dispatchCommand(domainId: string, instanceId: string, command: any): Promise<{ accepted: boolean; error?: string; errorCode?: string; errorParams?: Record<string, string | number> }> {\n const inst = this.instances[runtimeKey(domainId, instanceId)]\n const type = String(command?.type ?? '')\n const route = routeCommand(\n inst && { mode: inst.mode, hasRuntime: !!inst.runtime, hasKernelDispatch: typeof (inst.kernel as any)?.dispatch === 'function' },\n !!inst && inst.domainId === domainId,\n type\n )\n if (route.target === 'reject') {\n return { accepted: false, errorCode: route.errorCode, errorParams: route.errorParams, error: route.errorCode }\n }\n\n const cmd = { ...command, tenantId: domainId } // tenantId 는 호출자 도메인으로 각인(감사·무결성)\n if (route.target === 'runtime') return inst!.runtime!.dispatch(cmd)\n\n /*\n * 미러 — 관측 커널로 보내고, **커맨드가 낸 사실을 저널 큐에 실어** 코얼레서가 번호를 부여하게 한다.\n * 미러에는 State 구독 배관이 없어(시뮬은 그 경로로 저널링) 커널 방출이 아무 데도 닿지 않는다.\n * 여기서 DB 를 따로 읽어 번호를 매기면 인메모리 카운터와 어긋나 리비전이 겹친다(겹침은 오류를\n * 내지 않고 재생 순서만 조용히 뒤섞는다).\n */\n const kernel: any = inst!.kernel\n const emitted: any[] = []\n const off = kernel.onEvent?.((e: any) => emitted.push(e))\n let ack: any\n try {\n ack = kernel.dispatch(cmd)\n } finally {\n off?.()\n }\n if (ack?.accepted && emitted.length) {\n inst!.pendingJournal = [...(inst!.pendingJournal ?? []), ...emitted]\n inst!.dirty = true // 코얼레서가 이번 주기에 비우고 방송까지 하게 한다\n }\n return ack ?? { accepted: false, errorCode: 'unknown-command', error: 'unknown-command' }\n }\n\n /**\n * 도메인 소유 게이트 — 인스턴스가 이 도메인 소유일 때만 true(테넌트 격리).\n * 없거나 다른 도메인이면 false. 노출 리졸버(per-id metrics/attentions/state/stop/forecast)가\n * this.instances[id] 를 만지기 전에 반드시 이걸로 확인해야 한다. 인스턴스 id 는 추측 가능하므로\n * 검증 없이 접근하면 크로스테넌트 읽기/정지가 가능해진다.\n */\n /**\n * 이 런타임의 **관측 모드** — `'live'`(외부 실물을 미러) 또는 `'sim'`(커널이 굴린다). 떠 있지 않으면 없다.\n *\n * 소비처가 `instances[id].mode` 를 직접 읽던 자리를 대신한다. 레지스트리를 밖에 열면 도메인 확인이\n * 자리마다 제각각이 되고, 실제로 그렇게 됐다(테넌트 격리 전수 확인, 2026-08-06).\n */\n static modeOf(domainId: string, id: string): 'live' | 'sim' | undefined {\n return this.instances[runtimeKey(domainId, id)]?.mode\n }\n\n static owns(domainId: string, id: string): boolean {\n return !!this.instances[runtimeKey(domainId, id)]\n }\n\n /**\n * 이 트윈이 이 테넌트 것인가 — **떠 있든 아니든.**\n *\n * `owns()` 는 **떠 있는** 런타임만 안다. 그것을 이력 조회의 관문으로 쓰면, 꺼진 트윈의 저널을\n * 읽으려 할 때 \"이 테넌트에 없다\" 는 답이 돌아온다 — 두 가지가 틀렸다. 첫째, 저널은 트윈이 꺼져\n * 있을 때 **가장 필요한 것**이다(그게 이력의 존재 이유다). 둘째, 그 문장은 남의 것이라는 뜻이라\n * 사용자가 권한 문제로 오해한다. 실제로는 그냥 안 돌고 있을 뿐이다.\n *\n * 소유는 **등록부**가 안다. 이력·집계처럼 런타임과 무관한 질문은 이쪽에 묻는다.\n */\n static async ownsRegistered(domainId: string, instanceId: string): Promise<boolean> {\n if (this.owns(domainId, instanceId)) return true\n return !!(await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } }))\n }\n\n /**\n * **이 공간의 인스턴스들** — 한 현실을 여러 렌즈가 비추므로, 공간을 물으면 그 렌즈 전부를 답한다.\n *\n * 화면이 이 규칙을 손으로 짜지 않게 서버가 답한다. 예측 화면은 같은 확장을 **한 파일에서 두 번**\n * 복제하고 있었다(전체 목록을 받아 클라이언트에서 걸렀다) — 규칙이 흩어지면 한쪽만 고쳐진다.\n *\n * 떠 있지 않은 것도 포함한다: 공간에 무엇이 있는지는 기동 여부와 다른 사실이다.\n */\n static async instanceIdsOfSpace(domainId: string, spaceId: string): Promise<string[]> {\n if (!spaceId) return []\n const rows = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n return rows.map(r => r.instanceId).filter((x): x is string => !!x)\n }\n\n /**\n * **이 공간에서 봐야 할 것** — 공간의 모든 렌즈에서 신호를 모은다.\n *\n * 합집합이 그대로 뜻이 있는 유일한 렌즈다(예측은 합칠 수 없다 — P50 두 개를 더할 수 없다).\n * 정렬·잘라내기는 화면과 **같은 규칙**을 쓴다(`digestAttentions`) — 서버가 고른 상위 N 이 화면이\n * 고를 N 과 달라지면 그 어긋남은 아무 데서도 오류로 드러나지 않는다.\n *\n * 신호마다 어느 트윈에서 왔는지(`instanceId`)를 붙인다. 공간에서 보면 같은 자리 id 가 렌즈마다\n * 다른 것을 가리킬 수 있고, 조치는 결국 그 트윈에 보내야 한다.\n */\n static async attentionsOfSpace(domainId: string, spaceId: string, limit?: number): Promise<{ attentions: any[]; attentionTotal: number; severityByLocation: Record<string, string> }> {\n const ids = await this.instanceIdsOfSpace(domainId, spaceId)\n const lenses = ids\n /* 떠 있지 않은 트윈은 **지금** 신호가 없다(그 시절 신호는 시간여행이 답한다). */\n .filter(id => this.owns(domainId, id))\n .map(id => {\n const kernel: any = this.kernel(domainId, id)\n const snap = kernel?.getSnapshot?.() ?? this.snapshot(domainId, id)\n return { instanceId: id, attentions: snap?.attentions ?? [] }\n })\n /* 모으는 규칙(태깅·급한 순서·자리 색)은 순수 함수가 들고 있다 — 여기서 손으로 접지 않는다. */\n return mergeLensAttentions(lenses, limit)\n }\n\n /** 라이브 커널(ForecastTwin) — forecast/divergence 예측 연산용. */\n static kernel(domainId: string, id: string): any {\n return this.instances[runtimeKey(domainId, id)]?.kernel\n }\n\n /** 라이브 처리량 계측 스냅샷(모니터, ④-1) — 내부 누적(_acc*) 제외한 공개 지표. live 아니면 null. */\n static metrics(domainId: string, id: string): any {\n const m = this.instances[runtimeKey(domainId, 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 /* 도메인 없이 부르면 전 테넌트를 훑는다(내부 모니터용) — 키에서 도메인을 되돌려 각자에게 묻는다. */\n const rows = Object.keys(this.instances)\n .filter(key => !domainId || isOfDomain(key, domainId))\n .map(key => {\n const at = parseRuntimeKey(key)\n return this.metrics(at.domainId, at.instanceId)\n })\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 * `buildForecastKernel` 은 **사라졌다**(통합 P3, 2026-08-01).\n *\n * 라이브가 `StateProjector` 였을 때는 커널이 없어서, 예측하려면 관측 스냅샷 + 저널의 오더 원값으로\n * **일회용 커널을 세워야** 했다. 이제 라이브 인스턴스가 곧 커널이므로(`startLive`) 그 자리에서\n * `fork` 하면 된다 — `TwinEngine.kernel(id)` 가 sim·live 둘 다 돌려준다.\n *\n * (오더 원값을 저널에서 되찾던 이유도 사라졌다 — 상태가 requested·fulfilled·lines 를 지킨다.)\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, undefined, this.productionSpecOf(reg.board as BoardDef))\n k.loadBoard(reg.board as BoardDef)\n this.applyOperations(k, reg.board, instanceId) // 예측도 같은 명세로 굴러야 한다(화면과 다른 숫자 금지)\n await this.installEstimators(k, domainId, instanceId, reg.board) // 예측은 기다린다 — 실측을 놓치면 예측이 상수로 돈다\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(domainId: string, id: string): any {\n const inst = this.instances[runtimeKey(domainId, id)]\n if (inst?.mode === 'live' && inst.projector) {\n /* live: **커널이 주목 신호를 스스로 낸다**(관측 모드) — 호스트가 덧붙이던 withLiveAttentions 는\n * 필요 없다. OEE 만 호스트가 채운다: 원 시스템이 시간 누적을 보내 주지 않아 상태 전이를 적분해\n * 만드는 값이라 커널이 대신할 수 없다(적합성 하네스의 유일한 예외). */\n const st = inst.projector.snapshot()\n return inst.oee ? withLiveOee(st, inst.oee) : st\n }\n return inst?.runtime?.resync() ?? this.recovered[runtimeKey(domainId, id)]\n }\n}\n"]}
|