@things-factory/headless-twin 10.0.14 → 10.0.17

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 (478) hide show
  1. package/dist-server/engine/attention-digest.d.ts +4 -4
  2. package/dist-server/engine/attention-digest.js +7 -7
  3. package/dist-server/engine/attention-digest.js.map +1 -1
  4. package/dist-server/engine/canonical-ingest.d.ts +11 -2
  5. package/dist-server/engine/canonical-ingest.js +137 -8
  6. package/dist-server/engine/canonical-ingest.js.map +1 -1
  7. package/dist-server/engine/command-routing.js +1 -1
  8. package/dist-server/engine/command-routing.js.map +1 -1
  9. package/dist-server/engine/declared-stimulus.js +1 -1
  10. package/dist-server/engine/declared-stimulus.js.map +1 -1
  11. package/dist-server/engine/energy-topology.js +1 -1
  12. package/dist-server/engine/energy-topology.js.map +1 -1
  13. package/dist-server/engine/ingest-dedupe.d.ts +38 -0
  14. package/dist-server/engine/ingest-dedupe.js +145 -0
  15. package/dist-server/engine/ingest-dedupe.js.map +1 -0
  16. package/dist-server/engine/ingest-health.d.ts +124 -9
  17. package/dist-server/engine/ingest-health.js +169 -15
  18. package/dist-server/engine/ingest-health.js.map +1 -1
  19. package/dist-server/engine/integration-probes.d.ts +3 -3
  20. package/dist-server/engine/integration-probes.js +6 -6
  21. package/dist-server/engine/integration-probes.js.map +1 -1
  22. package/dist-server/engine/kpi-baseline.js +4 -4
  23. package/dist-server/engine/kpi-baseline.js.map +1 -1
  24. package/dist-server/engine/kpi-fold.d.ts +122 -12
  25. package/dist-server/engine/kpi-fold.js +247 -18
  26. package/dist-server/engine/kpi-fold.js.map +1 -1
  27. package/dist-server/engine/kpi-query.d.ts +11 -11
  28. package/dist-server/engine/kpi-query.js +185 -28
  29. package/dist-server/engine/kpi-query.js.map +1 -1
  30. package/dist-server/engine/live-feed-registry.d.ts +1 -1
  31. package/dist-server/engine/live-feed-registry.js +1 -1
  32. package/dist-server/engine/live-feed-registry.js.map +1 -1
  33. package/dist-server/engine/load-meter.d.ts +1 -1
  34. package/dist-server/engine/load-meter.js.map +1 -1
  35. package/dist-server/engine/local-declarations.d.ts +7 -7
  36. package/dist-server/engine/local-declarations.js +9 -9
  37. package/dist-server/engine/local-declarations.js.map +1 -1
  38. package/dist-server/engine/log.d.ts +1 -1
  39. package/dist-server/engine/log.js +1 -1
  40. package/dist-server/engine/log.js.map +1 -1
  41. package/dist-server/engine/measured-estimator.js +1 -1
  42. package/dist-server/engine/measured-estimator.js.map +1 -1
  43. package/dist-server/engine/measured-yield.js +1 -1
  44. package/dist-server/engine/measured-yield.js.map +1 -1
  45. package/dist-server/engine/model-basis.d.ts +1 -1
  46. package/dist-server/engine/model-basis.js +1 -1
  47. package/dist-server/engine/model-basis.js.map +1 -1
  48. package/dist-server/engine/model-gap.d.ts +3 -3
  49. package/dist-server/engine/model-gap.js +1 -1
  50. package/dist-server/engine/model-gap.js.map +1 -1
  51. package/dist-server/engine/model-vocabulary.js +1 -1
  52. package/dist-server/engine/model-vocabulary.js.map +1 -1
  53. package/dist-server/engine/oee-accumulator.d.ts +4 -4
  54. package/dist-server/engine/oee-accumulator.js +3 -3
  55. package/dist-server/engine/oee-accumulator.js.map +1 -1
  56. package/dist-server/engine/property-effects.js +2 -2
  57. package/dist-server/engine/property-effects.js.map +1 -1
  58. package/dist-server/engine/read-time.d.ts +22 -0
  59. package/dist-server/engine/read-time.js +81 -0
  60. package/dist-server/engine/read-time.js.map +1 -0
  61. package/dist-server/engine/restart-policy.js +1 -1
  62. package/dist-server/engine/restart-policy.js.map +1 -1
  63. package/dist-server/engine/runtime-key.js +1 -1
  64. package/dist-server/engine/runtime-key.js.map +1 -1
  65. package/dist-server/engine/spec-coverage.d.ts +2 -2
  66. package/dist-server/engine/spec-coverage.js +1 -1
  67. package/dist-server/engine/spec-coverage.js.map +1 -1
  68. package/dist-server/engine/stage-path.d.ts +4 -4
  69. package/dist-server/engine/stage-path.js +1 -1
  70. package/dist-server/engine/stage-path.js.map +1 -1
  71. package/dist-server/engine/state-axes.d.ts +1 -1
  72. package/dist-server/engine/state-axes.js +2 -2
  73. package/dist-server/engine/state-axes.js.map +1 -1
  74. package/dist-server/engine/travel-estimator.d.ts +2 -2
  75. package/dist-server/engine/travel-estimator.js +1 -1
  76. package/dist-server/engine/travel-estimator.js.map +1 -1
  77. package/dist-server/engine/twin-engine.d.ts +243 -53
  78. package/dist-server/engine/twin-engine.js +690 -191
  79. package/dist-server/engine/twin-engine.js.map +1 -1
  80. package/dist-server/engine/warm-start.d.ts +2 -2
  81. package/dist-server/engine/warm-start.js +5 -5
  82. package/dist-server/engine/warm-start.js.map +1 -1
  83. package/dist-server/index.js +1 -1
  84. package/dist-server/index.js.map +1 -1
  85. package/dist-server/migrations/1786000000000-RenameTwinInstanceBoardToModel.js +1 -1
  86. package/dist-server/migrations/1786000000000-RenameTwinInstanceBoardToModel.js.map +1 -1
  87. package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js +3 -3
  88. package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js.map +1 -1
  89. package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js +2 -2
  90. package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js.map +1 -1
  91. package/dist-server/migrations/1786300000000-IndexEventTypeByTime.d.ts +5 -0
  92. package/dist-server/migrations/1786300000000-IndexEventTypeByTime.js +54 -0
  93. package/dist-server/migrations/1786300000000-IndexEventTypeByTime.js.map +1 -0
  94. package/dist-server/migrations/1786400000000-IndexEventCreatedAt.d.ts +5 -0
  95. package/dist-server/migrations/1786400000000-IndexEventCreatedAt.js +44 -0
  96. package/dist-server/migrations/1786400000000-IndexEventCreatedAt.js.map +1 -0
  97. package/dist-server/migrations/1786500000000-CreateTwinSubjectEvents.d.ts +6 -0
  98. package/dist-server/migrations/1786500000000-CreateTwinSubjectEvents.js +84 -0
  99. package/dist-server/migrations/1786500000000-CreateTwinSubjectEvents.js.map +1 -0
  100. package/dist-server/migrations/index.js +7 -1
  101. package/dist-server/migrations/index.js.map +1 -1
  102. package/dist-server/routes.d.ts +1 -0
  103. package/dist-server/routes.js +69 -5
  104. package/dist-server/routes.js.map +1 -1
  105. package/dist-server/service/index.d.ts +2 -2
  106. package/dist-server/service/index.js +27 -24
  107. package/dist-server/service/index.js.map +1 -1
  108. package/dist-server/service/reference/control-routing.d.ts +1 -1
  109. package/dist-server/service/reference/control-routing.js +1 -1
  110. package/dist-server/service/reference/control-routing.js.map +1 -1
  111. package/dist-server/service/reference/discovery-result.d.ts +2 -2
  112. package/dist-server/service/reference/discovery-result.js +3 -3
  113. package/dist-server/service/reference/discovery-result.js.map +1 -1
  114. package/dist-server/service/reference/hook-contract.d.ts +43 -0
  115. package/dist-server/service/reference/hook-contract.js +59 -0
  116. package/dist-server/service/reference/hook-contract.js.map +1 -0
  117. package/dist-server/service/reference/ingest-space.d.ts +1 -1
  118. package/dist-server/service/reference/ingest-space.js +4 -4
  119. package/dist-server/service/reference/ingest-space.js.map +1 -1
  120. package/dist-server/service/reference/knob-defaults.d.ts +1 -1
  121. package/dist-server/service/reference/knob-defaults.js +4 -4
  122. package/dist-server/service/reference/knob-defaults.js.map +1 -1
  123. package/dist-server/service/reference/reference-adapter.d.ts +140 -8
  124. package/dist-server/service/reference/reference-adapter.js +27 -0
  125. package/dist-server/service/reference/reference-adapter.js.map +1 -1
  126. package/dist-server/service/reference/reference-hook.d.ts +20 -0
  127. package/dist-server/service/reference/reference-hook.js +133 -0
  128. package/dist-server/service/reference/reference-hook.js.map +1 -0
  129. package/dist-server/service/reference/reference-live.d.ts +2 -2
  130. package/dist-server/service/reference/reference-live.js +88 -13
  131. package/dist-server/service/reference/reference-live.js.map +1 -1
  132. package/dist-server/service/reference/reference-master.d.ts +14 -14
  133. package/dist-server/service/reference/reference-master.js +34 -12
  134. package/dist-server/service/reference/reference-master.js.map +1 -1
  135. package/dist-server/service/reference/reference-resolver.d.ts +1 -1
  136. package/dist-server/service/reference/reference-resolver.js +10 -10
  137. package/dist-server/service/reference/reference-resolver.js.map +1 -1
  138. package/dist-server/service/reference/twin-reference.d.ts +3 -3
  139. package/dist-server/service/reference/twin-reference.js.map +1 -1
  140. package/dist-server/service/twin-attention/twin-attention-query.d.ts +1 -1
  141. package/dist-server/service/twin-attention/twin-attention-query.js +1 -1
  142. package/dist-server/service/twin-attention/twin-attention-query.js.map +1 -1
  143. package/dist-server/service/twin-audit/command-audit.d.ts +1 -1
  144. package/dist-server/service/twin-audit/command-audit.js.map +1 -1
  145. package/dist-server/service/twin-audit/twin-audit-event.d.ts +1 -1
  146. package/dist-server/service/twin-audit/twin-audit-event.js.map +1 -1
  147. package/dist-server/service/twin-audit/twin-audit-query.js +1 -1
  148. package/dist-server/service/twin-audit/twin-audit-query.js.map +1 -1
  149. package/dist-server/service/twin-control/twin-control-mutation.js +1 -1
  150. package/dist-server/service/twin-control/twin-control-mutation.js.map +1 -1
  151. package/dist-server/service/twin-event/twin-event-keys.d.ts +22 -2
  152. package/dist-server/service/twin-event/twin-event-keys.js +37 -5
  153. package/dist-server/service/twin-event/twin-event-keys.js.map +1 -1
  154. package/dist-server/service/twin-event/twin-event-type.d.ts +1 -0
  155. package/dist-server/service/twin-event/twin-event-type.js +8 -1
  156. package/dist-server/service/twin-event/twin-event-type.js.map +1 -1
  157. package/dist-server/service/twin-event/twin-event.d.ts +2 -2
  158. package/dist-server/service/twin-event/twin-event.js +32 -4
  159. package/dist-server/service/twin-event/twin-event.js.map +1 -1
  160. package/dist-server/service/twin-forecast/forecast-metrics.js +1 -1
  161. package/dist-server/service/twin-forecast/forecast-metrics.js.map +1 -1
  162. package/dist-server/service/twin-forecast/gap-analytics.d.ts +1 -1
  163. package/dist-server/service/twin-forecast/gap-analytics.js.map +1 -1
  164. package/dist-server/service/twin-forecast/twin-forecast-query.js +29 -11
  165. package/dist-server/service/twin-forecast/twin-forecast-query.js.map +1 -1
  166. package/dist-server/service/twin-ingest-window/twin-ingest-window-query.d.ts +1 -1
  167. package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js +1 -1
  168. package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js.map +1 -1
  169. package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js +1 -1
  170. package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js.map +1 -1
  171. package/dist-server/service/twin-instance/twin-instance.js.map +1 -1
  172. package/dist-server/service/twin-journal/event-type-split-shape.d.ts +50 -0
  173. package/dist-server/service/twin-journal/event-type-split-shape.js +111 -0
  174. package/dist-server/service/twin-journal/event-type-split-shape.js.map +1 -0
  175. package/dist-server/service/twin-journal/event-type-split.d.ts +15 -0
  176. package/dist-server/service/twin-journal/event-type-split.js +102 -0
  177. package/dist-server/service/twin-journal/event-type-split.js.map +1 -0
  178. package/dist-server/service/twin-journal/journal-order.d.ts +15 -0
  179. package/dist-server/service/twin-journal/journal-order.js +17 -0
  180. package/dist-server/service/twin-journal/journal-order.js.map +1 -0
  181. package/dist-server/service/twin-journal/twin-journal-query.d.ts +5 -5
  182. package/dist-server/service/twin-journal/twin-journal-query.js +232 -21
  183. package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
  184. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.d.ts +27 -1
  185. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js +59 -3
  186. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +1 -1
  187. package/dist-server/service/twin-metrics/twin-metrics-query.js +14 -1
  188. package/dist-server/service/twin-metrics/twin-metrics-query.js.map +1 -1
  189. package/dist-server/service/twin-model/axis-journal-evidence.js +1 -1
  190. package/dist-server/service/twin-model/axis-journal-evidence.js.map +1 -1
  191. package/dist-server/service/twin-model/epcis-coverage.js +36 -1
  192. package/dist-server/service/twin-model/epcis-coverage.js.map +1 -1
  193. package/dist-server/service/twin-model/iec61850-coverage.js +1 -1
  194. package/dist-server/service/twin-model/iec61850-coverage.js.map +1 -1
  195. package/dist-server/service/twin-model/isa95-coverage.d.ts +15 -2
  196. package/dist-server/service/twin-model/isa95-coverage.js +32 -8
  197. package/dist-server/service/twin-model/isa95-coverage.js.map +1 -1
  198. package/dist-server/service/twin-model/item-ref.js +2 -2
  199. package/dist-server/service/twin-model/item-ref.js.map +1 -1
  200. package/dist-server/service/twin-model/name-index.d.ts +1 -1
  201. package/dist-server/service/twin-model/name-index.js +1 -1
  202. package/dist-server/service/twin-model/name-index.js.map +1 -1
  203. package/dist-server/service/twin-model/project-structure.d.ts +1 -1
  204. package/dist-server/service/twin-model/project-structure.js +3 -3
  205. package/dist-server/service/twin-model/project-structure.js.map +1 -1
  206. package/dist-server/service/twin-model/twin-equipment.d.ts +1 -1
  207. package/dist-server/service/twin-model/twin-equipment.js +1 -1
  208. package/dist-server/service/twin-model/twin-equipment.js.map +1 -1
  209. package/dist-server/service/twin-model/twin-lineage-query.js +16 -5
  210. package/dist-server/service/twin-model/twin-lineage-query.js.map +1 -1
  211. package/dist-server/service/twin-model/twin-location.d.ts +1 -1
  212. package/dist-server/service/twin-model/twin-location.js.map +1 -1
  213. package/dist-server/service/twin-model/twin-model-item-query.d.ts +3 -3
  214. package/dist-server/service/twin-model/twin-model-item-query.js +14 -14
  215. package/dist-server/service/twin-model/twin-model-item-query.js.map +1 -1
  216. package/dist-server/service/twin-model/twin-model-mutation.d.ts +2 -2
  217. package/dist-server/service/twin-model/twin-model-mutation.js +4 -4
  218. package/dist-server/service/twin-model/twin-model-mutation.js.map +1 -1
  219. package/dist-server/service/twin-model/twin-model-query.js +117 -28
  220. package/dist-server/service/twin-model/twin-model-query.js.map +1 -1
  221. package/dist-server/service/twin-model/twin-model-tree-query.js +22 -0
  222. package/dist-server/service/twin-model/twin-model-tree-query.js.map +1 -1
  223. package/dist-server/service/twin-model/twin-operation.d.ts +1 -1
  224. package/dist-server/service/twin-model/twin-operation.js +1 -1
  225. package/dist-server/service/twin-model/twin-operation.js.map +1 -1
  226. package/dist-server/service/twin-space/move-space.js +2 -2
  227. package/dist-server/service/twin-space/move-space.js.map +1 -1
  228. package/dist-server/service/twin-space/representation-role.d.ts +2 -0
  229. package/dist-server/service/twin-space/representation-role.js +18 -0
  230. package/dist-server/service/twin-space/representation-role.js.map +1 -0
  231. package/dist-server/service/twin-space/space-integrity.d.ts +1 -1
  232. package/dist-server/service/twin-space/space-integrity.js.map +1 -1
  233. package/dist-server/service/twin-space/twin-space-representation.d.ts +2 -0
  234. package/dist-server/service/twin-space/twin-space-representation.js +16 -0
  235. package/dist-server/service/twin-space/twin-space-representation.js.map +1 -1
  236. package/dist-server/service/twin-space/twin-space-resolver.d.ts +2 -2
  237. package/dist-server/service/twin-space/twin-space-resolver.js +36 -7
  238. package/dist-server/service/twin-space/twin-space-resolver.js.map +1 -1
  239. package/dist-server/service/twin-structure/twin-structure.js +3 -3
  240. package/dist-server/service/twin-structure/twin-structure.js.map +1 -1
  241. package/dist-server/service/twin-subject/event-subjects.d.ts +43 -0
  242. package/dist-server/service/twin-subject/event-subjects.js +137 -0
  243. package/dist-server/service/twin-subject/event-subjects.js.map +1 -0
  244. package/dist-server/service/twin-subject/index.d.ts +9 -0
  245. package/dist-server/service/twin-subject/index.js +16 -0
  246. package/dist-server/service/twin-subject/index.js.map +1 -0
  247. package/dist-server/service/twin-subject/item-resolver.d.ts +10 -0
  248. package/dist-server/service/twin-subject/item-resolver.js +93 -0
  249. package/dist-server/service/twin-subject/item-resolver.js.map +1 -0
  250. package/dist-server/service/twin-subject/subject-query-shape.d.ts +22 -0
  251. package/dist-server/service/twin-subject/subject-query-shape.js +88 -0
  252. package/dist-server/service/twin-subject/subject-query-shape.js.map +1 -0
  253. package/dist-server/service/twin-subject/twin-subject-backfill.d.ts +23 -0
  254. package/dist-server/service/twin-subject/twin-subject-backfill.js +159 -0
  255. package/dist-server/service/twin-subject/twin-subject-backfill.js.map +1 -0
  256. package/dist-server/service/twin-subject/twin-subject-event.d.ts +14 -0
  257. package/dist-server/service/twin-subject/twin-subject-event.js +111 -0
  258. package/dist-server/service/twin-subject/twin-subject-event.js.map +1 -0
  259. package/dist-server/service/twin-subject/twin-subject-fast-path.d.ts +39 -0
  260. package/dist-server/service/twin-subject/twin-subject-fast-path.js +295 -0
  261. package/dist-server/service/twin-subject/twin-subject-fast-path.js.map +1 -0
  262. package/dist-server/service/twin-subject/twin-subject-query.d.ts +27 -0
  263. package/dist-server/service/twin-subject/twin-subject-query.js +232 -0
  264. package/dist-server/service/twin-subject/twin-subject-query.js.map +1 -0
  265. package/dist-server/service/twin-subject/twin-subject-writer.d.ts +27 -0
  266. package/dist-server/service/twin-subject/twin-subject-writer.js +166 -0
  267. package/dist-server/service/twin-subject/twin-subject-writer.js.map +1 -0
  268. package/dist-server/service/twin-target/twin-target-resolver.js +1 -1
  269. package/dist-server/service/twin-target/twin-target-resolver.js.map +1 -1
  270. package/dist-shared/entity-delta.d.ts +1 -1
  271. package/dist-shared/entity-delta.js +3 -3
  272. package/dist-shared/entity-delta.js.map +1 -1
  273. package/dist-shared/touched-items.js +2 -2
  274. package/dist-shared/touched-items.js.map +1 -1
  275. package/dist-shared/twin-level.js +1 -1
  276. package/dist-shared/twin-level.js.map +1 -1
  277. package/package.json +3 -3
  278. package/server/engine/attention-digest.ts +9 -9
  279. package/server/engine/canonical-ingest.ts +170 -13
  280. package/server/engine/command-routing.ts +1 -1
  281. package/server/engine/declared-stimulus.ts +1 -1
  282. package/server/engine/energy-topology.ts +1 -1
  283. package/server/engine/ingest-dedupe.ts +149 -0
  284. package/server/engine/ingest-health.ts +234 -20
  285. package/server/engine/integration-probes.ts +7 -7
  286. package/server/engine/kpi-baseline.ts +4 -4
  287. package/server/engine/kpi-fold.ts +395 -27
  288. package/server/engine/kpi-query.ts +212 -46
  289. package/server/engine/live-feed-registry.ts +1 -1
  290. package/server/engine/load-meter.ts +1 -1
  291. package/server/engine/local-declarations.ts +13 -13
  292. package/server/engine/log.ts +1 -1
  293. package/server/engine/measured-estimator.ts +1 -1
  294. package/server/engine/measured-yield.ts +1 -1
  295. package/server/engine/model-basis.ts +2 -2
  296. package/server/engine/model-gap.ts +3 -3
  297. package/server/engine/model-vocabulary.ts +1 -1
  298. package/server/engine/oee-accumulator.ts +4 -4
  299. package/server/engine/property-effects.ts +2 -2
  300. package/server/engine/read-time.ts +77 -0
  301. package/server/engine/restart-policy.ts +1 -1
  302. package/server/engine/runtime-key.ts +1 -1
  303. package/server/engine/spec-coverage.ts +3 -3
  304. package/server/engine/stage-path.ts +5 -5
  305. package/server/engine/state-axes.ts +2 -2
  306. package/server/engine/travel-estimator.ts +2 -2
  307. package/server/engine/twin-engine.ts +764 -201
  308. package/server/engine/warm-start.ts +6 -6
  309. package/server/index.ts +1 -1
  310. package/server/migrations/1786000000000-RenameTwinInstanceBoardToModel.ts +1 -1
  311. package/server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.ts +3 -3
  312. package/server/migrations/1786200000000-CarryLiveFeedCursor.ts +2 -2
  313. package/server/migrations/1786300000000-IndexEventTypeByTime.ts +48 -0
  314. package/server/migrations/1786400000000-IndexEventCreatedAt.ts +38 -0
  315. package/server/migrations/1786500000000-CreateTwinSubjectEvents.ts +93 -0
  316. package/server/migrations/index.ts +7 -1
  317. package/server/routes.ts +68 -5
  318. package/server/service/index.ts +4 -1
  319. package/server/service/reference/control-routing.ts +1 -1
  320. package/server/service/reference/discovery-result.ts +3 -3
  321. package/server/service/reference/hook-contract.ts +103 -0
  322. package/server/service/reference/ingest-space.ts +4 -4
  323. package/server/service/reference/knob-defaults.ts +4 -4
  324. package/server/service/reference/reference-adapter.ts +166 -9
  325. package/server/service/reference/reference-hook.ts +145 -0
  326. package/server/service/reference/reference-live.ts +92 -14
  327. package/server/service/reference/reference-master.ts +39 -17
  328. package/server/service/reference/reference-resolver.ts +10 -10
  329. package/server/service/reference/twin-reference.ts +3 -3
  330. package/server/service/twin-attention/twin-attention-query.ts +1 -1
  331. package/server/service/twin-audit/command-audit.ts +1 -1
  332. package/server/service/twin-audit/twin-audit-event.ts +2 -2
  333. package/server/service/twin-audit/twin-audit-query.ts +1 -1
  334. package/server/service/twin-control/twin-control-mutation.ts +1 -1
  335. package/server/service/twin-event/twin-event-keys.ts +37 -5
  336. package/server/service/twin-event/twin-event-type.ts +18 -1
  337. package/server/service/twin-event/twin-event.ts +32 -6
  338. package/server/service/twin-forecast/forecast-metrics.ts +1 -1
  339. package/server/service/twin-forecast/gap-analytics.ts +1 -1
  340. package/server/service/twin-forecast/twin-forecast-query.ts +30 -11
  341. package/server/service/twin-ingest-window/twin-ingest-window-query.ts +1 -1
  342. package/server/service/twin-ingest-window/twin-ingest-window-writer.ts +1 -1
  343. package/server/service/twin-instance/twin-instance.ts +4 -4
  344. package/server/service/twin-journal/event-type-split-shape.ts +112 -0
  345. package/server/service/twin-journal/event-type-split.ts +144 -0
  346. package/server/service/twin-journal/journal-order.ts +20 -0
  347. package/server/service/twin-journal/twin-journal-query.ts +224 -20
  348. package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +57 -3
  349. package/server/service/twin-metrics/twin-metrics-query.ts +14 -1
  350. package/server/service/twin-model/axis-journal-evidence.ts +1 -1
  351. package/server/service/twin-model/epcis-coverage.ts +36 -1
  352. package/server/service/twin-model/iec61850-coverage.ts +1 -1
  353. package/server/service/twin-model/isa95-coverage.ts +45 -8
  354. package/server/service/twin-model/item-ref.ts +2 -2
  355. package/server/service/twin-model/name-index.ts +1 -1
  356. package/server/service/twin-model/project-structure.ts +4 -4
  357. package/server/service/twin-model/twin-equipment.ts +2 -2
  358. package/server/service/twin-model/twin-lineage-query.ts +16 -5
  359. package/server/service/twin-model/twin-location.ts +1 -1
  360. package/server/service/twin-model/twin-model-item-query.ts +14 -14
  361. package/server/service/twin-model/twin-model-mutation.ts +4 -4
  362. package/server/service/twin-model/twin-model-query.ts +117 -28
  363. package/server/service/twin-model/twin-model-tree-query.ts +25 -1
  364. package/server/service/twin-model/twin-operation.ts +2 -2
  365. package/server/service/twin-space/move-space.ts +3 -3
  366. package/server/service/twin-space/representation-role.ts +15 -0
  367. package/server/service/twin-space/space-integrity.ts +1 -1
  368. package/server/service/twin-space/twin-space-representation.ts +37 -0
  369. package/server/service/twin-space/twin-space-resolver.ts +39 -7
  370. package/server/service/twin-structure/twin-structure.ts +3 -3
  371. package/server/service/twin-subject/event-subjects.ts +155 -0
  372. package/server/service/twin-subject/index.ts +10 -0
  373. package/server/service/twin-subject/item-resolver.ts +92 -0
  374. package/server/service/twin-subject/subject-query-shape.ts +84 -0
  375. package/server/service/twin-subject/twin-subject-backfill.ts +196 -0
  376. package/server/service/twin-subject/twin-subject-event.ts +101 -0
  377. package/server/service/twin-subject/twin-subject-fast-path.ts +346 -0
  378. package/server/service/twin-subject/twin-subject-query.ts +210 -0
  379. package/server/service/twin-subject/twin-subject-writer.ts +189 -0
  380. package/server/service/twin-target/twin-target-resolver.ts +1 -1
  381. package/shared/entity-delta.ts +3 -3
  382. package/shared/touched-items.ts +2 -2
  383. package/shared/twin-level.ts +1 -1
  384. package/test/adopt-structure-live.test.ts +3 -3
  385. package/test/aggregate-not-findone.test.ts +112 -0
  386. package/test/attention-digest.test.ts +6 -6
  387. package/test/axis-read.test.ts +2 -2
  388. package/test/boot-resume.test.ts +20 -7
  389. package/test/broadcast-period.test.ts +2 -2
  390. package/test/broadcast-queue-overflow.test.ts +244 -0
  391. package/test/canonical-ingest-vocabularies.test.ts +179 -7
  392. package/test/canonical-quantity-door.test.ts +2 -2
  393. package/test/checkpoint-refuses-empty.test.ts +2 -2
  394. package/test/connector-capability-declaration.test.ts +88 -0
  395. package/test/control-capability.test.ts +1 -1
  396. package/test/cursor-stall-not-read-failure.test.ts +2 -2
  397. package/test/declaration-reaches-model.test.ts +5 -5
  398. package/test/declared-stimulus.test.ts +4 -4
  399. package/test/discovery-result.test.ts +2 -2
  400. package/test/entity-delta.test.ts +4 -4
  401. package/test/event-subjects.test.ts +147 -0
  402. package/test/event-time-column.test.ts +3 -3
  403. package/test/event-type-split.test.ts +155 -0
  404. package/test/fold-gap-speaks.test.ts +53 -0
  405. package/test/forecast-metrics.test.ts +1 -1
  406. package/test/forecast-tuning.test.ts +1 -1
  407. package/test/ingest-health-engine.test.ts +2 -2
  408. package/test/ingest-health-wiring.test.ts +7 -5
  409. package/test/ingest-health.test.ts +6 -6
  410. package/test/ingest-history.test.ts +2 -2
  411. package/test/ingest-idempotent.test.ts +132 -0
  412. package/test/ingest-space.test.ts +3 -3
  413. package/test/integration-probes.test.ts +3 -3
  414. package/test/integration-runner.test.ts +1 -1
  415. package/test/item-ref.test.ts +1 -1
  416. package/test/journal-order-axis.test.ts +80 -0
  417. package/test/journal-read-discipline.test.ts +16 -6
  418. package/test/journal-retention.test.ts +171 -29
  419. package/test/journal-sort-axis.test.ts +1 -1
  420. package/test/journal-write-door.test.ts +3 -3
  421. package/test/journal-write-trend.test.ts +1 -1
  422. package/test/kernel-kind-guard.test.ts +3 -3
  423. package/test/knob-defaults.test.ts +1 -1
  424. package/test/kpi-baseline-db.test.ts +2 -2
  425. package/test/kpi-fold.test.ts +185 -14
  426. package/test/kpi-query-bench.test.ts +3 -3
  427. package/test/live-cursor-wiring.test.ts +6 -6
  428. package/test/live-kernel-facts.test.ts +11 -11
  429. package/test/live-mirror-parity.test.ts +3 -3
  430. package/test/load-meter.test.ts +1 -1
  431. package/test/local-declarations.test.ts +10 -10
  432. package/test/log-stamp.test.ts +1 -1
  433. package/test/measured-yield.test.ts +2 -2
  434. package/test/merge-streams.test.ts +70 -0
  435. package/test/mirror-resumes-from-checkpoint.test.ts +13 -13
  436. package/test/model-basis.test.ts +2 -2
  437. package/test/model-gap.test.ts +4 -4
  438. package/test/model-vocabulary.test.ts +2 -2
  439. package/test/move-space.test.ts +1 -1
  440. package/test/oee-accumulator.test.ts +2 -2
  441. package/test/operational-vocabulary.test.ts +2 -2
  442. package/test/project-structure-db.test.ts +2 -2
  443. package/test/projection-reaches-screen.test.ts +2 -2
  444. package/test/property-effects.test.ts +3 -3
  445. package/test/read-failure-ledger.test.ts +106 -0
  446. package/test/read-failure-visible.test.ts +7 -7
  447. package/test/read-time.test.ts +118 -0
  448. package/test/reference-grounding.test.ts +1 -1
  449. package/test/reference-hook.test.ts +86 -0
  450. package/test/registry-key-guard.test.ts +1 -1
  451. package/test/rename-twin.test.ts +81 -0
  452. package/test/restart-policy.test.ts +3 -3
  453. package/test/resync-origin-site.test.ts +3 -3
  454. package/test/revision-axis.test.ts +14 -8
  455. package/test/runtime-key.test.ts +3 -3
  456. package/test/snapshot-freshness.test.ts +4 -4
  457. package/test/source-outcome-audit.test.ts +1 -1
  458. package/test/space-integrity.test.ts +1 -1
  459. package/test/space-representation.test.ts +66 -0
  460. package/test/space-scope-includes-stopped.test.ts +55 -0
  461. package/test/spec-coverage.test.ts +1 -1
  462. package/test/standard-coverage.test.ts +43 -1
  463. package/test/status-tally.test.ts +1 -1
  464. package/test/structure-revision-db.test.ts +7 -7
  465. package/test/subject-fast-path.test.ts +148 -0
  466. package/test/subject-read-model.test.ts +175 -0
  467. package/test/touched-items.test.ts +2 -2
  468. package/test/twin-audit.test.ts +1 -1
  469. package/test/twin-event-keys.test.ts +49 -3
  470. package/test/twin-model-item-db.test.ts +5 -5
  471. package/test/twin-model-tree-db.test.ts +35 -2
  472. package/test/twin-origin-resync.test.ts +1 -1
  473. package/test/warm-start-seam.test.ts +1 -1
  474. package/test/warm-start.test.ts +6 -6
  475. package/test/withheld-door.test.ts +95 -0
  476. package/test/yield-loop.test.ts +4 -4
  477. package/tsconfig.shared.tsbuildinfo +1 -1
  478. package/tsconfig.tsbuildinfo +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"twin-model-mutation.js","sourceRoot":"","sources":["../../../server/service/twin-model/twin-model-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'\n\nimport { ScalarObject, getRepository } from '@things-factory/shell'\n\nimport { TwinInstance } from '../twin-instance/twin-instance.js'\nimport { TwinSpace } from '../twin-space/twin-space.js'\nimport { TwinEngine } from '../../engine/twin-engine.js'\nimport {\n applyDeclarationLayers,\n applyLocalDeclarations,\n mergeLocalDeclarations,\n restoreRevoked,\n revokeLocalDeclarations,\n validateLocalDeclarations,\n type DeclarationRevocation,\n type LocalDeclaration\n} from '../../engine/local-declarations.js'\nimport { knownOperationKinds } from '../../engine/operation-basis.js'\nimport { projectStructure } from './project-structure.js'\n\n/*\n * 구조 테이블 **재생성** — 저장된 모델 문서로 캐시를 다시 그린다.\n *\n * ── 이것은 원본에서 다시 읽는 것과 다르다 ──────────────────────────────────────\n * `resyncTwin` 은 **원본**에 가서 현장이 지금 어떻게 생겼는지 다시 읽는다(모델이 바뀔 수 있다).\n * 여기는 **아무것도 다시 읽지 않는다** — 이미 갖고 있는 모델 문서를 테이블로 다시 푼다.\n * 그래서 모델은 한 글자도 바뀌지 않고, 테이블만 문서와 같아진다.\n *\n * ── 왜 필요한가 ────────────────────────────────────────────────────────────────\n * 이 앱에는 **투영이 생기기 전에 만들어진 트윈**이 있다. 문서에는 자리 6개·설비 32대가 있는데\n * 테이블은 0행이고, 그중 일부는 원천도 기억하지 않아 다시 읽을 수조차 없다 — 조회 화면이\n * 영구히 \"테이블이 뒤에 있습니다\" 만 말하는 막다른 상태다.\n *\n * ── 쓰기 경로가 둘이 되는 것 아닌가 ────────────────────────────────────────────\n * 아니다. 그 규율(ADR-0032-D)이 막는 것은 **다른 진실이 행을 쓰는 것**이다(예: 틱 루프가 관측을\n * 밀어 넣기). 여기서 쓰는 것은 인제스트가 쓰는 것과 **같은 문서·같은 투영**이고, 그 규율이 함께\n * 요구한 \"재생성 가능성을 구조로\" 가 바로 이것이다. 캐시는 언제든 다시 그릴 수 있어야 한다.\n */\n/**\n * 현장 겹을 **그 현장의 트윈 전부**에 얹는다 — 그러지 않으면 「현장 전체가 읽는다」가 거짓이 된다.\n *\n * ── 왜 필요한가 (2026-08-18) ────────────────────────────────────────────────\n * 처음에는 호출한 트윈에만 얹었다. 그러면 같은 현장의 다른 EMS 트윈은 **다음에 자기가 다시 그려질 때\n * 까지** 옛 값으로 돌아간다 — 화면은 「현장 전체」라고 말하는데 실제로는 한 트윈만 바뀐 상태다.\n *\n * 트윈마다 자기 겹을 그대로 얹는다(좁은 것이 이긴다). 돌고 있는 미러는 지금 받고, 시뮬레이션·정지\n * 트윈은 문서에 반영한다(재기동 때 받는다) — 그 차이를 결과에 적어 돌려준다.\n *\n * 얹을 자리가 없는 트윈은 **정상**이다(창고 트윈에 요금 자리가 없다). 그 사실도 세어 돌려준다 —\n * 「현장에 넣었는데 아무 트윈도 안 받았다」는 사용자가 알아야 할 사실이다.\n */\nasync function spreadSpaceLayer(\n domainId: string,\n spaceId: string,\n spaceLayer: LocalDeclaration[],\n comment: string\n): Promise<{\n spaceLayerApplied: LocalDeclaration[]\n twins: { instanceId: string; applied: string; landed: boolean; error?: string }[]\n}> {\n const repo = getRepository(TwinInstance)\n const twins = await repo.find({ where: { domain: { id: domainId }, spaceId } })\n const report: { instanceId: string; applied: string; landed: boolean; error?: string }[] = []\n let latest = spaceLayer\n for (const t of twins) {\n if (!t.model) continue\n const out = applyDeclarationLayers(t.model, latest, (t.localDeclarations ?? []) as LocalDeclaration[])\n /* 기억(`replaced`)은 **얹힌 트윈에서만** 채워진다 — 자리가 없는 트윈을 지나며 지워지지 않게 이어 든다. */\n latest = out.spaceLayerApplied\n const landed = !out.missingTargets.some(m => m.scope === 'space' && spaceLayer.some(d => d.id === m.id && d.target === m.target))\n t.localDeclarations = out.instanceLayerApplied as any\n const running = TwinEngine.modeOf(domainId, t.instanceId)\n /*\n * **트윈 하나가 실패해도 나머지는 받는다** — 다만 조용히 넘기지 않는다(2026-08-18 실측).\n *\n * 현장 선언을 처음 퍼뜨렸을 때 그 현장의 어떤 트윈에서 구조 투영이 터졌고(그 트윈 모델에 설비 id가\n * 겹쳐 있었다 — 선재 결함), 그 예외가 올라와 **한 트윈 때문에 현장 전체 선언이 실패**했다. 사용자는\n * 값을 넣었는데 아무 일도 일어나지 않은 것으로 본다.\n *\n * 그렇다고 삼키면 더 나쁘다: 「현장 전체가 읽는다」고 말한 뒤 몇 트윈이 못 읽는 상태가 된다. 그래서\n * 트윈별로 이유를 적어 돌려준다.\n */\n try {\n if (running === 'live') {\n await repo.save(t)\n await TwinEngine.adoptStructure(domainId, t.instanceId, out.model, comment)\n report.push({ instanceId: t.instanceId, applied: 'running', landed })\n continue\n }\n t.model = out.model\n await repo.save(t)\n await projectStructure(domainId, t.instanceId, out.model, t.instanceId)\n report.push({ instanceId: t.instanceId, applied: running ? 'on-restart' : 'stored', landed })\n } catch (e: any) {\n report.push({ instanceId: t.instanceId, applied: 'failed', landed, error: e?.message ?? 'failed' })\n }\n }\n return { spaceLayerApplied: latest, twins: report }\n}\n\n@Resolver()\nexport class TwinModelMutation {\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n \"Rebuild this twin's structure tables from the model document it already holds. Reads nothing from the source: the model is unchanged and only the cache is redrawn. Use resyncTwin instead when the source itself may have changed.\"\n })\n async reprojectTwinModel(@Arg('instanceId') instanceId: string, @Ctx() context: ResolverContext): Promise<any> {\n const domainId = context.state.domain.id\n const inst = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!inst) return { ok: false, error: `unknown twin: ${instanceId}` }\n if (!inst.model) return { ok: false, error: `twin \"${instanceId}\" has no model document — there is nothing to draw from` }\n\n try {\n /*\n * 출처 표식은 **이 트윈 자신**이다. 인제스트도 같은 값을 넣는다(`master.source` = instanceId) —\n * 여기서 다른 값을 넣으면 같은 행이 어디서 왔는지가 경로마다 달라진다.\n */\n const report = await projectStructure(domainId, instanceId, inst.model, instanceId)\n return { ok: true, ...report }\n } catch (e: any) {\n return { ok: false, error: e?.message || 'reprojection failed' }\n }\n }\n\n /**\n * 현장이 정하는 수를 트윈에 얹는다 — **구조는 원천이, 수는 현장이.**\n *\n * ── 왜 이 문이 필요했나 (2026-08-18) ──────────────────────────────────────\n * 커넥터로 만든 트윈은 계통도·계량 지점을 원 시스템에서 읽어 온다. 그런데 요금 단가·계약 정보·\n * 축전지 충전율은 원 시스템이 모른다(SCADA 게이트웨이는 우리 전기 계약을 알지 못한다). 그래서\n * 계량이 흐르는 트윈에서도 **금액이 영원히 나오지 않았다** — 넣을 문이 없었기 때문이다.\n *\n * 값은 `model` 에 직접 쓰지 않고 **겹**으로 보관한다: 모델은 원천의 사본이므로 다시 읽기가 그것을\n * 새로 그리면 직접 쓴 값은 조용히 사라진다. 겹은 모델을 그릴 때마다 다시 얹힌다.\n *\n * ── 돌고 있는 트윈에 어떻게 반영하나 ────────────────────────────────────────\n * 미러는 **동작 중에** 새 구조를 받는다(현실은 멈추지 않는다). 시뮬레이션은 받지 않는다 — 조건이\n * 바뀐 실험은 다른 실험이고, 커널이 그렇게 거절한다. 그때는 저장만 하고 **그 사실을 말한다**:\n * 조용히 성공으로 답하면 사용자는 지금 화면의 수가 새 선언으로 계산된 줄로 읽는다.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n \"Declare locally-owned numbers on a twin (tariff, contract, state of charge) as a layer on top of the reference-derived model, so a resync cannot drop them. Values carry source: local, telling every consumer that the authority for them sits here rather than in the source system. Values are validated against the kernel's property specification (unit and range). Mirrors adopt them while running; simulations keep their current declarations until restart, and the result says so.\"\n })\n async declareTwinProperties(\n @Arg('instanceId') instanceId: string,\n @Arg('declarations', type => [ScalarObject]) declarations: any[],\n @Ctx() context: ResolverContext\n ): Promise<any> {\n const domainId = context.state.domain.id\n const repo = getRepository(TwinInstance)\n const inst = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!inst) return { ok: false, error: `unknown twin: ${instanceId}` }\n if (!inst.model) return { ok: false, error: `twin \"${instanceId}\" has no model document — provision it before declaring values on it` }\n\n /*\n * **선언이 하나도 도착하지 않은 것**과 **받았지만 다 거절된 것**은 다른 일이다.\n *\n * 둘을 같은 문장으로 답했더니, 입력이 통째로 사라진 호출이 「받아준 선언이 없다 · 거절 목록 비어 있음」\n * 이라는 답을 받았다 — 사용자는 자기 값이 서버까지 오지 못한 것을 알 수 없다(실제로 겪었다: GraphQL\n * `Object` 스칼라에 인라인 리터럴로 주면 빈 배열이 되고, 변수로 주면 온다).\n */\n if (!declarations?.length) return { ok: false, error: 'no declaration arrived — the declarations argument was empty' }\n\n /*\n * 검사부터 — 받지 않은 것을 조용히 버리지 않는다(사용자는 값을 넣었다고 믿는다).\n *\n * 공정 이름은 **대조로만** 걸러진다(모델에 행이 없어도 성립하는 선언이라 다른 안전망이 없다). 아직\n * 돌지도 않고 명세 행도 없는 트윈이면 목록이 `undefined` 이고, 그때는 받아 주되 답에 그 사실을 싣는다.\n */\n const knownOperations = knownOperationKinds(\n inst.model,\n TwinEngine.kernel(domainId, instanceId),\n await TwinEngine.measuredOperationKinds(domainId, instanceId)\n )\n const { accepted, rejected } = validateLocalDeclarations(inst.kind, declarations as LocalDeclaration[], { knownOperations })\n if (!accepted.length) return { ok: false, error: 'no declaration was accepted', rejected }\n const unverifiedOperations = knownOperations\n ? []\n : accepted.filter(d => d.target === 'operation').map(d => d.id)\n\n /*\n * 현장 범위면 **공간에 적는다** — 그 현장의 트윈 전부가 읽는 자리다. 공간을 모르면 거절한다(트윈에\n * 몰래 적으면 사용자는 현장에 넣었다고 믿는다).\n */\n /* 현장 겹은 **읽기만** 한다 — 이 문은 트윈의 값만 넣는다(현장 값은 전용 문이 있다). 순서를 지키려면\n 현장 겹을 함께 얹어야 한다: 현장 먼저, 트윈이 나중. */\n const spaceRepo = getRepository(TwinSpace)\n const space =\n inst.spaceId ? await spaceRepo.findOne({ where: { domain: { id: domainId }, spaceId: inst.spaceId } }) : null\n const nextSpace = (space?.localDeclarations ?? []) as LocalDeclaration[]\n const nextInst = mergeLocalDeclarations((inst.localDeclarations ?? []) as LocalDeclaration[], accepted)\n\n /* 얹으면서 **무엇을 덮었는지** 적어 온 겹을 저장한다 — 철회는 그 기억이 있어야 성립한다.\n 순서가 규율이다: 현장 먼저, 트윈이 나중(좁은 것이 이긴다). */\n const applied = applyDeclarationLayers(inst.model, nextSpace, nextInst)\n const model = applied.model\n /* 현장 겹이 이 트윈에 얹을 자리가 없는 것은 정상이다(창고 트윈에 요금 자리가 없다) — 경고로 올리지 않는다. */\n const missingTargets = applied.missingTargets.filter(t => t.scope === 'instance').map(({ target, id }) => ({ target, id }))\n /* 읽을 수 있는 값으로 바꾸지 못한 선언 — 겹에는 남지만 계산에는 들어가지 않는다(그 사실을 말한다). */\n const unreadable = applied.unreadable.map(({ target, id, propertyId }) => ({ target, id, propertyId }))\n\n /* 겹은 언제나 남긴다 — 대상이 지금 없어도(구조가 바뀌었다) 사용자의 선언을 버리지 않는다. */\n inst.localDeclarations = applied.instanceLayerApplied\n await repo.save(inst)\n if (space) {\n space.localDeclarations = applied.spaceLayerApplied\n await spaceRepo.save(space)\n }\n\n const running = TwinEngine.modeOf(domainId, instanceId)\n if (running === 'live') {\n /* 미러는 지금 받는다 — 저장·구조 행·커널이 함께 움직인다(adoptStructure 가 셋을 묶는다). */\n const shift = await TwinEngine.adoptStructure(domainId, instanceId, model, 'local declarations (twin)')\n return {\n ok: true,\n applied: 'running',\n scope: 'instance',\n accepted,\n ...(rejected.length ? { rejected } : {}),\n ...(missingTargets.length ? { missingTargets } : {}),\n ...(unreadable.length ? { unreadable } : {}),\n ...(unverifiedOperations.length\n ? {\n unverifiedOperations,\n note: 'this twin has run no operations and declares no operation specification, so the operation name could not be checked — if it is misspelled the value will simply never be read'\n }\n : {}),\n revision: shift.rev\n }\n }\n\n /* 시뮬레이션·정지 트윈 — 문서와 구조 행에는 반영하고, 돌고 있는 커널에는 반영하지 않는다. */\n inst.model = model\n await repo.save(inst)\n const report = await projectStructure(domainId, instanceId, model, instanceId)\n return {\n ok: true,\n applied: running ? 'on-restart' : 'stored',\n scope: 'instance',\n ...(running ? { note: 'a running simulation keeps its current declarations — restart it to run on the new numbers' } : {}),\n accepted,\n ...(rejected.length ? { rejected } : {}),\n ...(missingTargets.length ? { missingTargets } : {}),\n ...(unreadable.length ? { unreadable } : {}),\n ...(unverifiedOperations.length\n ? {\n unverifiedOperations,\n note: 'this twin has run no operations and declares no operation specification, so the operation name could not be checked — if it is misspelled the value will simply never be read'\n }\n : {}),\n ...report\n }\n }\n\n /**\n * 선언을 **철회한다** — 잘못 넣은 값을 원천으로 되돌리는 문.\n *\n * ── 왜 따로 문이 필요한가 (2026-08-18) ──────────────────────────────────────\n * 선언은 겹에 보관되지만 **저장된 모델에 구워진다.** 그래서 겹에서 줄만 지워도 원래 값이 돌아오지\n * 않는다 — 되돌릴 방법이 아예 없어서, 오타를 「원래 값을 다시 선언하는」 우회로만 고칠 수 있었다\n * (사용자가 원래 값을 알고 있어야 한다는 뜻이고, 모르면 그 값은 영구히 이긴다).\n *\n * 그래서 겹이 **무엇을 덮었는지** 함께 기억하게 했고(`replaced`), 철회는 그 기억으로 되돌린다.\n * 기억이 없는 옛 선언은 **손대지 않고 그렇게 말한다**(`unknownSource`) — 원래 값을 지어내는 것은\n * 잘못 넣은 값을 그대로 두는 것보다 나쁘다. 그 자리는 다음 원천 재읽기가 바로잡는다.\n *\n * 반영 방식은 선언과 같다: 미러는 지금 받고(`adoptStructure`), 시뮬레이션은 재기동 때 받는다.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Revoke locally-declared values on a twin, restoring the value the reference system had when the declaration was applied (or removing the property if the source never had it). Declarations made before the overridden value was remembered are left untouched and reported, rather than guessed.'\n })\n async revokeTwinDeclarations(\n @Arg('instanceId') instanceId: string,\n @Arg('revocations', type => [ScalarObject]) revocations: any[],\n @Ctx() context: ResolverContext\n ): Promise<any> {\n const domainId = context.state.domain.id\n const repo = getRepository(TwinInstance)\n const inst = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!inst) return { ok: false, error: `unknown twin: ${instanceId}` }\n if (!inst.model) return { ok: false, error: `twin \"${instanceId}\" has no model document` }\n /* 도착 0건과 「겹에 없다」는 다른 일이다 — 선언 쪽에서 겪은 침묵을 여기서 되풀지 않는다. */\n if (!revocations?.length) return { ok: false, error: 'no revocation arrived — the revocations argument was empty' }\n\n const spaceRepo = getRepository(TwinSpace)\n const space =\n inst.spaceId ? await spaceRepo.findOne({ where: { domain: { id: domainId }, spaceId: inst.spaceId } }) : null\n const { layer, revoked, notFound } = revokeLocalDeclarations(\n inst.localDeclarations as LocalDeclaration[] | undefined,\n revocations as DeclarationRevocation[]\n )\n /* 이 문은 트윈 겹만 본다 — 현장 값을 여기서 빼려 하면 「겹에 없다」다(전용 문으로 가야 한다). */\n if (!revoked.length) return { ok: false, error: 'no declaration matched at this twin — a facility value is revoked at its facility', scope: 'instance', notFound }\n\n /*\n * 모델을 되돌리는 순서 — **뺀 뒤 남은 두 겹을 다시 얹는다.**\n *\n * 값을 「기억한 원천 값」으로 곧장 되돌리면, 트윈 겹을 뺐을 때 그 아래 있던 **현장 값이 되살아나지\n * 않는다**(원천 값이 그 자리를 차지한다). 겹이 둘이 된 뒤에는 「빼고 다시 얹기」가 유일하게 옳은\n * 되돌림이다 — 그러면 트윈 값을 빼면 현장 값이, 현장 값을 빼면 원천 값이 드러난다.\n */\n const restore = restoreRevoked(inst.model, revoked)\n const nextSpace = (space?.localDeclarations ?? []) as LocalDeclaration[]\n const nextInst = layer\n\n const relaid = applyDeclarationLayers(restore.model, nextSpace, nextInst)\n\n inst.localDeclarations = relaid.instanceLayerApplied\n await repo.save(inst)\n if (space) {\n space.localDeclarations = relaid.spaceLayerApplied\n await spaceRepo.save(space)\n }\n\n /*\n * **겹에서 뺀 것**과 **값을 되돌린 것**은 다른 일이다 — 갈라서 말한다.\n *\n * 처음에는 되돌린 것만 `revoked` 로 냈다. 그래서 기억 없는 옛 선언을 철회하면 「revoked: [] 」이\n * 돌아왔다 — 겹에서는 분명히 뺐는데(다시 얹히지 않는다) 아무 일도 없었던 것처럼 읽힌다.\n */\n const report = {\n scope: 'instance',\n withdrawn: revoked.map(r => ({ target: r.target, id: r.id, propertyId: r.propertyId })),\n restored: restore.restored,\n ...(notFound.length ? { notFound } : {}),\n ...(restore.unknownSource.length\n ? {\n unknownSource: restore.unknownSource,\n note: 'these declarations were made before the overridden value was remembered — the property keeps its current value until the next resync from the source'\n }\n : {}),\n ...(restore.missingTargets.length ? { missingTargets: restore.missingTargets } : {})\n }\n\n const running = TwinEngine.modeOf(domainId, instanceId)\n if (running === 'live') {\n const shift = await TwinEngine.adoptStructure(domainId, instanceId, relaid.model, 'revoked local declarations (twin)')\n return { ok: true, applied: 'running', ...report, revision: shift.rev }\n }\n\n inst.model = relaid.model\n await repo.save(inst)\n await projectStructure(domainId, instanceId, relaid.model, instanceId)\n return {\n ok: true,\n applied: running ? 'on-restart' : 'stored',\n ...(running ? { note: 'a running simulation keeps its current declarations — restart it to run without them' } : {}),\n ...report\n }\n }\n /**\n * **현장의 값을 선언한다** — 트윈이 아니라 현장이 주어다.\n *\n * ── 왜 트윈 문과 갈랐나 (2026-08-18) ───────────────────────────────────────\n * 처음에는 트윈 문에 범위 인자를 두었다. 그러면 **현장 값을 넣으려고 트윈을 골라야 한다** — 트윈은 그\n * 값을 읽는 쪽이므로 개념이 거꾸로다(사용자가 그 어긋남을 지적했다). 주어가 다르면 문도 다르다.\n *\n * 어휘는 **그 현장 트윈들의 합집합**으로 검사한다: 한 현장에 여러 종류가 살고, 요금은 에너지 트윈만\n * 읽는다. 어느 종류도 읽지 않는 속성은 거절한다(모르는 값을 받아 두면 사용자는 넣었다고 믿는다).\n *\n * 넣은 값은 그 현장의 **트윈 전부**에 얹힌다 — 한 트윈만 바꿔 두면 「현장 전체가 읽는다」가 거짓이 된다.\n * 얹을 자리가 없는 트윈은 정상이고(창고 트윈에 요금 자리가 없다), 아무 트윈도 받지 않았다면 그 사실을\n * 말한다.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Declare values that belong to a whole facility (space) rather than to one twin — tariff, currency, contracted power. They are applied to every twin in the facility (a twin-scope declaration of the same property still wins), and survive a resync from the source.'\n })\n async declareSpaceProperties(\n @Arg('spaceId') spaceId: string,\n @Arg('declarations', type => [ScalarObject]) declarations: any[],\n @Ctx() context: ResolverContext\n ): Promise<any> {\n const domainId = context.state.domain.id\n const spaceRepo = getRepository(TwinSpace)\n const space = await spaceRepo.findOne({ where: { domain: { id: domainId }, spaceId } })\n if (!space) return { ok: false, error: `unknown facility: ${spaceId}` }\n if (!declarations?.length) return { ok: false, error: 'no declaration arrived — the declarations argument was empty' }\n\n const twins = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n if (!twins.length) return { ok: false, error: `facility \"${spaceId}\" has no twin — nothing would read the value` }\n\n /*\n * 검사는 **어느 종류든 읽으면 통과**다 — 현장에 에너지·창고가 함께 있으면 요금은 에너지 쪽 어휘로\n * 받는다. 거절 이유는 종류별로 다를 수 있으니, 통과한 종류가 하나도 없을 때의 이유를 돌려준다.\n */\n /*\n * 공정 이름도 **현장 합집합**으로 대조한다 — 창고가 돌리는 `putaway` 와 야드가 돌리는 `spot` 이 한\n * 현장에 함께 있고, 현장 값은 그 전부에 얹힌다. 하나도 확인할 수 없으면 목록을 주지 않는다(모른다).\n */\n const knownSet = new Set<string>()\n for (const t of twins)\n for (const k of knownOperationKinds(\n t.model,\n TwinEngine.kernel(domainId, t.instanceId),\n await TwinEngine.measuredOperationKinds(domainId, t.instanceId)\n ) ?? [])\n knownSet.add(k)\n const knownOperations = knownSet.size ? [...knownSet] : undefined\n\n let accepted: LocalDeclaration[] = []\n let rejected: any[] = []\n for (const kind of [...new Set(twins.map(t => t.kind))]) {\n const r = validateLocalDeclarations(kind, declarations as LocalDeclaration[], { knownOperations })\n if (r.accepted.length > accepted.length) accepted = r.accepted\n if (!rejected.length) rejected = r.rejected\n }\n if (!accepted.length) return { ok: false, error: 'no declaration was accepted by any twin kind at this facility', rejected }\n\n const next = mergeLocalDeclarations(space.localDeclarations as LocalDeclaration[] | undefined, accepted)\n const spread = await spreadSpaceLayer(domainId, spaceId, next, 'local declarations (facility)')\n space.localDeclarations = spread.spaceLayerApplied as any\n await spaceRepo.save(space)\n\n const landed = spread.twins.filter(t => t.landed && t.applied !== 'failed')\n return {\n ok: true,\n scope: 'space',\n applied: landed.some(t => t.applied === 'running') ? 'running' : landed.length ? 'stored' : 'nowhere',\n accepted,\n ...(rejected.length ? { rejected } : {}),\n twins: spread.twins,\n ...(landed.length\n ? {}\n : { note: 'no twin at this facility has that target — the value is kept, but nothing reads it yet' })\n }\n }\n\n /**\n * 현장의 선언을 철회한다 — 그 현장의 **모든 트윈에서** 사라진다.\n *\n * 트윈이 같은 속성을 자기 겹에 갖고 있으면 그 값은 남는다(좁은 것이 이긴다) — 현장 값을 뺐는데 그\n * 트윈만 그대로인 것이 옳다. 트윈마다 「원천으로 되돌리고 남은 두 겹을 다시 얹기」를 한다.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Revoke facility-scope declarations, restoring on every twin in the facility the value that sat underneath (a twin-scope declaration of the same property stays, and the source value reappears where nothing else covers it).'\n })\n async revokeSpaceDeclarations(\n @Arg('spaceId') spaceId: string,\n @Arg('revocations', type => [ScalarObject]) revocations: any[],\n @Ctx() context: ResolverContext\n ): Promise<any> {\n const domainId = context.state.domain.id\n const spaceRepo = getRepository(TwinSpace)\n const space = await spaceRepo.findOne({ where: { domain: { id: domainId }, spaceId } })\n if (!space) return { ok: false, error: `unknown facility: ${spaceId}` }\n if (!revocations?.length) return { ok: false, error: 'no revocation arrived — the revocations argument was empty' }\n\n const { layer, revoked, notFound } = revokeLocalDeclarations(\n space.localDeclarations as LocalDeclaration[] | undefined,\n revocations as DeclarationRevocation[]\n )\n if (!revoked.length) return { ok: false, error: 'no facility declaration matched', scope: 'space', notFound }\n\n const repoAll = getRepository(TwinInstance)\n const twins = await repoAll.find({ where: { domain: { id: domainId }, spaceId } })\n const per: { instanceId: string; applied: string; error?: string }[] = []\n let spaceApplied = layer\n for (const t of twins) {\n if (!t.model) continue\n const back = restoreRevoked(t.model, revoked)\n const out = applyDeclarationLayers(back.model, spaceApplied, (t.localDeclarations ?? []) as LocalDeclaration[])\n spaceApplied = out.spaceLayerApplied\n t.localDeclarations = out.instanceLayerApplied as any\n const running = TwinEngine.modeOf(domainId, t.instanceId)\n /* 하나가 실패해도 나머지는 되돌린다 — 이유는 트윈별로 적어 돌려준다. */\n try {\n if (running === 'live') {\n await repoAll.save(t)\n await TwinEngine.adoptStructure(domainId, t.instanceId, out.model, 'revoked local declarations (facility)')\n per.push({ instanceId: t.instanceId, applied: 'running' })\n continue\n }\n t.model = out.model\n await repoAll.save(t)\n await projectStructure(domainId, t.instanceId, out.model, t.instanceId)\n per.push({ instanceId: t.instanceId, applied: running ? 'on-restart' : 'stored' })\n } catch (e: any) {\n per.push({ instanceId: t.instanceId, applied: 'failed', error: e?.message ?? 'failed' })\n }\n }\n space.localDeclarations = spaceApplied as any\n await spaceRepo.save(space)\n\n return {\n ok: true,\n scope: 'space',\n applied: per.some(x => x.applied === 'running') ? 'running' : 'stored',\n withdrawn: revoked.map(r => ({ target: r.target, id: r.id, propertyId: r.propertyId })),\n restored: revoked.filter(r => 'replaced' in r),\n ...(notFound.length ? { notFound } : {}),\n twins: per\n }\n }\n}\n"]}
1
+ {"version":3,"file":"twin-model-mutation.js","sourceRoot":"","sources":["../../../server/service/twin-model/twin-model-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'\n\nimport { ScalarObject, getRepository } from '@things-factory/shell'\n\nimport { TwinInstance } from '../twin-instance/twin-instance.js'\nimport { TwinSpace } from '../twin-space/twin-space.js'\nimport { TwinEngine } from '../../engine/twin-engine.js'\nimport {\n applyDeclarationLayers,\n applyLocalDeclarations,\n mergeLocalDeclarations,\n restoreRevoked,\n revokeLocalDeclarations,\n validateLocalDeclarations,\n type DeclarationRevocation,\n type LocalDeclaration\n} from '../../engine/local-declarations.js'\nimport { knownOperationKinds } from '../../engine/operation-basis.js'\nimport { projectStructure } from './project-structure.js'\n\n/*\n * 구조 테이블 **재생성** — 저장된 모델 문서로 캐시를 다시 그린다.\n *\n * ── 이것은 원본에서 다시 읽는 것과 다르다 ──────────────────────────────────────\n * `resyncTwin` 은 **원본**에 가서 현장이 지금 어떻게 생겼는지 다시 읽는다(모델이 바뀔 수 있다).\n * 여기는 **아무것도 다시 읽지 않는다** — 이미 갖고 있는 모델 문서를 테이블로 다시 푼다.\n * 그래서 모델은 한 글자도 바뀌지 않고, 테이블만 문서와 같아진다.\n *\n * ── 왜 필요한가 ────────────────────────────────────────────────────────────────\n * 이 앱에는 **투영이 생기기 전에 만들어진 트윈**이 있다. 문서에는 자리 6개·설비 32대가 있는데\n * 테이블은 0행이고, 그중 일부는 원천도 기억하지 않아 다시 읽을 수조차 없다 — 조회 화면이\n * 영구히 \"테이블이 뒤에 있습니다\" 만 말하는 막다른 상태다.\n *\n * ── 쓰기 경로가 둘이 되는 것 아닌가 ────────────────────────────────────────────\n * 아니다. 그 규율(ADR-0032-D)이 막는 것은 **다른 진실이 행을 쓰는 것**이다(예: 틱 루프가 관측을\n * 밀어 넣기). 여기서 쓰는 것은 인제스트가 쓰는 것과 **같은 문서·같은 투영**이고, 그 규율이 함께\n * 요구한 \"재생성 가능성을 구조로\" 가 바로 이것이다. 캐시는 언제든 다시 그릴 수 있어야 한다.\n */\n/**\n * 현장 겹을 **그 현장의 트윈 전부**에 얹는다 — 그러지 않으면 「현장 전체가 읽는다」가 거짓이 된다.\n *\n * ── 왜 필요한가 (2026-08-18) ────────────────────────────────────────────────\n * 처음에는 호출한 트윈에만 얹었다. 그러면 같은 현장의 다른 EMS 트윈은 **다음에 자기가 다시 그려질 때\n * 까지** 옛 값으로 돌아간다 — 화면은 「현장 전체」라고 말하는데 실제로는 한 트윈만 바뀐 상태다.\n *\n * 트윈마다 자기 겹을 그대로 얹는다(좁은 것이 이긴다). 돌고 있는 미러는 지금 받고, 시뮬레이션·정지\n * 트윈은 문서에 반영한다(재기동 때 받는다) — 그 차이를 결과에 적어 돌려준다.\n *\n * 얹을 자리가 없는 트윈은 **정상**이다(창고 트윈에 요금 자리가 없다). 그 사실도 세어 돌려준다 —\n * 「현장에 넣었는데 아무 트윈도 안 받았다」는 사용자가 알아야 할 사실이다.\n */\nasync function spreadSpaceLayer(\n domainId: string,\n spaceId: string,\n spaceLayer: LocalDeclaration[],\n comment: string\n): Promise<{\n spaceLayerApplied: LocalDeclaration[]\n twins: { instanceId: string; applied: string; landed: boolean; error?: string }[]\n}> {\n const repo = getRepository(TwinInstance)\n const twins = await repo.find({ where: { domain: { id: domainId }, spaceId } })\n const report: { instanceId: string; applied: string; landed: boolean; error?: string }[] = []\n let latest = spaceLayer\n for (const t of twins) {\n if (!t.model) continue\n const out = applyDeclarationLayers(t.model, latest, (t.localDeclarations ?? []) as LocalDeclaration[])\n /* 기억(`replaced`)은 **얹힌 트윈에서만** 채워진다 — 자리가 없는 트윈을 지나며 지워지지 않게 이어 든다. */\n latest = out.spaceLayerApplied\n const landed = !out.missingTargets.some(m => m.scope === 'space' && spaceLayer.some(d => d.id === m.id && d.target === m.target))\n t.localDeclarations = out.instanceLayerApplied as any\n const running = TwinEngine.modeOf(domainId, t.instanceId)\n /*\n * **트윈 하나가 실패해도 나머지는 받는다** — 다만 알리지 않고 넘기지 않는다(2026-08-18 실측).\n *\n * 현장 선언을 처음 퍼뜨렸을 때 그 현장의 어떤 트윈에서 구조 투영이 터졌고(그 트윈 모델에 설비 id가\n * 겹쳐 있었다 — 선재 결함), 그 예외가 올라와 **한 트윈 때문에 현장 전체 선언이 실패**했다. 사용자는\n * 값을 넣었는데 아무 일도 일어나지 않은 것으로 본다.\n *\n * 그렇다고 삼키면 더 나쁘다: 「현장 전체가 읽는다」고 말한 뒤 몇 트윈이 못 읽는 상태가 된다. 그래서\n * 트윈별로 이유를 적어 돌려준다.\n */\n try {\n if (running === 'live') {\n await repo.save(t)\n await TwinEngine.adoptStructure(domainId, t.instanceId, out.model, comment)\n report.push({ instanceId: t.instanceId, applied: 'running', landed })\n continue\n }\n t.model = out.model\n await repo.save(t)\n await projectStructure(domainId, t.instanceId, out.model, t.instanceId)\n report.push({ instanceId: t.instanceId, applied: running ? 'on-restart' : 'stored', landed })\n } catch (e: any) {\n report.push({ instanceId: t.instanceId, applied: 'failed', landed, error: e?.message ?? 'failed' })\n }\n }\n return { spaceLayerApplied: latest, twins: report }\n}\n\n@Resolver()\nexport class TwinModelMutation {\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n \"Rebuild this twin's structure tables from the model document it already holds. Reads nothing from the source: the model is unchanged and only the cache is redrawn. Use resyncTwin instead when the source itself may have changed.\"\n })\n async reprojectTwinModel(@Arg('instanceId') instanceId: string, @Ctx() context: ResolverContext): Promise<any> {\n const domainId = context.state.domain.id\n const inst = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!inst) return { ok: false, error: `unknown twin: ${instanceId}` }\n if (!inst.model) return { ok: false, error: `twin \"${instanceId}\" has no model document — there is nothing to draw from` }\n\n try {\n /*\n * 출처 표식은 **이 트윈 자신**이다. 인제스트도 같은 값을 넣는다(`master.source` = instanceId) —\n * 여기서 다른 값을 넣으면 같은 행이 어디서 왔는지가 경로마다 달라진다.\n */\n const report = await projectStructure(domainId, instanceId, inst.model, instanceId)\n return { ok: true, ...report }\n } catch (e: any) {\n return { ok: false, error: e?.message || 'reprojection failed' }\n }\n }\n\n /**\n * 현장이 정하는 수를 트윈에 얹는다 — **구조는 원천이, 수는 현장이.**\n *\n * ── 왜 이 문이 필요했나 (2026-08-18) ──────────────────────────────────────\n * 커넥터로 만든 트윈은 계통도·계량 지점을 원 시스템에서 읽어 온다. 그런데 요금 단가·계약 정보·\n * 축전지 충전율은 원 시스템이 모른다(SCADA 게이트웨이는 우리 전기 계약을 알지 못한다). 그래서\n * 계량이 흐르는 트윈에서도 **금액이 영원히 나오지 않았다** — 넣을 문이 없었기 때문이다.\n *\n * 값은 `model` 에 직접 쓰지 않고 **겹**으로 보관한다: 모델은 원천의 사본이므로 다시 읽기가 그것을\n * 새로 그리면 직접 쓴 값은 오류 없이 사라진다. 겹은 모델을 그릴 때마다 다시 얹힌다.\n *\n * ── 돌고 있는 트윈에 어떻게 반영하나 ────────────────────────────────────────\n * 미러는 **동작 중에** 새 구조를 받는다(현실은 멈추지 않는다). 시뮬레이션은 받지 않는다 — 조건이\n * 바뀐 실험은 다른 실험이고, 커널이 그렇게 거절한다. 그때는 저장만 하고 **그 사실을 말한다**:\n * 알리지 않고 성공으로 답하면 사용자는 지금 화면의 수가 새 선언으로 계산된 줄로 읽는다.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n \"Declare locally-owned numbers on a twin (tariff, contract, state of charge) as a layer on top of the reference-derived model, so a resync cannot drop them. Values carry source: local, telling every consumer that the authority for them sits here rather than in the source system. Values are validated against the kernel's property specification (unit and range). Mirrors adopt them while running; simulations keep their current declarations until restart, and the result says so.\"\n })\n async declareTwinProperties(\n @Arg('instanceId') instanceId: string,\n @Arg('declarations', type => [ScalarObject]) declarations: any[],\n @Ctx() context: ResolverContext\n ): Promise<any> {\n const domainId = context.state.domain.id\n const repo = getRepository(TwinInstance)\n const inst = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!inst) return { ok: false, error: `unknown twin: ${instanceId}` }\n if (!inst.model) return { ok: false, error: `twin \"${instanceId}\" has no model document — provision it before declaring values on it` }\n\n /*\n * **선언이 하나도 도착하지 않은 것**과 **받았지만 다 거절된 것**은 다른 일이다.\n *\n * 둘을 같은 문장으로 답했더니, 입력이 통째로 사라진 호출이 「받아준 선언이 없다 · 거절 목록 비어 있음」\n * 이라는 답을 받았다 — 사용자는 자기 값이 서버까지 오지 못한 것을 알 수 없다(실제로 겪었다: GraphQL\n * `Object` 스칼라에 인라인 리터럴로 주면 빈 배열이 되고, 변수로 주면 온다).\n */\n if (!declarations?.length) return { ok: false, error: 'no declaration arrived — the declarations argument was empty' }\n\n /*\n * 검사부터 — 받지 않은 것을 알리지 않고 버리지 않는다(사용자는 값을 넣었다고 믿는다).\n *\n * 공정 이름은 **대조로만** 걸러진다(모델에 행이 없어도 성립하는 선언이라 다른 안전망이 없다). 아직\n * 돌지도 않고 명세 행도 없는 트윈이면 목록이 `undefined` 이고, 그때는 받아 주되 답에 그 사실을 싣는다.\n */\n const knownOperations = knownOperationKinds(\n inst.model,\n TwinEngine.kernel(domainId, instanceId),\n await TwinEngine.measuredOperationKinds(domainId, instanceId)\n )\n const { accepted, rejected } = validateLocalDeclarations(inst.kind, declarations as LocalDeclaration[], { knownOperations })\n if (!accepted.length) return { ok: false, error: 'no declaration was accepted', rejected }\n const unverifiedOperations = knownOperations\n ? []\n : accepted.filter(d => d.target === 'operation').map(d => d.id)\n\n /*\n * 현장 범위면 **공간에 적는다** — 그 현장의 트윈 전부가 읽는 자리다. 공간을 모르면 거절한다(트윈에\n * 몰래 적으면 사용자는 현장에 넣었다고 믿는다).\n */\n /* 현장 겹은 **읽기만** 한다 — 이 문은 트윈의 값만 넣는다(현장 값은 전용 문이 있다). 순서를 지키려면\n 현장 겹을 함께 얹어야 한다: 현장 먼저, 트윈이 나중. */\n const spaceRepo = getRepository(TwinSpace)\n const space =\n inst.spaceId ? await spaceRepo.findOne({ where: { domain: { id: domainId }, spaceId: inst.spaceId } }) : null\n const nextSpace = (space?.localDeclarations ?? []) as LocalDeclaration[]\n const nextInst = mergeLocalDeclarations((inst.localDeclarations ?? []) as LocalDeclaration[], accepted)\n\n /* 얹으면서 **무엇을 덮었는지** 적어 온 겹을 저장한다 — 철회는 그 기억이 있어야 성립한다.\n 순서가 규율이다: 현장 먼저, 트윈이 나중(좁은 것이 이긴다). */\n const applied = applyDeclarationLayers(inst.model, nextSpace, nextInst)\n const model = applied.model\n /* 현장 겹이 이 트윈에 얹을 자리가 없는 것은 정상이다(창고 트윈에 요금 자리가 없다) — 경고로 올리지 않는다. */\n const missingTargets = applied.missingTargets.filter(t => t.scope === 'instance').map(({ target, id }) => ({ target, id }))\n /* 읽을 수 있는 값으로 바꾸지 못한 선언 — 겹에는 남지만 계산에는 들어가지 않는다(그 사실을 말한다). */\n const unreadable = applied.unreadable.map(({ target, id, propertyId }) => ({ target, id, propertyId }))\n\n /* 겹은 언제나 남긴다 — 대상이 지금 없어도(구조가 바뀌었다) 사용자의 선언을 버리지 않는다. */\n inst.localDeclarations = applied.instanceLayerApplied\n await repo.save(inst)\n if (space) {\n space.localDeclarations = applied.spaceLayerApplied\n await spaceRepo.save(space)\n }\n\n const running = TwinEngine.modeOf(domainId, instanceId)\n if (running === 'live') {\n /* 미러는 지금 받는다 — 저장·구조 행·커널이 함께 움직인다(adoptStructure 가 셋을 묶는다). */\n const shift = await TwinEngine.adoptStructure(domainId, instanceId, model, 'local declarations (twin)')\n return {\n ok: true,\n applied: 'running',\n scope: 'instance',\n accepted,\n ...(rejected.length ? { rejected } : {}),\n ...(missingTargets.length ? { missingTargets } : {}),\n ...(unreadable.length ? { unreadable } : {}),\n ...(unverifiedOperations.length\n ? {\n unverifiedOperations,\n note: 'this twin has run no operations and declares no operation specification, so the operation name could not be checked — if it is misspelled the value will simply never be read'\n }\n : {}),\n revision: shift.rev\n }\n }\n\n /* 시뮬레이션·정지 트윈 — 문서와 구조 행에는 반영하고, 돌고 있는 커널에는 반영하지 않는다. */\n inst.model = model\n await repo.save(inst)\n const report = await projectStructure(domainId, instanceId, model, instanceId)\n return {\n ok: true,\n applied: running ? 'on-restart' : 'stored',\n scope: 'instance',\n ...(running ? { note: 'a running simulation keeps its current declarations — restart it to run on the new numbers' } : {}),\n accepted,\n ...(rejected.length ? { rejected } : {}),\n ...(missingTargets.length ? { missingTargets } : {}),\n ...(unreadable.length ? { unreadable } : {}),\n ...(unverifiedOperations.length\n ? {\n unverifiedOperations,\n note: 'this twin has run no operations and declares no operation specification, so the operation name could not be checked — if it is misspelled the value will simply never be read'\n }\n : {}),\n ...report\n }\n }\n\n /**\n * 선언을 **철회한다** — 잘못 넣은 값을 원천으로 되돌리는 문.\n *\n * ── 왜 따로 문이 필요한가 (2026-08-18) ──────────────────────────────────────\n * 선언은 겹에 보관되지만 **저장된 모델에 구워진다.** 그래서 겹에서 줄만 지워도 원래 값이 돌아오지\n * 않는다 — 되돌릴 방법이 아예 없어서, 오타를 「원래 값을 다시 선언하는」 우회로만 고칠 수 있었다\n * (사용자가 원래 값을 알고 있어야 한다는 뜻이고, 모르면 그 값은 영구히 이긴다).\n *\n * 그래서 겹이 **무엇을 덮었는지** 함께 기억하게 했고(`replaced`), 철회는 그 기억으로 되돌린다.\n * 기억이 없는 옛 선언은 **손대지 않고 그렇게 말한다**(`unknownSource`) — 원래 값을 지어내는 것은\n * 잘못 넣은 값을 그대로 두는 것보다 나쁘다. 그 자리는 다음 원천 재읽기가 바로잡는다.\n *\n * 반영 방식은 선언과 같다: 미러는 지금 받고(`adoptStructure`), 시뮬레이션은 재기동 때 받는다.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Revoke locally-declared values on a twin, restoring the value the reference system had when the declaration was applied (or removing the property if the source never had it). Declarations made before the overridden value was remembered are left untouched and reported, rather than guessed.'\n })\n async revokeTwinDeclarations(\n @Arg('instanceId') instanceId: string,\n @Arg('revocations', type => [ScalarObject]) revocations: any[],\n @Ctx() context: ResolverContext\n ): Promise<any> {\n const domainId = context.state.domain.id\n const repo = getRepository(TwinInstance)\n const inst = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!inst) return { ok: false, error: `unknown twin: ${instanceId}` }\n if (!inst.model) return { ok: false, error: `twin \"${instanceId}\" has no model document` }\n /* 도착 0건과 「겹에 없다」는 다른 일이다 — 선언 쪽에서 겪은 침묵을 여기서 되풀지 않는다. */\n if (!revocations?.length) return { ok: false, error: 'no revocation arrived — the revocations argument was empty' }\n\n const spaceRepo = getRepository(TwinSpace)\n const space =\n inst.spaceId ? await spaceRepo.findOne({ where: { domain: { id: domainId }, spaceId: inst.spaceId } }) : null\n const { layer, revoked, notFound } = revokeLocalDeclarations(\n inst.localDeclarations as LocalDeclaration[] | undefined,\n revocations as DeclarationRevocation[]\n )\n /* 이 문은 트윈 겹만 본다 — 현장 값을 여기서 빼려 하면 「겹에 없다」다(전용 문으로 가야 한다). */\n if (!revoked.length) return { ok: false, error: 'no declaration matched at this twin — a facility value is revoked at its facility', scope: 'instance', notFound }\n\n /*\n * 모델을 되돌리는 순서 — **뺀 뒤 남은 두 겹을 다시 얹는다.**\n *\n * 값을 「기억한 원천 값」으로 곧장 되돌리면, 트윈 겹을 뺐을 때 그 아래 있던 **현장 값이 되살아나지\n * 않는다**(원천 값이 그 자리를 차지한다). 겹이 둘이 된 뒤에는 「빼고 다시 얹기」가 유일하게 옳은\n * 되돌림이다 — 그러면 트윈 값을 빼면 현장 값이, 현장 값을 빼면 원천 값이 드러난다.\n */\n const restore = restoreRevoked(inst.model, revoked)\n const nextSpace = (space?.localDeclarations ?? []) as LocalDeclaration[]\n const nextInst = layer\n\n const relaid = applyDeclarationLayers(restore.model, nextSpace, nextInst)\n\n inst.localDeclarations = relaid.instanceLayerApplied\n await repo.save(inst)\n if (space) {\n space.localDeclarations = relaid.spaceLayerApplied\n await spaceRepo.save(space)\n }\n\n /*\n * **겹에서 뺀 것**과 **값을 되돌린 것**은 다른 일이다 — 갈라서 말한다.\n *\n * 처음에는 되돌린 것만 `revoked` 로 냈다. 그래서 기억 없는 옛 선언을 철회하면 「revoked: [] 」이\n * 돌아왔다 — 겹에서는 분명히 뺐는데(다시 얹히지 않는다) 아무 일도 없었던 것처럼 읽힌다.\n */\n const report = {\n scope: 'instance',\n withdrawn: revoked.map(r => ({ target: r.target, id: r.id, propertyId: r.propertyId })),\n restored: restore.restored,\n ...(notFound.length ? { notFound } : {}),\n ...(restore.unknownSource.length\n ? {\n unknownSource: restore.unknownSource,\n note: 'these declarations were made before the overridden value was remembered — the property keeps its current value until the next resync from the source'\n }\n : {}),\n ...(restore.missingTargets.length ? { missingTargets: restore.missingTargets } : {})\n }\n\n const running = TwinEngine.modeOf(domainId, instanceId)\n if (running === 'live') {\n const shift = await TwinEngine.adoptStructure(domainId, instanceId, relaid.model, 'revoked local declarations (twin)')\n return { ok: true, applied: 'running', ...report, revision: shift.rev }\n }\n\n inst.model = relaid.model\n await repo.save(inst)\n await projectStructure(domainId, instanceId, relaid.model, instanceId)\n return {\n ok: true,\n applied: running ? 'on-restart' : 'stored',\n ...(running ? { note: 'a running simulation keeps its current declarations — restart it to run without them' } : {}),\n ...report\n }\n }\n /**\n * **현장의 값을 선언한다** — 트윈이 아니라 현장이 주어다.\n *\n * ── 왜 트윈 문과 갈랐나 (2026-08-18) ───────────────────────────────────────\n * 처음에는 트윈 문에 범위 인자를 두었다. 그러면 **현장 값을 넣으려고 트윈을 골라야 한다** — 트윈은 그\n * 값을 읽는 쪽이므로 개념이 거꾸로다(사용자가 그 어긋남을 지적했다). 주어가 다르면 문도 다르다.\n *\n * 어휘는 **그 현장 트윈들의 합집합**으로 검사한다: 한 현장에 여러 종류가 살고, 요금은 에너지 트윈만\n * 읽는다. 어느 종류도 읽지 않는 속성은 거절한다(모르는 값을 받아 두면 사용자는 넣었다고 믿는다).\n *\n * 넣은 값은 그 현장의 **트윈 전부**에 얹힌다 — 한 트윈만 바꿔 두면 「현장 전체가 읽는다」가 거짓이 된다.\n * 얹을 자리가 없는 트윈은 정상이고(창고 트윈에 요금 자리가 없다), 아무 트윈도 받지 않았다면 그 사실을\n * 말한다.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Declare values that belong to a whole facility (space) rather than to one twin — tariff, currency, contracted power. They are applied to every twin in the facility (a twin-scope declaration of the same property still wins), and survive a resync from the source.'\n })\n async declareSpaceProperties(\n @Arg('spaceId') spaceId: string,\n @Arg('declarations', type => [ScalarObject]) declarations: any[],\n @Ctx() context: ResolverContext\n ): Promise<any> {\n const domainId = context.state.domain.id\n const spaceRepo = getRepository(TwinSpace)\n const space = await spaceRepo.findOne({ where: { domain: { id: domainId }, spaceId } })\n if (!space) return { ok: false, error: `unknown facility: ${spaceId}` }\n if (!declarations?.length) return { ok: false, error: 'no declaration arrived — the declarations argument was empty' }\n\n const twins = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n if (!twins.length) return { ok: false, error: `facility \"${spaceId}\" has no twin — nothing would read the value` }\n\n /*\n * 검사는 **어느 종류든 읽으면 통과**다 — 현장에 에너지·창고가 함께 있으면 요금은 에너지 쪽 어휘로\n * 받는다. 거절 이유는 종류별로 다를 수 있으니, 통과한 종류가 하나도 없을 때의 이유를 돌려준다.\n */\n /*\n * 공정 이름도 **현장 합집합**으로 대조한다 — 창고가 돌리는 `putaway` 와 야드가 돌리는 `spot` 이 한\n * 현장에 함께 있고, 현장 값은 그 전부에 얹힌다. 하나도 확인할 수 없으면 목록을 주지 않는다(모른다).\n */\n const knownSet = new Set<string>()\n for (const t of twins)\n for (const k of knownOperationKinds(\n t.model,\n TwinEngine.kernel(domainId, t.instanceId),\n await TwinEngine.measuredOperationKinds(domainId, t.instanceId)\n ) ?? [])\n knownSet.add(k)\n const knownOperations = knownSet.size ? [...knownSet] : undefined\n\n let accepted: LocalDeclaration[] = []\n let rejected: any[] = []\n for (const kind of [...new Set(twins.map(t => t.kind))]) {\n const r = validateLocalDeclarations(kind, declarations as LocalDeclaration[], { knownOperations })\n if (r.accepted.length > accepted.length) accepted = r.accepted\n if (!rejected.length) rejected = r.rejected\n }\n if (!accepted.length) return { ok: false, error: 'no declaration was accepted by any twin kind at this facility', rejected }\n\n const next = mergeLocalDeclarations(space.localDeclarations as LocalDeclaration[] | undefined, accepted)\n const spread = await spreadSpaceLayer(domainId, spaceId, next, 'local declarations (facility)')\n space.localDeclarations = spread.spaceLayerApplied as any\n await spaceRepo.save(space)\n\n const landed = spread.twins.filter(t => t.landed && t.applied !== 'failed')\n return {\n ok: true,\n scope: 'space',\n applied: landed.some(t => t.applied === 'running') ? 'running' : landed.length ? 'stored' : 'nowhere',\n accepted,\n ...(rejected.length ? { rejected } : {}),\n twins: spread.twins,\n ...(landed.length\n ? {}\n : { note: 'no twin at this facility has that target — the value is kept, but nothing reads it yet' })\n }\n }\n\n /**\n * 현장의 선언을 철회한다 — 그 현장의 **모든 트윈에서** 사라진다.\n *\n * 트윈이 같은 속성을 자기 겹에 갖고 있으면 그 값은 남는다(좁은 것이 이긴다) — 현장 값을 뺐는데 그\n * 트윈만 그대로인 것이 옳다. 트윈마다 「원천으로 되돌리고 남은 두 겹을 다시 얹기」를 한다.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Revoke facility-scope declarations, restoring on every twin in the facility the value that sat underneath (a twin-scope declaration of the same property stays, and the source value reappears where nothing else covers it).'\n })\n async revokeSpaceDeclarations(\n @Arg('spaceId') spaceId: string,\n @Arg('revocations', type => [ScalarObject]) revocations: any[],\n @Ctx() context: ResolverContext\n ): Promise<any> {\n const domainId = context.state.domain.id\n const spaceRepo = getRepository(TwinSpace)\n const space = await spaceRepo.findOne({ where: { domain: { id: domainId }, spaceId } })\n if (!space) return { ok: false, error: `unknown facility: ${spaceId}` }\n if (!revocations?.length) return { ok: false, error: 'no revocation arrived — the revocations argument was empty' }\n\n const { layer, revoked, notFound } = revokeLocalDeclarations(\n space.localDeclarations as LocalDeclaration[] | undefined,\n revocations as DeclarationRevocation[]\n )\n if (!revoked.length) return { ok: false, error: 'no facility declaration matched', scope: 'space', notFound }\n\n const repoAll = getRepository(TwinInstance)\n const twins = await repoAll.find({ where: { domain: { id: domainId }, spaceId } })\n const per: { instanceId: string; applied: string; error?: string }[] = []\n let spaceApplied = layer\n for (const t of twins) {\n if (!t.model) continue\n const back = restoreRevoked(t.model, revoked)\n const out = applyDeclarationLayers(back.model, spaceApplied, (t.localDeclarations ?? []) as LocalDeclaration[])\n spaceApplied = out.spaceLayerApplied\n t.localDeclarations = out.instanceLayerApplied as any\n const running = TwinEngine.modeOf(domainId, t.instanceId)\n /* 하나가 실패해도 나머지는 되돌린다 — 이유는 트윈별로 적어 돌려준다. */\n try {\n if (running === 'live') {\n await repoAll.save(t)\n await TwinEngine.adoptStructure(domainId, t.instanceId, out.model, 'revoked local declarations (facility)')\n per.push({ instanceId: t.instanceId, applied: 'running' })\n continue\n }\n t.model = out.model\n await repoAll.save(t)\n await projectStructure(domainId, t.instanceId, out.model, t.instanceId)\n per.push({ instanceId: t.instanceId, applied: running ? 'on-restart' : 'stored' })\n } catch (e: any) {\n per.push({ instanceId: t.instanceId, applied: 'failed', error: e?.message ?? 'failed' })\n }\n }\n space.localDeclarations = spaceApplied as any\n await spaceRepo.save(space)\n\n return {\n ok: true,\n scope: 'space',\n applied: per.some(x => x.applied === 'running') ? 'running' : 'stored',\n withdrawn: revoked.map(r => ({ target: r.target, id: r.id, propertyId: r.propertyId })),\n restored: revoked.filter(r => 'replaced' in r),\n ...(notFound.length ? { notFound } : {}),\n twins: per\n }\n }\n}\n"]}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TwinModelQuery = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const axis_journal_evidence_js_1 = require("./axis-journal-evidence.js");
6
+ const read_time_js_1 = require("../../engine/read-time.js");
6
7
  const status_tally_js_1 = require("./status-tally.js");
7
8
  const twin_event_js_1 = require("../twin-event/twin-event.js");
8
9
  const type_graphql_1 = require("type-graphql");
@@ -116,8 +117,8 @@ async function emptyStateReason(domainId, instanceId, axis) {
116
117
  /**
117
118
  * 되세운 상태를 담아 둔다 — **열쇠에 저널 끝 리비전이 들어 있어** 새 사건이 오면 저절로 낡는다.
118
119
  *
119
- * 접기는 저널 전체를 훑는 일이라(리비전 12만에서 2~3초) 모델 화면을 열 때마다 그 값을 낼 수 없다.
120
- * 프로세스 안에만 두고 몇 개만 남긴다 — 다시 뜨면 다시 접는다(정확함이 캐시보다 앞선다).
120
+ * 계산은 저널 전체를 훑는 일이라(리비전 12만에서 2~3초) 모델 화면을 열 때마다 그 값을 낼 수 없다.
121
+ * 프로세스 안에만 두고 몇 개만 남긴다 — 다시 뜨면 다시 계산한다(정확함이 캐시보다 앞선다).
121
122
  */
122
123
  const RECALL_CACHE = new Map();
123
124
  const RECALL_CACHE_MAX = 8;
@@ -177,19 +178,37 @@ let TwinModelQuery = class TwinModelQuery {
177
178
  const inst = await (0, shell_1.getRepository)(twin_instance_js_1.TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } });
178
179
  if (!inst)
179
180
  return null;
180
- /* 어느 원본을 반영하나 — 없을 수 있다(템플릿으로 세운 트윈). 그 사실도 사실이다. */
181
+ /*
182
+ * 어느 원본을 반영하나 — 없을 수 있다(템플릿으로 세운 트윈). 그 사실도 사실이다.
183
+ *
184
+ * ── **레퍼런스 열쇠는 인스턴스 이름이 아니다** (2026-08-24 실측) ──────────────
185
+ * 여기서 `source: instanceId` 로 찾고 있었다. 레퍼런스 하나가 인스턴스 하나를 낳던 시절에는
186
+ * 두 값이 같았지만, **레퍼런스 하나가 여러 트윈을 먹이는 순간 어긋난다.**
187
+ *
188
+ * 인스턴스 operato-chef-v1-pocheon
189
+ * origin { kind: 'reference', source: 'seunghwa' } ← 이것이 레퍼런스 열쇠다
190
+ * 레퍼런스 seunghwa
191
+ *
192
+ * 그래서 요약의 `source` 가 **언제나 `null`** 이었다. 레퍼런스로 세운 트윈인데 화면이 그 원본을
193
+ * 못 찾았고, 「마지막 동기화」도 흐름별 신선도도 그릴 자리가 아예 없었다 — 그런데 오류는 없었다
194
+ * (`ref ? … : null` 이 알리지 않고 갈렸다).
195
+ *
196
+ * 인스턴스가 자기 원본을 말하고 있으므로 **그 말을 먼저 듣는다.** 옛 트윈은 두 값이 같으므로
197
+ * 뒤의 것으로 여전히 찾힌다 — 가산적이다.
198
+ */
199
+ const refKey = inst.origin?.source || instanceId;
181
200
  const ref = await (0, shell_1.getRepository)(twin_reference_js_1.TwinReference)
182
- .findOne({ where: { domain: { id: domainId }, source: instanceId } })
201
+ .findOne({ where: { domain: { id: domainId }, source: refKey } })
183
202
  .catch(() => null);
184
203
  const model = inst.model ?? {};
185
204
  /*
186
- * **한 요청에 저널은 한 번만 접는다.**
205
+ * **한 요청에 저널은 한 번만 계산한다.**
187
206
  *
188
207
  * 관측 축(`orders`·`tasks`)은 상태에서 센다. 그 둘이 각자 `recover()` 를 부르고 있었고, 커널이
189
- * 멈춰 있으면 그것은 **저널 전체를 다시 접는 일**이다(23,731건짜리 트윈에서 4.6초, 두 번이면 곱절).
208
+ * 멈춰 있으면 그것은 **저널 전체를 다시 계산하는 일**이다(23,731건짜리 트윈에서 4.6초, 두 번이면 곱절).
190
209
  * 트윈을 전부 멈춰도 이 화면이 5~7초 걸린 이유가 이것이다 — 부하가 아니라 같은 일을 두 번 한 것이다.
191
210
  *
192
- * 한 번만 접어 나눠 쓴다. 값이 같아지는 것은 덤이 아니라 **옳음**이다: 두 번 접으면 그 사이에
211
+ * 한 번만 계산해 나눠 쓴다. 값이 같아지는 것은 덤이 아니라 **옳음**이다: 두 번 계산하면 그 사이에
193
212
  * 들어온 이벤트 때문에 오더와 작업이 서로 다른 시점의 사실이 될 수 있다.
194
213
  */
195
214
  let statePromise = null;
@@ -215,29 +234,49 @@ let TwinModelQuery = class TwinModelQuery {
215
234
  * 그런데 읽기 커서가 정직해진 뒤로는 원본이 **지난 것을 다시 말하지 않는다.** 그래서 재고 741건이
216
235
  * 저널에 있는데 화면은 「0」을 보였다. 사용자가 「재고현황이 없다」고 물은 자리가 이것이다.
217
236
  *
218
- * 그 0 은 사실이 아니라 **우리가 잊은 것**이다. 저널을 접으면 그대로 되살아난다(실측: 리비전
219
- * 97,689 을 2.4초에 접어 물품 741 · 작업 9,145 · 지시 2,856).
237
+ * 그 0 은 사실이 아니라 **우리가 잊은 것**이다. 저널을 계산하면 그대로 되살아난다(실측: 리비전
238
+ * 97,689 을 2.4초에 계산해 물품 741 · 작업 9,145 · 지시 2,856).
220
239
  *
221
- * ── 그래서 접는다. 다만 **언제 들은 값인지 함께 낸다** ──────────────────────
222
- * 저널을 접는 것은 **원천이 우리에게 말한 것을 다시 세우는 일**이지, 없는 값을 심는 일이 아니다.
240
+ * ── 그래서 계산한다. 다만 **언제 들은 값인지 함께 낸다** ──────────────────────
241
+ * 저널을 계산하는 것은 **원천이 우리에게 말한 것을 다시 세우는 일**이지, 없는 값을 심는 일이 아니다.
223
242
  * 그러나 물품·재고처럼 **절대값인 축**은 우리가 못 듣는 사이 떠났을 수 있다 — 그래서 값과 함께
224
- * `heardAt`(그 접기의 시계)을 낸다. 사용자가 신선도를 스스로 판정할 수 있어야 하고, 화면은 그것을
243
+ * `heardAt`(그 계산의 시계)을 낸다. 사용자가 신선도를 스스로 판정할 수 있어야 하고, 화면은 그것을
225
244
  * 값 옆에 적는다. 시각 없이 수만 내면 낡은 값을 지금으로 읽는다.
226
245
  *
227
- * 접는 조건을 좁게 둔다: **관측 축이 비어 있고, 저널에 그 축의 사실이 있을 때만**(그 판정은 색인
228
- * 한 줄이다). 그리고 한 요청에 **한 번만** 접는다 — 위 `stateOnce` 와 같은 규율이다.
246
+ * 계산하는 조건을 좁게 둔다: **관측 축이 비어 있고, 저널에 그 축의 사실이 있을 때만**(그 판정은 색인
247
+ * 한 줄이다). 그리고 한 요청에 **한 번만** 계산한다 — 위 `stateOnce` 와 같은 규율이다.
229
248
  */
230
249
  let journalPromise = null;
231
250
  const journalOnce = () => (journalPromise ??= (async () => {
232
251
  try {
233
- const tip = await (0, shell_1.getRepository)(twin_event_js_1.TwinEvent).findOne({
234
- where: { domain: { id: domainId }, instanceId },
235
- order: { revision: 'DESC' }
236
- });
237
- if (!tip?.revision)
252
+ /*
253
+ * 관계로 묻지 않는다 — 두 단계 질의가 되어 안쪽에 상한이 없고, 그 트윈의 저널을 전부 만든 뒤
254
+ * 한 줄을 고른다(2026-08-28 · 같은 모양이 현장 성과 화면에서 7.2초였다). 색인의 끝만 읽는다.
255
+ */
256
+ const [tipRow, latestRow] = await Promise.all([
257
+ (0, shell_1.getRepository)(twin_event_js_1.TwinEvent)
258
+ .createQueryBuilder('e')
259
+ .select('MAX(e.revision)', 'max')
260
+ .where('e.domain = :domainId', { domainId })
261
+ .andWhere('e.instanceId = :instanceId', { instanceId })
262
+ .getRawOne(),
263
+ /*
264
+ * 「저널 끝의 사건 시각」은 **가장 늦은 사건 시각**이다 — 리비전이 가장 큰 행의 시각이
265
+ * 아니다. 그 둘은 어긋난다(연결된 시스템을 되읽는 트윈은 원본의 시각을 싣고 도착 순서로
266
+ * 리비전을 받는다). 색인의 끝을 집으므로 질의 둘이어도 각각 한 줄이다.
267
+ */
268
+ (0, shell_1.getRepository)(twin_event_js_1.TwinEvent)
269
+ .createQueryBuilder('e')
270
+ .select('MAX(e.eventTime)', 'at')
271
+ .where('e.domain = :domainId', { domainId })
272
+ .andWhere('e.instanceId = :instanceId', { instanceId })
273
+ .getRawOne()
274
+ ]);
275
+ const tip = { revision: Number(tipRow?.max) || 0, eventTime: (0, read_time_js_1.hydratedDate)((0, shell_1.getRepository)(twin_event_js_1.TwinEvent), 'eventTime', latestRow?.at) };
276
+ if (!tip.revision)
238
277
  return null;
239
278
  /*
240
- * **한 번 접은 것을 다시 접지 않는다.** 접기는 저널 전체를 훑는 일이다(리비전 12만에서 2~3초).
279
+ * **한 번 계산한 것을 다시 계산하지 않는다.** 계산은 저널 전체를 훑는 일이다(리비전 12만에서 2~3초).
241
280
  * 이 화면은 사람이 여러 번 들어오는 자리이므로 그대로 두면 매번 그 값을 낸다 — 그리고 저널이
242
281
  * 수백만 행이 되면 그 비용이 화면을 못 쓰게 만든다.
243
282
  *
@@ -251,8 +290,8 @@ let TwinModelQuery = class TwinModelQuery {
251
290
  const snap = (0, warm_start_js_1.unwrapState)(await index_js_1.TwinEngine.recover(domainId, instanceId, tip.revision));
252
291
  if (!snap)
253
292
  return null;
254
- /* 그 접기의 시계가 「언제 들은 값인가」다. 없으면 저널 끝의 사건 시각으로 답한다. */
255
- const out = { snap, heardAt: snap.nowTime ?? tip.eventTime ?? null };
293
+ /* 그 계산의 시계가 「언제 들은 값인가」다. 없으면 저널 끝의 사건 시각으로 답한다. */
294
+ const out = { snap, heardAt: snap.nowTime ?? tip.eventTime?.toISOString() ?? null };
256
295
  RECALL_CACHE.set(key, out);
257
296
  /* 오래된 열쇠부터 버린다 — 트윈 몇 개를 번갈아 봐도 메모리가 자라지 않게. */
258
297
  while (RECALL_CACHE.size > RECALL_CACHE_MAX)
@@ -260,7 +299,7 @@ let TwinModelQuery = class TwinModelQuery {
260
299
  return out;
261
300
  }
262
301
  catch {
263
- /* 접지 못했으면 아무 말도 만들지 않는다 — 라이브가 말한 것을 그대로 둔다. */
302
+ /* 계산하지 못했으면 아무 말도 만들지 않는다 — 라이브가 말한 것을 그대로 둔다. */
264
303
  return null;
265
304
  }
266
305
  })());
@@ -310,7 +349,7 @@ let TwinModelQuery = class TwinModelQuery {
310
349
  *
311
350
  * 행으로 옮긴 축이라도 그 트윈이 투영을 거치지 않았으면 행은 0이다(인제스트 없이
312
351
  * warm-start 된 트윈이 그렇다). 행만 보고 답하면 문서에 자리 6개가 있는데 화면은
313
- * **0 이라고 말한다** — 조용한 거짓이고, 이 프로젝트가 내내 잡아 온 바로 그 부류다.
352
+ * **0 이라고 말한다** — 들어온 것이 없는 거짓이고, 이 프로젝트가 내내 잡아 온 바로 그 부류다.
314
353
  *
315
354
  * 그래서 어느 하나로 메우지 않는다. 행 수를 답하되 문서 수를 함께 내고, 다르면
316
355
  * `stale` 로 표시한다 — 그 차이 자체가 "이 트윈은 투영 이후 인제스트되지 않았다" 는 정보다.
@@ -344,7 +383,7 @@ let TwinModelQuery = class TwinModelQuery {
344
383
  /*
345
384
  * 관측 중인지는 **런타임이 있는지**로 본다 — 캐시된 스냅샷은 관측이 아니다.
346
385
  *
347
- * 동작하지 않으면 저널을 접어 답한다(라이브=권위 · 히스토리=파생). 카드는 그 차이를 `basis` 로
386
+ * 동작하지 않으면 저널을 계산해 답한다(라이브=권위 · 히스토리=파생). 카드는 그 차이를 `basis` 로
348
387
  * 말한다: 파생을 권위처럼 내면 다시 계산한 수를 "지금 이만큼" 으로 읽게 된다.
349
388
  */
350
389
  const { snap, folded, observing } = await stateOnce();
@@ -355,7 +394,7 @@ let TwinModelQuery = class TwinModelQuery {
355
394
  let fromJournal = false;
356
395
  /*
357
396
  * 라이브가 잊은 축은 **저널에서 되세운다**(§`journalOnce`). 그 축의 사실이 저널에 있을 때만
358
- * 접고, 값과 함께 「언제 들은 값인가」를 낸다 — 시각 없이 수만 내면 낡은 값을 지금으로 읽는다.
397
+ * 계산하고, 값과 함께 「언제 들은 값인가」를 낸다 — 시각 없이 수만 내면 낡은 값을 지금으로 읽는다.
359
398
  */
360
399
  if (!folded && Array.isArray(bucket) && bucket.length === 0) {
361
400
  const seen = await (0, axis_journal_evidence_js_1.axisSeenInJournal)((0, shell_1.getRepository)(twin_event_js_1.TwinEvent), { domain: { id: domainId }, instanceId }, a.axis).catch(() => null);
@@ -444,7 +483,7 @@ let TwinModelQuery = class TwinModelQuery {
444
483
  /*
445
484
  * **원본이 모르는데 실행 중인 것** — 커널은 마스터에 없던 자원도 이벤트로 알게 되고
446
485
  * `origin: 'observed'` 를 단다(`observed-reducer`). 그것을 표에 밀어 넣지 않는다 — 그러면
447
- * 틱 루프에서 DB 로 쓰는 **두 번째 쓰기 경로**가 생기고, 실패하면 조용히 어긋난다
486
+ * 틱 루프에서 DB 로 쓰는 **두 번째 쓰기 경로**가 생기고, 실패하면 알리지 않고 어긋난다
448
487
  * (쓰기 경로는 인제스트 하나, ADR-0032-D).
449
488
  *
450
489
  * 대신 **여기서 비교해 낸다.** 이 차이는 숨겨야 할 불일치가 아니라 인스펙션이 답해야 할
@@ -511,11 +550,61 @@ let TwinModelQuery = class TwinModelQuery {
511
550
  recipeLabel: material?.label ?? material?.name ?? null
512
551
  };
513
552
  })(),
553
+ /*
554
+ * ── **식별자가 무엇에 근거하나** (2026-08-24) ──────────────────────────────
555
+ * 요약이 `production.companyPrefix` 를 그대로 보이는데 **그것이 발급받은 번호인지 말할 근거가
556
+ * 없었다.** 그래서 사용자가 긴 URI 를 보고 「GS1 을 강제하는 것인가」를 물었다 — 강제는 **이미
557
+ * 없고**(GS1 프리픽스가 없는 현장은 자기 도메인 아래에서 식별자를 만든다, CBV 2.0 §8.3.4)
558
+ * 없다는 사실이 화면에 없었던 것이 문제였다.
559
+ *
560
+ * ★ **이 축만은 무표를 쓰지 않는다.** GS1 형태의 식별자를 본 사람은 그것이 진짜 발급받은
561
+ * 번호라고 가정하므로, 표식이 없으면 그 가정이 곧 거짓 안심이 된다. 계약도 그렇게 적고 있다 —
562
+ * 「없으면 소비처는 판정하지 않는다. 기본값으로 `issued` 를 가정하면 그 화면이 곧 거짓이 된다.」
563
+ * 그래서 화면이 네 갈래 모두에 낱말을 붙일 수 있게 **그대로** 낸다
564
+ * (`claimed-issued`·`declared-namespace`·`gs1-shaped`·`kernel-constant`).
565
+ *
566
+ * 커널이 내는 것을 그대로 넘긴다 — 여기서 다시 판정하면 스냅샷과 요약이 다른 말을 한다.
567
+ * 트윈이 돌지 않거나 커널이 말하지 않으면 `null` 이고, 그때 화면은 **재지 않는다.**
568
+ */
569
+ identityGrounding: (await stateOnce()).snap?.identityGrounding ?? null,
514
570
  description: inst.description ?? null,
515
571
  kind: inst.kind,
516
572
  restartPolicy: inst.restartPolicy,
517
573
  source: ref
518
- ? { referenceId: ref.source, adapterType: ref.adapterType, status: ref.status, lastSyncedAt: ref.lastSyncedAt }
574
+ ? {
575
+ referenceId: ref.source,
576
+ adapterType: ref.adapterType,
577
+ status: ref.status,
578
+ lastSyncedAt: ref.lastSyncedAt,
579
+ /*
580
+ * ── **원본의 어느 흐름이 어디까지 살아 있나** (2026-08-24) ──────────────
581
+ * 사용자가 「지금 데이터가 들어오는 것이 사실이냐」고 물었고, 화면이 답할 것이 「붙어 있다」
582
+ * 뿐이었다. 그런데 한 원본 안에서 흐름마다 신선도가 **크게 다르다**(실측: 재고 08-23 ·
583
+ * 계측 08-12 · 작업지시 05-10 · 공정·로트 04-15). 「붙어 있다」 하나로 뭉치면 넉 달 멈춘
584
+ * 흐름이 살아 있는 것으로 읽힌다.
585
+ *
586
+ * **계약에는 자리가 있다** — `LiveFeedCursor.since` 가 「그 흐름에서 마지막으로 본 시각
587
+ * (원본의 시각)」이고 `onCursor` 가 그것을 `TwinReference.liveCursor` 에 적는다. 없던 것은
588
+ * **화면으로 가는 문**이고, 그 문이 여기다.
589
+ *
590
+ * ★ **다만 지금은 비어 있다** — 실 저장값을 확인했다:
591
+ * `{"streams":{},"firstAttachedAt":"2026-03-25T…"}`. 즉 어댑터가 흐름별 커서를 적지 않는다.
592
+ * 그래서 이 문을 열어도 당장은 빈 목록이 나오고, **그것이 정직한 답이다**: 어댑터가 말하지
593
+ * 않는 것을 여기서 지어내지 않는다. 채우는 것은 어댑터의 몫이고 그쪽에 알렸다.
594
+ *
595
+ * 빈 목록과 「흐름이 없다」를 화면이 구별할 수 있어야 한다 — 이 값이 비면 그것은
596
+ * 「어댑터가 아직 말하지 않는다」이고 「원본에 흐름이 없다」가 아니다.
597
+ *
598
+ * `seen`(중복 걸러낸 행 id)은 내지 않는다 — 읽기 내부 상태이고 수천 개가 될 수 있다.
599
+ * 흐름 열쇠는 **어댑터가 정한다**(계약이 이름을 닫지 않는다). 그래서 이름을 번역하지 않고
600
+ * 그대로 낸다 — 화면이 모르는 이름을 만나면 그 이름을 보이는 것이 맞다.
601
+ */
602
+ streams: Object.entries(ref.liveCursor?.streams ?? {})
603
+ .map(([stream, c]) => ({ stream, since: c?.since ?? null }))
604
+ /* 시각을 말하지 않는 흐름도 낸다 — 「모른다」와 「없다」는 다르고, 빼면 그 흐름이 사라진다. */
605
+ .sort((a, b) => String(b.since ?? '').localeCompare(String(a.since ?? ''))),
606
+ firstAttachedAt: ref.liveCursor?.firstAttachedAt ?? null
607
+ }
519
608
  : null,
520
609
  /*
521
610
  * **다시 읽을 수 있는가** — 이 트윈이 자기 원본을 기억하고 있나(`TwinInstance.origin`).