@things-factory/headless-twin 10.1.278 → 10.1.280

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (614) hide show
  1. package/package.json +21 -7
  2. package/dist-server/engine/attention-digest.js.map +0 -1
  3. package/dist-server/engine/canonical-ingest.js.map +0 -1
  4. package/dist-server/engine/checkpoint-fold.js.map +0 -1
  5. package/dist-server/engine/command-routing.js.map +0 -1
  6. package/dist-server/engine/declared-stimulus.js.map +0 -1
  7. package/dist-server/engine/energy-topology.js.map +0 -1
  8. package/dist-server/engine/event-time.js.map +0 -1
  9. package/dist-server/engine/index.js.map +0 -1
  10. package/dist-server/engine/ingest-dedupe.js.map +0 -1
  11. package/dist-server/engine/ingest-health.js.map +0 -1
  12. package/dist-server/engine/integration-coverage.js.map +0 -1
  13. package/dist-server/engine/integration-probes.js.map +0 -1
  14. package/dist-server/engine/integration-runner.js.map +0 -1
  15. package/dist-server/engine/integration-target-profile.js.map +0 -1
  16. package/dist-server/engine/kpi-baseline.js.map +0 -1
  17. package/dist-server/engine/kpi-fold.js.map +0 -1
  18. package/dist-server/engine/kpi-query.js.map +0 -1
  19. package/dist-server/engine/kpi-target.js.map +0 -1
  20. package/dist-server/engine/live-attentions.js.map +0 -1
  21. package/dist-server/engine/live-feed-registry.js.map +0 -1
  22. package/dist-server/engine/load-meter.js.map +0 -1
  23. package/dist-server/engine/local-declarations.js.map +0 -1
  24. package/dist-server/engine/log.js.map +0 -1
  25. package/dist-server/engine/loop-lag.js.map +0 -1
  26. package/dist-server/engine/measured-estimator.js.map +0 -1
  27. package/dist-server/engine/measured-yield.js.map +0 -1
  28. package/dist-server/engine/model-basis.js.map +0 -1
  29. package/dist-server/engine/model-gap.js.map +0 -1
  30. package/dist-server/engine/model-refusal.js.map +0 -1
  31. package/dist-server/engine/model-vocabulary.js.map +0 -1
  32. package/dist-server/engine/oee-accumulator.js.map +0 -1
  33. package/dist-server/engine/operation-basis.js.map +0 -1
  34. package/dist-server/engine/producer-guard.js.map +0 -1
  35. package/dist-server/engine/property-effects.js.map +0 -1
  36. package/dist-server/engine/read-time.js.map +0 -1
  37. package/dist-server/engine/restart-policy.js.map +0 -1
  38. package/dist-server/engine/runtime-key.js.map +0 -1
  39. package/dist-server/engine/spec-coverage.js.map +0 -1
  40. package/dist-server/engine/stage-path.js.map +0 -1
  41. package/dist-server/engine/state-axes.js.map +0 -1
  42. package/dist-server/engine/structure-diff.js.map +0 -1
  43. package/dist-server/engine/travel-estimator.js.map +0 -1
  44. package/dist-server/engine/twin-engine.js.map +0 -1
  45. package/dist-server/engine/twin-state-channel.js.map +0 -1
  46. package/dist-server/engine/warm-start.js.map +0 -1
  47. package/dist-server/index.js.map +0 -1
  48. package/dist-server/migrations/1786000000000-RenameTwinInstanceBoardToModel.js.map +0 -1
  49. package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js.map +0 -1
  50. package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js.map +0 -1
  51. package/dist-server/migrations/1786300000000-IndexEventTypeByTime.js.map +0 -1
  52. package/dist-server/migrations/1786400000000-IndexEventCreatedAt.js.map +0 -1
  53. package/dist-server/migrations/1786500000000-CreateTwinSubjectEvents.js.map +0 -1
  54. package/dist-server/migrations/1786600000000-RenameOperatoMesAdapterType.js.map +0 -1
  55. package/dist-server/migrations/1786700000000-AddDispatchRetryColumns.js.map +0 -1
  56. package/dist-server/migrations/1786800000000-CreateTwinReferenceReconciliations.js.map +0 -1
  57. package/dist-server/migrations/index.js.map +0 -1
  58. package/dist-server/routes.js.map +0 -1
  59. package/dist-server/service/actuation/actuation-advisor.js.map +0 -1
  60. package/dist-server/service/actuation/actuation-outcome.js.map +0 -1
  61. package/dist-server/service/actuation/actuation-rule-resolver.js.map +0 -1
  62. package/dist-server/service/actuation/actuation-rule.js.map +0 -1
  63. package/dist-server/service/actuation/approval-gateway.js.map +0 -1
  64. package/dist-server/service/actuation/catch-up-effects.js.map +0 -1
  65. package/dist-server/service/actuation/command-dispatcher.js.map +0 -1
  66. package/dist-server/service/actuation/command-store.js.map +0 -1
  67. package/dist-server/service/actuation/dispatch-after-approval.js.map +0 -1
  68. package/dist-server/service/actuation/effect-match.js.map +0 -1
  69. package/dist-server/service/actuation/index.js.map +0 -1
  70. package/dist-server/service/actuation/retry-plan.js.map +0 -1
  71. package/dist-server/service/actuation/rule-evaluate.js.map +0 -1
  72. package/dist-server/service/actuation/rule-loop.js.map +0 -1
  73. package/dist-server/service/actuation/rule-runner.js.map +0 -1
  74. package/dist-server/service/actuation/rule-wiring.js.map +0 -1
  75. package/dist-server/service/actuation/settle-effects.js.map +0 -1
  76. package/dist-server/service/actuation/sweep-dispatch.js.map +0 -1
  77. package/dist-server/service/actuation/twin-command-resolver.js.map +0 -1
  78. package/dist-server/service/actuation/twin-command.js.map +0 -1
  79. package/dist-server/service/actuation/twin-now.js.map +0 -1
  80. package/dist-server/service/index.js.map +0 -1
  81. package/dist-server/service/reference/actuation-routing.js.map +0 -1
  82. package/dist-server/service/reference/actuation-target.js.map +0 -1
  83. package/dist-server/service/reference/actuation-verification.js.map +0 -1
  84. package/dist-server/service/reference/attention-lane.js.map +0 -1
  85. package/dist-server/service/reference/connection-portability-resolver.js.map +0 -1
  86. package/dist-server/service/reference/connection-portability.js.map +0 -1
  87. package/dist-server/service/reference/control-routing.js.map +0 -1
  88. package/dist-server/service/reference/discovery-result.js.map +0 -1
  89. package/dist-server/service/reference/fill-cadence.js.map +0 -1
  90. package/dist-server/service/reference/fill-dedupe.js.map +0 -1
  91. package/dist-server/service/reference/fill-loop.js.map +0 -1
  92. package/dist-server/service/reference/fill-span.js.map +0 -1
  93. package/dist-server/service/reference/hook-contract.js.map +0 -1
  94. package/dist-server/service/reference/hook-rejected.js.map +0 -1
  95. package/dist-server/service/reference/hook-store.js.map +0 -1
  96. package/dist-server/service/reference/index.js.map +0 -1
  97. package/dist-server/service/reference/ingest-space.js.map +0 -1
  98. package/dist-server/service/reference/knob-defaults.js.map +0 -1
  99. package/dist-server/service/reference/live-cadence.js.map +0 -1
  100. package/dist-server/service/reference/live-feed-lease.js.map +0 -1
  101. package/dist-server/service/reference/live-ingest.js.map +0 -1
  102. package/dist-server/service/reference/reference-adapter.js.map +0 -1
  103. package/dist-server/service/reference/reference-assessment.js.map +0 -1
  104. package/dist-server/service/reference/reference-fill-run.js.map +0 -1
  105. package/dist-server/service/reference/reference-fill.js.map +0 -1
  106. package/dist-server/service/reference/reference-hook.js.map +0 -1
  107. package/dist-server/service/reference/reference-link-groups.js.map +0 -1
  108. package/dist-server/service/reference/reference-links.js.map +0 -1
  109. package/dist-server/service/reference/reference-live.js.map +0 -1
  110. package/dist-server/service/reference/reference-master.js.map +0 -1
  111. package/dist-server/service/reference/reference-probe.js.map +0 -1
  112. package/dist-server/service/reference/reference-progress-channel.js.map +0 -1
  113. package/dist-server/service/reference/reference-progress-subscription.js.map +0 -1
  114. package/dist-server/service/reference/reference-progress.js.map +0 -1
  115. package/dist-server/service/reference/reference-reconciliation-query.js.map +0 -1
  116. package/dist-server/service/reference/reference-reconciliation-writer.js.map +0 -1
  117. package/dist-server/service/reference/reference-reconciliation.js.map +0 -1
  118. package/dist-server/service/reference/reference-registry.js.map +0 -1
  119. package/dist-server/service/reference/reference-resolver.js.map +0 -1
  120. package/dist-server/service/reference/template-registry.js.map +0 -1
  121. package/dist-server/service/reference/twin-reference-reconciliation.js.map +0 -1
  122. package/dist-server/service/reference/twin-reference.js.map +0 -1
  123. package/dist-server/service/twin-attention/index.js.map +0 -1
  124. package/dist-server/service/twin-attention/twin-attention-query.js.map +0 -1
  125. package/dist-server/service/twin-audit/command-audit.js.map +0 -1
  126. package/dist-server/service/twin-audit/index.js.map +0 -1
  127. package/dist-server/service/twin-audit/twin-audit-event.js.map +0 -1
  128. package/dist-server/service/twin-audit/twin-audit-query.js.map +0 -1
  129. package/dist-server/service/twin-backfill/backfill-period-facts.js.map +0 -1
  130. package/dist-server/service/twin-backfill/backfill-shape.js.map +0 -1
  131. package/dist-server/service/twin-backfill/index.js.map +0 -1
  132. package/dist-server/service/twin-backfill/twin-backfill-resolver.js.map +0 -1
  133. package/dist-server/service/twin-control/index.js.map +0 -1
  134. package/dist-server/service/twin-control/twin-control-mutation.js.map +0 -1
  135. package/dist-server/service/twin-event/index.js.map +0 -1
  136. package/dist-server/service/twin-event/journal-count.js.map +0 -1
  137. package/dist-server/service/twin-event/twin-event-keys.js.map +0 -1
  138. package/dist-server/service/twin-event/twin-event-type.js.map +0 -1
  139. package/dist-server/service/twin-event/twin-event.js.map +0 -1
  140. package/dist-server/service/twin-forecast/forecast-metrics.js.map +0 -1
  141. package/dist-server/service/twin-forecast/forecast-tuning.js.map +0 -1
  142. package/dist-server/service/twin-forecast/gap-analytics.js.map +0 -1
  143. package/dist-server/service/twin-forecast/index.js.map +0 -1
  144. package/dist-server/service/twin-forecast/twin-forecast-query.js.map +0 -1
  145. package/dist-server/service/twin-ingest-window/index.js.map +0 -1
  146. package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js.map +0 -1
  147. package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js.map +0 -1
  148. package/dist-server/service/twin-ingest-window/twin-ingest-window.js.map +0 -1
  149. package/dist-server/service/twin-instance/index.js.map +0 -1
  150. package/dist-server/service/twin-instance/twin-instance.js.map +0 -1
  151. package/dist-server/service/twin-journal/event-type-split-shape.js.map +0 -1
  152. package/dist-server/service/twin-journal/event-type-split.js.map +0 -1
  153. package/dist-server/service/twin-journal/index.js.map +0 -1
  154. package/dist-server/service/twin-journal/journal-order.js.map +0 -1
  155. package/dist-server/service/twin-journal/twin-journal-query.js.map +0 -1
  156. package/dist-server/service/twin-lifecycle/domain-catalog.js.map +0 -1
  157. package/dist-server/service/twin-lifecycle/index.js.map +0 -1
  158. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +0 -1
  159. package/dist-server/service/twin-metrics/index.js.map +0 -1
  160. package/dist-server/service/twin-metrics/twin-metrics-query.js.map +0 -1
  161. package/dist-server/service/twin-model/axis-journal-evidence.js.map +0 -1
  162. package/dist-server/service/twin-model/choose-recipe.js.map +0 -1
  163. package/dist-server/service/twin-model/epcis-coverage.js.map +0 -1
  164. package/dist-server/service/twin-model/external-resolver.js.map +0 -1
  165. package/dist-server/service/twin-model/iec61850-coverage.js.map +0 -1
  166. package/dist-server/service/twin-model/index.js.map +0 -1
  167. package/dist-server/service/twin-model/isa95-coverage.js.map +0 -1
  168. package/dist-server/service/twin-model/item-ref.js.map +0 -1
  169. package/dist-server/service/twin-model/name-index.js.map +0 -1
  170. package/dist-server/service/twin-model/project-structure.js.map +0 -1
  171. package/dist-server/service/twin-model/standard-coverage.js.map +0 -1
  172. package/dist-server/service/twin-model/status-tally.js.map +0 -1
  173. package/dist-server/service/twin-model/twin-equipment.js.map +0 -1
  174. package/dist-server/service/twin-model/twin-lineage-query.js.map +0 -1
  175. package/dist-server/service/twin-model/twin-location.js.map +0 -1
  176. package/dist-server/service/twin-model/twin-model-item-query.js.map +0 -1
  177. package/dist-server/service/twin-model/twin-model-mutation.js.map +0 -1
  178. package/dist-server/service/twin-model/twin-model-query.js.map +0 -1
  179. package/dist-server/service/twin-model/twin-model-tree-query.js.map +0 -1
  180. package/dist-server/service/twin-model/twin-operation.js.map +0 -1
  181. package/dist-server/service/twin-readiness/index.js.map +0 -1
  182. package/dist-server/service/twin-readiness/twin-readiness-query.js.map +0 -1
  183. package/dist-server/service/twin-space/area-resolver.js.map +0 -1
  184. package/dist-server/service/twin-space/index.js.map +0 -1
  185. package/dist-server/service/twin-space/move-space.js.map +0 -1
  186. package/dist-server/service/twin-space/representation-role.js.map +0 -1
  187. package/dist-server/service/twin-space/space-integrity.js.map +0 -1
  188. package/dist-server/service/twin-space/twin-area.js.map +0 -1
  189. package/dist-server/service/twin-space/twin-space-area.js.map +0 -1
  190. package/dist-server/service/twin-space/twin-space-representation.js.map +0 -1
  191. package/dist-server/service/twin-space/twin-space-resolver.js.map +0 -1
  192. package/dist-server/service/twin-space/twin-space.js.map +0 -1
  193. package/dist-server/service/twin-state/index.js.map +0 -1
  194. package/dist-server/service/twin-state/twin-state-subscription.js.map +0 -1
  195. package/dist-server/service/twin-structure/index.js.map +0 -1
  196. package/dist-server/service/twin-structure/twin-structure.js.map +0 -1
  197. package/dist-server/service/twin-subject/event-subjects.js.map +0 -1
  198. package/dist-server/service/twin-subject/index.js.map +0 -1
  199. package/dist-server/service/twin-subject/item-resolver.js.map +0 -1
  200. package/dist-server/service/twin-subject/subject-query-shape.js.map +0 -1
  201. package/dist-server/service/twin-subject/twin-subject-backfill.js.map +0 -1
  202. package/dist-server/service/twin-subject/twin-subject-event.js.map +0 -1
  203. package/dist-server/service/twin-subject/twin-subject-fast-path.js.map +0 -1
  204. package/dist-server/service/twin-subject/twin-subject-query.js.map +0 -1
  205. package/dist-server/service/twin-subject/twin-subject-writer.js.map +0 -1
  206. package/dist-server/service/twin-target/index.js.map +0 -1
  207. package/dist-server/service/twin-target/twin-target-resolver.js.map +0 -1
  208. package/dist-server/service/twin-target/twin-target.js.map +0 -1
  209. package/dist-shared/axis-read.js.map +0 -1
  210. package/dist-shared/entity-delta.js.map +0 -1
  211. package/dist-shared/kpi-broadcast.js.map +0 -1
  212. package/dist-shared/touched-items.js.map +0 -1
  213. package/dist-shared/twin-level.js.map +0 -1
  214. package/server/engine/attention-digest.ts +0 -102
  215. package/server/engine/canonical-ingest.ts +0 -511
  216. package/server/engine/checkpoint-fold.ts +0 -12
  217. package/server/engine/command-routing.ts +0 -67
  218. package/server/engine/declared-stimulus.ts +0 -66
  219. package/server/engine/energy-topology.ts +0 -189
  220. package/server/engine/event-time.ts +0 -96
  221. package/server/engine/index.ts +0 -51
  222. package/server/engine/ingest-dedupe.ts +0 -24
  223. package/server/engine/ingest-health.ts +0 -24
  224. package/server/engine/integration-coverage.ts +0 -147
  225. package/server/engine/integration-probes.ts +0 -144
  226. package/server/engine/integration-runner.ts +0 -95
  227. package/server/engine/integration-target-profile.ts +0 -103
  228. package/server/engine/kpi-baseline.ts +0 -202
  229. package/server/engine/kpi-fold.ts +0 -1516
  230. package/server/engine/kpi-query.ts +0 -1210
  231. package/server/engine/kpi-target.ts +0 -248
  232. package/server/engine/live-attentions.ts +0 -30
  233. package/server/engine/live-feed-registry.ts +0 -59
  234. package/server/engine/load-meter.ts +0 -393
  235. package/server/engine/local-declarations.ts +0 -779
  236. package/server/engine/log.ts +0 -72
  237. package/server/engine/loop-lag.ts +0 -120
  238. package/server/engine/measured-estimator.ts +0 -91
  239. package/server/engine/measured-yield.ts +0 -89
  240. package/server/engine/model-basis.ts +0 -162
  241. package/server/engine/model-gap.ts +0 -168
  242. package/server/engine/model-refusal.ts +0 -31
  243. package/server/engine/model-vocabulary.ts +0 -82
  244. package/server/engine/oee-accumulator.ts +0 -195
  245. package/server/engine/operation-basis.ts +0 -131
  246. package/server/engine/producer-guard.ts +0 -64
  247. package/server/engine/property-effects.ts +0 -216
  248. package/server/engine/read-time.ts +0 -77
  249. package/server/engine/restart-policy.ts +0 -55
  250. package/server/engine/runtime-key.ts +0 -58
  251. package/server/engine/spec-coverage.ts +0 -105
  252. package/server/engine/stage-path.ts +0 -172
  253. package/server/engine/state-axes.ts +0 -60
  254. package/server/engine/structure-diff.ts +0 -88
  255. package/server/engine/travel-estimator.ts +0 -138
  256. package/server/engine/twin-engine.ts +0 -4979
  257. package/server/engine/twin-state-channel.ts +0 -39
  258. package/server/engine/warm-start.ts +0 -265
  259. package/server/index.ts +0 -90
  260. package/server/migrations/1786000000000-RenameTwinInstanceBoardToModel.ts +0 -43
  261. package/server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.ts +0 -54
  262. package/server/migrations/1786200000000-CarryLiveFeedCursor.ts +0 -53
  263. package/server/migrations/1786300000000-IndexEventTypeByTime.ts +0 -48
  264. package/server/migrations/1786400000000-IndexEventCreatedAt.ts +0 -38
  265. package/server/migrations/1786500000000-CreateTwinSubjectEvents.ts +0 -93
  266. package/server/migrations/1786600000000-RenameOperatoMesAdapterType.ts +0 -66
  267. package/server/migrations/1786700000000-AddDispatchRetryColumns.ts +0 -82
  268. package/server/migrations/1786800000000-CreateTwinReferenceReconciliations.ts +0 -39
  269. package/server/migrations/index.ts +0 -25
  270. package/server/routes.ts +0 -75
  271. package/server/service/actuation/actuation-advisor.ts +0 -131
  272. package/server/service/actuation/actuation-outcome.ts +0 -97
  273. package/server/service/actuation/actuation-rule-resolver.ts +0 -147
  274. package/server/service/actuation/actuation-rule.ts +0 -139
  275. package/server/service/actuation/approval-gateway.ts +0 -44
  276. package/server/service/actuation/catch-up-effects.ts +0 -152
  277. package/server/service/actuation/command-dispatcher.ts +0 -474
  278. package/server/service/actuation/command-store.ts +0 -236
  279. package/server/service/actuation/dispatch-after-approval.ts +0 -71
  280. package/server/service/actuation/effect-match.ts +0 -124
  281. package/server/service/actuation/index.ts +0 -27
  282. package/server/service/actuation/retry-plan.ts +0 -145
  283. package/server/service/actuation/rule-evaluate.ts +0 -352
  284. package/server/service/actuation/rule-loop.ts +0 -160
  285. package/server/service/actuation/rule-runner.ts +0 -216
  286. package/server/service/actuation/rule-wiring.ts +0 -84
  287. package/server/service/actuation/settle-effects.ts +0 -115
  288. package/server/service/actuation/sweep-dispatch.ts +0 -179
  289. package/server/service/actuation/twin-command-resolver.ts +0 -387
  290. package/server/service/actuation/twin-command.ts +0 -232
  291. package/server/service/actuation/twin-now.ts +0 -97
  292. package/server/service/index.ts +0 -100
  293. package/server/service/reference/actuation-routing.ts +0 -192
  294. package/server/service/reference/actuation-target.ts +0 -163
  295. package/server/service/reference/actuation-verification.ts +0 -85
  296. package/server/service/reference/attention-lane.ts +0 -21
  297. package/server/service/reference/connection-portability-resolver.ts +0 -171
  298. package/server/service/reference/connection-portability.ts +0 -329
  299. package/server/service/reference/control-routing.ts +0 -62
  300. package/server/service/reference/discovery-result.ts +0 -95
  301. package/server/service/reference/fill-cadence.ts +0 -29
  302. package/server/service/reference/fill-dedupe.ts +0 -66
  303. package/server/service/reference/fill-loop.ts +0 -153
  304. package/server/service/reference/fill-span.ts +0 -31
  305. package/server/service/reference/hook-contract.ts +0 -364
  306. package/server/service/reference/hook-rejected.ts +0 -53
  307. package/server/service/reference/hook-store.ts +0 -28
  308. package/server/service/reference/index.ts +0 -18
  309. package/server/service/reference/ingest-space.ts +0 -104
  310. package/server/service/reference/knob-defaults.ts +0 -59
  311. package/server/service/reference/live-cadence.ts +0 -129
  312. package/server/service/reference/live-feed-lease.ts +0 -56
  313. package/server/service/reference/live-ingest.ts +0 -94
  314. package/server/service/reference/reference-adapter.ts +0 -985
  315. package/server/service/reference/reference-assessment.ts +0 -250
  316. package/server/service/reference/reference-fill-run.ts +0 -179
  317. package/server/service/reference/reference-fill.ts +0 -223
  318. package/server/service/reference/reference-hook.ts +0 -479
  319. package/server/service/reference/reference-link-groups.ts +0 -21
  320. package/server/service/reference/reference-links.ts +0 -77
  321. package/server/service/reference/reference-live.ts +0 -420
  322. package/server/service/reference/reference-master.ts +0 -999
  323. package/server/service/reference/reference-probe.ts +0 -264
  324. package/server/service/reference/reference-progress-channel.ts +0 -26
  325. package/server/service/reference/reference-progress-subscription.ts +0 -78
  326. package/server/service/reference/reference-progress.ts +0 -95
  327. package/server/service/reference/reference-reconciliation-query.ts +0 -28
  328. package/server/service/reference/reference-reconciliation-writer.ts +0 -38
  329. package/server/service/reference/reference-reconciliation.ts +0 -55
  330. package/server/service/reference/reference-registry.ts +0 -17
  331. package/server/service/reference/reference-resolver.ts +0 -969
  332. package/server/service/reference/template-registry.ts +0 -85
  333. package/server/service/reference/twin-reference-reconciliation.ts +0 -27
  334. package/server/service/reference/twin-reference.ts +0 -190
  335. package/server/service/twin-attention/index.ts +0 -3
  336. package/server/service/twin-attention/twin-attention-query.ts +0 -70
  337. package/server/service/twin-audit/command-audit.ts +0 -114
  338. package/server/service/twin-audit/index.ts +0 -5
  339. package/server/service/twin-audit/twin-audit-event.ts +0 -158
  340. package/server/service/twin-audit/twin-audit-query.ts +0 -72
  341. package/server/service/twin-backfill/backfill-period-facts.ts +0 -168
  342. package/server/service/twin-backfill/backfill-shape.ts +0 -86
  343. package/server/service/twin-backfill/index.ts +0 -3
  344. package/server/service/twin-backfill/twin-backfill-resolver.ts +0 -35
  345. package/server/service/twin-control/index.ts +0 -3
  346. package/server/service/twin-control/twin-control-mutation.ts +0 -150
  347. package/server/service/twin-event/index.ts +0 -3
  348. package/server/service/twin-event/journal-count.ts +0 -53
  349. package/server/service/twin-event/twin-event-keys.ts +0 -215
  350. package/server/service/twin-event/twin-event-type.ts +0 -68
  351. package/server/service/twin-event/twin-event.ts +0 -250
  352. package/server/service/twin-forecast/forecast-metrics.ts +0 -106
  353. package/server/service/twin-forecast/forecast-tuning.ts +0 -40
  354. package/server/service/twin-forecast/gap-analytics.ts +0 -139
  355. package/server/service/twin-forecast/index.ts +0 -3
  356. package/server/service/twin-forecast/twin-forecast-query.ts +0 -486
  357. package/server/service/twin-ingest-window/index.ts +0 -7
  358. package/server/service/twin-ingest-window/twin-ingest-window-query.ts +0 -125
  359. package/server/service/twin-ingest-window/twin-ingest-window-writer.ts +0 -57
  360. package/server/service/twin-ingest-window/twin-ingest-window.ts +0 -113
  361. package/server/service/twin-instance/index.ts +0 -3
  362. package/server/service/twin-instance/twin-instance.ts +0 -199
  363. package/server/service/twin-journal/event-type-split-shape.ts +0 -112
  364. package/server/service/twin-journal/event-type-split.ts +0 -144
  365. package/server/service/twin-journal/index.ts +0 -3
  366. package/server/service/twin-journal/journal-order.ts +0 -20
  367. package/server/service/twin-journal/twin-journal-query.ts +0 -615
  368. package/server/service/twin-lifecycle/domain-catalog.ts +0 -51
  369. package/server/service/twin-lifecycle/index.ts +0 -3
  370. package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +0 -285
  371. package/server/service/twin-metrics/index.ts +0 -3
  372. package/server/service/twin-metrics/twin-metrics-query.ts +0 -172
  373. package/server/service/twin-model/axis-journal-evidence.ts +0 -57
  374. package/server/service/twin-model/choose-recipe.ts +0 -31
  375. package/server/service/twin-model/epcis-coverage.ts +0 -251
  376. package/server/service/twin-model/external-resolver.ts +0 -173
  377. package/server/service/twin-model/iec61850-coverage.ts +0 -111
  378. package/server/service/twin-model/index.ts +0 -25
  379. package/server/service/twin-model/isa95-coverage.ts +0 -320
  380. package/server/service/twin-model/item-ref.ts +0 -80
  381. package/server/service/twin-model/name-index.ts +0 -94
  382. package/server/service/twin-model/project-structure.ts +0 -213
  383. package/server/service/twin-model/standard-coverage.ts +0 -35
  384. package/server/service/twin-model/status-tally.ts +0 -37
  385. package/server/service/twin-model/twin-equipment.ts +0 -191
  386. package/server/service/twin-model/twin-lineage-query.ts +0 -327
  387. package/server/service/twin-model/twin-location.ts +0 -147
  388. package/server/service/twin-model/twin-model-item-query.ts +0 -1029
  389. package/server/service/twin-model/twin-model-mutation.ts +0 -503
  390. package/server/service/twin-model/twin-model-query.ts +0 -792
  391. package/server/service/twin-model/twin-model-tree-query.ts +0 -211
  392. package/server/service/twin-model/twin-operation.ts +0 -157
  393. package/server/service/twin-readiness/index.ts +0 -3
  394. package/server/service/twin-readiness/twin-readiness-query.ts +0 -96
  395. package/server/service/twin-space/area-resolver.ts +0 -75
  396. package/server/service/twin-space/index.ts +0 -8
  397. package/server/service/twin-space/move-space.ts +0 -262
  398. package/server/service/twin-space/representation-role.ts +0 -15
  399. package/server/service/twin-space/space-integrity.ts +0 -293
  400. package/server/service/twin-space/twin-area.ts +0 -63
  401. package/server/service/twin-space/twin-space-area.ts +0 -66
  402. package/server/service/twin-space/twin-space-representation.ts +0 -99
  403. package/server/service/twin-space/twin-space-resolver.ts +0 -582
  404. package/server/service/twin-space/twin-space.ts +0 -148
  405. package/server/service/twin-state/index.ts +0 -3
  406. package/server/service/twin-state/twin-state-subscription.ts +0 -62
  407. package/server/service/twin-structure/index.ts +0 -3
  408. package/server/service/twin-structure/twin-structure.ts +0 -96
  409. package/server/service/twin-subject/event-subjects.ts +0 -162
  410. package/server/service/twin-subject/index.ts +0 -10
  411. package/server/service/twin-subject/item-resolver.ts +0 -92
  412. package/server/service/twin-subject/subject-query-shape.ts +0 -84
  413. package/server/service/twin-subject/twin-subject-backfill.ts +0 -196
  414. package/server/service/twin-subject/twin-subject-event.ts +0 -101
  415. package/server/service/twin-subject/twin-subject-fast-path.ts +0 -346
  416. package/server/service/twin-subject/twin-subject-query.ts +0 -210
  417. package/server/service/twin-subject/twin-subject-writer.ts +0 -189
  418. package/server/service/twin-target/index.ts +0 -5
  419. package/server/service/twin-target/twin-target-resolver.ts +0 -142
  420. package/server/service/twin-target/twin-target.ts +0 -97
  421. package/server/types/global.d.ts +0 -22
  422. package/shared/axis-read.ts +0 -28
  423. package/shared/entity-delta.ts +0 -335
  424. package/shared/kpi-broadcast.ts +0 -13
  425. package/shared/touched-items.ts +0 -73
  426. package/shared/twin-level.ts +0 -48
  427. package/test/ack-shape-alignment.test.ts +0 -97
  428. package/test/actuation-advisor.test.ts +0 -55
  429. package/test/actuation-approval-door.test.ts +0 -411
  430. package/test/actuation-dispatch.test.ts +0 -209
  431. package/test/actuation-effect.test.ts +0 -162
  432. package/test/actuation-outcome.test.ts +0 -152
  433. package/test/actuation-rule-runner.test.ts +0 -281
  434. package/test/actuation-rule.test.ts +0 -266
  435. package/test/actuation-seam.test.ts +0 -255
  436. package/test/actuation-settle.test.ts +0 -164
  437. package/test/actuation-target.test.ts +0 -145
  438. package/test/actuation-verification-state.test.ts +0 -139
  439. package/test/adopt-structure-live.test.ts +0 -133
  440. package/test/aggregate-not-findone.test.ts +0 -112
  441. package/test/area-resolver-db.test.ts +0 -110
  442. package/test/attention-digest.test.ts +0 -161
  443. package/test/axis-declaration-passthrough-db.test.ts +0 -152
  444. package/test/axis-journal-evidence.test.ts +0 -71
  445. package/test/axis-read.test.ts +0 -188
  446. package/test/backfill-shape.test.ts +0 -89
  447. package/test/boot-resume.test.ts +0 -287
  448. package/test/broadcast-cost-baseline.test.ts +0 -201
  449. package/test/broadcast-period.test.ts +0 -58
  450. package/test/broadcast-queue-overflow.test.ts +0 -244
  451. package/test/canonical-ingest-vocabularies.test.ts +0 -451
  452. package/test/canonical-quantity-door.test.ts +0 -61
  453. package/test/capability-mapping.test.ts +0 -89
  454. package/test/checkpoint-refuses-empty.test.ts +0 -103
  455. package/test/choose-recipe.test.ts +0 -117
  456. package/test/column-type-portability.test.ts +0 -122
  457. package/test/command-routing.test.ts +0 -61
  458. package/test/command-store-writes-columns.test.ts +0 -126
  459. package/test/connection-portability-doors.test.ts +0 -87
  460. package/test/connector-capability-declaration.test.ts +0 -195
  461. package/test/contract-layer-guard.test.ts +0 -48
  462. package/test/control-capability.test.ts +0 -98
  463. package/test/cursor-stall-not-read-failure.test.ts +0 -126
  464. package/test/declaration-reaches-model.test.ts +0 -226
  465. package/test/declared-location-types.test.ts +0 -89
  466. package/test/declared-stimulus.test.ts +0 -88
  467. package/test/dedupe-transformation.test.ts +0 -112
  468. package/test/discovery-result.test.ts +0 -75
  469. package/test/dispatch-after-approval-source.test.ts +0 -81
  470. package/test/duration-estimators.test.ts +0 -144
  471. package/test/energy-topology.test.ts +0 -113
  472. package/test/entity-delta.test.ts +0 -352
  473. package/test/equipment-identity-reaches.test.ts +0 -57
  474. package/test/event-subjects.test.ts +0 -148
  475. package/test/event-time-column.test.ts +0 -67
  476. package/test/event-type-split.test.ts +0 -178
  477. package/test/external-resolver.test.ts +0 -177
  478. package/test/fact-scope-wiring.test.ts +0 -96
  479. package/test/fill-dedupe.test.ts +0 -59
  480. package/test/fill-loop.test.ts +0 -35
  481. package/test/first-envelope.test.ts +0 -153
  482. package/test/fold-gap-speaks.test.ts +0 -53
  483. package/test/fold-shift-dst.test.ts +0 -110
  484. package/test/forecast-metrics.test.ts +0 -157
  485. package/test/forecast-tuning.test.ts +0 -42
  486. package/test/gap-analytics.test.ts +0 -113
  487. package/test/generated-not-counted.test.ts +0 -99
  488. package/test/guard-roots.ts +0 -76
  489. package/test/home-in-area.test.ts +0 -90
  490. package/test/hook-address.test.ts +0 -28
  491. package/test/hook-rejected-shape.test.ts +0 -86
  492. package/test/hook-response-sum.test.ts +0 -193
  493. package/test/hook-sequence.test.ts +0 -333
  494. package/test/ingest-bench.test.ts +0 -70
  495. package/test/ingest-dedupe.test.ts +0 -56
  496. package/test/ingest-expected-quiet.test.ts +0 -111
  497. package/test/ingest-health-engine.test.ts +0 -248
  498. package/test/ingest-health-wiring.test.ts +0 -120
  499. package/test/ingest-health.test.ts +0 -306
  500. package/test/ingest-history.test.ts +0 -247
  501. package/test/ingest-idempotent.test.ts +0 -211
  502. package/test/ingest-reconcile-four-ways.test.ts +0 -97
  503. package/test/ingest-rules-header.test.ts +0 -100
  504. package/test/ingest-running-guard.test.ts +0 -136
  505. package/test/ingest-space.test.ts +0 -78
  506. package/test/ingest-window-rolls-unobserved.test.ts +0 -72
  507. package/test/ingest-wiring-guard.test.ts +0 -197
  508. package/test/instance-cache-lifecycle.test.ts +0 -110
  509. package/test/intake-mapping-parity.test.ts +0 -175
  510. package/test/integration-probes.test.ts +0 -103
  511. package/test/integration-runner.test.ts +0 -95
  512. package/test/item-ref.test.ts +0 -78
  513. package/test/journal-order-axis.test.ts +0 -80
  514. package/test/journal-read-discipline.test.ts +0 -186
  515. package/test/journal-retention.test.ts +0 -275
  516. package/test/journal-sort-axis.test.ts +0 -142
  517. package/test/journal-write-door.test.ts +0 -110
  518. package/test/journal-write-trend.test.ts +0 -115
  519. package/test/kernel-kind-guard.test.ts +0 -98
  520. package/test/knob-defaults.test.ts +0 -72
  521. package/test/kpi-baseline-db.test.ts +0 -216
  522. package/test/kpi-baseline.test.ts +0 -196
  523. package/test/kpi-fold.test.ts +0 -1456
  524. package/test/kpi-query-bench.test.ts +0 -130
  525. package/test/lens-own-places.test.ts +0 -50
  526. package/test/lineage-survives-restart.test.ts +0 -234
  527. package/test/live-cadence.test.ts +0 -170
  528. package/test/live-cursor-wiring.test.ts +0 -87
  529. package/test/live-feed-lease.test.ts +0 -63
  530. package/test/live-feed-registry.test.ts +0 -75
  531. package/test/live-kernel-facts.test.ts +0 -161
  532. package/test/live-mirror-parity.test.ts +0 -286
  533. package/test/load-meter.test.ts +0 -328
  534. package/test/local-declarations.test.ts +0 -662
  535. package/test/log-stamp.test.ts +0 -59
  536. package/test/loop-lag.test.ts +0 -82
  537. package/test/master-to-twin.test.ts +0 -279
  538. package/test/measured-yield.test.ts +0 -90
  539. package/test/merge-streams.test.ts +0 -70
  540. package/test/mirror-resumes-from-checkpoint.test.ts +0 -192
  541. package/test/model-basis.test.ts +0 -141
  542. package/test/model-gap.test.ts +0 -153
  543. package/test/model-refusal.test.ts +0 -75
  544. package/test/model-vocabulary.test.ts +0 -114
  545. package/test/move-space.test.ts +0 -149
  546. package/test/mutation-gate.test.ts +0 -122
  547. package/test/oee-accumulator.test.ts +0 -204
  548. package/test/oee-site-calendar.test.ts +0 -146
  549. package/test/open-doors.test.ts +0 -197
  550. package/test/operation-basis.test.ts +0 -127
  551. package/test/operational-vocabulary.test.ts +0 -108
  552. package/test/operations-capability-db.test.ts +0 -165
  553. package/test/order-and-transaction-split.test.ts +0 -107
  554. package/test/order-fold-host.test.ts +0 -112
  555. package/test/producer-guard.test.ts +0 -66
  556. package/test/project-structure-db.test.ts +0 -226
  557. package/test/projection-reaches-screen.test.ts +0 -277
  558. package/test/projection-reads-declared.test.ts +0 -109
  559. package/test/property-effects.test.ts +0 -128
  560. package/test/provenance-promotion.test.ts +0 -99
  561. package/test/read-failure-ledger.test.ts +0 -106
  562. package/test/read-failure-visible.test.ts +0 -145
  563. package/test/read-time.test.ts +0 -118
  564. package/test/reference-fill.test.ts +0 -235
  565. package/test/reference-grounding.test.ts +0 -70
  566. package/test/reference-hook.test.ts +0 -177
  567. package/test/reference-links.test.ts +0 -56
  568. package/test/reference-reconciliation.test.ts +0 -39
  569. package/test/registry-key-guard.test.ts +0 -80
  570. package/test/rejection-carries-event-id.test.ts +0 -101
  571. package/test/rename-twin.test.ts +0 -89
  572. package/test/resolve-ts-siblings.mjs +0 -52
  573. package/test/restart-policy.test.ts +0 -111
  574. package/test/resync-origin-site.test.ts +0 -83
  575. package/test/retry-plan.test.ts +0 -139
  576. package/test/revision-axis.test.ts +0 -110
  577. package/test/runtime-key.test.ts +0 -66
  578. package/test/save-intake-collision.test.ts +0 -91
  579. package/test/scale-twin-bench.test.ts +0 -103
  580. package/test/secrets-at-rest.test.ts +0 -135
  581. package/test/snapshot-freshness.test.ts +0 -60
  582. package/test/source-outcome-audit.test.ts +0 -104
  583. package/test/space-integrity.test.ts +0 -223
  584. package/test/space-representation.test.ts +0 -66
  585. package/test/space-scope-includes-stopped.test.ts +0 -55
  586. package/test/spec-coverage.test.ts +0 -113
  587. package/test/stage-path.test.ts +0 -95
  588. package/test/standard-coverage.test.ts +0 -148
  589. package/test/state-axes.test.ts +0 -74
  590. package/test/status-tally.test.ts +0 -55
  591. package/test/streamline-e2e.test.ts +0 -76
  592. package/test/structure-revision-db.test.ts +0 -315
  593. package/test/subject-fast-path.test.ts +0 -148
  594. package/test/subject-read-model.test.ts +0 -175
  595. package/test/sweep-dispatch.test.ts +0 -191
  596. package/test/tenant-registry-db.test.ts +0 -149
  597. package/test/time-range.test.ts +0 -152
  598. package/test/touched-items.test.ts +0 -61
  599. package/test/twin-audit.test.ts +0 -83
  600. package/test/twin-event-keys.test.ts +0 -193
  601. package/test/twin-model-item-db.test.ts +0 -319
  602. package/test/twin-model-parent-relation-db.test.ts +0 -125
  603. package/test/twin-model-tree-db.test.ts +0 -209
  604. package/test/twin-origin-resync.test.ts +0 -133
  605. package/test/twin-state-channel.test.ts +0 -111
  606. package/test/vocabulary-guard.test.ts +0 -43
  607. package/test/warm-start-seam.test.ts +0 -162
  608. package/test/warm-start.test.ts +0 -297
  609. package/test/withheld-door.test.ts +0 -95
  610. package/test/yield-loop.test.ts +0 -199
  611. package/tsconfig.json +0 -15
  612. package/tsconfig.shared.json +0 -23
  613. package/tsconfig.shared.tsbuildinfo +0 -1
  614. package/tsconfig.tsbuildinfo +0 -1
@@ -1,130 +0,0 @@
1
- /*
2
- * 구간 성과 질의 비용 측정 — **브로드캐스팅이냐 질의냐를 숫자로 정한다.**
3
- *
4
- * ── 왜 재는가 (2026-08-06) ─────────────────────────────────────────────────
5
- * 성과 카드를 여러 단계(공간·트윈·구역·자리·설비)에 붙이려 한다. 두 방법이 있다.
6
- *
7
- * · 브로드캐스팅 — 서버가 주기마다 전 단계를 계산해 밀어 준다. 자리가 트윈당 최대 200개고 지표가 6개라
8
- * 태그가 1,200개가 된다. **모델에 카드를 하나도 안 놓아도 계산은 돈다.**
9
- * · 질의 — 카드가 필요할 때 묻는다. **모델에 놓인 카드 수만큼만** 든다. 시각(`toTime`)도 물을 수 있어
10
- * 타임라인과 맞고, 공간 단위 합산(여러 트윈을 한 번에 계산)은 질의에만 있다.
11
- *
12
- * 질의로 정하려면 **한 번의 비용**을 알아야 한다. 카드 20장이 30초마다 물으면 감당되는지가 결정을
13
- * 가른다. 짐작하지 않고 잰다.
14
- *
15
- * 빌드 산출물을 실행한다 — **소스를 고친 뒤에는 `npm run build:server` 를 먼저 돌린다.**
16
- */
17
- import { test, before, after } from 'node:test'
18
- import { createRequire } from 'node:module'
19
- import type { DataSource } from 'typeorm'
20
-
21
- const req = createRequire(import.meta.url)
22
- const { NamingStrategy, addDataSource, entities: shellEntities, Domain } = req('@things-factory/shell')
23
- const { entities: authEntities } = req('@things-factory/auth-base')
24
- const { entities: twinEntities } = req('../dist-server/service/index.js')
25
- const { computeTwinKpi } = req('../dist-server/engine/index.js')
26
- const { TwinEvent } = req('../dist-server/service/twin-event/twin-event.js')
27
- const { TwinInstance } = req('../dist-server/service/twin-instance/twin-instance.js')
28
- const { DataSource: TypeOrmDataSource } = req('typeorm')
29
-
30
- let ds: DataSource
31
- let domainId: string
32
-
33
- const INSTANCE = 'kpi-bench'
34
- const TO = Date.parse('2026-03-10T10:00:00.000Z')
35
- const WINDOW_MIN = 60
36
-
37
- /** 자리 200개 — 실측한 최대 규모(트윈당 자리 최대 200, 평균 19). */
38
- const LOCATIONS = 200
39
- /** 창 안의 완료 작업 수 — 한 건이 두 줄(시작·완료)이라 이벤트는 두 배가 된다. */
40
- const TASK_COUNTS = [500, 2_000, 10_000]
41
-
42
- function taskRows(count: number, revBase: number) {
43
- const rows: any[] = []
44
- for (let i = 0; i < count; i++) {
45
- const done = TO - 60_000 - (i % (WINDOW_MIN * 60)) * 1000
46
- const started = done - 30_000
47
- const at = `loc-${i % LOCATIONS}`
48
- rows.push(
49
- {
50
- domain: { id: domainId },
51
- instanceId: INSTANCE,
52
- revision: revBase + i * 2,
53
- eventType: 'task.status',
54
- eventTime: new Date(started).toISOString(),
55
- payload: { data: { taskId: `t-${i}`, status: 'in-progress', resourceRef: 'fk-1', locationRef: at } }
56
- },
57
- {
58
- domain: { id: domainId },
59
- instanceId: INSTANCE,
60
- revision: revBase + i * 2 + 1,
61
- eventType: 'task.status',
62
- eventTime: new Date(done).toISOString(),
63
- payload: { data: { taskId: `t-${i}`, status: 'completed', resourceRef: 'fk-1', locationRef: at } }
64
- }
65
- )
66
- }
67
- return rows
68
- }
69
-
70
- before(async () => {
71
- ds = new TypeOrmDataSource({
72
- type: 'sqlite',
73
- database: ':memory:',
74
- synchronize: true,
75
- dropSchema: true,
76
- namingStrategy: new NamingStrategy(),
77
- entities: [...shellEntities, ...authEntities, ...twinEntities],
78
- logging: false
79
- })
80
- await ds.initialize()
81
- addDataSource('default', ds)
82
- const d = await ds.getRepository(Domain).save({ name: 'kpi-bench', subdomain: 'kpi-bench' } as any)
83
- domainId = d.id
84
-
85
- /* 자리 계층 — 자리 200개를 구역 4개에 나눠 붙인다(구역 단위 계산 비용도 재려면 부모가 있어야 한다). */
86
- const locations = Array.from({ length: LOCATIONS }, (_, i) => ({
87
- id: `loc-${i}`,
88
- type: 'storage',
89
- capacity: 10,
90
- parentId: `area-${i % 4}`
91
- }))
92
- await ds.getRepository(TwinInstance).save({
93
- domain: { id: domainId },
94
- instanceId: INSTANCE,
95
- kind: 'wms',
96
- restartPolicy: 'reset', /* 선언은 이제 필수 — 비워 두면 읽는 자리마다 기본값을 고른다 */
97
- purpose: 'operational',
98
- status: 'stopped',
99
- model: { locations, equipment: [{ id: 'fk-1', kind: 'forklift', homeLocation: 'loc-0' }] }
100
- } as any)
101
- })
102
-
103
- after(async () => {
104
- await ds?.destroy()
105
- })
106
-
107
- const ms = async (fn: () => Promise<any>) => {
108
- const t = process.hrtime.bigint()
109
- await fn()
110
- return Number(process.hrtime.bigint() - t) / 1e6
111
- }
112
-
113
- test('bench: 구간 성과 폴드 한 번의 비용 vs 창 안의 작업 수', async () => {
114
- let seeded = 0
115
- for (const count of TASK_COUNTS) {
116
- await ds.getRepository(TwinEvent).save(taskRows(count - seeded, seeded * 2 + 1000))
117
- seeded = count
118
-
119
- const args = { domainId, instanceId: INSTANCE, toTime: new Date(TO).toISOString(), windowMinutes: WINDOW_MIN }
120
- await computeTwinKpi(args) // 워밍업(연결·스키마 캐시)
121
-
122
- const plain = await ms(() => computeTwinKpi(args))
123
- const byArea = await ms(() => computeTwinKpi({ ...args, groupBy: 'area' }))
124
-
125
- console.log(` 작업 ${count.toLocaleString()}건(이벤트 ${(count * 2).toLocaleString()}줄) · 자리 ${LOCATIONS}개`)
126
- console.log(` 폴드 1회 ${plain.toFixed(1)}ms`)
127
- console.log(` 구역별 폴드 1회 ${byArea.toFixed(1)}ms`)
128
- console.log(` 카드 20장 동시 ${(plain * 20).toFixed(0)}ms (직렬 상한 — 실제로는 한 번 계산해 나눠 쓸 수 있다)`)
129
- }
130
- })
@@ -1,50 +0,0 @@
1
- /*
2
- * **렌즈는 자기 영역의 자리만 세운다** — ADR-0081 보탬(수석 아키텍트 판정 2026-09-24).
3
- *
4
- * 사람이 보는 장면: 창고 트윈 miratek-wms 를 불러오면 「종류를 모르는 자리 assembly-line (…00007.0)」 경고가 떴다. 그 자리는 plant 의
5
- * 조립 라인 자리다. 이제 창고 렌즈는 그 자리를 참조로만 들고 경고하지 않는다. 같은 기준정보를 plant 렌즈로 불러오면 도크가 참조다.
6
- */
7
- import { test } from 'node:test'
8
- import assert from 'node:assert/strict'
9
- import { createRequire } from 'node:module'
10
-
11
- const req = createRequire(import.meta.url)
12
- const { masterToTwin } = req('../dist-server/service/reference/reference-master.js')
13
-
14
- const CATALOG = { wms: { locationTypes: ['dock', 'storage'] }, mes: { locationTypes: ['assembly-line'] } }
15
- const LINE = 'urn:epc:id:sgln:0614141.00007.0'
16
-
17
- const master = (system: string) => ({
18
- source: `ops-${system}`,
19
- system,
20
- siteName: 'miratek',
21
- space: { spaceId: 'miratek', width: 60, depth: 30, unit: 'm' },
22
- locations: [
23
- { id: 'dock-recv', type: 'dock', role: 'location' as const, system: 'wms' },
24
- { id: 'bin-1', type: 'storage', role: 'location' as const, system: 'wms' },
25
- { id: LINE, type: 'assembly-line', role: 'location' as const, system: 'mes' },
26
- { id: 'legacy', type: 'storage', role: 'location' as const }
27
- ],
28
- equipment: []
29
- })
30
- const unknown = (r: any) => (r.warnings ?? []).filter((w: any) => w.code === 'unknown-location-type')
31
-
32
- test('★ 창고 렌즈는 조립 라인 자리를 참조로 들고 경고하지 않는다', () => {
33
- const r = masterToTwin(master('wms'), CATALOG)
34
- assert.deepEqual(unknown(r), [], '종류 모르는 자리 경고 0')
35
- assert.deepEqual(r.model.locations.map((l: any) => l.id), ['dock-recv', 'bin-1', 'legacy'])
36
- assert.deepEqual(r.model.referencedLocations, [{ id: LINE, system: 'mes' }])
37
- })
38
-
39
- test('★ plant 렌즈로 보면 도크와 보관 자리가 참조다', () => {
40
- const r = masterToTwin(master('mes'), CATALOG)
41
- assert.deepEqual(r.model.locations.map((l: any) => l.id), [LINE, 'legacy'])
42
- assert.deepEqual(r.model.referencedLocations.map((x: any) => x.id), ['dock-recv', 'bin-1'])
43
- })
44
-
45
- test('영역을 말하지 않은 원본은 지금처럼 선다 — 참조 칸을 만들지 않는다', () => {
46
- const m = { ...master('wms'), locations: master('wms').locations.map(({ system, ...l }: any) => l) }
47
- const r = masterToTwin(m, CATALOG)
48
- assert.equal(r.model.locations.length, 4)
49
- assert.equal('referencedLocations' in r.model, false)
50
- })
@@ -1,234 +0,0 @@
1
- /*
2
- * ★ 재기동을 건너도 **계보에 입력이 남는다** — 호스트의 웜스타트 경로로 확인한다.
3
- *
4
- * ── 무엇이 잘못돼 있었나 ──────────────────────────────────────────────────────
5
- * 오더의 진행 중 할당(`allocated`)과 거래번호(`bizTransaction`)가 상태 계약에 없어서, 웜스타트가
6
- * 오더를 되살릴 때 둘 다 비운 채로 세웠다. 그 오더의 진행 중 작업이 완료되면
7
- * `TransformationEvent` 가 **입력 없이** 나간다 — "무엇이 무엇으로 바뀌었나" 에서 "무엇이" 가
8
- * 통째로 빠지고, 계보를 거슬러 올라갈 수 없다.
9
- *
10
- * 실 앱에서 변환 36건 중 35건이 입력 0 이었고 모든 이벤트의 거래번호가 빈값이었다.
11
- *
12
- * ── 왜 커널 검사만으로 충분하지 않나 ──────────────────────────────────────────
13
- * 커널 검사는 `hydrateObserved` 로 직접 심어 확인한다. 호스트는 **저널을 재생해서** 그 씨앗을
14
- * 만든다(`recover` → `replay`). 그 경로에서 한 번 더 떨어질 수 있으므로 여기서 실제로 걷는다.
15
- */
16
- import { test, before, after } from 'node:test'
17
- import assert from 'node:assert/strict'
18
- import { createRequire } from 'node:module'
19
- import type { DataSource } from 'typeorm'
20
-
21
- const req = createRequire(import.meta.url)
22
- const { NamingStrategy, addDataSource, entities: shellEntities, Domain } = req('@things-factory/shell')
23
- const { entities: authEntities } = req('@things-factory/auth-base')
24
- const { entities: twinEntities } = req('../dist-server/service/index.js')
25
- const { TwinEngine } = req('../dist-server/engine/index.js')
26
- const { TwinEvent } = req('../dist-server/service/twin-event/twin-event.js')
27
- const { TwinLineageQuery } = req('../dist-server/service/twin-model/twin-lineage-query.js')
28
- const { DataSource: TypeOrmDataSource } = req('typeorm')
29
-
30
- let ds: DataSource
31
- let domainId: string
32
-
33
- const INSTANCE = 'lineage-probe'
34
- const CP = '0614141'
35
- const pat = (ref: string) => `urn:epc:idpat:sgtin:${CP}.${ref}.*`
36
-
37
- /** 원자재 하나로 완제품 하나를 만드는 2단 라인 — 실제 트레일러 템플릿의 축소판. */
38
- const master = (): any => ({
39
- source: INSTANCE,
40
- system: 'mes',
41
- siteName: '계보 공장',
42
- space: { width: 60, depth: 30, unit: 'm' },
43
- locations: [
44
- { id: 'raw-store', type: 'raw-store', role: 'location', capacity: 500 },
45
- { id: 'cut-station', type: 'cut-station', role: 'location', capacity: 50 },
46
- { id: 'weld-station', type: 'weld-station', role: 'location', capacity: 50 },
47
- { id: 'fg-store', type: 'fg-store', role: 'location', capacity: 500 }
48
- ],
49
- equipment: [
50
- { id: 'cutter-1', kind: 'cutter', homeLocationId: 'cut-station' },
51
- { id: 'welder-1', kind: 'welder', homeLocationId: 'weld-station' }
52
- ],
53
- productionSpec: {
54
- companyPrefix: CP,
55
- binding: { steel: '077101', frame: '078101' },
56
- /*
57
- * 작업지시의 문서 식별자를 **이 현장이 선언한다** — 커널은 문서 타입을 정하지 않습니다(0.7.43).
58
- * GDTI 는 「회사 프리픽스 + 문서 타입 + 일련번호」이고, 그 타입은 프리픽스를 배정받은 회사가
59
- * 자기 번호 용량에서 배정합니다. 그러니 픽스처도 그 선언을 해야 합니다.
60
- */
61
- identity: { documentTypes: { workorder: '403' } },
62
- definition: {
63
- /* 자재는 **자기 보관 자리를 선언한다** — 커널이 자재가 놓이는 자리를 지어내지 않습니다(0.7.43). */
64
- materials: [
65
- { key: 'steel', label: '강재', locationType: 'raw-store' },
66
- { key: 'frame', label: '프레임', locationType: 'fg-store' }
67
- ],
68
- locationTypes: [
69
- { key: 'raw-store', label: '자재 보관' },
70
- { key: 'cut-station', label: '절단' },
71
- { key: 'weld-station', label: '용접' },
72
- { key: 'fg-store', label: '완제품 보관' }
73
- ],
74
- routes: [{ key: 'frame-route', steps: ['cut', 'weld'] }],
75
- recipes: [{ key: 'frame-recipe', label: 'f', route: 'frame-route', inputs: [{ material: 'steel', qty: 2 }], outputs: [{ material: 'frame', qty: 1 }] }],
76
- operations: [
77
- { key: 'cut', label: '절단', intent: 'process', locationType: 'cut-station', resourceType: 'cutter', duration: 'PT1M' },
78
- { key: 'weld', label: '용접', intent: 'process', locationType: 'weld-station', resourceType: 'welder', duration: 'PT1M' }
79
- ]
80
- }
81
- }
82
- })
83
-
84
- const SCENARIO = {
85
- seed: 9,
86
- generators: [
87
- { kind: 'inbound-arrival', stimulus: 'arrival', rate: { distribution: 'constant', meanPerHour: 3600 },
88
- content: { skuMix: [{ gtin: pat('077101'), weight: 1 }], qtyPerLine: { min: 1, max: 1 } } },
89
- { kind: 'production-order', stimulus: 'order', rate: { distribution: 'constant', meanPerHour: 120 },
90
- content: { skuMix: [{ gtin: pat('078101'), weight: 1 }], qtyPerLine: { min: 1, max: 1 } } }
91
- ]
92
- }
93
-
94
- /** 저널에 남은 변환 이벤트들 — 계보가 실제로 무엇을 기록했나. */
95
- async function transforms(): Promise<{ inputs: number; outputs: number; tx: string }[]> {
96
- const rows: any[] = await ds.getRepository(TwinEvent).find({ where: { domain: { id: domainId } as any, instanceId: INSTANCE } as any })
97
- return rows
98
- .filter(r => r.eventType === 'epcis.TransformationEvent')
99
- .map(r => ({
100
- inputs: (r.payload?.data?.inputEPCList ?? []).length,
101
- outputs: (r.payload?.data?.outputEPCList ?? []).length,
102
- tx: r.payload?.data?.bizTransactionList?.[0]?.bizTransaction ?? ''
103
- }))
104
- }
105
-
106
- /**
107
- * 틱과 자극은 **런타임**에 있다 — `startFromRegistry` 가 돌려주는 것은 호스트의 인스턴스 기록이고
108
- * 커널 런타임은 그 안에 있다(둘을 같은 것으로 보면 `scenario` 가 없다고 나온다).
109
- */
110
- const runtime = () => TwinEngine.runtime(domainId, INSTANCE)
111
-
112
- function tick(n: number): void {
113
- const rt = runtime()
114
- for (let i = 0; i < n; i++) rt.tick(1000)
115
- }
116
-
117
- /**
118
- * 상태는 런타임의 `resync()` 로 얻는다 — `{ revision, state }` 를 돌려주므로 축은 그 **안에** 있다.
119
- * (`TwinEngine.snapshot` 도 이것을 그대로 넘겨 주므로 축이 한 겹 안에 들어 있다.)
120
- */
121
- const orders = () => ((runtime().resync().state?.orders ?? []) as any[])
122
-
123
- function drive(): void {
124
- const rt = runtime()
125
- rt.scenario.load(SCENARIO)
126
- rt.scenario.start()
127
- }
128
-
129
- before(async () => {
130
- ds = new TypeOrmDataSource({
131
- type: 'sqlite',
132
- database: ':memory:',
133
- synchronize: true,
134
- dropSchema: true,
135
- namingStrategy: new NamingStrategy(),
136
- entities: [...shellEntities, ...authEntities, ...twinEntities],
137
- logging: false
138
- })
139
- await ds.initialize()
140
- addDataSource('default', ds)
141
- const d = await ds.getRepository(Domain).save({ name: 'lineage-test', subdomain: 'lineage-test' } as any)
142
- domainId = d.id
143
- await TwinEngine.ingestMaster(domainId, master(), 'reset')
144
- })
145
-
146
- after(async () => {
147
- await TwinEngine.stop(domainId, INSTANCE).catch(() => {})
148
- await ds?.destroy()
149
- })
150
-
151
- test('재기동을 건너도 계보에 입력이 실린다 — 웜스타트가 확보분을 잃지 않는다', async () => {
152
- /* ① 한 번 굴려 진행 중 할당을 만든다. */
153
- await TwinEngine.startFromRegistry(domainId, INSTANCE, 'resume')
154
- drive()
155
- tick(200)
156
- const workingBefore = orders().filter(o => (o.allocated ?? []).length)
157
- assert.ok(workingBefore.length, '진행 중 확보분이 있어야 이 검사가 뜻이 있다')
158
-
159
- /* ② 멈추고 **저널을 재생해** 다시 세운다 — 호스트의 웜스타트 경로 그대로. */
160
- await TwinEngine.stop(domainId, INSTANCE)
161
- await TwinEngine.startFromRegistry(domainId, INSTANCE, 'resume')
162
-
163
- const revived = orders().filter(o => (o.allocated ?? []).length)
164
- assert.ok(revived.length, '되살아난 오더가 확보분을 들고 있어야 한다 — 잃으면 계보의 입력이 빈다')
165
-
166
- /* ③ 되살아난 작업이 끝날 만큼 더 굴린다. */
167
- drive()
168
- tick(300)
169
-
170
- const all = await transforms()
171
- assert.ok(all.length, '변환이 저널에 남아야 이 검사가 뜻이 있다')
172
- const withInputs = all.filter(t => t.inputs > 0)
173
- assert.ok(withInputs.length, '입력이 실린 변환이 하나도 없다 — 계보의 "어디서 왔나" 가 통째로 빈다')
174
-
175
- /* 거래번호도 함께 — 계보가 **무슨 거래로** 일어났는지 잇는 축이다. */
176
- assert.ok(all.some(t => t.tx), '거래번호가 전부 빈값이다 — 계보를 거래로 이을 수 없다')
177
- })
178
-
179
- test('계보를 거슬러 올라가 선언과 나란히 놓는다 — 그 차이가 진단이다', async () => {
180
- const q = new TwinLineageQuery()
181
- const ctx = { state: { domain: { id: domainId } } } as any
182
-
183
- /* 완제품 하나를 고른다 — 저널이 그것을 산출로 실은 변환이 있어야 계보가 있다. */
184
- const rows: any[] = await ds.getRepository(TwinEvent).find({ where: { domain: { id: domainId } as any, instanceId: INSTANCE } as any })
185
- /* **완제품**을 고른다. 변환에는 중간 산물(WIP)을 내는 것도 있어서 아무거나 집으면 WIP 이 잡히고,
186
- WIP 은 선언된 자재가 아니라 라우트의 내부 산물이므로 견줄 대상이 아니다. */
187
- const made = rows
188
- .filter(r => r.eventType === 'epcis.TransformationEvent' && (r.payload?.data?.inputEPCList ?? []).length)
189
- .flatMap(r => r.payload.data.outputEPCList ?? [])
190
- .filter((e: string) => e.includes(`.078101.`))
191
- assert.ok(made.length, '완제품을 낸 변환이 있어야 이 검사가 뜻이 있다')
192
-
193
- const lin = await q.twinItemLineage(INSTANCE, made[0], ctx)
194
- assert.ok(lin, '계보가 나와야 한다')
195
- assert.equal(lin.epc, made[0])
196
- assert.ok(lin.items.length > 1, '거슬러 올라간 것이 있어야 한다 — 하나면 아무것도 안 찾은 것이다')
197
- assert.ok(lin.edges.some((e: any) => e.from === made[0]), '이 개체를 만든 직접 투입이 보여야 한다')
198
-
199
- /* 근거를 밝힌다 — 창을 넘겨 끊겼으면 계보가 실제보다 얕게 보인다. */
200
- assert.equal(lin.basis.source, 'journal')
201
- assert.equal(typeof lin.basis.transformationsRead, 'number')
202
-
203
- /* **겹쳐 보기** — 선언(레시피)과 관측(실제 투입)을 자재별로 나란히. */
204
- assert.equal(lin.conformance.comparable, true, `견줄 수 없으면 이유를 말한다: ${lin.conformance?.reason}`)
205
- const steel = lin.conformance.lines.find((l: any) => l.material === 'steel')
206
- assert.ok(steel, '레시피가 선언한 자재가 줄로 나와야 한다')
207
- assert.equal(steel.declared, 2, '레시피는 강재 2개를 요구한다')
208
- assert.equal(steel.observed, 2, '실제로도 2개를 먹었다 — 설계대로다')
209
- assert.equal(steel.matches, true)
210
- })
211
-
212
- test('★ 만든 것을 관측하지 못했으면 「다르다」고 하지 않는다 — 안 본 것과 어긋난 것은 다른 사실이다', async () => {
213
- const q = new TwinLineageQuery()
214
- const ctx = { state: { domain: { id: domainId } } } as any
215
- /*
216
- * 완제품 클래스의 개체이지만 저널에 그것을 낸 변환이 없다 — 자재로도 이어지고 레시피도 하나다.
217
- * 예전에는 여기서 셈이 그대로 돌아 관측을 전부 0 으로 적고 「레시피와 다릅니다」를 냈다
218
- * (2026-09-18 :3000 에서 카메라 로트 23 줄이 그렇게 보였다).
219
- */
220
- const lin = await q.twinItemLineage(INSTANCE, `urn:epc:id:sgtin:${CP}.078101.999999`, ctx)
221
- assert.equal(lin.conformance.comparable, false, `관측이 없는데 견주었다: ${JSON.stringify(lin.conformance?.lines?.slice(0, 2))}`)
222
- assert.equal(lin.conformance.reason, 'made-not-observed')
223
- assert.ok(lin.conformance.recipe, '어느 레시피와 견주려 했는지는 말한다 — 사람이 다음 걸음을 안다')
224
- assert.equal(lin.basis.transformationsRead >= 0, true)
225
- })
226
-
227
- test('바인딩이 없으면 비교하지 않고 이유를 알린다 — 짐작으로 이으면 거짓 진단이 된다', async () => {
228
- const q = new TwinLineageQuery()
229
- const ctx = { state: { domain: { id: domainId } } } as any
230
- /* 개체이긴 하지만 바인딩에 없는 품목 — 짐작으로 자재에 붙이면 "설계와 다르다" 는 거짓이 나온다. */
231
- const lin = await q.twinItemLineage(INSTANCE, `urn:epc:id:sgtin:${CP}.099999.1`, ctx)
232
- assert.equal(lin.conformance.comparable, false)
233
- assert.equal(lin.conformance.reason, 'item-not-bound')
234
- })
@@ -1,170 +0,0 @@
1
- /*
2
- * ★ **원천마다 시간의 결이 다르다** — 밤마다 나던 거짓 빨강의 나머지 반쪽.
3
- *
4
- * 판정은 이미 두 값을 받을 수 있다(`syncVerdictOf` 의 `expectedSilenceMs`·`quietNow`). 없던 것은
5
- * **원천이 그것을 말할 자리**였다. 인티그레이션 레인이 다섯을 재 왔다.
6
- *
7
- * ppms 발전 일몰에 멈춘다 — 두 사이트가 같은 분 19:25 에 함께
8
- * ppms 계측 밤에도 온다 · 15분마다
9
- * ppms 가격 화·목만 거래된다 · 그 날 하루 한 번
10
- * plant 근무시간 창 · 훅이라 「보내면 온다」
11
- * chef 조업시간 창 · 같음
12
- *
13
- * 셋이 다 다르다 — 해에 매인 것, 사람 근무에 매인 것, 거래일에 매인 것. 그런데 **두 축으로
14
- * 덮인다**: 「지금이 활동 시각인가」와 「그 안에서 얼마나 뜸한가」.
15
- */
16
- import { test } from 'node:test'
17
- import assert from 'node:assert/strict'
18
-
19
- import { cadenceOf, ingestExpectation, type LiveCadence } from '../server/service/reference/live-cadence.js'
20
-
21
- const NOW = 1_800_000_000_000
22
-
23
- /* ── 축을 찾는다 ──────────────────────────────────────────────────────────── */
24
-
25
- test('★ 선언한 축을 찾는다', () => {
26
- const cadences: LiveCadence[] = [
27
- { axis: 'equipment.status', windowKind: 'daylight' },
28
- { axis: 'quality.output', expectedSilenceMs: 900_000 }
29
- ]
30
-
31
- assert.equal(cadenceOf(cadences, 'quality.output')?.expectedSilenceMs, 900_000)
32
- assert.equal(cadenceOf(cadences, 'equipment.status')?.windowKind, 'daylight')
33
- })
34
-
35
- test('★ 선언하지 않은 축은 없다고 답한다 — 옛 거동으로 견주게', () => {
36
- assert.equal(cadenceOf([{ axis: 'quality.output' }], 'order.status'), undefined)
37
- assert.equal(cadenceOf(undefined, 'quality.output'), undefined)
38
- })
39
-
40
- /* ── 판정에 넘길 두 값으로 옮긴다 ───────────────────────────────────────── */
41
-
42
- test('★ 선언이 없으면 아무것도 답하지 않는다 — 「모른다」를 「안 와도 된다」로 접지 않는다', () => {
43
- /*
44
- * 여기서 `quietNow: true` 를 내면 **선언 안 한 원천이 전부 조용해진다.** 정말 끊긴 것도
45
- * 조용해지고, 그러면 이 축을 만든 목적을 잃는다.
46
- */
47
- assert.deepEqual(ingestExpectation(undefined, { nowMs: NOW }), {})
48
- })
49
-
50
- test('★ 15분마다 긷는 원천 — 주기만 넘긴다', () => {
51
- const out = ingestExpectation({ axis: 'quality.output', expectedSilenceMs: 900_000 }, { nowMs: NOW })
52
-
53
- assert.equal(out.expectedSilenceMs, 900_000)
54
- assert.equal(out.quietNow, undefined, '창을 선언하지 않았는데 시각을 단언했다')
55
- })
56
-
57
- test('0이나 음수 주기는 선언이 아니다', () => {
58
- for (const bad of [0, -1, NaN]) {
59
- const out = ingestExpectation({ axis: 'a', expectedSilenceMs: bad }, { nowMs: NOW })
60
- assert.equal(out.expectedSilenceMs, undefined, `${bad} 를 주기로 받았다`)
61
- }
62
- })
63
-
64
- /* ── 「보내면 온다」 ──────────────────────────────────────────────────────── */
65
-
66
- test('★ 훅으로 미는 축은 침묵으로 판정하지 않는다 — plant 가 그렇다', () => {
67
- /*
68
- * 보낼 것이 없으면 안 보내는 것이 정상이다. 「주기가 없다」와 「모른다」를 가르는 값이다.
69
- */
70
- const out = ingestExpectation({ axis: 'order.status', pushed: true }, { nowMs: NOW })
71
-
72
- assert.equal(out.quietNow, true)
73
- })
74
-
75
- test('★ 미는 축은 창 판정을 기다리지 않는다 — 판정 수단이 없어도 답한다', () => {
76
- const out = ingestExpectation(
77
- { axis: 'order.status', pushed: true, window: [{ id: 'day', entryType: 'production', startTime: '09:00', endTime: '18:00' }] },
78
- { nowMs: NOW } /* inWindow 를 주지 않았다 */
79
- )
80
-
81
- assert.equal(out.quietNow, true)
82
- })
83
-
84
- /* ── 창 ──────────────────────────────────────────────────────────────────── */
85
-
86
- test('★ 활동 시각 안이면 조용할 때가 아니다', () => {
87
- const out = ingestExpectation(
88
- { axis: 'quality.output', window: [{ id: 'day', entryType: 'production', startTime: '09:00', endTime: '18:00' }] },
89
- { nowMs: NOW, inWindow: () => true }
90
- )
91
-
92
- assert.equal(out.quietNow, false)
93
- })
94
-
95
- test('★ 활동 시각 밖이면 조용할 때다', () => {
96
- const out = ingestExpectation(
97
- { axis: 'quality.output', window: [{ id: 'day', entryType: 'production', startTime: '09:00', endTime: '18:00' }] },
98
- { nowMs: NOW, inWindow: () => false }
99
- )
100
-
101
- assert.equal(out.quietNow, true)
102
- })
103
-
104
- test('★ 판정 수단을 안 받았으면 시각을 단언하지 않는다 — 지어낸 값을 만들지 않는다', () => {
105
- /*
106
- * 부르는 쪽이 달력 판정 함수를 주지 않았는데 우리가 「활동 시각이다」로 답하면, 창을 선언한
107
- * 원천이 **창이 없는 것과 같아진다.** 그것은 조용한 실패다.
108
- */
109
- const out = ingestExpectation(
110
- { axis: 'quality.output', window: [{ id: 'day', entryType: 'production', startTime: '09:00', endTime: '18:00' }] },
111
- { nowMs: NOW }
112
- )
113
-
114
- assert.equal(out.quietNow, undefined)
115
- })
116
-
117
- test('빈 창은 창이 아니다', () => {
118
- assert.equal(ingestExpectation({ axis: 'a', window: [] }, { nowMs: NOW, inWindow: () => false }).quietNow, undefined)
119
- })
120
-
121
- /* ── 두 축이 함께 온다 ──────────────────────────────────────────────────── */
122
-
123
- test('★ 주기와 창을 같이 선언할 수 있다 — 인증서 가격이 그 모양이다', () => {
124
- /*
125
- * 화·목만 거래되고 그 날 하루 한 번 온다. 「매일 와야 한다」로 재면 주 5일 중 3일이 빨갛고,
126
- * 「주 2회」로 재면 이어 쓴 날을 못 본다. 두 축이면 둘 다 답한다.
127
- */
128
- const out = ingestExpectation(
129
- {
130
- axis: 'quality.output',
131
- expectedSilenceMs: 26 * 3_600_000,
132
- window: [
133
- { id: 'tue', entryType: 'production', startTime: '00:00', endTime: '23:59' },
134
- { id: 'thu', entryType: 'production', startTime: '00:00', endTime: '23:59' }
135
- ]
136
- },
137
- { nowMs: NOW, inWindow: () => false }
138
- )
139
-
140
- assert.equal(out.expectedSilenceMs, 26 * 3_600_000)
141
- assert.equal(out.quietNow, true, '거래일이 아니면 조용한 것이 정상이다')
142
- })
143
-
144
- /* ── 「해 있는 동안」은 호스트가 채운다 ──────────────────────────────────── */
145
-
146
- test('★ 종류만 선언한 것으로는 창 판정을 하지 않는다 — 호스트가 채워야 한다', () => {
147
- /*
148
- * 커널은 일출·일몰을 계산하지 않는다(굴절·고위도·박명 정의가 다 선택이고, 정하면 방언이다).
149
- * 원천은 종류만 말하고, 좌표를 아는 호스트가 날마다 구체적인 구간을 채운다.
150
- *
151
- * 그러니 `windowKind` 만 있고 `window` 가 비어 있으면 **아직 채워지지 않은 것**이고, 그때
152
- * 판정하지 않는다. `false` 로 접으면 태양광이 밤에도 활동 시각인 것이 된다.
153
- */
154
- const out = ingestExpectation({ axis: 'equipment.status', windowKind: 'daylight' }, { nowMs: NOW, inWindow: () => true })
155
-
156
- assert.equal(out.quietNow, undefined)
157
- })
158
-
159
- test('★ 호스트가 채우면 그것으로 판정한다', () => {
160
- const out = ingestExpectation(
161
- {
162
- axis: 'equipment.status',
163
- windowKind: 'daylight',
164
- window: [{ id: 'today', entryType: 'production', startTime: '06:12', endTime: '19:25' }]
165
- },
166
- { nowMs: NOW, inWindow: () => false }
167
- )
168
-
169
- assert.equal(out.quietNow, true)
170
- })