@things-factory/headless-twin 10.1.277 → 10.1.279

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,335 +0,0 @@
1
- import { ORDER_FOLD_DEFAULT, finishedFlowOrdersWithin, foldedOrderCount, type OrderFoldPolicy } from '@operato/ops-contract'
2
-
3
- /*
4
- * 트윈 State 스냅샷 → 라이브 바인딩 delta 목록 (순수 매핑 — pubsub/도메인 무관 → 단위 테스트 가능).
5
- * publishEntityData 가 이 목록을 엔티티별 시그니처로 dedup 후 data(tag) 채널로 발행한다.
6
- *
7
- * ── 규율: 레퍼런스가 아는 것은 **전부** 내보낸다 ────────────────────────────
8
- * 트윈에서 사소한 속성은 없다. 소속 구역·소속 팔레트·수량·만료처럼 곁가지로 보이는 값이 실제로는
9
- * 구역 롤업·적재 표현·로트 추적의 전제다. 그래서 여기서 **필드를 손으로 골라 담지 않는다.**
10
- *
11
- * 예전에는 엔티티마다 필요할 것 같은 필드만 열거했고, 그 결과 계약에 있는 것이 오류 없이 빠졌다
12
- * (2026-08-01 감사: 노드 parentId 누락 · 작업 전량 누락 · 물품 전량 누락). 화이트리스트 방식은
13
- * **계약이 자라도 화면이 따라오지 못한다** — 커널이 속성을 늘릴 때마다 이 파일을 고쳐야 하고, 고치는
14
- * 것을 잊으면 아무 신호 없이 정보가 사라진다.
15
- *
16
- * 그래서 반대로 한다: **상태 객체가 가진 것을 그대로 통과**시키고, 통과시키지 **않을** 것만 이유와 함께
17
- * 열거한다(EXCLUDED). 새 속성은 자동으로 화면에 도달하고, 빼려면 이유를 적어야 한다.
18
- *
19
- * ── 표식은 도메인 낱말을 훔치지 않는다 ─────────────────────────────────────
20
- * 예전 payload 는 엔티티 종류 표식을 `kind` 로 실었다. 그런데 `kind` 는 **도메인의 낱말**이다 —
21
- * 무버 kind=cutter, 작업 kind=putaway, 오더 kind=workorder. 표식이 그 이름을 차지하면 도메인 속성을
22
- * 실을 자리가 없어진다(같은 병을 오늘 ox-timeline 의 `group` 에서도 고쳤다).
23
- * 그래서 표식은 `entity`(우리 이름)로 옮기고 `kind` 는 도메인에 돌려준다.
24
- *
25
- * payload 계약(씬 컴포넌트가 소비): `entity`(표식) + 그 엔티티의 모든 속성(도메인 `kind` 포함).
26
- * entity = location · equipment · person · asset · order · task · item,
27
- * 그리고 집약 태그(__orders__ · __tasks__ · __items__ · __persons__ · __assets__).
28
- */
29
-
30
- export interface EntityDelta {
31
- tag: string
32
- data: any
33
- }
34
-
35
- /** 집약 고정 태그 — 클라 provider 와 일치해야 한다(런타임 생성 엔티티는 개별 배치가 불가하므로 집약 뷰). */
36
- /*
37
- * 집약 채널의 접두사 — **실제 태그는 트윈 식별자를 붙여 만든다.**
38
- *
39
- * 예전에는 이 상수가 곧 태그였다. 그런데 발행 키는 (도메인, 태그)이고, **한 공간에 트윈이 여럿**
40
- * 있으면(실측: 3곳 × 3개) 셋이 같은 태그로 발행해 서로 덮었다. 보드의 주문 목록판이 세 공장의 주문
41
- * 중 마지막에 도착한 것을 보여 준다 — 오류 없이.
42
- *
43
- * 구간 성과 태그가 이미 `__kpi__:<트윈>` 으로 트윈을 붙이고 있었다(`kpi-broadcast.ts`). 같은 규약으로 맞춘다.
44
- */
45
- export const ORDERS_TAG_PREFIX = '__orders__'
46
- export const TASKS_TAG_PREFIX = '__tasks__'
47
- export const ITEMS_TAG_PREFIX = '__items__'
48
- export const PERSONS_TAG_PREFIX = '__persons__'
49
- export const ASSETS_TAG_PREFIX = '__assets__'
50
- /** 에너지 집약 — 수요 구간·피크·계약은 **트윈 하나의 사실**이라 개체 태그가 없다. */
51
- export const ENERGY_TAG_PREFIX = '__energy__'
52
-
53
- /** 이 트윈의 집약 채널 태그. 트윈 식별자가 없으면 만들지 않는다 — 덮어쓰기의 원인이었다. */
54
- export function aggregateTag(prefix: string, instanceId: string): string {
55
- if (!instanceId) throw new Error('aggregateTag: instanceId required — tags without instanceId overwrite other twin states across tenants')
56
-
57
- return `${prefix}:${instanceId}`
58
- }
59
-
60
- export const ordersTag = (instanceId: string) => aggregateTag(ORDERS_TAG_PREFIX, instanceId)
61
- export const tasksTag = (instanceId: string) => aggregateTag(TASKS_TAG_PREFIX, instanceId)
62
- export const itemsTag = (instanceId: string) => aggregateTag(ITEMS_TAG_PREFIX, instanceId)
63
- export const personsTag = (instanceId: string) => aggregateTag(PERSONS_TAG_PREFIX, instanceId)
64
- export const assetsTag = (instanceId: string) => aggregateTag(ASSETS_TAG_PREFIX, instanceId)
65
- export const energyTag = (instanceId: string) => aggregateTag(ENERGY_TAG_PREFIX, instanceId)
66
-
67
- /**
68
- * 통과시키지 않는 필드 — **빼는 데는 이유가 필요하다.**
69
- *
70
- * · `id`/`epc` — 태그로 이미 나가므로 개별 payload 에 중복해 싣지 않는다(집약 뷰에는 넣는다).
71
- * · `oee` — 원시 누적(idleMs 등)이 매 delta 증가해 "무변화 생략" 을 무력화한다. shapeOee 로 정형화해 얹는다.
72
- */
73
- const EXCLUDED = new Set(['id', 'epc', 'oee'])
74
-
75
- /**
76
- * OEE 원시 비율/카운트 → 표시용 정수 퍼센트 + 카운트.
77
- * 원시 누적 ms(idleMs 등)는 매 delta 증가해 무변화-생략을 무력화하므로 제외(유휴 자원의 매초 재브로드캐스팅 억제).
78
- * oee 미측정이면 undefined.
79
- */
80
- function shapeOee(o: any): any {
81
- if (!o) return undefined
82
- return {
83
- overall: Math.round((o.overall ?? 0) * 100),
84
- availability: Math.round((o.availability ?? 0) * 100),
85
- performance: Math.round((o.performance ?? 0) * 100),
86
- quality: Math.round((o.quality ?? 0) * 100),
87
- good: o.goodCount ?? 0,
88
- scrap: o.nonconformingCount ?? 0
89
- }
90
- }
91
-
92
- /**
93
- * 엔티티 하나의 payload — `entity` 표식 + 나머지 전부(도메인 `kind` 포함).
94
- *
95
- * `undefined` 값은 싣지 않는다(키의 유무가 시그니처를 흔들지 않게). 값이 없는 것과 키가 없는 것은
96
- * 소비처에서 같으므로 안전하고, 무변화 생략이 잘 듣는다.
97
- */
98
- function payloadOf(entityKind: string, entity: any): any {
99
- /* 표식은 `entity` — 도메인의 `kind` 를 덮지 않는다. */
100
- const data: any = { entity: entityKind }
101
- for (const [k, v] of Object.entries(entity ?? {})) {
102
- if (EXCLUDED.has(k) || v === undefined) continue
103
- data[k] = v
104
- }
105
- return data
106
- }
107
-
108
- /**
109
- * 집약 뷰의 항목 — 개별 payload 와 같은 내용 + 식별자.
110
- * 집약은 "전체를 한 컴포넌트가 추적" 하는 용도라 식별자가 있어야 한다.
111
- */
112
- function aggregateItem(entity: any, idKey: 'id' | 'epc'): any {
113
- const out: any = { [idKey]: entity?.[idKey] }
114
- for (const [k, v] of Object.entries(entity ?? {})) {
115
- if (k === idKey || k === 'oee' || v === undefined) continue
116
- out[k] = v
117
- }
118
- const shaped = shapeOee(entity?.oee)
119
- if (shaped) out.oee = shaped
120
- return out
121
- }
122
-
123
- /**
124
- * 물품 집약의 상한 — 큰 현장은 물품이 수만 개라, 전량을 매 브로드캐스팅에 실으면 전달이 현장을 느리게 한다.
125
- *
126
- * **알리지 않고 자르지 않는다**: 넘치면 `total`(전체 수)과 `truncated`(잘린 수)를 함께 실어, 소비처가
127
- * "이게 전부" 라고 오해하지 않게 한다. 개별 물품은 태그별 delta 로 따로 나가고 그쪽은 시그니처 dedup
128
- * 이 걸려 **변한 것만** 재브로드캐스팅된다.
129
- */
130
- export const ITEMS_AGGREGATE_LIMIT = 500
131
-
132
- /**
133
- * 자리별 에너지 — **그 자리의 계량기들이 잰 것**을 그 자리 태그에 실을 수 있게 모은다.
134
- *
135
- * ── 왜 자리에도 필요한가 (2026-08-14) ───────────────────────────────────────
136
- * 카탈로그는 자리에도 `metered` 를 준다(수전·분기·구역 계량은 재는 자리다). 그런데 값은 계량기
137
- * **설비** 태그로만 나갔다. 그래서 계통도의 분기 자리에 계량 컴포넌트를 놓으면 **영원히 「—」** 였다 —
138
- * 능력은 「잰다」고 말하는데 값이 오지 않는 자리.
139
- *
140
- * 「이 구간이 얼마를 먹나」는 자리의 사실이고, 사람은 계통도의 자리에 붙여 본다.
141
- *
142
- * ── 계층은 여기서 문제가 되지 않는다 ────────────────────────────────────────
143
- * 각 자리에는 **그 자리에 붙은 계량기만** 더한다(수전 자리에는 수전 계량기, 분기 자리에는 그 분기의
144
- * 것). 커널이 부하를 뿌리로만 세는 것과 다른 층의 계산이다 — 여기서는 자리마다 자기 것을 말한다.
145
- *
146
- * 근거를 함께 낸다(`meters`) — 그 자리의 수가 어느 계량기에서 왔는지 되짚을 수 있어야 한다.
147
- */
148
- function energyByLocation(state: any): Map<string, Record<string, unknown>> {
149
- const out = new Map<string, Record<string, unknown>>()
150
- const points = state?.energy?.points
151
- if (!Array.isArray(points) || !points.length) return out
152
-
153
- /* 계량기 → 자리. 자리를 모르는 계량기는 자리 payload 에 실을 데가 없다(설비 태그로만 나간다). */
154
- const locOf = new Map<string, string>()
155
- for (const e of state?.equipment ?? []) if (e?.id && e?.homeLocation) locOf.set(e.id, e.homeLocation)
156
-
157
- for (const pt of points) {
158
- const loc = pt?.id ? locOf.get(pt.id) : undefined
159
- if (!loc) continue
160
- const acc = out.get(loc) ?? { meters: [] as string[], samplesInWindow: 0 }
161
- ;(acc.meters as string[]).push(pt.id)
162
- acc.samplesInWindow = Number(acc.samplesInWindow ?? 0) + (Number(pt.samplesInWindow) || 0)
163
- /* 값은 **있는 것만** 더한다 — 하나도 없으면 키를 만들지 않는다(0 은 「안 썼다」가 된다). */
164
- if (Number.isFinite(Number(pt.kW))) acc.kW = Number(acc.kW ?? 0) + Number(pt.kW)
165
- if (Number.isFinite(Number(pt.kWh))) acc.kWh = Number(acc.kWh ?? 0) + Number(pt.kWh)
166
- /* 나이는 **가장 최근**을 쓴다 — 자리에 계량기가 여럿이면 그중 마지막 관측이 그 자리의 나이다. */
167
- if (pt.atMs !== undefined) {
168
- const iso = new Date(Number(pt.atMs)).toISOString()
169
- if (!acc.measuredAt || String(acc.measuredAt) < iso) acc.measuredAt = iso
170
- }
171
- out.set(loc, acc)
172
- }
173
- return out
174
- }
175
-
176
- /**
177
- * 물품 축만 **범위를 줄일 수 있다** (2026-08-21).
178
- *
179
- * ── 왜 이 인자가 생겼나 ─────────────────────────────────────────────────────
180
- * 브로드캐스팅 한 번이 만드는 payload 는 엔티티 수만큼이고 그 대부분이 물품이다(실측: 엔티티 3,611 중
181
- * 물품 2,400 · 만드는 데 1.8ms · 문자열로 바꾸는 데 1.0ms). 바뀐 것이 물품 하나여도 전부 만들어
182
- * 「같다」를 확인하고 버렸다.
183
- *
184
- * `items` 를 주면 **그 태그의 물품만** 개별 payload 를 만든다. 주지 않으면(`undefined`) 전부 만든다 —
185
- * 부르는 쪽이 무엇이 바뀌었는지 말할 수 없을 때의 답이다.
186
- *
187
- * **집약 뷰는 범위를 받지 않는다.** 집약은 목록 전체가 한 payload 라서, 한 물품이 바뀌면 그 payload 는
188
- * 통째로 새로 만들어야 한다(상한 500으로 이미 묶여 있다). 자리·설비·인원·자산·작업·오더도 범위를 받지
189
- * 않는다 — 수가 적고, 잘못 걸러서 잃는 것이 크다(자리 점유는 물품이 떠난 자리와 도착한 자리가 함께
190
- * 바뀌는데 사건은 한 지점만 말한다).
191
- */
192
- export interface EntityDeltaScope {
193
- /** 개별 payload 를 만들 물품 태그. 없으면 전부. */
194
- items?: ReadonlySet<string>
195
- }
196
-
197
- export function buildEntityDeltas(
198
- state: any,
199
- instanceId: string,
200
- scope?: EntityDeltaScope,
201
- /** 끝난 오더를 접는 경계(모델의 `orderFold`) — 「최근 T 완료」의 T 다. 없으면 커널의 기본. */
202
- orderFold?: OrderFoldPolicy
203
- ): EntityDelta[] {
204
- const out: EntityDelta[] = []
205
- const locEnergy = energyByLocation(state)
206
-
207
- for (const n of state?.locations ?? []) {
208
- /* 에너지는 자리 payload 에 **합친다** — 같은 태그로 두 번 보내면 뒤엣것이 앞을 덮는다. */
209
- const energy = locEnergy.get(n.id)
210
- out.push({ tag: n.id, data: energy ? { ...payloadOf('location', n), ...energy } : payloadOf('location', n) })
211
- }
212
- for (const m of state?.equipment ?? []) {
213
- /* Mobile(location/motion) + Operable(status/held) + Processable(oee) — 한 payload 로.
214
- * oee 만 정형화가 필요해 따로 얹는다(나머지는 통과). */
215
- const data = payloadOf('equipment', m)
216
- const oee = shapeOee(m?.oee)
217
- if (oee) data.oee = oee
218
- out.push({ tag: m.id, data })
219
- }
220
- /* 사람 — 설비와 별개 엔티티다. 같은 통과 규칙(가진 것을 전부 내보낸다). */
221
- for (const p of state?.persons ?? []) {
222
- out.push({ tag: p.id, data: payloadOf('person', p) })
223
- }
224
- /* 물리 자산(반복사용) — 물품도 설비도 아닌 네 번째 자원. */
225
- for (const a of state?.assets ?? []) {
226
- out.push({ tag: a.id, data: payloadOf('asset', a) })
227
- }
228
- for (const o of state?.orders ?? []) {
229
- out.push({ tag: o.id, data: payloadOf('order', o) })
230
- }
231
- for (const t of state?.tasks ?? []) {
232
- out.push({ tag: t.id, data: payloadOf('task', t) })
233
- }
234
- for (const it of state?.items ?? []) {
235
- /* 물품의 태그는 epc(개체 식별자) — 자리·설비와 달리 id 가 아니다. */
236
- if (!it?.epc) continue
237
- /* 범위가 주어졌으면 그 안의 물품만 만든다 — 나머지는 값이 그대로이므로 보낼 것이 없다. */
238
- if (scope?.items && !scope.items.has(it.epc)) continue
239
- out.push({ tag: it.epc, data: payloadOf('item', it) })
240
- }
241
-
242
- /* ── 집약 뷰 ──────────────────────────────────────────────────────────────
243
- * 런타임에 생기고 사라지는 엔티티(오더·작업·물품)는 보드에 개별 배치할 수 없다 → 한 컴포넌트가
244
- * 전체를 추적하는 집약 태그를 항상 방출한다. */
245
- const orders = state?.orders ?? []
246
- /*
247
- * **「최근 T 안에 끝난」 수와 접힌 수를 함께 싣는다**(ADR-0092 결정 2 보탬 · 3). 칩은 뜨거운 줄로 세면 건수 경계(N)에서
248
- * 멈추므로, 접힌 쪽의 시간 칸까지 더한 수를 계약의 한 함수(`finishedFlowOrdersWithin`, KPI 와 같은 판정)로 낸다. 「지금」은
249
- * 그 구동의 지금(`nowTime` — 시뮬은 시계, 미러는 들은 시각의 최대)이다. 모르면 싣지 않는다 — 0 으로 메우지 않는다.
250
- */
251
- const nowMs = Date.parse(String(state?.nowTime ?? ''))
252
- const policy = orderFold ?? ORDER_FOLD_DEFAULT
253
- const finished = Number.isFinite(nowMs) ? finishedFlowOrdersWithin(orders, state?.foldedOrders, nowMs, policy) : undefined
254
- const folded = foldedOrderCount(state?.foldedOrders)
255
- out.push({
256
- tag: ordersTag(instanceId),
257
- data: {
258
- entity: 'orders',
259
- orders: orders.map((o: any) => aggregateItem(o, 'id')),
260
- ...(finished ? { finished: { ...finished, windowMs: policy.afterMs } } : {}),
261
- ...(folded ? { folded } : {})
262
- }
263
- })
264
-
265
- const tasks = state?.tasks ?? []
266
- out.push({ tag: tasksTag(instanceId), data: { entity: 'tasks', tasks: tasks.map((t: any) => aggregateItem(t, 'id')) } })
267
-
268
- /* 사람 집약 — 인원은 보드에 개별 배치할 수도 있지만(설비처럼), 전체를 한눈에 보는 소비처도 있다.
269
- * 인원을 선언하지 않은 트윈에서는 빈 배열이 나간다(없음과 모름을 구별). */
270
- const persons = state?.persons ?? []
271
- out.push({ tag: personsTag(instanceId), data: { entity: 'persons', persons: persons.map((p: any) => aggregateItem(p, 'id')) } })
272
-
273
- const assets = state?.assets ?? []
274
- out.push({ tag: assetsTag(instanceId), data: { entity: 'assets', assets: assets.map((a: any) => aggregateItem(a, 'id')) } })
275
-
276
- const items = state?.items ?? []
277
- const shown = items.slice(0, ITEMS_AGGREGATE_LIMIT)
278
- out.push({
279
- tag: itemsTag(instanceId),
280
- data: {
281
- entity: 'items',
282
- items: shown.map((it: any) => aggregateItem(it, 'epc')),
283
- total: items.length,
284
- /* 잘렸으면 그 사실을 말한다 — "이게 전부" 로 읽히면 재고를 과소 판단한다. */
285
- ...(items.length > shown.length ? { truncated: items.length - shown.length } : {})
286
- }
287
- })
288
-
289
- /*
290
- * ── 에너지 (EMS) ─────────────────────────────────────────────────────────
291
- *
292
- * 계측은 `state.energy` 에 산다 — 자원 축(`equipment`·`locations`)이 아니다. 그래서 이 매핑이 없으면
293
- * 보드에 놓은 계량기가 **아무 값도 받지 못한다**(컴포넌트는 있는데 영원히 빈 모습).
294
- *
295
- * 두 갈래로 낸다:
296
- * · **개체별** — 계량 지점 하나하나의 마지막 관측(kW·kWh·역률·시각). 태그는 그 설비 id 다.
297
- * · **집약** — 수요 구간·피크·계약전력. 이것은 트윈 하나의 사실이라 개체에 실을 수 없다.
298
- *
299
- * 값이 없으면 **키를 넣지 않는다**(0 으로 만들지 않는다) — 「못 읽었다」와 「0 이었다」는 다른 사실이고,
300
- * 그 구별이 이 트윈의 값어치다.
301
- */
302
- const energy = state?.energy
303
- if (energy) {
304
- for (const pt of energy.points ?? []) {
305
- if (!pt?.id) continue
306
- out.push({
307
- tag: pt.id,
308
- data: {
309
- entity: 'meter',
310
- ...(pt.kW !== undefined ? { kW: pt.kW } : {}),
311
- ...(pt.kWh !== undefined ? { kWh: pt.kWh } : {}),
312
- ...(pt.powerFactor !== undefined ? { powerFactor: pt.powerFactor } : {}),
313
- /* 마지막 표본 시각 — 계측이 끊긴 것을 화면이 스스로 알 수 있게(우리가 판정하지 않는다). */
314
- ...(pt.atMs !== undefined ? { measuredAt: new Date(pt.atMs).toISOString() } : {}),
315
- samplesInWindow: pt.samplesInWindow ?? 0
316
- }
317
- })
318
- }
319
- out.push({
320
- tag: energyTag(instanceId),
321
- data: {
322
- entity: 'energy',
323
- ...(energy.contractKW !== undefined ? { contractKW: energy.contractKW } : {}),
324
- ...(energy.open ? { open: energy.open } : {}),
325
- ...(energy.peakSince ? { peakSince: energy.peakSince } : {}),
326
- /* 마감된 구간은 **최근 것만** 낸다 — 하루치를 매 브로드캐스팅에 실으면 채널이 그것으로 찬다.
327
- 전체 수는 함께 낸다(알리지 않고 자르지 않는다). */
328
- recent: (energy.closed ?? []).slice(-8),
329
- closedTotal: energy.closedTotal ?? 0
330
- }
331
- })
332
- }
333
-
334
- return out
335
- }
@@ -1,13 +0,0 @@
1
- /*
2
- * 구간 성과 카드의 **대상 식별자**.
3
- *
4
- * 예전에는 이 파일이 브로드캐스팅 payload 도 만들었다(`shapeKpiBroadcast`). 2026-08-06 에 브로드캐스팅을 없애고 카드가
5
- * `twinKpi` 를 직접 묻게 바꿔서, 남은 것은 팔레트가 대상을 가리킬 때 쓰는 식별자뿐이다.
6
- * 왜 바꿨는지는 `twin-engine.ts` 의 주석과 `operato-twin/client/scene/twin-kpi-source.ts` 에 있다.
7
- */
8
- export const KPI_TAG_PREFIX = '__kpi__'
9
-
10
- /** 이 트윈의 구간 성과 태그. */
11
- export const kpiTag = (instanceId: string) => `${KPI_TAG_PREFIX}:${instanceId}`
12
-
13
- /** 표식은 `entity` 로 — `kind` 는 도메인의 낱말이라 표식이 훔치지 않는다(`entity-delta.ts` 와 같은 규약). */
@@ -1,73 +0,0 @@
1
- /*
2
- * 한 사건이 **어느 물품을 건드렸나** — 브로드캐스팅이 바뀐 것만 만들 수 있게. 순수(import 없음).
3
- *
4
- * ── 왜 물품만인가 (2026-08-21 실측) ─────────────────────────────────────────
5
- * 브로드캐스팅 한 번이 만드는 payload 는 엔티티 수만큼이고, 그 대부분이 물품이다(실측: 엔티티 3,611 중
6
- * 물품 2,400). 자리·설비·인원·자산은 모델이 정한 수라 적고(자리 최대 200, 평균 19), 작업·오더는 수백이다.
7
- * 그래서 **물품 축만 걸러도** 만드는 양의 3분의 2가 사라진다.
8
- *
9
- * 나머지 축은 **매번 전부 만든다.** 걸러서 얻는 것이 적고, 잘못 걸러서 잃는 것이 크기 때문이다 —
10
- * 예를 들어 물품이 한 자리에서 다른 자리로 가면 **두 자리의 점유가 함께 바뀌는데** EPCIS 사건은 읽은
11
- * 지점 하나만 말한다. 그것으로 자리를 걸렀으면 떠난 자리의 점유가 낡은 값으로 남는다(오류 없이).
12
- *
13
- * ── 모르면 전부다 ───────────────────────────────────────────────────────────
14
- * 이 함수가 `null` 을 돌려주면 「이 사건이 어느 물품을 건드렸는지 말할 수 없다」는 뜻이고, 그때 호출자는
15
- * **전부 다시 만든다**(지금까지의 거동). 낯선 어휘가 오면 알리지 않고 빠뜨리는 것이 아니라 비싸게 안전한
16
- * 쪽으로 떨어진다 — 화면이 낡는 것보다 계산을 한 번 더 하는 것이 낫다.
17
- */
18
-
19
- /** 물품 태그는 개체 식별자(epc)다 — 자리·설비와 달리 id 가 아니다(entity-delta 와 같은 규약). */
20
- function push(out: Set<string>, v: unknown): void {
21
- if (typeof v === 'string' && v) out.add(v)
22
- }
23
-
24
- /**
25
- * 물품을 건드리지 않는다고 **선언된** 사건들 — 커널의 운영 델타와 에너지 사건.
26
- *
27
- * 이 목록은 커널 계약(`OP_EVENT`·`ENERGY_EVENT`)에서 왔다. 여기 없는 낱말이 오면 「모른다」로 떨어져
28
- * 전부 다시 만든다 — 커널이 사건을 늘렸을 때 알리지 않고 빠뜨리는 대신 비싸게 안전한 쪽을 고른다.
29
- *
30
- * 근거: 미러의 리듀서에서 이 사건들은 작업·설비·인원·자산·오더·계량만 바꾼다(물품 축을 만지지 않는다).
31
- * 자리 점유는 이 사건들도 바꾸지만, 자리는 **어차피 매번 전부 다시 만든다**(위 주석).
32
- */
33
- const ITEM_FREE_EVENTS = new Set([
34
- 'task.status',
35
- 'equipment.status',
36
- 'person.status',
37
- 'asset.status',
38
- 'order.status',
39
- 'quality.output',
40
- 'attention.acked'
41
- ])
42
-
43
- /**
44
- * 이 사건이 건드린 물품 태그들. **말할 수 없으면 `null`** — 호출자는 그때 전부 다시 만든다.
45
- *
46
- * 개체를 말하는 자리를 전부 본다: `epcList`(관측·커미셔닝) · `parentID`(집약의 부모) ·
47
- * `childEPCs`(집약의 자식) · `inputEPCList`·`outputEPCList`(변환의 입출력).
48
- */
49
- export function touchedItemKeys(envelope: any): Set<string> | null {
50
- const type = envelope?.eventType
51
- if (typeof type !== 'string') return null
52
- const d = envelope?.data ?? envelope
53
- if (!d || typeof d !== 'object') return null
54
-
55
- if (type.startsWith('energy.') || ITEM_FREE_EVENTS.has(type)) return new Set()
56
- /* EPCIS 밖의 낯선 낱말 — 무엇을 바꿨는지 우리가 모른다. */
57
- if (!type.startsWith('epcis.')) return null
58
-
59
- const out = new Set<string>()
60
- for (const v of d.epcList ?? []) push(out, v)
61
- for (const v of d.childEPCs ?? []) push(out, v)
62
- for (const v of d.inputEPCList ?? []) push(out, v)
63
- for (const v of d.outputEPCList ?? []) push(out, v)
64
- push(out, d.parentID)
65
-
66
- /*
67
- * 개체를 하나도 말하지 않은 EPCIS 사건은 **부류 수량**으로 말한 것이다(`quantityList`). 그 부류의
68
- * 물품이 어느 것인지는 여기서 알 수 없으므로 전부 다시 만든다.
69
- */
70
- if (!out.size) return null
71
-
72
- return out
73
- }
@@ -1,48 +0,0 @@
1
- /*
2
- * 공간 계층의 **단계** — 성과를 어느 단위로 보는가. 순수(import 없음).
3
- *
4
- * ── 왜 여기 있나 ───────────────────────────────────────────────────────────
5
- * 이 목록을 세 곳이 쓴다: 씬 표현이 "나는 어느 단계에 붙는다" 고 선언할 때(클라이언트), 성과 카드가
6
- * "이 단계로 나눠 달라" 고 물을 때(클라이언트), AI 가 "구역별로 보여 줘" 를 제안할 때(서버).
7
- * 세 곳이 각자 목록을 적으면 하나가 늘 때 나머지가 알리지 않고 뒤처진다 — 집약 태그에서 이미 겪었다.
8
- *
9
- * 그래서 **한 곳**에 두고 셋이 가져다 쓴다. 이 파일은 import 가 없어 클라이언트 번들에 서버 코드를
10
- * 끌고 들어가지 않는다.
11
- */
12
-
13
- /**
14
- * 성과를 접을 수 있는 단계 — 좁은 것부터.
15
- *
16
- * `equipment` 는 커널 축 이름으로 `resource` 다(설비·인원·자산을 아우르는 이름). 화면과 AI 는
17
- * "설비" 로 말하고, 커널에 물을 때만 축 이름으로 바꾼다 — 그 변환이 아래 한 곳에 있다.
18
- */
19
- export const TWIN_LEVELS = ['space', 'twin', 'area', 'location', 'equipment'] as const
20
- export type TwinLevel = (typeof TWIN_LEVELS)[number]
21
-
22
- export function isTwinLevel(v: unknown): v is TwinLevel {
23
- return typeof v === 'string' && (TWIN_LEVELS as readonly string[]).includes(v)
24
- }
25
-
26
- /**
27
- * 단계 → 커널의 나누는 축(`KpiGroupBy`). **전체를 보는 단계는 축이 없다** — 나누지 않고 통째로 접는다.
28
- *
29
- * `space` 와 `twin` 이 축 없이 같은 이유: 둘의 차이는 "무엇을 대상으로 삼는가"(공간 전체 대 트윈 하나)이지
30
- * "어떻게 나누는가" 가 아니다. 대상은 질의의 `spaceId`/`instanceId` 가 정한다.
31
- */
32
- export function kpiGroupByOfLevel(level: TwinLevel): 'area' | 'location' | 'resource' | undefined {
33
- if (level === 'area') return 'area'
34
- if (level === 'location') return 'location'
35
- if (level === 'equipment') return 'resource'
36
-
37
- return undefined
38
- }
39
-
40
- /**
41
- * 그 단계의 카드가 **대상 하나마다 한 장**인가.
42
- *
43
- * 구역·자리·설비는 여럿이라 카드가 그 수만큼 생긴다. 공간·트윈은 하나뿐이다. 보드를 자동으로 조립할 때
44
- * 몇 장이 생길지 미리 알아야 한다 — 자리 200개 × 지표 4개면 800장이다.
45
- */
46
- export function isPerTargetLevel(level: TwinLevel): boolean {
47
- return kpiGroupByOfLevel(level) !== undefined
48
- }
@@ -1,97 +0,0 @@
1
- /*
2
- * ★ **답의 모양이 세 곳에서 같아야 한다** — 어댑터가 답한 칸이 중간에서 사라지지 않게.
3
- *
4
- * ── 무엇이 있었나 (2026-09-04, 인티그레이션 레인이 찾음) ────────────────────
5
- * 조치의 답이 세 타입을 지난다.
6
- *
7
- * ReferenceAdapter.actuate 반환 커넥터가 만든다
8
- * ActuationAck routeActuation 이 되돌린다
9
- * CommandAck dispatch 가 받아 표에 적는다
10
- *
11
- * 가운데가 `ok`·`ref`·`error` 셋만 들고 있었다. 그래서 **타입은 `note`·`noteNext`·`retry` 를
12
- * 버린다고 말했다.** 값은 흘렀다 — JS 객체가 키를 안 버리므로. 실제로 `dispatch_note` 에 앉았다.
13
- *
14
- * 그런데 **커넥터를 만드는 사람이 그 칸이 있다는 것을 알 방법이 없었다.** 이 저장소에서 하루
15
- * 종일 「자리는 있고 길이 없다」로 부른 것의 타입 버전이다 — 동작은 하고 계약이 안 알려 준다.
16
- *
17
- * ── 왜 원문을 읽나 ──────────────────────────────────────────────────────────
18
- * 타입은 런타임에 없다. 그래서 「세 모양이 같은가」를 값으로 잴 수 없고, 원문에서 읽는 것이
19
- * 지금 할 수 있는 최선이다. 이 검사가 막으려는 것은 **한 곳에만 칸을 더하는 일**이다.
20
- */
21
- import { test } from 'node:test'
22
- import assert from 'node:assert/strict'
23
- import { readFileSync } from 'node:fs'
24
-
25
- /** 주석 속 낱말이 세어지지 않게 — 오늘 두 번 그 함정에 걸렸다. */
26
- const bare = (p: string): string =>
27
- readFileSync(new URL(p, import.meta.url), 'utf8')
28
- .replace(/\/\*[\s\S]*?\*\//g, '')
29
- .replace(/\/\/[^\n]*/g, '')
30
-
31
- /** 답이 반드시 나를 칸 — 하나라도 중간에서 사라지면 커넥터가 적은 것이 버려진다. */
32
- const CARRIED = ['note', 'noteNext', 'retry'] as const
33
-
34
- const SOURCES = {
35
- '어댑터 actuate 반환': '../server/service/reference/reference-adapter.ts',
36
- ActuationAck: '../server/service/reference/actuation-routing.ts',
37
- CommandAck: '../server/service/actuation/command-dispatcher.ts'
38
- } as const
39
-
40
- test('★ 세 타입이 같은 칸을 든다 — 한 곳에만 더하면 값이 중간에서 버려진다', () => {
41
- const missing: string[] = []
42
-
43
- for (const [label, path] of Object.entries(SOURCES)) {
44
- const src = bare(path)
45
- for (const field of CARRIED) {
46
- /* `field?:` 로 선언된 자리를 찾는다 — 이름만 스치는 것은 세지 않는다. */
47
- if (!new RegExp(`\\b${field}\\?:`).test(src)) missing.push(`${label} 에 ${field} 없음`)
48
- }
49
- }
50
-
51
- assert.deepEqual(
52
- missing,
53
- [],
54
- '조치의 답이 지나는 세 타입 중 한 곳이 칸을 버린다. 값은 흐르지만 커넥터를 만드는 사람은\n' +
55
- '그 칸이 있다는 것을 알 수 없다:\n ' + missing.join('\n ')
56
- )
57
- })
58
-
59
- test('★ 갈래 셋은 한 곳에서 정의되고 나머지는 그것을 가리킨다 — 반복하면 갈라진다', () => {
60
- /*
61
- * `again`·`after-fix`·`never` 는 어댑터가 고르고 일꾼이 판정한다. 세 곳에 낱말을 각각 적으면
62
- * 한쪽만 늘어나는 날 다른 쪽이 **모르는 값을 「말하지 않은 것」으로 읽어 조용히 집지 않는다.**
63
- *
64
- * 처음에 이 검사를 「세 곳에 낱말이 다 있는가」로 뒀다. 그것이 곧 **반복을 요구하는 검사**였고,
65
- * 반복이 바로 갈라짐의 원인이다. 그래서 규칙을 바꿨다: 정의는 한 곳, 나머지는 그 이름을 가리킨다.
66
- */
67
- const outlooks = ['again', 'after-fix', 'never'] as const
68
-
69
- /* 정의하는 자리 — 셋을 다 안다. */
70
- const plan = bare('../server/service/actuation/retry-plan.ts')
71
- assert.match(plan, /export type RetryOutlook/, '갈래를 정의하는 자리가 없다')
72
- for (const o of outlooks) assert.ok(plan.includes(`'${o}'`), `정의가 갈래 '${o}' 를 모른다`)
73
-
74
- /* 선언하는 자리는 낱말을 다 적거나 그 이름을 가리켜야 한다. */
75
- const loose: string[] = []
76
- for (const [label, path] of Object.entries(SOURCES)) {
77
- const src = bare(path)
78
- if (!/\bretry\?:/.test(src)) continue
79
-
80
- const namesType = /retry\?:\s*RetryOutlook/.test(src)
81
- const listsAll = outlooks.every(o => src.includes(`'${o}'`))
82
- if (!namesType && !listsAll) loose.push(`${label} 이 갈래를 좁히지 않는다`)
83
- }
84
-
85
- assert.deepEqual(
86
- loose,
87
- [],
88
- '갈래를 문자열로 열어 두면 커넥터가 모르는 낱말을 보내도 타입이 통과시킨다:\n ' + loose.join('\n ')
89
- )
90
- })
91
-
92
- test('★ 이 검사가 실제로 무언가를 잰다 — 원문을 못 읽으면 빨강', () => {
93
- for (const [label, path] of Object.entries(SOURCES)) {
94
- const src = bare(path)
95
- assert.ok(src.length > 1000, `${label} 원문이 ${src.length}자다 — 경로가 틀렸다`)
96
- }
97
- })
@@ -1,55 +0,0 @@
1
- /*
2
- * The approval screen's AI advisor — it is asked with the tenant, and every way of not answering is named.
3
- *
4
- * 2026-09-17: the twin app's advisor called its tools with no domain, because `advise` had no place for one.
5
- * Every tool answered "no domain context" and the opinion was written from the prompt alone. The first test
6
- * holds the domain on the way through; the resolver test holds that the resolver hands it over.
7
- */
8
- import { test } from 'node:test'
9
- import assert from 'node:assert/strict'
10
- import { readFileSync } from 'node:fs'
11
-
12
- import { askAdvisor, setActuationAdvisor, type ActuationAdvisor } from '../server/service/actuation/actuation-advisor.ts'
13
-
14
- const command = { id: 'cmd-1', instanceId: 'wms-1', type: 'order.hold', args: {} } as any
15
- const twinNow = { attentions: [] } as any
16
-
17
- function install(advise: ActuationAdvisor['advise']) {
18
- setActuationAdvisor({ label: 'AI', advise })
19
- }
20
-
21
- test('the advisor is asked with the domain the command belongs to', async () => {
22
- let seen: any
23
- install(async input => {
24
- seen = input
25
- return { stance: 'unsure', text: 'not enough to go on' }
26
- })
27
- const r = await askAdvisor({ domainId: 'tenant-a', command, twinNow, locale: 'ko' })
28
- assert.equal(seen.domainId, 'tenant-a')
29
- assert.equal(seen.command, command)
30
- assert.equal(seen.locale, 'ko')
31
- assert.equal(r.opinion?.stance, 'unsure')
32
- })
33
-
34
- test('an advisor that throws is an absent opinion with its reason, not silence', async () => {
35
- install(async () => {
36
- throw new Error('model unavailable')
37
- })
38
- const r = await askAdvisor({ domainId: 'tenant-a', command, twinNow })
39
- assert.equal(r.opinion, undefined)
40
- assert.match(String(r.absent), /model unavailable/)
41
- })
42
-
43
- test('an advisor that does not answer in time is absent, and says it was time', async () => {
44
- install(() => new Promise(() => {}))
45
- const r = await askAdvisor({ domainId: 'tenant-a', command, twinNow, budgetMs: 10 })
46
- assert.equal(r.opinion, undefined)
47
- assert.ok(r.absent)
48
- })
49
-
50
- test('the resolver hands the tenant to the advisor', () => {
51
- const src = readFileSync(new URL('../server/service/actuation/twin-command-resolver.ts', import.meta.url), 'utf-8')
52
- const call = src.match(/askAdvisor\(\{([^}]*)\}/)
53
- assert.ok(call, 'askAdvisor call not found in the resolver')
54
- assert.match(call[1], /\bdomainId\b/)
55
- })