@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,99 +0,0 @@
1
- /*
2
- * **창에 다 들어오지 않은 발전 기간을 조용히 버리지 않는다.**
3
- *
4
- * ── 무엇이 일어났나 (2026-08-30) ──────────────────────────────────────────
5
- * 어제 발전량이 저널에 멀쩡히 있는데 화면이 비어 있었다. 발전 기간은 하루 단위이고(`08-28 15:00 →
6
- * 08-29 15:00`), 성과 구간은 「지금부터 24시간 전」이라 한낮에서 시작한다(`08-29 02:53 → 08-30 02:53`).
7
- * 하루 기간이 그 구간에 **온전히 들어오지 않는다.**
8
- *
9
- * 더하지 않는 것 자체는 맞다 — 걸친 기간을 더하면 다른 날의 값이 이 창의 값인 척한다. 틀린 것은
10
- * **아무 말도 하지 않은 것**이다. 사용자는 빈 화면을 「발전량이 없다」로 읽는다. 그 둘은 완전히
11
- * 다른 상황이다.
12
- */
13
- import { test } from 'node:test'
14
- import assert from 'node:assert/strict'
15
-
16
- import { foldKpi } from '../server/engine/kpi-fold.ts'
17
-
18
- const T = (iso: string) => Date.parse(iso)
19
-
20
- /** 실측값 — 오창의 8월 29일 하루. */
21
- const DAY_START = '2026-08-28T15:00:00.000Z'
22
- const DAY_END = '2026-08-29T15:00:00.000Z'
23
-
24
- const period = (equipmentId: string, kWh: number) => ({
25
- eventType: 'energy.generation.period',
26
- eventTime: DAY_END,
27
- payload: {
28
- eventId: `id|${equipmentId}`,
29
- data: {
30
- equipmentId,
31
- kWh,
32
- periodStart: DAY_START,
33
- periodEnd: DAY_END,
34
- observedFrom: DAY_START,
35
- observedTo: DAY_END,
36
- accumulation: 'daily',
37
- boundary: 'offset'
38
- }
39
- }
40
- })
41
-
42
- const EVENTS = [period('002', 127.1), period('003', 104.1), period('004', 312.4), period('005', 102.3)] as any
43
-
44
- test('★ 창이 기간을 온전히 담으면 더한다', () => {
45
- const r = foldKpi(EVENTS, { fromMs: T(DAY_START), toMs: T(DAY_END) })
46
- const g = r.energy?.generated
47
- assert.ok(g, '발전량이 있어야 한다')
48
- assert.equal(g.counted, 4)
49
- assert.equal(Math.round(g.kWh * 10) / 10, 645.9)
50
- assert.equal(g.notCounted, undefined, '버린 것이 없으면 말하지 않는다')
51
- })
52
-
53
- test('★ 창이 기간을 반만 담으면 더하지 않되 **버렸다고 말한다**', () => {
54
- /* 실제로 났던 구간 — 하루 기간의 한가운데에서 시작한다. */
55
- const r = foldKpi(EVENTS, { fromMs: T('2026-08-29T02:53:00.000Z'), toMs: T('2026-08-30T02:53:00.000Z') })
56
- const g = r.energy?.generated
57
- assert.ok(g, '값이 없다고 아무것도 내지 않으면 화면은 「발전량 없음」으로 읽는다')
58
- assert.equal(g.kWh, 0, '걸친 기간은 더하지 않는다 — 더하면 다른 날 값이 섞인다')
59
- assert.equal(g.counted, 0)
60
- assert.ok(g.notCounted, '버린 것을 말해야 한다')
61
- assert.equal(g.notCounted.periods, 4)
62
- assert.equal(Math.round(g.notCounted.kWh * 10) / 10, 645.9, '얼마를 못 세었는지 말한다')
63
- assert.equal(g.notCounted.earliestStart, DAY_START)
64
- assert.equal(g.notCounted.latestEnd, DAY_END)
65
- })
66
-
67
- test('창이 기간과 아예 겹치지 않으면 말할 것이 없다 — 없는 것을 만들지 않는다', () => {
68
- const r = foldKpi(EVENTS, { fromMs: T('2026-07-01T00:00:00.000Z'), toMs: T('2026-07-02T00:00:00.000Z') })
69
- assert.equal(r.energy?.generated, undefined)
70
- })
71
-
72
- test('온전히 든 것과 걸친 것이 섞이면 더한 것과 못 센 것을 함께 낸다', () => {
73
- const earlier = {
74
- ...period('002', 100),
75
- eventTime: '2026-08-28T15:00:00.000Z',
76
- payload: {
77
- eventId: 'id|earlier',
78
- data: {
79
- equipmentId: '002',
80
- kWh: 100,
81
- periodStart: '2026-08-27T15:00:00.000Z',
82
- periodEnd: '2026-08-28T15:00:00.000Z',
83
- observedFrom: '2026-08-27T15:00:00.000Z',
84
- observedTo: '2026-08-28T15:00:00.000Z',
85
- accumulation: 'daily',
86
- boundary: 'offset'
87
- }
88
- }
89
- }
90
- const r = foldKpi([earlier, ...EVENTS] as any, {
91
- fromMs: T('2026-08-27T15:00:00.000Z'),
92
- toMs: T('2026-08-29T02:00:00.000Z')
93
- })
94
- const g = r.energy?.generated
95
- assert.ok(g)
96
- assert.equal(g.counted, 1, '27→28 하루만 온전히 들었다')
97
- assert.equal(g.kWh, 100)
98
- assert.equal(g.notCounted?.periods, 4, '28→29 넷은 창의 끝을 넘는다')
99
- })
@@ -1,76 +0,0 @@
1
- import { existsSync } from 'node:fs'
2
- import { fileURLToPath } from 'node:url'
3
-
4
- /*
5
- * ═══════════════════════════════════════════════════════════════════════════
6
- * Where the source-reading guards look, and what happens when a place is gone.
7
- *
8
- * ── Why this exists (2026-09-08) ───────────────────────────────────────────
9
- * Four guards in this package read the *consumer's* source as well as their own, because the
10
- * defects they catch are committed by callers: a caller that fills a kernel kind with a
11
- * literal, a caller that reads the journal without saying it is folding, a caller that
12
- * ingests without writing to the ledger.
13
- *
14
- * The applications then moved to their own repository, and `../../operato-twin/server` stopped
15
- * existing. Two of the four failed with ENOENT. **The other two passed** — their directory
16
- * walker swallows a missing root:
17
- *
18
- * try { entries = readdirSync(dir) } catch { … }
19
- *
20
- * So half of each of those guards was scanning nothing and reporting green. A guard that
21
- * quietly stops guarding is worse than one that fails, because the failure is the only signal
22
- * that it was ever load-bearing.
23
- *
24
- * ── So a missing root is an error, not a skip ──────────────────────────────
25
- * `guardRoots` refuses to hand back a root that is not there. The message says which place is
26
- * gone and what to do about it, because the answer is not "delete the root" — the code being
27
- * guarded still exists, it is just in another repository now, and the guard has to follow it
28
- * there.
29
- * ═══════════════════════════════════════════════════════════════════════════
30
- */
31
-
32
- /**
33
- * Resolve the places a guard scans, and fail loudly if any of them is missing.
34
- *
35
- * @param base `import.meta.url` of the calling test.
36
- * @param places Paths relative to that test file.
37
- */
38
- export function guardRoots(base: string, places: readonly string[]): string[] {
39
- const missing: string[] = []
40
- const roots = places.map(place => {
41
- const path = fileURLToPath(new URL(place, base))
42
- if (!existsSync(path)) missing.push(place)
43
- return path
44
- })
45
-
46
- if (missing.length) {
47
- throw new Error(
48
- `guard root missing: ${missing.join(' · ')}\n` +
49
- 'This guard reads a consumer\'s source, and that source is no longer at this path.\n' +
50
- 'The applications moved to the operato-application repository (ADR-0041 era). Move the\n' +
51
- 'consumer half of this guard there rather than deleting the root — a root removed here\n' +
52
- 'is a rule that stops being checked, and nothing will say so.'
53
- )
54
- }
55
-
56
- return roots
57
- }
58
-
59
- /**
60
- * Resolve one file a guard reads, and fail loudly if it is gone.
61
- *
62
- * Same reason as above, for the guards that read a single named file rather than walking a
63
- * tree. `readFileSync` would already throw here — this only replaces `ENOENT: no such file`
64
- * with a sentence that says what to do.
65
- */
66
- export function guardFile(base: string, place: string): string {
67
- const path = fileURLToPath(new URL(place, base))
68
- if (!existsSync(path)) {
69
- throw new Error(
70
- `guard file missing: ${place}\n` +
71
- 'This guard reads a consumer\'s source. That file moved to the operato-application\n' +
72
- 'repository — move this assertion there rather than deleting it.'
73
- )
74
- }
75
- return path
76
- }
@@ -1,90 +0,0 @@
1
- /*
2
- * **설비는 자리에도 구역에도 설 수 있다.**
3
- *
4
- * ── 실물 (2026-09-06) ───────────────────────────────────────────────────────
5
- * `EQ-CAM-SHOWER-01`(에어샤워)이 `LINE-CAM` 이라는 **구역**에 딸려 있다. 라인 전체에 붙는 설비는
6
- * 자리 하나를 고를 수 없고, 그것이 정상이다.
7
- *
8
- * 그런데 인제스트가 그 참조를 **「끊어졌다」고 경고**했다. 자리 목록에서만 찾았기 때문이다.
9
- *
10
- * ```
11
- * unresolved-reference
12
- * equipment.homeLocation points at something that is not in this twin (EQ-CAM-SHOWER-01→LINE-CAM)
13
- * ```
14
- *
15
- * 계약이 그 갈림을 위해 `homeLocationKind = 'location' | 'area'` 를 두었는데 **아무도 안 채우고
16
- * 있었다** — 선언만 있고 읽는 쪽도 쓰는 쪽도 0곳이었다.
17
- *
18
- * 짐작하지 않는다. 마스터가 이미 `role` 로 자리와 구역을 가르고 있으므로 그것을 읽는다.
19
- */
20
- import { test } from 'node:test'
21
- import assert from 'node:assert/strict'
22
-
23
- import { masterToTwin } from '../server/service/reference/reference-master.ts'
24
-
25
- const master = (): any => ({
26
- source: 'm',
27
- system: 'mes',
28
- siteName: 'S',
29
- space: { spaceId: 'm-site', width: 100, depth: 60, unit: 'm' },
30
- locations: [
31
- { id: 'ST-1', role: 'location', type: 'weld-station', capacity: 1 },
32
- { id: 'LINE-CAM', role: 'area', type: 'line' }
33
- ],
34
- equipment: [
35
- { id: 'EQ-WELD-1', kind: 'welder', homeLocationId: 'ST-1' },
36
- { id: 'EQ-CAM-SHOWER-01', kind: 'air-shower', homeLocationId: 'LINE-CAM' }
37
- ]
38
- })
39
-
40
- const eq = (model: any, id: string) => model.equipment.find((e: any) => e.id === id)
41
-
42
- test('★ 구역에 선 설비는 homeLocationKind 로 그것을 말한다', () => {
43
- const { model } = masterToTwin(master())
44
- const shower = eq(model, 'EQ-CAM-SHOWER-01')
45
-
46
- assert.equal(shower.homeLocation, 'LINE-CAM')
47
- assert.equal(shower.homeLocationKind, 'area', '구역인 것을 안 말하면 읽는 쪽이 자리로 읽는다')
48
- })
49
-
50
- test('★ 자리에 선 설비는 그 칸을 안 만든다 — 계약의 기본값이 location 이다', () => {
51
- /*
52
- * 없는 칸을 만들면 화면이 그것을 그리고, 「자리」라는 당연한 말이 모든 줄에 붙는다.
53
- * `homeOf()` 가 없을 때 `'location'` 을 내는 것이 그래서다.
54
- */
55
- const { model } = masterToTwin(master())
56
- const welder = eq(model, 'EQ-WELD-1')
57
-
58
- assert.equal(welder.homeLocation, 'ST-1')
59
- assert.equal('homeLocationKind' in welder, false)
60
- })
61
-
62
- test("★ role 이 'both' 면 자리다 — 구역으로 만들지 않는다", () => {
63
- /*
64
- * `both` 는 그 줄이 자리 목록에도 구역 목록에도 들어간다는 뜻이다. 설비가 그것을 가리키면
65
- * **자리 쪽이 이긴다** — 자리는 설비가 실제로 서는 지점이고, 구역은 그것을 담는 넓이다.
66
- */
67
- const m = master()
68
- m.locations = [{ id: 'CELL-1', role: 'both', type: 'cell', capacity: 1 }]
69
- m.equipment = [{ id: 'EQ-1', kind: 'welder', homeLocationId: 'CELL-1' }]
70
-
71
- const { model } = masterToTwin(m)
72
- assert.equal('homeLocationKind' in eq(model, 'EQ-1'), false)
73
- })
74
-
75
- test('기준 자리가 없는 설비는 그 칸도 없다', () => {
76
- const m = master()
77
- m.equipment = [{ id: 'EQ-FREE', kind: 'agv' }]
78
- const { model } = masterToTwin(m)
79
- assert.equal('homeLocationKind' in eq(model, 'EQ-FREE'), false)
80
- })
81
-
82
- test('★ 이 테스트가 실제로 무언가를 잰다 — 견준 것이 0이면 빨강', () => {
83
- const { model } = masterToTwin(master())
84
- assert.equal(model.equipment.length, 2, '설비를 하나도 안 읽었다')
85
- assert.notEqual(
86
- eq(model, 'EQ-CAM-SHOWER-01').homeLocationKind,
87
- eq(model, 'EQ-WELD-1').homeLocationKind,
88
- '구역에 선 설비와 자리에 선 설비가 같아졌다'
89
- )
90
- })
@@ -1,28 +0,0 @@
1
- /*
2
- * ★ The hook address the contract comments give is the address the route answers.
3
- *
4
- * 2026-10-11: both contract comments said `POST /domain/<도메인>/twin/hook/…`. The route sits on the
5
- * domain-public router with no prefix, so the warehouse destination, written from that comment, got 405
6
- * for every fact. The tenant travels in the X-Things-Factory-Domain header (the webhook destination's
7
- * params.receivingDomain), not in the path.
8
- */
9
- import { test } from 'node:test'
10
- import assert from 'node:assert/strict'
11
- import { readFileSync } from 'node:fs'
12
-
13
- const read = (rel: string) => readFileSync(new URL(`../server/${rel}`, import.meta.url), 'utf8')
14
-
15
- const route = read('routes.ts').match(/router\.post\('([^']*twin\/hook[^']*)'/)?.[1]
16
-
17
- test('the hook route is registered without a domain prefix', () => {
18
- assert.equal(route, '/twin/hook/:source/:instanceId')
19
- })
20
-
21
- for (const file of ['service/reference/hook-contract.ts', 'service/reference/reference-hook.ts']) {
22
- test(`${file} gives the address the route answers`, () => {
23
- const line = read(file).match(/주소\s+POST\s+(\S+)/)?.[1]
24
- assert.ok(line, 'no address line')
25
- assert.equal(line, '/twin/hook/<연결이름>/<트윈>')
26
- assert.equal(line.replace(/<[^>]+>/g, 'x'), route!.replace(/:\w+/g, 'x'), 'the comment and the route name different paths')
27
- })
28
- }
@@ -1,86 +0,0 @@
1
- /*
2
- * 떨어진 것에 봉투 id 가 실리나.
3
- *
4
- * ── 왜 필요한가 (2026-09-07 측정) ───────────────────────────────────────────
5
- * 훅 응답의 떨어진 목록이 `{ record, errors }` 였고, plant 은 그것을 **봉투 id 문자열 목록**으로
6
- * 읽고 있었다.
7
- *
8
- * ```
9
- * headless-twin rejected: { record, errors }[] 객체 배열
10
- * plant "rejected is a list of envelope ids" 문자열 배열
11
- * ```
12
- *
13
- * `Array.isArray` 는 통과하니 그쪽 guard 도 안 걸렸다. id 를 맞추는데 객체라 하나도 안 맞고
14
- * **묶음 전체가 「보냈음」으로 찍혔다** — 422 와 `ok: false` 를 보냈는데 재시도 0 · 오류 없음이었다.
15
- *
16
- * 우리가 말했는데 상대가 못 알아듣는 모양이면, 말한 것이 아니다.
17
- *
18
- * 이 시험은 **모양**을 본다. 값이 흐르는지는 다른 시험이 보고, 여기서는 보내는 쪽이 자기 행을 찾을 수
19
- * 있는 열쇠가 실리는지만 본다.
20
- */
21
- import test from 'node:test'
22
- import assert from 'node:assert/strict'
23
-
24
- import { rejectedForCaller } from '../server/service/reference/hook-rejected.js'
25
-
26
- const bad = { orderId: 'WO-1' }
27
- const worse = { orderId: 'WO-2' }
28
- const ERRORS = ['order: at 없음/형식 오류']
29
-
30
- test('봉투 id 를 아는 것은 id 로 나간다 — 보내는 쪽이 그 행만 표시할 수 있다', () => {
31
- const out = rejectedForCaller([{ record: bad, errors: ERRORS }], [{ record: bad, eventId: 'evt-1' }])
32
-
33
- assert.deepEqual(out, [{ eventId: 'evt-1', errors: ERRORS }])
34
- })
35
-
36
- test('id 를 모르면 레코드를 그대로 싣는다 — 빈 id 를 넣지 않는다', () => {
37
- /*
38
- * 빈 id 를 실으면 보내는 쪽이 아무 행도 못 찾으면서 「알았다」고 여긴다. 그때는 무엇이 떨어졌는지
39
- * 보여 주는 것이 유일한 답이다.
40
- */
41
- const out = rejectedForCaller([{ record: bad, errors: ERRORS }], [{ record: bad }])
42
-
43
- assert.deepEqual(out, [{ record: bad, errors: ERRORS }])
44
- })
45
-
46
- test('짝은 객체 동일성으로 짓는다 — 같은 모양의 레코드 둘이 서로의 id 를 가져가지 않는다', () => {
47
- const twinA = { orderId: 'SAME' }
48
- const twinB = { orderId: 'SAME' }
49
- const out = rejectedForCaller(
50
- [{ record: twinB, errors: ERRORS }],
51
- [
52
- { record: twinA, eventId: 'evt-A' },
53
- { record: twinB, eventId: 'evt-B' }
54
- ]
55
- )
56
-
57
- assert.deepEqual(out, [{ eventId: 'evt-B', errors: ERRORS }], '값으로 비교하면 evt-A 가 나온다')
58
- })
59
-
60
- test('여러 건이 각자의 id 로 나간다', () => {
61
- const out = rejectedForCaller(
62
- [
63
- { record: bad, errors: ERRORS },
64
- { record: worse, errors: ['다른 까닭'] }
65
- ],
66
- [
67
- { record: bad, eventId: 'evt-1' },
68
- { record: worse, eventId: 'evt-2' }
69
- ]
70
- )
71
-
72
- assert.deepEqual(out, [
73
- { eventId: 'evt-1', errors: ERRORS },
74
- { eventId: 'evt-2', errors: ['다른 까닭'] }
75
- ])
76
- })
77
-
78
- test('빈 문자열·공백 id 는 없는 것으로 본다 — 아무 행도 못 찾는 열쇠다', () => {
79
- assert.deepEqual(rejectedForCaller([{ record: bad, errors: ERRORS }], [{ record: bad, eventId: ' ' }]), [
80
- { record: bad, errors: ERRORS }
81
- ])
82
- })
83
-
84
- test('떨어진 것이 없으면 빈 목록이다', () => {
85
- assert.deepEqual(rejectedForCaller([], [{ record: bad, eventId: 'evt-1' }]), [])
86
- })
@@ -1,193 +0,0 @@
1
- /*
2
- * Does the reply's own arithmetic close.
3
- *
4
- * ── Why this exists (2026-09-07) ───────────────────────────────────────────
5
- * The contract now declares the response a sender reads, and the reason it had to is that a
6
- * sender guessed instead: operato-plant read `rejected` as a list of envelope id strings, the
7
- * receiver sent `{record, errors}`, `Array.isArray` passed on both, and a batch of three was
8
- * stamped delivered while one envelope never landed (mes_outbox_events seq 178 — SENT,
9
- * attempts 0, no error).
10
- *
11
- * `offered` is the field that makes that catchable without reading the rejection list at all:
12
- *
13
- * offered === applied + duplicates + rejected.length + vocabulary
14
- *
15
- * ── What this file is really guarding ──────────────────────────────────────
16
- * The first version of that sum left `vocabulary` out, and it was wrong. Vocabulary elements are
17
- * counted in `offered` and deliberately kept out of the other three — they set state and must
18
- * never reach the journal, because they carry no time axis. So every batch carrying one would
19
- * have failed a sender's check, the warning would have been ignored within a week, and the real
20
- * loss would have been ignored with it.
21
- *
22
- * The integration lane found that by looking for a counterexample rather than a confirmation,
23
- * and had a measured one: 32 distinct facts reconciled as 29 journal + 2 rejected + 1 vocabulary.
24
- *
25
- * The count already existed — `liveIngest` has returned `vocabulary` all along — and this
26
- * boundary dropped it, because the callback was typed as `IngestResult` and the field was not on
27
- * it. A declared field nobody fills is the same defect one layer over, so what is asserted here
28
- * is that a number handed to `ingest` arrives in the reply, and that the sum closes on a batch
29
- * where it is not zero.
30
- */
31
- import { test } from 'node:test'
32
- import assert from 'node:assert/strict'
33
-
34
- import { WEBHOOK_STATUS } from '@operato/ops-contract'
35
-
36
- import { handleHook, type HookStore } from '../server/service/reference/reference-hook.js'
37
- import { registerAdapterType, getAdapter } from '../server/service/reference/reference-adapter.js'
38
-
39
- const DOMAIN = 'd-1'
40
- const SOURCE = 'sum-source'
41
- const TWIN = 'twin-a'
42
- const SECRET = 'shared-secret'
43
-
44
- /** Hands every item straight through — this file is about the counts, not about translation. */
45
- const ADAPTER_TYPE = 'test-sum-push'
46
- if (!getAdapter(ADAPTER_TYPE)) {
47
- registerAdapterType({
48
- type: ADAPTER_TYPE,
49
- label: 'sum push (test)',
50
- handleInbound: (_cfg: any, _site: any, body: any) => ({ items: body?.items ?? [] })
51
- } as any)
52
- }
53
-
54
- function makeStore(): HookStore {
55
- const row = {
56
- id: 'ref-1',
57
- source: SOURCE,
58
- adapterType: ADAPTER_TYPE,
59
- connectionConfig: { hookSecret: SECRET },
60
- scopeSpec: { produced: [{ siteId: 'site-a', instanceId: TWIN }] }
61
- }
62
- return {
63
- load: async (domainId: string, source: string) => (domainId === DOMAIN && source === SOURCE ? row : null),
64
- saveCursor: async () => {}
65
- } as any
66
- }
67
-
68
- /** `count` unnumbered items — no `scope`, so sequence checking stays out of the way. */
69
- function items(count: number) {
70
- return Array.from({ length: count }, (_v, i) => ({ record: { moverId: `eq-${i}`, kind: 'press', status: 'idle' } }))
71
- }
72
-
73
- function push(count: number, ingest: any) {
74
- return handleHook({
75
- domainId: DOMAIN,
76
- source: SOURCE,
77
- instanceId: TWIN,
78
- headers: { 'x-twin-hook-secret': SECRET },
79
- body: { items: items(count) },
80
- nowMs: Date.parse('2026-09-07T02:00:00.000Z'),
81
- ingest,
82
- store: makeStore()
83
- })
84
- }
85
-
86
- /** What the sender is told to check. Written once so every case below reads the same way. */
87
- function closes(body: any) {
88
- return body.offered === body.applied + body.duplicates + (body.rejected?.length ?? 0) + body.vocabulary
89
- }
90
-
91
- test('the sum closes when everything was applied', async () => {
92
- const out = await push(3, (_id: string, r: unknown[]) => ({ applied: r.length, duplicates: 0, rejected: [] }))
93
-
94
- assert.equal(out.status, WEBHOOK_STATUS.ok)
95
- assert.equal(out.body.offered, 3)
96
- assert.equal(out.body.vocabulary, 0)
97
- assert.ok(closes(out.body), JSON.stringify(out.body))
98
- })
99
-
100
- test('the sum closes when a batch carried vocabulary — this is the case that failed', async () => {
101
- /*
102
- * Three offered: two events seated, one vocabulary element. Without `vocabulary` in the reply
103
- * the sender sees `3 - 2 - 0 - 0 = 1` and calls it a loss, on traffic that is entirely correct.
104
- */
105
- const out = await push(3, () => ({ applied: 2, duplicates: 0, rejected: [], vocabulary: 1 }))
106
-
107
- assert.equal(out.body.offered, 3)
108
- assert.equal(out.body.applied, 2)
109
- assert.equal(out.body.vocabulary, 1, 'the count exists in liveIngest; this boundary must carry it')
110
- assert.ok(closes(out.body), JSON.stringify(out.body))
111
- })
112
-
113
- test('a batch that is only vocabulary is not read as a dead twin', async () => {
114
- /*
115
- * This is what the sum test found, and it was a live defect rather than a missing field.
116
- *
117
- * The 503 branch inferred "the twin is not running live" from applied, duplicates and rejected
118
- * all being zero. A vocabulary-only batch is exactly that shape and yet everything in it
119
- * landed, so the receiver answered 503 to correct traffic — and a 503 means hold and retry, so
120
- * the sender would have re-sent that batch every thirty seconds indefinitely.
121
- *
122
- * An absence is not a cause. The fourth term is what tells the two apart.
123
- */
124
- const out = await push(2, () => ({ applied: 0, duplicates: 0, rejected: [], vocabulary: 2 }))
125
-
126
- assert.equal(out.status, WEBHOOK_STATUS.ok, 'zero events applied is not a twin that stopped')
127
- assert.equal(out.body.applied, 0)
128
- assert.equal(out.body.vocabulary, 2)
129
- assert.ok(closes(out.body), 'zero applied is not zero received')
130
- })
131
-
132
- test('a dead twin is still reported as one — the fourth term did not loosen the check', async () => {
133
- /*
134
- * Breaking the case above must not cost the case it was guarding. Nothing applied and no
135
- * vocabulary either is the real "nothing landed", and it has to keep answering 503: a 200 there
136
- * would have the sender mark those facts sent and drop them.
137
- */
138
- const out = await push(2, () => ({ applied: 0, duplicates: 0, rejected: [], vocabulary: 0 }))
139
-
140
- assert.equal(out.status, WEBHOOK_STATUS.notLive)
141
- assert.equal(out.body.retryAfterMs, 30_000, 'hold and come back, do not drop')
142
- })
143
-
144
- test('the sum closes on a partial — the rejected list is a term in it', async () => {
145
- const out = await push(3, (_id: string, r: unknown[]) => ({
146
- applied: 1,
147
- duplicates: 0,
148
- rejected: [{ record: r[1], errors: ['no inputQuantityList'] }],
149
- vocabulary: 1
150
- }))
151
-
152
- assert.equal(out.status, WEBHOOK_STATUS.partial, '422 is what a sender must not resend')
153
- assert.equal(out.body.rejected?.length, 1)
154
- assert.ok(closes(out.body), JSON.stringify(out.body))
155
- })
156
-
157
- test('duplicates are a term too — a resend is normal here, not a loss', async () => {
158
- const out = await push(4, () => ({ applied: 1, duplicates: 3, rejected: [] }))
159
-
160
- assert.equal(out.body.duplicates, 3)
161
- assert.ok(closes(out.body))
162
- })
163
-
164
- test('an ingest that says nothing about vocabulary still reports the term', async () => {
165
- /*
166
- * `vocabulary` is optional on `IngestResult` so a caller that does not count it need not claim
167
- * none. The reply must still carry the term: a field that appears only sometimes leaves the
168
- * sender unable to tell "none" from "this receiver does not count it", which is the same
169
- * ambiguity that made `rejected` guessable.
170
- */
171
- const out = await push(2, () => ({ applied: 2, duplicates: 0, rejected: [] }))
172
-
173
- assert.equal(out.body.vocabulary, 0)
174
- assert.ok('vocabulary' in (out.body as any))
175
- })
176
-
177
- test('seq 178 as it would read now — three offered, two applied', async () => {
178
- /*
179
- * The real batch: one of the three had no `inputQuantityList` and the kernel was right to
180
- * refuse it. What went wrong was that the sender could not read the refusal, so it marked all
181
- * three sent. The sum alone says otherwise, whatever shape the rejection list is in.
182
- */
183
- const out = await push(3, (_id: string, r: unknown[]) => ({
184
- applied: 2,
185
- duplicates: 0,
186
- rejected: [{ record: r[2], errors: ['transformation: inputQuantityList is empty'] }]
187
- }))
188
-
189
- assert.equal(out.body.offered, 3)
190
- assert.equal(out.body.applied, 2)
191
- assert.equal(out.body.offered - out.body.applied - out.body.duplicates - out.body.vocabulary, 1)
192
- assert.ok(closes(out.body), 'and the missing one is accounted for by the rejected list')
193
- })