@omnitron-dev/omnitron 0.3.1 → 0.3.2

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 (1687) hide show
  1. package/README.md +575 -0
  2. package/data/operations/managed-kernel.mjs +302 -0
  3. package/data/operations/stage-kernel.mjs +125 -0
  4. package/dist/BUILD.json +4 -3
  5. package/dist/cli/exit-after-output.d.ts +3 -0
  6. package/dist/cli/exit-after-output.d.ts.map +1 -0
  7. package/dist/cli/exit-after-output.js +11 -0
  8. package/dist/cli/exit-after-output.js.map +1 -0
  9. package/dist/cli/installed.d.ts +3 -0
  10. package/dist/cli/installed.d.ts.map +1 -0
  11. package/dist/cli/installed.js +17 -0
  12. package/dist/cli/installed.js.map +1 -0
  13. package/dist/cli/omnitron.js +432 -100
  14. package/dist/cli/omnitron.js.map +1 -1
  15. package/dist/cli/output-command.d.ts +13 -0
  16. package/dist/cli/output-command.d.ts.map +1 -0
  17. package/dist/cli/output-command.js +48 -0
  18. package/dist/cli/output-command.js.map +1 -0
  19. package/dist/cluster/cluster.rpc-service.d.ts +9 -77
  20. package/dist/cluster/cluster.rpc-service.d.ts.map +1 -1
  21. package/dist/cluster/cluster.rpc-service.js +20 -107
  22. package/dist/cluster/cluster.rpc-service.js.map +1 -1
  23. package/dist/cluster/enrollment.d.ts +9 -0
  24. package/dist/cluster/enrollment.d.ts.map +1 -0
  25. package/dist/cluster/enrollment.js +49 -0
  26. package/dist/cluster/enrollment.js.map +1 -0
  27. package/dist/cluster/index.d.ts +1 -1
  28. package/dist/cluster/index.d.ts.map +1 -1
  29. package/dist/cluster/leader-election.d.ts +39 -211
  30. package/dist/cluster/leader-election.d.ts.map +1 -1
  31. package/dist/cluster/leader-election.js +235 -512
  32. package/dist/cluster/leader-election.js.map +1 -1
  33. package/dist/cluster/mesh-link.d.ts +18 -51
  34. package/dist/cluster/mesh-link.d.ts.map +1 -1
  35. package/dist/cluster/mesh-link.js +65 -77
  36. package/dist/cluster/mesh-link.js.map +1 -1
  37. package/dist/cluster/mesh.d.ts +3 -1
  38. package/dist/cluster/mesh.d.ts.map +1 -1
  39. package/dist/cluster/mesh.js +76 -60
  40. package/dist/cluster/mesh.js.map +1 -1
  41. package/dist/cluster/slave-connector.d.ts +40 -4
  42. package/dist/cluster/slave-connector.d.ts.map +1 -1
  43. package/dist/cluster/slave-connector.js +348 -195
  44. package/dist/cluster/slave-connector.js.map +1 -1
  45. package/dist/cluster/standalone-infrastructure.d.ts +3 -0
  46. package/dist/cluster/standalone-infrastructure.d.ts.map +1 -0
  47. package/dist/cluster/standalone-infrastructure.js +25 -0
  48. package/dist/cluster/standalone-infrastructure.js.map +1 -0
  49. package/dist/cluster/stop-authority.d.ts +45 -0
  50. package/dist/cluster/stop-authority.d.ts.map +1 -0
  51. package/dist/cluster/stop-authority.js +112 -0
  52. package/dist/cluster/stop-authority.js.map +1 -0
  53. package/dist/commands/access.d.ts +9 -0
  54. package/dist/commands/access.d.ts.map +1 -0
  55. package/dist/commands/access.js +45 -0
  56. package/dist/commands/access.js.map +1 -0
  57. package/dist/commands/audit.d.ts +2 -0
  58. package/dist/commands/audit.d.ts.map +1 -1
  59. package/dist/commands/audit.js +9 -4
  60. package/dist/commands/audit.js.map +1 -1
  61. package/dist/commands/backend.d.ts +17 -0
  62. package/dist/commands/backend.d.ts.map +1 -0
  63. package/dist/commands/backend.js +264 -0
  64. package/dist/commands/backend.js.map +1 -0
  65. package/dist/commands/backup.d.ts +5 -0
  66. package/dist/commands/backup.d.ts.map +1 -1
  67. package/dist/commands/backup.js +17 -2
  68. package/dist/commands/backup.js.map +1 -1
  69. package/dist/commands/cluster.d.ts.map +1 -1
  70. package/dist/commands/cluster.js +33 -42
  71. package/dist/commands/cluster.js.map +1 -1
  72. package/dist/commands/daemon-cmd.d.ts.map +1 -1
  73. package/dist/commands/daemon-cmd.js +14 -3
  74. package/dist/commands/daemon-cmd.js.map +1 -1
  75. package/dist/commands/doctor.d.ts +11 -29
  76. package/dist/commands/doctor.d.ts.map +1 -1
  77. package/dist/commands/doctor.js +47 -45
  78. package/dist/commands/doctor.js.map +1 -1
  79. package/dist/commands/files.d.ts +19 -0
  80. package/dist/commands/files.d.ts.map +1 -0
  81. package/dist/commands/files.js +226 -0
  82. package/dist/commands/files.js.map +1 -0
  83. package/dist/commands/fleet-rollout.d.ts +25 -0
  84. package/dist/commands/fleet-rollout.d.ts.map +1 -0
  85. package/dist/commands/fleet-rollout.js +155 -0
  86. package/dist/commands/fleet-rollout.js.map +1 -0
  87. package/dist/commands/fleet.d.ts.map +1 -1
  88. package/dist/commands/fleet.js +1 -0
  89. package/dist/commands/fleet.js.map +1 -1
  90. package/dist/commands/health-check.d.ts.map +1 -1
  91. package/dist/commands/health-check.js +13 -6
  92. package/dist/commands/health-check.js.map +1 -1
  93. package/dist/commands/infra.d.ts +5 -2
  94. package/dist/commands/infra.d.ts.map +1 -1
  95. package/dist/commands/infra.js +145 -53
  96. package/dist/commands/infra.js.map +1 -1
  97. package/dist/commands/logs.d.ts +6 -23
  98. package/dist/commands/logs.d.ts.map +1 -1
  99. package/dist/commands/logs.js +114 -38
  100. package/dist/commands/logs.js.map +1 -1
  101. package/dist/commands/metrics.d.ts.map +1 -1
  102. package/dist/commands/metrics.js +7 -1
  103. package/dist/commands/metrics.js.map +1 -1
  104. package/dist/commands/migrate.d.ts +8 -0
  105. package/dist/commands/migrate.d.ts.map +1 -0
  106. package/dist/commands/migrate.js +64 -0
  107. package/dist/commands/migrate.js.map +1 -0
  108. package/dist/commands/node-reconcile.d.ts +8 -0
  109. package/dist/commands/node-reconcile.d.ts.map +1 -0
  110. package/dist/commands/node-reconcile.js +49 -0
  111. package/dist/commands/node-reconcile.js.map +1 -0
  112. package/dist/commands/node.d.ts +0 -8
  113. package/dist/commands/node.d.ts.map +1 -1
  114. package/dist/commands/node.js +32 -35
  115. package/dist/commands/node.js.map +1 -1
  116. package/dist/commands/output.d.ts +3 -9
  117. package/dist/commands/output.d.ts.map +1 -1
  118. package/dist/commands/output.js +34 -25
  119. package/dist/commands/output.js.map +1 -1
  120. package/dist/commands/pipeline.d.ts +11 -2
  121. package/dist/commands/pipeline.d.ts.map +1 -1
  122. package/dist/commands/pipeline.js +75 -15
  123. package/dist/commands/pipeline.js.map +1 -1
  124. package/dist/commands/project.d.ts +8 -0
  125. package/dist/commands/project.d.ts.map +1 -1
  126. package/dist/commands/project.js +67 -1
  127. package/dist/commands/project.js.map +1 -1
  128. package/dist/commands/release-store.js +1 -1
  129. package/dist/commands/release-store.js.map +1 -1
  130. package/dist/commands/release.d.ts +5 -12
  131. package/dist/commands/release.d.ts.map +1 -1
  132. package/dist/commands/release.js +141 -33
  133. package/dist/commands/release.js.map +1 -1
  134. package/dist/commands/scale.d.ts +1 -4
  135. package/dist/commands/scale.d.ts.map +1 -1
  136. package/dist/commands/scale.js +39 -19
  137. package/dist/commands/scale.js.map +1 -1
  138. package/dist/commands/secret-input.d.ts +3 -0
  139. package/dist/commands/secret-input.d.ts.map +1 -0
  140. package/dist/commands/secret-input.js +36 -0
  141. package/dist/commands/secret-input.js.map +1 -0
  142. package/dist/commands/secret.d.ts +4 -2
  143. package/dist/commands/secret.d.ts.map +1 -1
  144. package/dist/commands/secret.js +12 -2
  145. package/dist/commands/secret.js.map +1 -1
  146. package/dist/commands/service-resident.d.ts +25 -0
  147. package/dist/commands/service-resident.d.ts.map +1 -0
  148. package/dist/commands/service-resident.js +236 -0
  149. package/dist/commands/service-resident.js.map +1 -0
  150. package/dist/commands/service-units.d.ts +13 -1
  151. package/dist/commands/service-units.d.ts.map +1 -1
  152. package/dist/commands/service-units.js +38 -16
  153. package/dist/commands/service-units.js.map +1 -1
  154. package/dist/commands/service.d.ts +2 -24
  155. package/dist/commands/service.d.ts.map +1 -1
  156. package/dist/commands/service.js +89 -7
  157. package/dist/commands/service.js.map +1 -1
  158. package/dist/commands/stack.d.ts +11 -6
  159. package/dist/commands/stack.d.ts.map +1 -1
  160. package/dist/commands/stack.js +212 -38
  161. package/dist/commands/stack.js.map +1 -1
  162. package/dist/commands/start.d.ts +0 -21
  163. package/dist/commands/start.d.ts.map +1 -1
  164. package/dist/commands/start.js +33 -43
  165. package/dist/commands/start.js.map +1 -1
  166. package/dist/commands/status.d.ts +1 -5
  167. package/dist/commands/status.d.ts.map +1 -1
  168. package/dist/commands/status.js +5 -1
  169. package/dist/commands/status.js.map +1 -1
  170. package/dist/commands/stop.d.ts +0 -22
  171. package/dist/commands/stop.d.ts.map +1 -1
  172. package/dist/commands/stop.js +26 -86
  173. package/dist/commands/stop.js.map +1 -1
  174. package/dist/commands/system.d.ts +4 -0
  175. package/dist/commands/system.d.ts.map +1 -0
  176. package/dist/commands/system.js +41 -0
  177. package/dist/commands/system.js.map +1 -0
  178. package/dist/commands/terminal.d.ts +7 -0
  179. package/dist/commands/terminal.d.ts.map +1 -0
  180. package/dist/commands/terminal.js +184 -0
  181. package/dist/commands/terminal.js.map +1 -0
  182. package/dist/commands/topology.d.ts +3 -0
  183. package/dist/commands/topology.d.ts.map +1 -0
  184. package/dist/commands/topology.js +107 -0
  185. package/dist/commands/topology.js.map +1 -0
  186. package/dist/commands/up.d.ts +4 -54
  187. package/dist/commands/up.d.ts.map +1 -1
  188. package/dist/commands/up.js +41 -98
  189. package/dist/commands/up.js.map +1 -1
  190. package/dist/commands/webapp.d.ts +0 -9
  191. package/dist/commands/webapp.d.ts.map +1 -1
  192. package/dist/commands/webapp.js +116 -69
  193. package/dist/commands/webapp.js.map +1 -1
  194. package/dist/config/app-path.d.ts +4 -0
  195. package/dist/config/app-path.d.ts.map +1 -0
  196. package/dist/config/app-path.js +6 -0
  197. package/dist/config/app-path.js.map +1 -0
  198. package/dist/config/defaults.d.ts.map +1 -1
  199. package/dist/config/defaults.js +9 -3
  200. package/dist/config/defaults.js.map +1 -1
  201. package/dist/config/define-ecosystem.d.ts.map +1 -1
  202. package/dist/config/define-ecosystem.js +12 -0
  203. package/dist/config/define-ecosystem.js.map +1 -1
  204. package/dist/config/index.d.ts +3 -1
  205. package/dist/config/index.d.ts.map +1 -1
  206. package/dist/config/index.js +1 -1
  207. package/dist/config/index.js.map +1 -1
  208. package/dist/config/loader-child.d.ts +2 -0
  209. package/dist/config/loader-child.d.ts.map +1 -0
  210. package/dist/config/loader-child.js +56 -0
  211. package/dist/config/loader-child.js.map +1 -0
  212. package/dist/config/loader.d.ts +7 -2
  213. package/dist/config/loader.d.ts.map +1 -1
  214. package/dist/config/loader.js +14 -27
  215. package/dist/config/loader.js.map +1 -1
  216. package/dist/config/saved.d.ts +67 -0
  217. package/dist/config/saved.d.ts.map +1 -0
  218. package/dist/config/saved.js +81 -0
  219. package/dist/config/saved.js.map +1 -0
  220. package/dist/config/types.d.ts +96 -52
  221. package/dist/config/types.d.ts.map +1 -1
  222. package/dist/daemon/backend-candidate.d.ts +32 -0
  223. package/dist/daemon/backend-candidate.d.ts.map +1 -0
  224. package/dist/daemon/backend-candidate.js +129 -0
  225. package/dist/daemon/backend-candidate.js.map +1 -0
  226. package/dist/daemon/backend-child.d.ts +5 -0
  227. package/dist/daemon/backend-child.d.ts.map +1 -0
  228. package/dist/daemon/backend-child.js +13 -0
  229. package/dist/daemon/backend-child.js.map +1 -0
  230. package/dist/daemon/backend-control.d.ts +43 -0
  231. package/dist/daemon/backend-control.d.ts.map +1 -0
  232. package/dist/daemon/backend-control.js +155 -0
  233. package/dist/daemon/backend-control.js.map +1 -0
  234. package/dist/daemon/backend-crash-recovery.d.ts +4 -0
  235. package/dist/daemon/backend-crash-recovery.d.ts.map +1 -0
  236. package/dist/daemon/backend-crash-recovery.js +136 -0
  237. package/dist/daemon/backend-crash-recovery.js.map +1 -0
  238. package/dist/daemon/backend-handoff-types.d.ts +27 -0
  239. package/dist/daemon/backend-handoff-types.d.ts.map +1 -0
  240. package/dist/daemon/backend-handoff-types.js +33 -0
  241. package/dist/daemon/backend-handoff-types.js.map +1 -0
  242. package/dist/daemon/backend-recovery-journal.d.ts +30 -0
  243. package/dist/daemon/backend-recovery-journal.d.ts.map +1 -0
  244. package/dist/daemon/backend-recovery-journal.js +67 -0
  245. package/dist/daemon/backend-recovery-journal.js.map +1 -0
  246. package/dist/daemon/backend-recovery-monitor.d.ts +35 -0
  247. package/dist/daemon/backend-recovery-monitor.d.ts.map +1 -0
  248. package/dist/daemon/backend-recovery-monitor.js +113 -0
  249. package/dist/daemon/backend-recovery-monitor.js.map +1 -0
  250. package/dist/daemon/backend-supervisor-entry.d.ts +2 -0
  251. package/dist/daemon/backend-supervisor-entry.d.ts.map +1 -0
  252. package/dist/daemon/backend-supervisor-entry.js +3 -0
  253. package/dist/daemon/backend-supervisor-entry.js.map +1 -0
  254. package/dist/daemon/backend-supervisor-main.d.ts +2 -0
  255. package/dist/daemon/backend-supervisor-main.d.ts.map +1 -0
  256. package/dist/daemon/backend-supervisor-main.js +45 -0
  257. package/dist/daemon/backend-supervisor-main.js.map +1 -0
  258. package/dist/daemon/backend-supervisor.d.ts +61 -0
  259. package/dist/daemon/backend-supervisor.d.ts.map +1 -0
  260. package/dist/daemon/backend-supervisor.js +339 -0
  261. package/dist/daemon/backend-supervisor.js.map +1 -0
  262. package/dist/daemon/backend-upgrade.d.ts +41 -0
  263. package/dist/daemon/backend-upgrade.d.ts.map +1 -0
  264. package/dist/daemon/backend-upgrade.js +444 -0
  265. package/dist/daemon/backend-upgrade.js.map +1 -0
  266. package/dist/daemon/backend.rpc-service.d.ts +11 -0
  267. package/dist/daemon/backend.rpc-service.d.ts.map +1 -0
  268. package/dist/daemon/backend.rpc-service.js +44 -0
  269. package/dist/daemon/backend.rpc-service.js.map +1 -0
  270. package/dist/daemon/daemon-client.d.ts +12 -79
  271. package/dist/daemon/daemon-client.d.ts.map +1 -1
  272. package/dist/daemon/daemon-client.js +28 -270
  273. package/dist/daemon/daemon-client.js.map +1 -1
  274. package/dist/daemon/daemon-entry.d.ts +0 -7
  275. package/dist/daemon/daemon-entry.d.ts.map +1 -1
  276. package/dist/daemon/daemon-entry.js +2 -115
  277. package/dist/daemon/daemon-entry.js.map +1 -1
  278. package/dist/daemon/daemon-main.d.ts +9 -0
  279. package/dist/daemon/daemon-main.d.ts.map +1 -0
  280. package/dist/daemon/daemon-main.js +105 -0
  281. package/dist/daemon/daemon-main.js.map +1 -0
  282. package/dist/daemon/daemon-scheduler.d.ts +8 -5
  283. package/dist/daemon/daemon-scheduler.d.ts.map +1 -1
  284. package/dist/daemon/daemon-scheduler.js +45 -73
  285. package/dist/daemon/daemon-scheduler.js.map +1 -1
  286. package/dist/daemon/daemon-state-store.service.d.ts +5 -39
  287. package/dist/daemon/daemon-state-store.service.d.ts.map +1 -1
  288. package/dist/daemon/daemon-state-store.service.js +30 -17
  289. package/dist/daemon/daemon-state-store.service.js.map +1 -1
  290. package/dist/daemon/daemon.d.ts +45 -60
  291. package/dist/daemon/daemon.d.ts.map +1 -1
  292. package/dist/daemon/daemon.js +720 -396
  293. package/dist/daemon/daemon.js.map +1 -1
  294. package/dist/daemon/daemon.module.d.ts +13 -11
  295. package/dist/daemon/daemon.module.d.ts.map +1 -1
  296. package/dist/daemon/daemon.module.js +136 -101
  297. package/dist/daemon/daemon.module.js.map +1 -1
  298. package/dist/daemon/daemon.rpc-service.d.ts +9 -17
  299. package/dist/daemon/daemon.rpc-service.d.ts.map +1 -1
  300. package/dist/daemon/daemon.rpc-service.js +83 -22
  301. package/dist/daemon/daemon.rpc-service.js.map +1 -1
  302. package/dist/daemon/darwin-owner-evidence.d.ts +57 -0
  303. package/dist/daemon/darwin-owner-evidence.d.ts.map +1 -0
  304. package/dist/daemon/darwin-owner-evidence.js +131 -0
  305. package/dist/daemon/darwin-owner-evidence.js.map +1 -0
  306. package/dist/daemon/database-startup.d.ts +7 -0
  307. package/dist/daemon/database-startup.d.ts.map +1 -0
  308. package/dist/daemon/database-startup.js +40 -0
  309. package/dist/daemon/database-startup.js.map +1 -0
  310. package/dist/daemon/entry-guard.d.ts +2 -0
  311. package/dist/daemon/entry-guard.d.ts.map +1 -0
  312. package/dist/daemon/entry-guard.js +34 -0
  313. package/dist/daemon/entry-guard.js.map +1 -0
  314. package/dist/daemon/execution-capabilities.d.ts +7 -0
  315. package/dist/daemon/execution-capabilities.d.ts.map +1 -0
  316. package/dist/daemon/execution-capabilities.js +23 -0
  317. package/dist/daemon/execution-capabilities.js.map +1 -0
  318. package/dist/daemon/execution-client.d.ts +88 -0
  319. package/dist/daemon/execution-client.d.ts.map +1 -0
  320. package/dist/daemon/execution-client.js +433 -0
  321. package/dist/daemon/execution-client.js.map +1 -0
  322. package/dist/daemon/execution-config.d.ts +7 -0
  323. package/dist/daemon/execution-config.d.ts.map +1 -0
  324. package/dist/daemon/execution-config.js +61 -0
  325. package/dist/daemon/execution-config.js.map +1 -0
  326. package/dist/daemon/execution-entry.d.ts +2 -0
  327. package/dist/daemon/execution-entry.d.ts.map +1 -0
  328. package/dist/daemon/execution-entry.js +3 -0
  329. package/dist/daemon/execution-entry.js.map +1 -0
  330. package/dist/daemon/execution-host.d.ts +133 -0
  331. package/dist/daemon/execution-host.d.ts.map +1 -0
  332. package/dist/daemon/execution-host.js +308 -0
  333. package/dist/daemon/execution-host.js.map +1 -0
  334. package/dist/daemon/execution-journal.d.ts +17 -0
  335. package/dist/daemon/execution-journal.d.ts.map +1 -0
  336. package/dist/daemon/execution-journal.js +75 -0
  337. package/dist/daemon/execution-journal.js.map +1 -0
  338. package/dist/daemon/execution-launcher.d.ts +12 -0
  339. package/dist/daemon/execution-launcher.d.ts.map +1 -0
  340. package/dist/daemon/execution-launcher.js +110 -0
  341. package/dist/daemon/execution-launcher.js.map +1 -0
  342. package/dist/daemon/execution-main.d.ts +2 -0
  343. package/dist/daemon/execution-main.d.ts.map +1 -0
  344. package/dist/daemon/execution-main.js +48 -0
  345. package/dist/daemon/execution-main.js.map +1 -0
  346. package/dist/daemon/execution-owner.d.ts +16 -0
  347. package/dist/daemon/execution-owner.d.ts.map +1 -0
  348. package/dist/daemon/execution-owner.js +97 -0
  349. package/dist/daemon/execution-owner.js.map +1 -0
  350. package/dist/daemon/execution-platform.d.ts +3 -0
  351. package/dist/daemon/execution-platform.d.ts.map +1 -0
  352. package/dist/daemon/execution-platform.js +23 -0
  353. package/dist/daemon/execution-platform.js.map +1 -0
  354. package/dist/daemon/execution-shutdown.d.ts +13 -0
  355. package/dist/daemon/execution-shutdown.d.ts.map +1 -0
  356. package/dist/daemon/execution-shutdown.js +30 -0
  357. package/dist/daemon/execution-shutdown.js.map +1 -0
  358. package/dist/daemon/managed-entry.d.ts +2 -0
  359. package/dist/daemon/managed-entry.d.ts.map +1 -0
  360. package/dist/daemon/managed-entry.js +3 -0
  361. package/dist/daemon/managed-entry.js.map +1 -0
  362. package/dist/daemon/managed-main.d.ts +2 -0
  363. package/dist/daemon/managed-main.d.ts.map +1 -0
  364. package/dist/daemon/managed-main.js +29 -0
  365. package/dist/daemon/managed-main.js.map +1 -0
  366. package/dist/daemon/managed-owner-build.d.ts +17 -0
  367. package/dist/daemon/managed-owner-build.d.ts.map +1 -0
  368. package/dist/daemon/managed-owner-build.js +108 -0
  369. package/dist/daemon/managed-owner-build.js.map +1 -0
  370. package/dist/daemon/managed-owner-entry.d.ts +2 -0
  371. package/dist/daemon/managed-owner-entry.d.ts.map +1 -0
  372. package/dist/daemon/managed-owner-entry.js +3 -0
  373. package/dist/daemon/managed-owner-entry.js.map +1 -0
  374. package/dist/daemon/managed-owner-main.d.ts +2 -0
  375. package/dist/daemon/managed-owner-main.d.ts.map +1 -0
  376. package/dist/daemon/managed-owner-main.js +53 -0
  377. package/dist/daemon/managed-owner-main.js.map +1 -0
  378. package/dist/daemon/managed-runtime.d.ts +39 -0
  379. package/dist/daemon/managed-runtime.d.ts.map +1 -0
  380. package/dist/daemon/managed-runtime.js +137 -0
  381. package/dist/daemon/managed-runtime.js.map +1 -0
  382. package/dist/daemon/network-publication.d.ts +5 -0
  383. package/dist/daemon/network-publication.d.ts.map +1 -0
  384. package/dist/daemon/network-publication.js +25 -0
  385. package/dist/daemon/network-publication.js.map +1 -0
  386. package/dist/daemon/owner-reconciliation.d.ts +58 -0
  387. package/dist/daemon/owner-reconciliation.d.ts.map +1 -0
  388. package/dist/daemon/owner-reconciliation.js +265 -0
  389. package/dist/daemon/owner-reconciliation.js.map +1 -0
  390. package/dist/daemon/pid-manager.d.ts +2 -0
  391. package/dist/daemon/pid-manager.d.ts.map +1 -1
  392. package/dist/daemon/pid-manager.js +5 -0
  393. package/dist/daemon/pid-manager.js.map +1 -1
  394. package/dist/daemon/private-control-client.d.ts +8 -0
  395. package/dist/daemon/private-control-client.d.ts.map +1 -0
  396. package/dist/daemon/private-control-client.js +41 -0
  397. package/dist/daemon/private-control-client.js.map +1 -0
  398. package/dist/daemon/recovery-state.d.ts +20 -0
  399. package/dist/daemon/recovery-state.d.ts.map +1 -0
  400. package/dist/daemon/recovery-state.js +53 -0
  401. package/dist/daemon/recovery-state.js.map +1 -0
  402. package/dist/daemon/rpc-connection.d.ts +29 -0
  403. package/dist/daemon/rpc-connection.d.ts.map +1 -0
  404. package/dist/daemon/rpc-connection.js +137 -0
  405. package/dist/daemon/rpc-connection.js.map +1 -0
  406. package/dist/daemon/runtime-installation.d.ts +58 -0
  407. package/dist/daemon/runtime-installation.d.ts.map +1 -0
  408. package/dist/daemon/runtime-installation.js +346 -0
  409. package/dist/daemon/runtime-installation.js.map +1 -0
  410. package/dist/daemon/runtime-launcher.d.ts +6 -0
  411. package/dist/daemon/runtime-launcher.d.ts.map +1 -0
  412. package/dist/daemon/runtime-launcher.js +45 -0
  413. package/dist/daemon/runtime-launcher.js.map +1 -0
  414. package/dist/daemon/schema-transition.d.ts +43 -0
  415. package/dist/daemon/schema-transition.d.ts.map +1 -0
  416. package/dist/daemon/schema-transition.js +239 -0
  417. package/dist/daemon/schema-transition.js.map +1 -0
  418. package/dist/daemon/spawn-daemon.d.ts +2 -0
  419. package/dist/daemon/spawn-daemon.d.ts.map +1 -1
  420. package/dist/daemon/spawn-daemon.js +4 -0
  421. package/dist/daemon/spawn-daemon.js.map +1 -1
  422. package/dist/daemon/startup-config.d.ts +77 -0
  423. package/dist/daemon/startup-config.d.ts.map +1 -0
  424. package/dist/daemon/startup-config.js +31 -0
  425. package/dist/daemon/startup-config.js.map +1 -0
  426. package/dist/daemon/startup-failure-journal.d.ts +3 -0
  427. package/dist/daemon/startup-failure-journal.d.ts.map +1 -0
  428. package/dist/daemon/startup-failure-journal.js +29 -0
  429. package/dist/daemon/startup-failure-journal.js.map +1 -0
  430. package/dist/daemon/state-store.d.ts +16 -24
  431. package/dist/daemon/state-store.d.ts.map +1 -1
  432. package/dist/daemon/state-store.js +51 -9
  433. package/dist/daemon/state-store.js.map +1 -1
  434. package/dist/daemon/supervisor-transition.d.ts +101 -0
  435. package/dist/daemon/supervisor-transition.d.ts.map +1 -0
  436. package/dist/daemon/supervisor-transition.js +503 -0
  437. package/dist/daemon/supervisor-transition.js.map +1 -0
  438. package/dist/daemon/system-guardian-cgroup.d.ts +16 -0
  439. package/dist/daemon/system-guardian-cgroup.d.ts.map +1 -0
  440. package/dist/daemon/system-guardian-cgroup.js +202 -0
  441. package/dist/daemon/system-guardian-cgroup.js.map +1 -0
  442. package/dist/daemon/system-guardian-unit.d.ts +9 -0
  443. package/dist/daemon/system-guardian-unit.d.ts.map +1 -0
  444. package/dist/daemon/system-guardian-unit.js +41 -0
  445. package/dist/daemon/system-guardian-unit.js.map +1 -0
  446. package/dist/database/connection.d.ts.map +1 -1
  447. package/dist/database/connection.js +2 -6
  448. package/dist/database/connection.js.map +1 -1
  449. package/dist/database/log-durability.d.ts +5 -0
  450. package/dist/database/log-durability.d.ts.map +1 -0
  451. package/dist/database/log-durability.js +28 -0
  452. package/dist/database/log-durability.js.map +1 -0
  453. package/dist/database/migrate.js +2 -15
  454. package/dist/database/migrate.js.map +1 -1
  455. package/dist/database/migration-registry-compatibility.d.ts +13 -0
  456. package/dist/database/migration-registry-compatibility.d.ts.map +1 -0
  457. package/dist/database/migration-registry-compatibility.js +108 -0
  458. package/dist/database/migration-registry-compatibility.js.map +1 -0
  459. package/dist/database/migration-runner.d.ts +8 -42
  460. package/dist/database/migration-runner.d.ts.map +1 -1
  461. package/dist/database/migration-runner.js +114 -123
  462. package/dist/database/migration-runner.js.map +1 -1
  463. package/dist/database/migrations/014_replication_receipts.d.ts +5 -0
  464. package/dist/database/migrations/014_replication_receipts.d.ts.map +1 -0
  465. package/dist/database/migrations/014_replication_receipts.js +6 -0
  466. package/dist/database/migrations/014_replication_receipts.js.map +1 -0
  467. package/dist/database/migrations/015_persistent_metrics.d.ts +5 -0
  468. package/dist/database/migrations/015_persistent_metrics.d.ts.map +1 -0
  469. package/dist/database/migrations/015_persistent_metrics.js +7 -0
  470. package/dist/database/migrations/015_persistent_metrics.js.map +1 -0
  471. package/dist/database/migrations/016_cluster_lease.d.ts +4 -0
  472. package/dist/database/migrations/016_cluster_lease.d.ts.map +1 -0
  473. package/dist/database/migrations/016_cluster_lease.js +6 -0
  474. package/dist/database/migrations/016_cluster_lease.js.map +1 -0
  475. package/dist/database/migrations/index.d.ts +1 -1
  476. package/dist/database/migrations/index.d.ts.map +1 -1
  477. package/dist/database/migrations/index.js +22 -13
  478. package/dist/database/migrations/index.js.map +1 -1
  479. package/dist/database/schema-compatibility.d.ts +34 -0
  480. package/dist/database/schema-compatibility.d.ts.map +1 -0
  481. package/dist/database/schema-compatibility.js +109 -0
  482. package/dist/database/schema-compatibility.js.map +1 -0
  483. package/dist/database/schema-expansion-policy.d.ts +10 -0
  484. package/dist/database/schema-expansion-policy.d.ts.map +1 -0
  485. package/dist/database/schema-expansion-policy.js +21 -0
  486. package/dist/database/schema-expansion-policy.js.map +1 -0
  487. package/dist/database/schema-transition-plan.d.ts +53 -0
  488. package/dist/database/schema-transition-plan.d.ts.map +1 -0
  489. package/dist/database/schema-transition-plan.js +102 -0
  490. package/dist/database/schema-transition-plan.js.map +1 -0
  491. package/dist/database/schema-worker.d.ts +2 -0
  492. package/dist/database/schema-worker.d.ts.map +1 -0
  493. package/dist/database/schema-worker.js +55 -0
  494. package/dist/database/schema-worker.js.map +1 -0
  495. package/dist/database/schema.d.ts +6 -1
  496. package/dist/database/schema.d.ts.map +1 -1
  497. package/dist/database/slave-migrations/001_replication_evidence.d.ts +4 -0
  498. package/dist/database/slave-migrations/001_replication_evidence.d.ts.map +1 -0
  499. package/dist/database/slave-migrations/001_replication_evidence.js +89 -0
  500. package/dist/database/slave-migrations/001_replication_evidence.js.map +1 -0
  501. package/dist/database/slave-migrations/index.d.ts +6 -0
  502. package/dist/database/slave-migrations/index.d.ts.map +1 -0
  503. package/dist/database/slave-migrations/index.js +10 -0
  504. package/dist/database/slave-migrations/index.js.map +1 -0
  505. package/dist/diagnostics/index.d.ts +16 -0
  506. package/dist/diagnostics/index.d.ts.map +1 -0
  507. package/dist/diagnostics/index.js +22 -0
  508. package/dist/diagnostics/index.js.map +1 -0
  509. package/dist/execution/command-failure.d.ts +7 -0
  510. package/dist/execution/command-failure.d.ts.map +1 -0
  511. package/dist/execution/command-failure.js +29 -0
  512. package/dist/execution/command-failure.js.map +1 -0
  513. package/dist/execution/execution.service.d.ts +6 -1
  514. package/dist/execution/execution.service.d.ts.map +1 -1
  515. package/dist/execution/execution.service.js +32 -30
  516. package/dist/execution/execution.service.js.map +1 -1
  517. package/dist/files/archive-codec.d.ts +57 -0
  518. package/dist/files/archive-codec.d.ts.map +1 -0
  519. package/dist/files/archive-codec.js +454 -0
  520. package/dist/files/archive-codec.js.map +1 -0
  521. package/dist/files/archive-node.d.ts +27 -0
  522. package/dist/files/archive-node.d.ts.map +1 -0
  523. package/dist/files/archive-node.js +379 -0
  524. package/dist/files/archive-node.js.map +1 -0
  525. package/dist/files/archive-publication.d.ts +26 -0
  526. package/dist/files/archive-publication.d.ts.map +1 -0
  527. package/dist/files/archive-publication.js +224 -0
  528. package/dist/files/archive-publication.js.map +1 -0
  529. package/dist/files/file-config.d.ts +7 -0
  530. package/dist/files/file-config.d.ts.map +1 -0
  531. package/dist/files/file-config.js +11 -0
  532. package/dist/files/file-config.js.map +1 -0
  533. package/dist/files/file-node.d.ts +65 -0
  534. package/dist/files/file-node.d.ts.map +1 -0
  535. package/dist/files/file-node.js +863 -0
  536. package/dist/files/file-node.js.map +1 -0
  537. package/dist/files/file-node.rpc-service.d.ts +12 -0
  538. package/dist/files/file-node.rpc-service.d.ts.map +1 -0
  539. package/dist/files/file-node.rpc-service.js +42 -0
  540. package/dist/files/file-node.rpc-service.js.map +1 -0
  541. package/dist/files/files.rpc-service.d.ts +107 -0
  542. package/dist/files/files.rpc-service.d.ts.map +1 -0
  543. package/dist/files/files.rpc-service.js +769 -0
  544. package/dist/files/files.rpc-service.js.map +1 -0
  545. package/dist/files/structural-policy.d.ts +3 -0
  546. package/dist/files/structural-policy.d.ts.map +1 -0
  547. package/dist/files/structural-policy.js +27 -0
  548. package/dist/files/structural-policy.js.map +1 -0
  549. package/dist/health/contracts.d.ts +30 -0
  550. package/dist/health/contracts.d.ts.map +1 -0
  551. package/dist/health/contracts.js +58 -0
  552. package/dist/health/contracts.js.map +1 -0
  553. package/dist/health/heartbeat.d.ts +11 -0
  554. package/dist/health/heartbeat.d.ts.map +1 -0
  555. package/dist/health/heartbeat.js +32 -0
  556. package/dist/health/heartbeat.js.map +1 -0
  557. package/dist/health/index.d.ts +4 -0
  558. package/dist/health/index.d.ts.map +1 -0
  559. package/dist/health/index.js +2 -0
  560. package/dist/health/index.js.map +1 -0
  561. package/dist/health/readiness.d.ts +15 -0
  562. package/dist/health/readiness.d.ts.map +1 -0
  563. package/dist/health/readiness.js +170 -0
  564. package/dist/health/readiness.js.map +1 -0
  565. package/dist/index.d.ts +1 -0
  566. package/dist/index.d.ts.map +1 -1
  567. package/dist/infrastructure/apt-packages.d.ts +34 -0
  568. package/dist/infrastructure/apt-packages.d.ts.map +1 -0
  569. package/dist/infrastructure/apt-packages.js +232 -0
  570. package/dist/infrastructure/apt-packages.js.map +1 -0
  571. package/dist/infrastructure/bare-metal-plan.d.ts +10 -1
  572. package/dist/infrastructure/bare-metal-plan.d.ts.map +1 -1
  573. package/dist/infrastructure/bare-metal-plan.js +21 -0
  574. package/dist/infrastructure/bare-metal-plan.js.map +1 -1
  575. package/dist/infrastructure/bare-metal-runner.d.ts.map +1 -1
  576. package/dist/infrastructure/bare-metal-runner.js +13 -2
  577. package/dist/infrastructure/bare-metal-runner.js.map +1 -1
  578. package/dist/infrastructure/config-normalizer.d.ts +4 -3
  579. package/dist/infrastructure/config-normalizer.d.ts.map +1 -1
  580. package/dist/infrastructure/config-normalizer.js +11 -3
  581. package/dist/infrastructure/config-normalizer.js.map +1 -1
  582. package/dist/infrastructure/container-runtime.d.ts +37 -3
  583. package/dist/infrastructure/container-runtime.d.ts.map +1 -1
  584. package/dist/infrastructure/container-runtime.js +235 -64
  585. package/dist/infrastructure/container-runtime.js.map +1 -1
  586. package/dist/infrastructure/health-recovery.d.ts +19 -0
  587. package/dist/infrastructure/health-recovery.d.ts.map +1 -0
  588. package/dist/infrastructure/health-recovery.js +39 -0
  589. package/dist/infrastructure/health-recovery.js.map +1 -0
  590. package/dist/infrastructure/host-ingress-config.d.ts.map +1 -1
  591. package/dist/infrastructure/host-ingress-config.js +11 -8
  592. package/dist/infrastructure/host-ingress-config.js.map +1 -1
  593. package/dist/infrastructure/host-ingress-lock.d.ts +2 -3
  594. package/dist/infrastructure/host-ingress-lock.d.ts.map +1 -1
  595. package/dist/infrastructure/host-ingress-lock.js +1 -35
  596. package/dist/infrastructure/host-ingress-lock.js.map +1 -1
  597. package/dist/infrastructure/host-ingress-takeover.js +3 -3
  598. package/dist/infrastructure/host-ingress-takeover.js.map +1 -1
  599. package/dist/infrastructure/host-ingress-types.d.ts +4 -2
  600. package/dist/infrastructure/host-ingress-types.d.ts.map +1 -1
  601. package/dist/infrastructure/host-ingress.service.d.ts.map +1 -1
  602. package/dist/infrastructure/host-ingress.service.js +6 -6
  603. package/dist/infrastructure/host-ingress.service.js.map +1 -1
  604. package/dist/infrastructure/host-inspection.d.ts +1 -0
  605. package/dist/infrastructure/host-inspection.d.ts.map +1 -1
  606. package/dist/infrastructure/host-inspection.js +3 -2
  607. package/dist/infrastructure/host-inspection.js.map +1 -1
  608. package/dist/infrastructure/infrastructure.service.d.ts +80 -29
  609. package/dist/infrastructure/infrastructure.service.d.ts.map +1 -1
  610. package/dist/infrastructure/infrastructure.service.js +561 -216
  611. package/dist/infrastructure/infrastructure.service.js.map +1 -1
  612. package/dist/infrastructure/merge-config.d.ts +10 -0
  613. package/dist/infrastructure/merge-config.d.ts.map +1 -0
  614. package/dist/infrastructure/merge-config.js +27 -0
  615. package/dist/infrastructure/merge-config.js.map +1 -0
  616. package/dist/infrastructure/orphan-containers.d.ts +1 -0
  617. package/dist/infrastructure/orphan-containers.d.ts.map +1 -1
  618. package/dist/infrastructure/orphan-containers.js +1 -1
  619. package/dist/infrastructure/orphan-containers.js.map +1 -1
  620. package/dist/infrastructure/owned-container.d.ts +4 -0
  621. package/dist/infrastructure/owned-container.d.ts.map +1 -0
  622. package/dist/infrastructure/owned-container.js +13 -0
  623. package/dist/infrastructure/owned-container.js.map +1 -0
  624. package/dist/infrastructure/phantom-endpoint-janitor.d.ts +4 -1
  625. package/dist/infrastructure/phantom-endpoint-janitor.d.ts.map +1 -1
  626. package/dist/infrastructure/phantom-endpoint-janitor.js +11 -2
  627. package/dist/infrastructure/phantom-endpoint-janitor.js.map +1 -1
  628. package/dist/infrastructure/presets/minio.d.ts.map +1 -1
  629. package/dist/infrastructure/presets/minio.js +15 -25
  630. package/dist/infrastructure/presets/minio.js.map +1 -1
  631. package/dist/infrastructure/presets/postgres.d.ts.map +1 -1
  632. package/dist/infrastructure/presets/postgres.js +35 -31
  633. package/dist/infrastructure/presets/postgres.js.map +1 -1
  634. package/dist/infrastructure/presets/tor.d.ts +1 -2
  635. package/dist/infrastructure/presets/tor.d.ts.map +1 -1
  636. package/dist/infrastructure/presets/tor.js +7 -13
  637. package/dist/infrastructure/presets/tor.js.map +1 -1
  638. package/dist/infrastructure/provisioning-outcome.d.ts +7 -0
  639. package/dist/infrastructure/provisioning-outcome.d.ts.map +1 -1
  640. package/dist/infrastructure/provisioning-outcome.js +41 -8
  641. package/dist/infrastructure/provisioning-outcome.js.map +1 -1
  642. package/dist/infrastructure/service-resolver.d.ts +1 -1
  643. package/dist/infrastructure/service-resolver.d.ts.map +1 -1
  644. package/dist/infrastructure/service-resolver.js +22 -10
  645. package/dist/infrastructure/service-resolver.js.map +1 -1
  646. package/dist/infrastructure/stack-infra-manager.d.ts +25 -4
  647. package/dist/infrastructure/stack-infra-manager.d.ts.map +1 -1
  648. package/dist/infrastructure/stack-infra-manager.js +181 -21
  649. package/dist/infrastructure/stack-infra-manager.js.map +1 -1
  650. package/dist/infrastructure/types.d.ts +60 -3
  651. package/dist/infrastructure/types.d.ts.map +1 -1
  652. package/dist/mcp/mcp-bridge.js +1 -1
  653. package/dist/mcp/mcp-bridge.js.map +1 -1
  654. package/dist/mcp/monitoring-reading.d.ts +18 -0
  655. package/dist/mcp/monitoring-reading.d.ts.map +1 -0
  656. package/dist/mcp/monitoring-reading.js +84 -0
  657. package/dist/mcp/monitoring-reading.js.map +1 -0
  658. package/dist/mcp/tool-groups/apps.tools.d.ts.map +1 -1
  659. package/dist/mcp/tool-groups/apps.tools.js +6 -4
  660. package/dist/mcp/tool-groups/apps.tools.js.map +1 -1
  661. package/dist/mcp/tool-groups/management.tools.d.ts +2 -0
  662. package/dist/mcp/tool-groups/management.tools.d.ts.map +1 -1
  663. package/dist/mcp/tool-groups/management.tools.js +17 -38
  664. package/dist/mcp/tool-groups/management.tools.js.map +1 -1
  665. package/dist/mcp/tool-groups/monitoring.tools.d.ts.map +1 -1
  666. package/dist/mcp/tool-groups/monitoring.tools.js +45 -2
  667. package/dist/mcp/tool-groups/monitoring.tools.js.map +1 -1
  668. package/dist/mcp/unavailable-tools.js +2 -2
  669. package/dist/mcp/unavailable-tools.js.map +1 -1
  670. package/dist/migration/configuration.d.ts +8 -0
  671. package/dist/migration/configuration.d.ts.map +1 -0
  672. package/dist/migration/configuration.js +16 -0
  673. package/dist/migration/configuration.js.map +1 -0
  674. package/dist/migration/index.d.ts +25 -0
  675. package/dist/migration/index.d.ts.map +1 -0
  676. package/dist/migration/index.js +27 -0
  677. package/dist/migration/index.js.map +1 -0
  678. package/dist/migration/operation.d.ts +31 -0
  679. package/dist/migration/operation.d.ts.map +1 -0
  680. package/dist/migration/operation.js +67 -0
  681. package/dist/migration/operation.js.map +1 -0
  682. package/dist/migration/workspace.d.ts +28 -0
  683. package/dist/migration/workspace.d.ts.map +1 -0
  684. package/dist/migration/workspace.js +91 -0
  685. package/dist/migration/workspace.js.map +1 -0
  686. package/dist/monitoring/app-health.indicator.d.ts +1 -1
  687. package/dist/monitoring/app-health.indicator.d.ts.map +1 -1
  688. package/dist/monitoring/docker-health.indicator.d.ts +4 -2
  689. package/dist/monitoring/docker-health.indicator.d.ts.map +1 -1
  690. package/dist/monitoring/docker-health.indicator.js +66 -5
  691. package/dist/monitoring/docker-health.indicator.js.map +1 -1
  692. package/dist/monitoring/event-loop-watch.d.ts.map +1 -1
  693. package/dist/monitoring/event-loop-watch.js.map +1 -1
  694. package/dist/monitoring/infrastructure-health.d.ts +15 -0
  695. package/dist/monitoring/infrastructure-health.d.ts.map +1 -0
  696. package/dist/monitoring/infrastructure-health.js +2 -0
  697. package/dist/monitoring/infrastructure-health.js.map +1 -0
  698. package/dist/monitoring/log-entry.d.ts +7 -0
  699. package/dist/monitoring/log-entry.d.ts.map +1 -0
  700. package/dist/monitoring/log-entry.js +16 -0
  701. package/dist/monitoring/log-entry.js.map +1 -0
  702. package/dist/monitoring/log-journal.d.ts +40 -0
  703. package/dist/monitoring/log-journal.d.ts.map +1 -0
  704. package/dist/monitoring/log-journal.js +158 -0
  705. package/dist/monitoring/log-journal.js.map +1 -0
  706. package/dist/monitoring/log-line.d.ts +19 -14
  707. package/dist/monitoring/log-line.d.ts.map +1 -1
  708. package/dist/monitoring/log-line.js +70 -59
  709. package/dist/monitoring/log-line.js.map +1 -1
  710. package/dist/monitoring/log-manager.d.ts +34 -37
  711. package/dist/monitoring/log-manager.d.ts.map +1 -1
  712. package/dist/monitoring/log-manager.js +164 -63
  713. package/dist/monitoring/log-manager.js.map +1 -1
  714. package/dist/monitoring/log-sink-health.indicator.d.ts +10 -0
  715. package/dist/monitoring/log-sink-health.indicator.d.ts.map +1 -0
  716. package/dist/monitoring/log-sink-health.indicator.js +21 -0
  717. package/dist/monitoring/log-sink-health.indicator.js.map +1 -0
  718. package/dist/monitoring/metrics-storage.indicator.d.ts +9 -0
  719. package/dist/monitoring/metrics-storage.indicator.d.ts.map +1 -0
  720. package/dist/monitoring/metrics-storage.indicator.js +18 -0
  721. package/dist/monitoring/metrics-storage.indicator.js.map +1 -0
  722. package/dist/monitoring/process-lifetime.d.ts +11 -0
  723. package/dist/monitoring/process-lifetime.d.ts.map +1 -0
  724. package/dist/monitoring/process-lifetime.js +45 -0
  725. package/dist/monitoring/process-lifetime.js.map +1 -0
  726. package/dist/monitoring/runtime-diagnostics.d.ts +47 -0
  727. package/dist/monitoring/runtime-diagnostics.d.ts.map +1 -0
  728. package/dist/monitoring/runtime-diagnostics.js +88 -0
  729. package/dist/monitoring/runtime-diagnostics.js.map +1 -0
  730. package/dist/observability/metrics-bridge.d.ts +5 -1
  731. package/dist/observability/metrics-bridge.d.ts.map +1 -1
  732. package/dist/observability/metrics-bridge.js +11 -0
  733. package/dist/observability/metrics-bridge.js.map +1 -1
  734. package/dist/operations.d.ts +1 -0
  735. package/dist/operations.d.ts.map +1 -1
  736. package/dist/operations.js.map +1 -1
  737. package/dist/orchestrator/app-handle.d.ts +24 -6
  738. package/dist/orchestrator/app-handle.d.ts.map +1 -1
  739. package/dist/orchestrator/app-handle.js +39 -8
  740. package/dist/orchestrator/app-handle.js.map +1 -1
  741. package/dist/orchestrator/application-runtime-child.d.ts +2 -0
  742. package/dist/orchestrator/application-runtime-child.d.ts.map +1 -0
  743. package/dist/orchestrator/application-runtime-child.js +15 -0
  744. package/dist/orchestrator/application-runtime-child.js.map +1 -0
  745. package/dist/orchestrator/application-runtime-resolution.d.ts +4 -0
  746. package/dist/orchestrator/application-runtime-resolution.d.ts.map +1 -0
  747. package/dist/orchestrator/application-runtime-resolution.js +62 -0
  748. package/dist/orchestrator/application-runtime-resolution.js.map +1 -0
  749. package/dist/orchestrator/application-runtime.d.ts +3 -0
  750. package/dist/orchestrator/application-runtime.d.ts.map +1 -0
  751. package/dist/orchestrator/application-runtime.js +20 -0
  752. package/dist/orchestrator/application-runtime.js.map +1 -0
  753. package/dist/orchestrator/application-topology.d.ts +20 -0
  754. package/dist/orchestrator/application-topology.d.ts.map +1 -0
  755. package/dist/orchestrator/application-topology.js +90 -0
  756. package/dist/orchestrator/application-topology.js.map +1 -0
  757. package/dist/orchestrator/bootstrap-loader-child.d.ts +1 -1
  758. package/dist/orchestrator/bootstrap-loader-child.js +7 -16
  759. package/dist/orchestrator/bootstrap-loader-child.js.map +1 -1
  760. package/dist/orchestrator/bootstrap-loader.d.ts +8 -18
  761. package/dist/orchestrator/bootstrap-loader.d.ts.map +1 -1
  762. package/dist/orchestrator/bootstrap-loader.js +21 -204
  763. package/dist/orchestrator/bootstrap-loader.js.map +1 -1
  764. package/dist/orchestrator/bootstrap-process.d.ts +5 -5
  765. package/dist/orchestrator/bootstrap-process.d.ts.map +1 -1
  766. package/dist/orchestrator/bootstrap-process.js +37 -38
  767. package/dist/orchestrator/bootstrap-process.js.map +1 -1
  768. package/dist/orchestrator/build-service.d.ts +3 -3
  769. package/dist/orchestrator/build-service.d.ts.map +1 -1
  770. package/dist/orchestrator/build-service.js +29 -80
  771. package/dist/orchestrator/build-service.js.map +1 -1
  772. package/dist/orchestrator/call-exposed-service.d.ts +8 -0
  773. package/dist/orchestrator/call-exposed-service.d.ts.map +1 -1
  774. package/dist/orchestrator/classic-launcher.d.ts +3 -2
  775. package/dist/orchestrator/classic-launcher.d.ts.map +1 -1
  776. package/dist/orchestrator/classic-launcher.js +26 -22
  777. package/dist/orchestrator/classic-launcher.js.map +1 -1
  778. package/dist/orchestrator/dependency-resolver.d.ts.map +1 -1
  779. package/dist/orchestrator/dependency-resolver.js +7 -38
  780. package/dist/orchestrator/dependency-resolver.js.map +1 -1
  781. package/dist/orchestrator/execution-contract.d.ts +67 -0
  782. package/dist/orchestrator/execution-contract.d.ts.map +1 -0
  783. package/dist/orchestrator/execution-contract.js +2 -0
  784. package/dist/orchestrator/execution-contract.js.map +1 -0
  785. package/dist/orchestrator/file-watcher.d.ts +1 -1
  786. package/dist/orchestrator/file-watcher.d.ts.map +1 -1
  787. package/dist/orchestrator/file-watcher.js +10 -3
  788. package/dist/orchestrator/file-watcher.js.map +1 -1
  789. package/dist/orchestrator/installed-execution.d.ts +7 -0
  790. package/dist/orchestrator/installed-execution.d.ts.map +1 -0
  791. package/dist/orchestrator/installed-execution.js +25 -0
  792. package/dist/orchestrator/installed-execution.js.map +1 -0
  793. package/dist/orchestrator/module-worker-process.d.ts.map +1 -1
  794. package/dist/orchestrator/module-worker-process.js +2 -1
  795. package/dist/orchestrator/module-worker-process.js.map +1 -1
  796. package/dist/orchestrator/orchestrator.service.d.ts +87 -76
  797. package/dist/orchestrator/orchestrator.service.d.ts.map +1 -1
  798. package/dist/orchestrator/orchestrator.service.js +941 -469
  799. package/dist/orchestrator/orchestrator.service.js.map +1 -1
  800. package/dist/orchestrator/process-janitor.d.ts +3 -0
  801. package/dist/orchestrator/process-janitor.d.ts.map +1 -1
  802. package/dist/orchestrator/process-janitor.js +5 -1
  803. package/dist/orchestrator/process-janitor.js.map +1 -1
  804. package/dist/orchestrator/runtime-package-resolution.d.ts +8 -0
  805. package/dist/orchestrator/runtime-package-resolution.d.ts.map +1 -0
  806. package/dist/orchestrator/runtime-package-resolution.js +56 -0
  807. package/dist/orchestrator/runtime-package-resolution.js.map +1 -0
  808. package/dist/orchestrator/service-router.d.ts +4 -108
  809. package/dist/orchestrator/service-router.d.ts.map +1 -1
  810. package/dist/orchestrator/service-router.js +51 -237
  811. package/dist/orchestrator/service-router.js.map +1 -1
  812. package/dist/orchestrator/ts-compiler.d.ts.map +1 -1
  813. package/dist/orchestrator/ts-compiler.js +9 -17
  814. package/dist/orchestrator/ts-compiler.js.map +1 -1
  815. package/dist/project/artifact-builder.d.ts +17 -7
  816. package/dist/project/artifact-builder.d.ts.map +1 -1
  817. package/dist/project/artifact-builder.js +89 -56
  818. package/dist/project/artifact-builder.js.map +1 -1
  819. package/dist/project/bootstrap-metadata.d.ts +42 -0
  820. package/dist/project/bootstrap-metadata.d.ts.map +1 -0
  821. package/dist/project/bootstrap-metadata.js +76 -0
  822. package/dist/project/bootstrap-metadata.js.map +1 -0
  823. package/dist/project/config-resolver.js +3 -3
  824. package/dist/project/config-resolver.js.map +1 -1
  825. package/dist/project/configuration-catalog.d.ts +8 -0
  826. package/dist/project/configuration-catalog.d.ts.map +1 -0
  827. package/dist/project/configuration-catalog.js +29 -0
  828. package/dist/project/configuration-catalog.js.map +1 -0
  829. package/dist/project/declared-config.d.ts +2 -0
  830. package/dist/project/declared-config.d.ts.map +1 -1
  831. package/dist/project/declared-config.js +8 -5
  832. package/dist/project/declared-config.js.map +1 -1
  833. package/dist/project/dependency-topology.d.ts +10 -0
  834. package/dist/project/dependency-topology.d.ts.map +1 -0
  835. package/dist/project/dependency-topology.js +55 -0
  836. package/dist/project/dependency-topology.js.map +1 -0
  837. package/dist/project/infrastructure-ownership.d.ts +5 -0
  838. package/dist/project/infrastructure-ownership.d.ts.map +1 -0
  839. package/dist/project/infrastructure-ownership.js +26 -0
  840. package/dist/project/infrastructure-ownership.js.map +1 -0
  841. package/dist/project/installed-stack-resume.d.ts +62 -0
  842. package/dist/project/installed-stack-resume.d.ts.map +1 -0
  843. package/dist/project/installed-stack-resume.js +261 -0
  844. package/dist/project/installed-stack-resume.js.map +1 -0
  845. package/dist/project/launch-failure.d.ts +3 -0
  846. package/dist/project/launch-failure.d.ts.map +1 -0
  847. package/dist/project/launch-failure.js +32 -0
  848. package/dist/project/launch-failure.js.map +1 -0
  849. package/dist/project/local-release-selection.d.ts +18 -0
  850. package/dist/project/local-release-selection.d.ts.map +1 -0
  851. package/dist/project/local-release-selection.js +36 -0
  852. package/dist/project/local-release-selection.js.map +1 -0
  853. package/dist/project/node-app-config.d.ts +8 -1
  854. package/dist/project/node-app-config.d.ts.map +1 -1
  855. package/dist/project/node-app-config.js +20 -28
  856. package/dist/project/node-app-config.js.map +1 -1
  857. package/dist/project/node-stack-stop.d.ts +83 -0
  858. package/dist/project/node-stack-stop.d.ts.map +1 -0
  859. package/dist/project/node-stack-stop.js +219 -0
  860. package/dist/project/node-stack-stop.js.map +1 -0
  861. package/dist/project/public-stack.d.ts +4 -0
  862. package/dist/project/public-stack.d.ts.map +1 -0
  863. package/dist/project/public-stack.js +29 -0
  864. package/dist/project/public-stack.js.map +1 -0
  865. package/dist/project/registry.d.ts +18 -27
  866. package/dist/project/registry.d.ts.map +1 -1
  867. package/dist/project/registry.js +244 -55
  868. package/dist/project/registry.js.map +1 -1
  869. package/dist/project/requirements-scanner.d.ts +4 -8
  870. package/dist/project/requirements-scanner.d.ts.map +1 -1
  871. package/dist/project/requirements-scanner.js +39 -146
  872. package/dist/project/requirements-scanner.js.map +1 -1
  873. package/dist/project/stack-diagnosis.d.ts +18 -0
  874. package/dist/project/stack-diagnosis.d.ts.map +1 -0
  875. package/dist/project/stack-diagnosis.js +94 -0
  876. package/dist/project/stack-diagnosis.js.map +1 -0
  877. package/dist/project/stack-health.d.ts +12 -0
  878. package/dist/project/stack-health.d.ts.map +1 -0
  879. package/dist/project/stack-health.js +27 -0
  880. package/dist/project/stack-health.js.map +1 -0
  881. package/dist/project/stack-observation.d.ts +8 -0
  882. package/dist/project/stack-observation.d.ts.map +1 -0
  883. package/dist/project/stack-observation.js +126 -0
  884. package/dist/project/stack-observation.js.map +1 -0
  885. package/dist/project/stack-placement.d.ts +11 -0
  886. package/dist/project/stack-placement.d.ts.map +1 -0
  887. package/dist/project/stack-placement.js +57 -0
  888. package/dist/project/stack-placement.js.map +1 -0
  889. package/dist/project/stack-stop-review.d.ts +14 -0
  890. package/dist/project/stack-stop-review.d.ts.map +1 -0
  891. package/dist/project/stack-stop-review.js +22 -0
  892. package/dist/project/stack-stop-review.js.map +1 -0
  893. package/dist/project/stack-targets.d.ts +24 -0
  894. package/dist/project/stack-targets.d.ts.map +1 -0
  895. package/dist/project/stack-targets.js +67 -0
  896. package/dist/project/stack-targets.js.map +1 -0
  897. package/dist/project/topology-control.d.ts +41 -0
  898. package/dist/project/topology-control.d.ts.map +1 -0
  899. package/dist/project/topology-control.js +133 -0
  900. package/dist/project/topology-control.js.map +1 -0
  901. package/dist/project/topology-plan.d.ts +11 -0
  902. package/dist/project/topology-plan.d.ts.map +1 -0
  903. package/dist/project/topology-plan.js +154 -0
  904. package/dist/project/topology-plan.js.map +1 -0
  905. package/dist/project/topology-services.d.ts +7 -0
  906. package/dist/project/topology-services.d.ts.map +1 -0
  907. package/dist/project/topology-services.js +36 -0
  908. package/dist/project/topology-services.js.map +1 -0
  909. package/dist/project/topology-state.d.ts +27 -0
  910. package/dist/project/topology-state.d.ts.map +1 -0
  911. package/dist/project/topology-state.js +71 -0
  912. package/dist/project/topology-state.js.map +1 -0
  913. package/dist/project/workspace-kind.d.ts +3 -0
  914. package/dist/project/workspace-kind.d.ts.map +1 -0
  915. package/dist/project/workspace-kind.js +13 -0
  916. package/dist/project/workspace-kind.js.map +1 -0
  917. package/dist/readiness.d.ts +4 -0
  918. package/dist/readiness.d.ts.map +1 -0
  919. package/dist/readiness.js +3 -0
  920. package/dist/readiness.js.map +1 -0
  921. package/dist/release/application-closure.d.ts +4 -0
  922. package/dist/release/application-closure.d.ts.map +1 -0
  923. package/dist/release/application-closure.js +61 -0
  924. package/dist/release/application-closure.js.map +1 -0
  925. package/dist/release/archive.d.ts +3 -0
  926. package/dist/release/archive.d.ts.map +1 -0
  927. package/dist/release/archive.js +3 -0
  928. package/dist/release/archive.js.map +1 -0
  929. package/dist/release/artifact-inspection.d.ts +50 -0
  930. package/dist/release/artifact-inspection.d.ts.map +1 -0
  931. package/dist/release/artifact-inspection.js +169 -0
  932. package/dist/release/artifact-inspection.js.map +1 -0
  933. package/dist/release/artifact-volumes.d.ts +10 -0
  934. package/dist/release/artifact-volumes.d.ts.map +1 -0
  935. package/dist/release/artifact-volumes.js +112 -0
  936. package/dist/release/artifact-volumes.js.map +1 -0
  937. package/dist/release/build-run.d.ts +12 -15
  938. package/dist/release/build-run.d.ts.map +1 -1
  939. package/dist/release/build-run.js +260 -73
  940. package/dist/release/build-run.js.map +1 -1
  941. package/dist/release/builder.d.ts +8 -2
  942. package/dist/release/builder.d.ts.map +1 -1
  943. package/dist/release/builder.js +18 -4
  944. package/dist/release/builder.js.map +1 -1
  945. package/dist/release/closure-library-path.d.ts +26 -0
  946. package/dist/release/closure-library-path.d.ts.map +1 -0
  947. package/dist/release/closure-library-path.js +160 -0
  948. package/dist/release/closure-library-path.js.map +1 -0
  949. package/dist/release/definition-inputs.d.ts +6 -3
  950. package/dist/release/definition-inputs.d.ts.map +1 -1
  951. package/dist/release/definition-inputs.js +145 -14
  952. package/dist/release/definition-inputs.js.map +1 -1
  953. package/dist/release/framework-source.d.ts +22 -0
  954. package/dist/release/framework-source.d.ts.map +1 -0
  955. package/dist/release/framework-source.js +54 -0
  956. package/dist/release/framework-source.js.map +1 -0
  957. package/dist/release/frozen-installation.d.ts +23 -0
  958. package/dist/release/frozen-installation.d.ts.map +1 -0
  959. package/dist/release/frozen-installation.js +159 -0
  960. package/dist/release/frozen-installation.js.map +1 -0
  961. package/dist/release/import-artifacts.d.ts +9 -0
  962. package/dist/release/import-artifacts.d.ts.map +1 -0
  963. package/dist/release/import-artifacts.js +60 -0
  964. package/dist/release/import-artifacts.js.map +1 -0
  965. package/dist/release/infrastructure.d.ts +6 -0
  966. package/dist/release/infrastructure.d.ts.map +1 -0
  967. package/dist/release/infrastructure.js +74 -0
  968. package/dist/release/infrastructure.js.map +1 -0
  969. package/dist/release/installed-artifacts.d.ts +12 -0
  970. package/dist/release/installed-artifacts.d.ts.map +1 -0
  971. package/dist/release/installed-artifacts.js +199 -0
  972. package/dist/release/installed-artifacts.js.map +1 -0
  973. package/dist/release/installed-graph.d.ts +28 -0
  974. package/dist/release/installed-graph.d.ts.map +1 -0
  975. package/dist/release/installed-graph.js +138 -0
  976. package/dist/release/installed-graph.js.map +1 -0
  977. package/dist/release/installed-origin.d.ts +42 -0
  978. package/dist/release/installed-origin.d.ts.map +1 -0
  979. package/dist/release/installed-origin.js +130 -0
  980. package/dist/release/installed-origin.js.map +1 -0
  981. package/dist/release/installed-release.d.ts +23 -0
  982. package/dist/release/installed-release.d.ts.map +1 -0
  983. package/dist/release/installed-release.js +141 -0
  984. package/dist/release/installed-release.js.map +1 -0
  985. package/dist/release/layout.d.ts +27 -32
  986. package/dist/release/layout.d.ts.map +1 -1
  987. package/dist/release/layout.js +162 -51
  988. package/dist/release/layout.js.map +1 -1
  989. package/dist/release/load.d.ts +3 -0
  990. package/dist/release/load.d.ts.map +1 -1
  991. package/dist/release/load.js +50 -8
  992. package/dist/release/load.js.map +1 -1
  993. package/dist/release/local-installation.d.ts +20 -0
  994. package/dist/release/local-installation.d.ts.map +1 -0
  995. package/dist/release/local-installation.js +298 -0
  996. package/dist/release/local-installation.js.map +1 -0
  997. package/dist/release/manifest.d.ts +87 -12
  998. package/dist/release/manifest.d.ts.map +1 -1
  999. package/dist/release/manifest.js +31 -7
  1000. package/dist/release/manifest.js.map +1 -1
  1001. package/dist/release/migration-programs.d.ts +12 -0
  1002. package/dist/release/migration-programs.d.ts.map +1 -0
  1003. package/dist/release/migration-programs.js +45 -0
  1004. package/dist/release/migration-programs.js.map +1 -0
  1005. package/dist/release/migrations.d.ts +12 -1
  1006. package/dist/release/migrations.d.ts.map +1 -1
  1007. package/dist/release/migrations.js +124 -9
  1008. package/dist/release/migrations.js.map +1 -1
  1009. package/dist/release/origin.d.ts +33 -0
  1010. package/dist/release/origin.d.ts.map +1 -0
  1011. package/dist/release/origin.js +253 -0
  1012. package/dist/release/origin.js.map +1 -0
  1013. package/dist/release/owner-admission.d.ts +15 -0
  1014. package/dist/release/owner-admission.d.ts.map +1 -0
  1015. package/dist/release/owner-admission.js +37 -0
  1016. package/dist/release/owner-admission.js.map +1 -0
  1017. package/dist/release/owner-executable.d.ts +3 -0
  1018. package/dist/release/owner-executable.d.ts.map +1 -0
  1019. package/dist/release/owner-executable.js +40 -0
  1020. package/dist/release/owner-executable.js.map +1 -0
  1021. package/dist/release/package-gates.d.ts +9 -0
  1022. package/dist/release/package-gates.d.ts.map +1 -0
  1023. package/dist/release/package-gates.js +42 -0
  1024. package/dist/release/package-gates.js.map +1 -0
  1025. package/dist/release/package-resolution.d.ts +4 -0
  1026. package/dist/release/package-resolution.d.ts.map +1 -0
  1027. package/dist/release/package-resolution.js +28 -0
  1028. package/dist/release/package-resolution.js.map +1 -0
  1029. package/dist/release/portable-archive.d.ts +12 -0
  1030. package/dist/release/portable-archive.d.ts.map +1 -0
  1031. package/dist/release/portable-archive.js +96 -0
  1032. package/dist/release/portable-archive.js.map +1 -0
  1033. package/dist/release/registry-download.d.ts +2 -0
  1034. package/dist/release/registry-download.d.ts.map +1 -0
  1035. package/dist/release/registry-download.js +157 -0
  1036. package/dist/release/registry-download.js.map +1 -0
  1037. package/dist/release/registry-framework.d.ts +39 -0
  1038. package/dist/release/registry-framework.d.ts.map +1 -0
  1039. package/dist/release/registry-framework.js +279 -0
  1040. package/dist/release/registry-framework.js.map +1 -0
  1041. package/dist/release/registry-transport.d.ts +27 -0
  1042. package/dist/release/registry-transport.d.ts.map +1 -0
  1043. package/dist/release/registry-transport.js +96 -0
  1044. package/dist/release/registry-transport.js.map +1 -0
  1045. package/dist/release/repository-identity.d.ts +12 -0
  1046. package/dist/release/repository-identity.d.ts.map +1 -0
  1047. package/dist/release/repository-identity.js +62 -0
  1048. package/dist/release/repository-identity.js.map +1 -0
  1049. package/dist/release/runtime-extractor.d.ts +4 -0
  1050. package/dist/release/runtime-extractor.d.ts.map +1 -0
  1051. package/dist/release/runtime-extractor.js +15 -0
  1052. package/dist/release/runtime-extractor.js.map +1 -0
  1053. package/dist/release/runtime-provenance.d.ts +40 -0
  1054. package/dist/release/runtime-provenance.d.ts.map +1 -0
  1055. package/dist/release/runtime-provenance.js +229 -0
  1056. package/dist/release/runtime-provenance.js.map +1 -0
  1057. package/dist/release/source.d.ts +12 -0
  1058. package/dist/release/source.d.ts.map +1 -0
  1059. package/dist/release/source.js +168 -0
  1060. package/dist/release/source.js.map +1 -0
  1061. package/dist/release/store.d.ts +13 -4
  1062. package/dist/release/store.d.ts.map +1 -1
  1063. package/dist/release/store.js +70 -14
  1064. package/dist/release/store.js.map +1 -1
  1065. package/dist/release/target-runtime.d.ts +19 -0
  1066. package/dist/release/target-runtime.d.ts.map +1 -0
  1067. package/dist/release/target-runtime.js +41 -0
  1068. package/dist/release/target-runtime.js.map +1 -0
  1069. package/dist/release/vendored-framework.d.ts +28 -0
  1070. package/dist/release/vendored-framework.d.ts.map +1 -0
  1071. package/dist/release/vendored-framework.js +98 -0
  1072. package/dist/release/vendored-framework.js.map +1 -0
  1073. package/dist/release/workspace-source.d.ts +3 -0
  1074. package/dist/release/workspace-source.d.ts.map +1 -0
  1075. package/dist/release/workspace-source.js +33 -0
  1076. package/dist/release/workspace-source.js.map +1 -0
  1077. package/dist/runtime/context.d.ts +29 -0
  1078. package/dist/runtime/context.d.ts.map +1 -0
  1079. package/dist/runtime/context.js +111 -0
  1080. package/dist/runtime/context.js.map +1 -0
  1081. package/dist/runtime/identity.d.ts +15 -0
  1082. package/dist/runtime/identity.d.ts.map +1 -0
  1083. package/dist/runtime/identity.js +33 -0
  1084. package/dist/runtime/identity.js.map +1 -0
  1085. package/dist/runtime/index.d.ts +3 -0
  1086. package/dist/runtime/index.d.ts.map +1 -0
  1087. package/dist/runtime/index.js +3 -0
  1088. package/dist/runtime/index.js.map +1 -0
  1089. package/dist/services/access.rpc-service.d.ts +41 -0
  1090. package/dist/services/access.rpc-service.d.ts.map +1 -0
  1091. package/dist/services/access.rpc-service.js +248 -0
  1092. package/dist/services/access.rpc-service.js.map +1 -0
  1093. package/dist/services/alert.service.d.ts +1 -1
  1094. package/dist/services/alert.service.d.ts.map +1 -1
  1095. package/dist/services/alert.service.js +1 -1
  1096. package/dist/services/anonymous-input.d.ts +0 -21
  1097. package/dist/services/anonymous-input.d.ts.map +1 -1
  1098. package/dist/services/anonymous-input.js +1 -27
  1099. package/dist/services/anonymous-input.js.map +1 -1
  1100. package/dist/services/audit.service.d.ts +10 -30
  1101. package/dist/services/audit.service.d.ts.map +1 -1
  1102. package/dist/services/audit.service.js +72 -18
  1103. package/dist/services/audit.service.js.map +1 -1
  1104. package/dist/services/auth-context.d.ts +2 -0
  1105. package/dist/services/auth-context.d.ts.map +1 -1
  1106. package/dist/services/auth-context.js +4 -1
  1107. package/dist/services/auth-context.js.map +1 -1
  1108. package/dist/services/auth.rpc-service.d.ts +3 -1
  1109. package/dist/services/auth.rpc-service.d.ts.map +1 -1
  1110. package/dist/services/auth.rpc-service.js +13 -3
  1111. package/dist/services/auth.rpc-service.js.map +1 -1
  1112. package/dist/services/auth.service.d.ts +11 -21
  1113. package/dist/services/auth.service.d.ts.map +1 -1
  1114. package/dist/services/auth.service.js +125 -139
  1115. package/dist/services/auth.service.js.map +1 -1
  1116. package/dist/services/backup-storage.d.ts +14 -0
  1117. package/dist/services/backup-storage.d.ts.map +1 -0
  1118. package/dist/services/backup-storage.js +195 -0
  1119. package/dist/services/backup-storage.js.map +1 -0
  1120. package/dist/services/backup.rpc-service.d.ts +2 -0
  1121. package/dist/services/backup.rpc-service.d.ts.map +1 -1
  1122. package/dist/services/backup.rpc-service.js +9 -0
  1123. package/dist/services/backup.rpc-service.js.map +1 -1
  1124. package/dist/services/backup.service.d.ts +33 -126
  1125. package/dist/services/backup.service.d.ts.map +1 -1
  1126. package/dist/services/backup.service.js +174 -153
  1127. package/dist/services/backup.service.js.map +1 -1
  1128. package/dist/services/bundle-builder.d.ts +12 -0
  1129. package/dist/services/bundle-builder.d.ts.map +1 -1
  1130. package/dist/services/bundle-builder.js +77 -62
  1131. package/dist/services/bundle-builder.js.map +1 -1
  1132. package/dist/services/bundle-overrides.d.ts +25 -0
  1133. package/dist/services/bundle-overrides.d.ts.map +1 -0
  1134. package/dist/services/bundle-overrides.js +96 -0
  1135. package/dist/services/bundle-overrides.js.map +1 -0
  1136. package/dist/services/daemon-authority.d.ts +16 -0
  1137. package/dist/services/daemon-authority.d.ts.map +1 -0
  1138. package/dist/services/daemon-authority.js +54 -0
  1139. package/dist/services/daemon-authority.js.map +1 -0
  1140. package/dist/services/daemon-principal.d.ts +31 -0
  1141. package/dist/services/daemon-principal.d.ts.map +1 -0
  1142. package/dist/services/daemon-principal.js +37 -0
  1143. package/dist/services/daemon-principal.js.map +1 -0
  1144. package/dist/services/deploy.service.d.ts +13 -57
  1145. package/dist/services/deploy.service.d.ts.map +1 -1
  1146. package/dist/services/deploy.service.js +15 -263
  1147. package/dist/services/deploy.service.js.map +1 -1
  1148. package/dist/services/event-broadcaster.rpc-service.d.ts +7 -1
  1149. package/dist/services/event-broadcaster.rpc-service.d.ts.map +1 -1
  1150. package/dist/services/event-broadcaster.rpc-service.js +89 -11
  1151. package/dist/services/event-broadcaster.rpc-service.js.map +1 -1
  1152. package/dist/services/fleet.rpc-service.d.ts +0 -6
  1153. package/dist/services/fleet.rpc-service.d.ts.map +1 -1
  1154. package/dist/services/fleet.rpc-service.js +0 -13
  1155. package/dist/services/fleet.rpc-service.js.map +1 -1
  1156. package/dist/services/health-check.service.d.ts +1 -1
  1157. package/dist/services/health-check.service.d.ts.map +1 -1
  1158. package/dist/services/health-check.service.js +30 -5
  1159. package/dist/services/health-check.service.js.map +1 -1
  1160. package/dist/services/host-upgrade.d.ts +55 -3
  1161. package/dist/services/host-upgrade.d.ts.map +1 -1
  1162. package/dist/services/host-upgrade.js +167 -16
  1163. package/dist/services/host-upgrade.js.map +1 -1
  1164. package/dist/services/infrastructure.rpc-service.d.ts +9 -2
  1165. package/dist/services/infrastructure.rpc-service.d.ts.map +1 -1
  1166. package/dist/services/infrastructure.rpc-service.js +117 -36
  1167. package/dist/services/infrastructure.rpc-service.js.map +1 -1
  1168. package/dist/services/kernel-catalog.d.ts +14 -0
  1169. package/dist/services/kernel-catalog.d.ts.map +1 -0
  1170. package/dist/services/kernel-catalog.js +172 -0
  1171. package/dist/services/kernel-catalog.js.map +1 -0
  1172. package/dist/services/kernel-distribution.d.ts +5 -0
  1173. package/dist/services/kernel-distribution.d.ts.map +1 -0
  1174. package/dist/services/kernel-distribution.js +49 -0
  1175. package/dist/services/kernel-distribution.js.map +1 -0
  1176. package/dist/services/kernel-rollout.service.d.ts +55 -0
  1177. package/dist/services/kernel-rollout.service.d.ts.map +1 -0
  1178. package/dist/services/kernel-rollout.service.js +394 -0
  1179. package/dist/services/kernel-rollout.service.js.map +1 -0
  1180. package/dist/services/local-bundle.d.ts.map +1 -1
  1181. package/dist/services/local-bundle.js +3 -1
  1182. package/dist/services/local-bundle.js.map +1 -1
  1183. package/dist/services/log-collector.rpc-service.d.ts +5 -11
  1184. package/dist/services/log-collector.rpc-service.d.ts.map +1 -1
  1185. package/dist/services/log-collector.rpc-service.js +6 -6
  1186. package/dist/services/log-collector.rpc-service.js.map +1 -1
  1187. package/dist/services/log-collector.service.d.ts +39 -109
  1188. package/dist/services/log-collector.service.d.ts.map +1 -1
  1189. package/dist/services/log-collector.service.js +286 -261
  1190. package/dist/services/log-collector.service.js.map +1 -1
  1191. package/dist/services/log-query.d.ts +6 -0
  1192. package/dist/services/log-query.d.ts.map +1 -0
  1193. package/dist/services/log-query.js +46 -0
  1194. package/dist/services/log-query.js.map +1 -0
  1195. package/dist/services/managed-rollout.d.ts +54 -0
  1196. package/dist/services/managed-rollout.d.ts.map +1 -0
  1197. package/dist/services/managed-rollout.js +124 -0
  1198. package/dist/services/managed-rollout.js.map +1 -0
  1199. package/dist/services/metrics.rpc-service.d.ts +23 -0
  1200. package/dist/services/metrics.rpc-service.d.ts.map +1 -0
  1201. package/dist/services/metrics.rpc-service.js +73 -0
  1202. package/dist/services/metrics.rpc-service.js.map +1 -0
  1203. package/dist/services/migration-process.d.ts +32 -0
  1204. package/dist/services/migration-process.d.ts.map +1 -0
  1205. package/dist/services/migration-process.js +71 -0
  1206. package/dist/services/migration-process.js.map +1 -0
  1207. package/dist/services/migration-target.d.ts +57 -0
  1208. package/dist/services/migration-target.d.ts.map +1 -0
  1209. package/dist/services/migration-target.js +221 -0
  1210. package/dist/services/migration-target.js.map +1 -0
  1211. package/dist/services/node-health.repository.d.ts +2 -59
  1212. package/dist/services/node-health.repository.d.ts.map +1 -1
  1213. package/dist/services/node-health.repository.js.map +1 -1
  1214. package/dist/services/node-host-key.d.ts +9 -0
  1215. package/dist/services/node-host-key.d.ts.map +1 -0
  1216. package/dist/services/node-host-key.js +17 -0
  1217. package/dist/services/node-host-key.js.map +1 -0
  1218. package/dist/services/node-manager.rpc-service.d.ts +44 -37
  1219. package/dist/services/node-manager.rpc-service.d.ts.map +1 -1
  1220. package/dist/services/node-manager.rpc-service.js +208 -37
  1221. package/dist/services/node-manager.rpc-service.js.map +1 -1
  1222. package/dist/services/node-manager.service.d.ts +3 -0
  1223. package/dist/services/node-manager.service.d.ts.map +1 -1
  1224. package/dist/services/node-manager.service.js +78 -27
  1225. package/dist/services/node-manager.service.js.map +1 -1
  1226. package/dist/services/node-registration.d.ts +17 -0
  1227. package/dist/services/node-registration.d.ts.map +1 -0
  1228. package/dist/services/node-registration.js +73 -0
  1229. package/dist/services/node-registration.js.map +1 -0
  1230. package/dist/services/node-upgrade.service.d.ts +2 -28
  1231. package/dist/services/node-upgrade.service.d.ts.map +1 -1
  1232. package/dist/services/node-upgrade.service.js +2 -3
  1233. package/dist/services/node-upgrade.service.js.map +1 -1
  1234. package/dist/services/pipeline-definition.d.ts +14 -0
  1235. package/dist/services/pipeline-definition.d.ts.map +1 -0
  1236. package/dist/services/pipeline-definition.js +77 -0
  1237. package/dist/services/pipeline-definition.js.map +1 -0
  1238. package/dist/services/pipeline.rpc-service.d.ts +10 -3
  1239. package/dist/services/pipeline.rpc-service.d.ts.map +1 -1
  1240. package/dist/services/pipeline.rpc-service.js +38 -14
  1241. package/dist/services/pipeline.rpc-service.js.map +1 -1
  1242. package/dist/services/pipeline.service.d.ts +30 -46
  1243. package/dist/services/pipeline.service.d.ts.map +1 -1
  1244. package/dist/services/pipeline.service.js +401 -344
  1245. package/dist/services/pipeline.service.js.map +1 -1
  1246. package/dist/services/project.rpc-service.d.ts +212 -14
  1247. package/dist/services/project.rpc-service.d.ts.map +1 -1
  1248. package/dist/services/project.rpc-service.js +303 -31
  1249. package/dist/services/project.rpc-service.js.map +1 -1
  1250. package/dist/services/project.service.d.ts +174 -56
  1251. package/dist/services/project.service.d.ts.map +1 -1
  1252. package/dist/services/project.service.js +1962 -653
  1253. package/dist/services/project.service.js.map +1 -1
  1254. package/dist/services/release.rpc-service.d.ts +5 -18
  1255. package/dist/services/release.rpc-service.d.ts.map +1 -1
  1256. package/dist/services/release.rpc-service.js +34 -11
  1257. package/dist/services/release.rpc-service.js.map +1 -1
  1258. package/dist/services/release.service.d.ts +2 -47
  1259. package/dist/services/release.service.d.ts.map +1 -1
  1260. package/dist/services/release.service.js +26 -2
  1261. package/dist/services/release.service.js.map +1 -1
  1262. package/dist/services/remote-deployer.service.d.ts +41 -113
  1263. package/dist/services/remote-deployer.service.d.ts.map +1 -1
  1264. package/dist/services/remote-deployer.service.js +415 -378
  1265. package/dist/services/remote-deployer.service.js.map +1 -1
  1266. package/dist/services/remote-provisioner.d.ts +1 -1
  1267. package/dist/services/remote-provisioner.js +1 -1
  1268. package/dist/services/replication-evidence.d.ts +24 -0
  1269. package/dist/services/replication-evidence.d.ts.map +1 -0
  1270. package/dist/services/replication-evidence.js +61 -0
  1271. package/dist/services/replication-evidence.js.map +1 -0
  1272. package/dist/services/replication-history.d.ts +80 -0
  1273. package/dist/services/replication-history.d.ts.map +1 -0
  1274. package/dist/services/replication-history.js +279 -0
  1275. package/dist/services/replication-history.js.map +1 -0
  1276. package/dist/services/replication-reconciliation.d.ts +74 -0
  1277. package/dist/services/replication-reconciliation.d.ts.map +1 -0
  1278. package/dist/services/replication-reconciliation.js +351 -0
  1279. package/dist/services/replication-reconciliation.js.map +1 -0
  1280. package/dist/services/slave-storage.service.d.ts +2 -19
  1281. package/dist/services/slave-storage.service.d.ts.map +1 -1
  1282. package/dist/services/slave-storage.service.js +19 -6
  1283. package/dist/services/slave-storage.service.js.map +1 -1
  1284. package/dist/services/static-carry-forward.d.ts +2 -2
  1285. package/dist/services/static-carry-forward.d.ts.map +1 -1
  1286. package/dist/services/static-carry-forward.js +10 -3
  1287. package/dist/services/static-carry-forward.js.map +1 -1
  1288. package/dist/services/sync-summary.d.ts.map +1 -1
  1289. package/dist/services/sync-summary.js +1 -18
  1290. package/dist/services/sync-summary.js.map +1 -1
  1291. package/dist/services/sync.rpc-service.d.ts +17 -20
  1292. package/dist/services/sync.rpc-service.d.ts.map +1 -1
  1293. package/dist/services/sync.rpc-service.js +23 -37
  1294. package/dist/services/sync.rpc-service.js.map +1 -1
  1295. package/dist/services/sync.service.d.ts +53 -157
  1296. package/dist/services/sync.service.d.ts.map +1 -1
  1297. package/dist/services/sync.service.js +239 -337
  1298. package/dist/services/sync.service.js.map +1 -1
  1299. package/dist/services/system-info.rpc-service.d.ts +3 -1
  1300. package/dist/services/system-info.rpc-service.d.ts.map +1 -1
  1301. package/dist/services/system-info.rpc-service.js +5 -5
  1302. package/dist/services/system-info.rpc-service.js.map +1 -1
  1303. package/dist/services/system-info.service.d.ts +3 -1
  1304. package/dist/services/system-info.service.d.ts.map +1 -1
  1305. package/dist/services/system-info.service.js +17 -9
  1306. package/dist/services/system-info.service.js.map +1 -1
  1307. package/dist/services/telemetry.rpc-service.d.ts +4 -23
  1308. package/dist/services/telemetry.rpc-service.d.ts.map +1 -1
  1309. package/dist/services/telemetry.rpc-service.js +4 -32
  1310. package/dist/services/telemetry.rpc-service.js.map +1 -1
  1311. package/dist/services/telemetry.service.d.ts +2 -30
  1312. package/dist/services/telemetry.service.d.ts.map +1 -1
  1313. package/dist/services/telemetry.service.js +25 -131
  1314. package/dist/services/telemetry.service.js.map +1 -1
  1315. package/dist/services/terminal-ssh.d.ts +16 -0
  1316. package/dist/services/terminal-ssh.d.ts.map +1 -0
  1317. package/dist/services/terminal-ssh.js +101 -0
  1318. package/dist/services/terminal-ssh.js.map +1 -0
  1319. package/dist/services/terminal.rpc-service.d.ts +84 -0
  1320. package/dist/services/terminal.rpc-service.d.ts.map +1 -0
  1321. package/dist/services/terminal.rpc-service.js +508 -0
  1322. package/dist/services/terminal.rpc-service.js.map +1 -0
  1323. package/dist/services/trace-collector.rpc-service.js +3 -3
  1324. package/dist/services/trace-collector.rpc-service.js.map +1 -1
  1325. package/dist/services/wait-for-postgres.d.ts +1 -1
  1326. package/dist/services/wait-for-postgres.d.ts.map +1 -1
  1327. package/dist/services/wait-for-postgres.js +13 -28
  1328. package/dist/services/wait-for-postgres.js.map +1 -1
  1329. package/dist/shared/build-stamp.d.ts +4 -1
  1330. package/dist/shared/build-stamp.d.ts.map +1 -1
  1331. package/dist/shared/build-stamp.js +14 -6
  1332. package/dist/shared/build-stamp.js.map +1 -1
  1333. package/dist/shared/describe-error.d.ts +1 -21
  1334. package/dist/shared/describe-error.d.ts.map +1 -1
  1335. package/dist/shared/describe-error.js +1 -38
  1336. package/dist/shared/describe-error.js.map +1 -1
  1337. package/dist/shared/dto/access.d.ts +55 -0
  1338. package/dist/shared/dto/access.d.ts.map +1 -0
  1339. package/dist/shared/dto/access.js +2 -0
  1340. package/dist/shared/dto/access.js.map +1 -0
  1341. package/dist/shared/dto/audit.d.ts +32 -0
  1342. package/dist/shared/dto/audit.d.ts.map +1 -0
  1343. package/dist/shared/dto/audit.js +3 -0
  1344. package/dist/shared/dto/audit.js.map +1 -0
  1345. package/dist/shared/dto/auth.d.ts +2 -0
  1346. package/dist/shared/dto/auth.d.ts.map +1 -1
  1347. package/dist/shared/dto/auth.js +5 -1
  1348. package/dist/shared/dto/auth.js.map +1 -1
  1349. package/dist/shared/dto/backend.d.ts +50 -0
  1350. package/dist/shared/dto/backend.d.ts.map +1 -0
  1351. package/dist/shared/dto/backend.js +3 -0
  1352. package/dist/shared/dto/backend.js.map +1 -0
  1353. package/dist/shared/dto/backups.d.ts +99 -0
  1354. package/dist/shared/dto/backups.d.ts.map +1 -1
  1355. package/dist/shared/dto/cluster.d.ts +44 -0
  1356. package/dist/shared/dto/cluster.d.ts.map +1 -0
  1357. package/dist/shared/dto/cluster.js +3 -0
  1358. package/dist/shared/dto/cluster.js.map +1 -0
  1359. package/dist/shared/dto/files.d.ts +328 -0
  1360. package/dist/shared/dto/files.d.ts.map +1 -0
  1361. package/dist/shared/dto/files.js +2 -0
  1362. package/dist/shared/dto/files.js.map +1 -0
  1363. package/dist/shared/dto/health.d.ts +59 -0
  1364. package/dist/shared/dto/health.d.ts.map +1 -1
  1365. package/dist/shared/dto/installed-release.d.ts +40 -0
  1366. package/dist/shared/dto/installed-release.d.ts.map +1 -0
  1367. package/dist/shared/dto/installed-release.js +2 -0
  1368. package/dist/shared/dto/installed-release.js.map +1 -0
  1369. package/dist/shared/dto/kernel-catalog.d.ts +11 -0
  1370. package/dist/shared/dto/kernel-catalog.d.ts.map +1 -0
  1371. package/dist/shared/dto/kernel-catalog.js +2 -0
  1372. package/dist/shared/dto/kernel-catalog.js.map +1 -0
  1373. package/dist/shared/dto/logs.d.ts +21 -0
  1374. package/dist/shared/dto/logs.d.ts.map +1 -1
  1375. package/dist/shared/dto/metrics.d.ts +4 -64
  1376. package/dist/shared/dto/metrics.d.ts.map +1 -1
  1377. package/dist/shared/dto/metrics.js +0 -15
  1378. package/dist/shared/dto/metrics.js.map +1 -1
  1379. package/dist/shared/dto/nodes.d.ts +96 -22
  1380. package/dist/shared/dto/nodes.d.ts.map +1 -1
  1381. package/dist/shared/dto/pipelines.d.ts +22 -1
  1382. package/dist/shared/dto/pipelines.d.ts.map +1 -1
  1383. package/dist/shared/dto/project.d.ts +289 -30
  1384. package/dist/shared/dto/project.d.ts.map +1 -1
  1385. package/dist/shared/dto/releases.d.ts +59 -0
  1386. package/dist/shared/dto/releases.d.ts.map +1 -0
  1387. package/dist/shared/dto/releases.js +2 -0
  1388. package/dist/shared/dto/releases.js.map +1 -0
  1389. package/dist/shared/dto/services.d.ts +174 -37
  1390. package/dist/shared/dto/services.d.ts.map +1 -1
  1391. package/dist/shared/dto/services.js +15 -6
  1392. package/dist/shared/dto/services.js.map +1 -1
  1393. package/dist/shared/dto/stack-diagnosis.d.ts +20 -0
  1394. package/dist/shared/dto/stack-diagnosis.d.ts.map +1 -0
  1395. package/dist/shared/dto/stack-diagnosis.js +8 -0
  1396. package/dist/shared/dto/stack-diagnosis.js.map +1 -0
  1397. package/dist/shared/dto/stack-execution.d.ts +65 -0
  1398. package/dist/shared/dto/stack-execution.d.ts.map +1 -0
  1399. package/dist/shared/dto/stack-execution.js +33 -0
  1400. package/dist/shared/dto/stack-execution.js.map +1 -0
  1401. package/dist/shared/dto/system-info.d.ts +11 -0
  1402. package/dist/shared/dto/system-info.d.ts.map +1 -1
  1403. package/dist/shared/dto/system-info.js +7 -1
  1404. package/dist/shared/dto/system-info.js.map +1 -1
  1405. package/dist/shared/dto/terminal.d.ts +40 -0
  1406. package/dist/shared/dto/terminal.d.ts.map +1 -0
  1407. package/dist/shared/dto/terminal.js +2 -0
  1408. package/dist/shared/dto/terminal.js.map +1 -0
  1409. package/dist/shared/dto/topology.d.ts +96 -0
  1410. package/dist/shared/dto/topology.d.ts.map +1 -0
  1411. package/dist/shared/dto/topology.js +2 -0
  1412. package/dist/shared/dto/topology.js.map +1 -0
  1413. package/dist/shared/emergency-output.d.ts +3 -0
  1414. package/dist/shared/emergency-output.d.ts.map +1 -0
  1415. package/dist/shared/emergency-output.js +22 -0
  1416. package/dist/shared/emergency-output.js.map +1 -0
  1417. package/dist/shared/env-config.d.ts +2 -0
  1418. package/dist/shared/env-config.d.ts.map +1 -1
  1419. package/dist/shared/env-config.js +1 -0
  1420. package/dist/shared/env-config.js.map +1 -1
  1421. package/dist/shared/events.d.ts +2 -0
  1422. package/dist/shared/events.d.ts.map +1 -1
  1423. package/dist/shared/events.js.map +1 -1
  1424. package/dist/shared/execution-identity.d.ts +39 -0
  1425. package/dist/shared/execution-identity.d.ts.map +1 -0
  1426. package/dist/shared/execution-identity.js +160 -0
  1427. package/dist/shared/execution-identity.js.map +1 -0
  1428. package/dist/shared/file-policy.d.ts +5 -0
  1429. package/dist/shared/file-policy.d.ts.map +1 -0
  1430. package/dist/shared/file-policy.js +18 -0
  1431. package/dist/shared/file-policy.js.map +1 -0
  1432. package/dist/shared/framework-source.d.ts +11 -0
  1433. package/dist/shared/framework-source.d.ts.map +1 -0
  1434. package/dist/shared/framework-source.js +31 -0
  1435. package/dist/shared/framework-source.js.map +1 -0
  1436. package/dist/shared/fresh-module-reader.d.ts +40 -0
  1437. package/dist/shared/fresh-module-reader.d.ts.map +1 -0
  1438. package/dist/shared/fresh-module-reader.js +257 -0
  1439. package/dist/shared/fresh-module-reader.js.map +1 -0
  1440. package/dist/shared/host-boot-identity.d.ts +12 -0
  1441. package/dist/shared/host-boot-identity.d.ts.map +1 -0
  1442. package/dist/shared/host-boot-identity.js +89 -0
  1443. package/dist/shared/host-boot-identity.js.map +1 -0
  1444. package/dist/shared/kernel-file-lock.d.ts +3 -0
  1445. package/dist/shared/kernel-file-lock.d.ts.map +1 -0
  1446. package/dist/shared/kernel-file-lock.js +53 -0
  1447. package/dist/shared/kernel-file-lock.js.map +1 -0
  1448. package/dist/shared/linux-file-lock.d.ts +4 -0
  1449. package/dist/shared/linux-file-lock.d.ts.map +1 -0
  1450. package/dist/shared/linux-file-lock.js +36 -0
  1451. package/dist/shared/linux-file-lock.js.map +1 -0
  1452. package/dist/shared/log-ingestion-reading.d.ts +9 -0
  1453. package/dist/shared/log-ingestion-reading.d.ts.map +1 -0
  1454. package/dist/shared/log-ingestion-reading.js +32 -0
  1455. package/dist/shared/log-ingestion-reading.js.map +1 -0
  1456. package/dist/shared/log-levels.d.ts +19 -0
  1457. package/dist/shared/log-levels.d.ts.map +1 -0
  1458. package/dist/shared/log-levels.js +23 -0
  1459. package/dist/shared/log-levels.js.map +1 -0
  1460. package/dist/shared/metrics-storage-reading.d.ts +8 -0
  1461. package/dist/shared/metrics-storage-reading.d.ts.map +1 -0
  1462. package/dist/shared/metrics-storage-reading.js +27 -0
  1463. package/dist/shared/metrics-storage-reading.js.map +1 -0
  1464. package/dist/shared/pnpm.d.ts.map +1 -1
  1465. package/dist/shared/pnpm.js +7 -0
  1466. package/dist/shared/pnpm.js.map +1 -1
  1467. package/dist/shared/pool-scale.d.ts +10 -0
  1468. package/dist/shared/pool-scale.d.ts.map +1 -0
  1469. package/dist/shared/pool-scale.js +25 -0
  1470. package/dist/shared/pool-scale.js.map +1 -0
  1471. package/dist/shared/private-files.d.ts +10 -22
  1472. package/dist/shared/private-files.d.ts.map +1 -1
  1473. package/dist/shared/private-files.js +95 -82
  1474. package/dist/shared/private-files.js.map +1 -1
  1475. package/dist/shared/relay-reading.d.ts +19 -0
  1476. package/dist/shared/relay-reading.d.ts.map +1 -0
  1477. package/dist/shared/relay-reading.js +22 -0
  1478. package/dist/shared/relay-reading.js.map +1 -0
  1479. package/dist/shared/release-reading.d.ts +124 -32
  1480. package/dist/shared/release-reading.d.ts.map +1 -1
  1481. package/dist/shared/release-reading.js +208 -28
  1482. package/dist/shared/release-reading.js.map +1 -1
  1483. package/dist/shared/roles.d.ts +19 -18
  1484. package/dist/shared/roles.d.ts.map +1 -1
  1485. package/dist/shared/roles.js +21 -26
  1486. package/dist/shared/roles.js.map +1 -1
  1487. package/dist/shared/runtime-artifact.d.ts +20 -0
  1488. package/dist/shared/runtime-artifact.d.ts.map +1 -0
  1489. package/dist/shared/runtime-artifact.js +83 -0
  1490. package/dist/shared/runtime-artifact.js.map +1 -0
  1491. package/dist/shared/stack-reading.d.ts +18 -0
  1492. package/dist/shared/stack-reading.d.ts.map +1 -0
  1493. package/dist/shared/stack-reading.js +15 -0
  1494. package/dist/shared/stack-reading.js.map +1 -0
  1495. package/dist/shared/sync-reading.d.ts +30 -38
  1496. package/dist/shared/sync-reading.d.ts.map +1 -1
  1497. package/dist/shared/sync-reading.js +90 -29
  1498. package/dist/shared/sync-reading.js.map +1 -1
  1499. package/dist/shared/tokens.d.ts +3 -1
  1500. package/dist/shared/tokens.d.ts.map +1 -1
  1501. package/dist/shared/tokens.js +1 -0
  1502. package/dist/shared/tokens.js.map +1 -1
  1503. package/dist/supervisor/restart-policy.d.ts.map +1 -1
  1504. package/dist/supervisor/restart-policy.js +7 -5
  1505. package/dist/supervisor/restart-policy.js.map +1 -1
  1506. package/dist/webapp/console-container.d.ts +7 -0
  1507. package/dist/webapp/console-container.d.ts.map +1 -0
  1508. package/dist/webapp/console-container.js +23 -0
  1509. package/dist/webapp/console-container.js.map +1 -0
  1510. package/dist/webapp/webapp.service.d.ts.map +1 -1
  1511. package/dist/webapp/webapp.service.js +71 -24
  1512. package/dist/webapp/webapp.service.js.map +1 -1
  1513. package/dist/workers/health-monitor.service.d.ts.map +1 -1
  1514. package/dist/workers/health-monitor.service.js +8 -1
  1515. package/dist/workers/health-monitor.service.js.map +1 -1
  1516. package/dist/workers/types.d.ts +2 -0
  1517. package/dist/workers/types.d.ts.map +1 -1
  1518. package/package.json +106 -44
  1519. package/webapp/dist/BUILD.json +4 -3
  1520. package/webapp/dist/assets/access-48hkC2-P.js +1 -0
  1521. package/webapp/dist/assets/access-jWkHxGc7.js +1 -0
  1522. package/webapp/dist/assets/admin-data-table-BKSDI8sU.js +1 -0
  1523. package/webapp/dist/assets/alert-expression-CSblScoa.js +1 -0
  1524. package/webapp/dist/assets/alert-notify-settings-C_CHZrFm.js +1 -0
  1525. package/webapp/dist/assets/alert-uBG6r9NW.js +1 -0
  1526. package/webapp/dist/assets/alerts-CuPQ9YQJ.js +1 -0
  1527. package/webapp/dist/assets/app-address-BCXfN59F.js +1 -0
  1528. package/webapp/dist/assets/apps-Drio028B.js +1 -0
  1529. package/webapp/dist/assets/audit-npSFJECe.js +1 -0
  1530. package/webapp/dist/assets/auth-CcgjP7hR.js +1 -0
  1531. package/webapp/dist/assets/card-DkH32gMY.js +1 -0
  1532. package/webapp/dist/assets/chart-BpGXlCJc.js +2 -0
  1533. package/webapp/dist/assets/charts-BY7qI6s2.js +41 -0
  1534. package/webapp/dist/assets/charts-CpBdHU_A.js +56 -0
  1535. package/webapp/dist/assets/client-DFnuv2z3.js +3 -0
  1536. package/webapp/dist/assets/code-editor-DK6Tmmxv.js +4 -0
  1537. package/webapp/dist/assets/comparison-bars-BtC0dHjF.js +1 -0
  1538. package/webapp/dist/assets/confirm-dialog-BbGsAz7_.js +1 -0
  1539. package/webapp/dist/assets/console-keyboard-D3YCA0yU.js +1 -0
  1540. package/webapp/dist/assets/constants-CyhngVXh.js +1 -0
  1541. package/webapp/dist/assets/containers-Bl8gAyZX.js +3 -0
  1542. package/webapp/dist/assets/context-FIuwpd9_.js +1 -0
  1543. package/webapp/dist/assets/controls-C5W8gHU4.js +1 -0
  1544. package/webapp/dist/assets/daemon-memory-BiEtr9jr.js +1 -0
  1545. package/webapp/dist/assets/dashboard-UHlet3H9.js +1 -0
  1546. package/webapp/dist/assets/dashboard-builder-67PZFqhE.js +1 -0
  1547. package/webapp/dist/assets/dayjs.min-DHwAvH5f.js +1 -0
  1548. package/webapp/dist/assets/deploy-release-dialog-BOXcD5Wo.js +1 -0
  1549. package/webapp/dist/assets/deployments-qV20Ak0P.js +1 -0
  1550. package/webapp/dist/assets/detail-B4TiBfxU.js +8 -0
  1551. package/webapp/dist/assets/detail-B85-Wees.js +2 -0
  1552. package/webapp/dist/assets/detail-CYS81K6Y.js +1 -0
  1553. package/webapp/dist/assets/dist-BUDn8hLh.js +11 -0
  1554. package/webapp/dist/assets/dist-Ci5pYRbx.js +1 -0
  1555. package/webapp/dist/assets/dist-DQmjHv4-.js +1 -0
  1556. package/webapp/dist/assets/dist-De9Fty7a.js +1 -0
  1557. package/webapp/dist/assets/dist-DsGmKwmk.js +23 -0
  1558. package/webapp/dist/assets/empty-content-7jOFhG4C.js +1 -0
  1559. package/webapp/dist/assets/error-boundary-CLLI8PWw.js +3 -0
  1560. package/webapp/dist/assets/event-fields-CiyqrRO8.js +1 -0
  1561. package/webapp/dist/assets/files-DigwXndm.js +2 -0
  1562. package/webapp/dist/assets/formatters-RnRy4bXm.js +1 -0
  1563. package/webapp/dist/assets/icons-OboZgWSt.js +1 -0
  1564. package/webapp/dist/assets/index-uq8Dkk4c.js +1 -0
  1565. package/webapp/dist/assets/label-B1SF0RTL.js +1 -0
  1566. package/webapp/dist/assets/log-level-filter-Bcn31D1F.js +1 -0
  1567. package/webapp/dist/assets/log-location-DuBjh6HQ.js +1 -0
  1568. package/webapp/dist/assets/logs-BqHOufk8.js +4 -0
  1569. package/webapp/dist/assets/metric-chart-M-kI-XOt.js +1 -0
  1570. package/webapp/dist/assets/metric-series-WxePniyw.js +1 -0
  1571. package/webapp/dist/assets/metrics-QIQaF7iS.js +1 -0
  1572. package/webapp/dist/assets/model-ZEXEHm0l.js +2 -0
  1573. package/webapp/dist/assets/mui-6ssfcZcz.js +1 -0
  1574. package/webapp/dist/assets/mui-AnEgAVjz.js +52 -0
  1575. package/webapp/dist/assets/mui-B1jrje6Z.js +1 -0
  1576. package/webapp/dist/assets/mui-BIz4LSVs.js +1 -0
  1577. package/webapp/dist/assets/mui-BTN91yBK.js +28 -0
  1578. package/webapp/dist/assets/mui-BXSXx9c9.js +124 -0
  1579. package/webapp/dist/assets/mui-BwsIrivo.js +37 -0
  1580. package/webapp/dist/assets/mui-C_hromOc.js +1 -0
  1581. package/webapp/dist/assets/mui-Cd711nOk.js +4 -0
  1582. package/webapp/dist/assets/mui-CdB_p2lt.js +10 -0
  1583. package/webapp/dist/assets/mui-DyT2n1lx.js +1 -0
  1584. package/webapp/dist/assets/mui-agG5dued.js +1 -0
  1585. package/webapp/dist/assets/mui-y44PQOfG.js +1 -0
  1586. package/webapp/dist/assets/nodes-BJPk02vv.js +7 -0
  1587. package/webapp/dist/assets/omnitron-logo-koMCbsCv.js +1 -0
  1588. package/webapp/dist/assets/operation-status-Bm1x1wTz.js +1 -0
  1589. package/webapp/dist/assets/page-breadcrumbs-fR7Jmpp4.js +1 -0
  1590. package/webapp/dist/assets/pipelines-T6Ch9LTw.js +3 -0
  1591. package/webapp/dist/assets/popper-m_9b0JRf.js +1 -0
  1592. package/webapp/dist/assets/preload-helper-DzCYNvzR.js +1 -0
  1593. package/webapp/dist/assets/project.store--G5pIF-J.js +1 -0
  1594. package/webapp/dist/assets/projects-YoBzcQ24.js +1 -0
  1595. package/webapp/dist/assets/react-BN8qLIAi.js +9 -0
  1596. package/webapp/dist/assets/react-CEuifcaQ.js +1 -0
  1597. package/webapp/dist/assets/react-apexcharts.esm-DoOt-pu4.js +1 -0
  1598. package/webapp/dist/assets/realtime.store-CBDO4Abj.js +1 -0
  1599. package/webapp/dist/assets/release-bits-B2a_wbft.js +1 -0
  1600. package/webapp/dist/assets/release-build-panel-BQmIdKW9.js +1 -0
  1601. package/webapp/dist/assets/release-deployment-state-DRrEI2pP.js +1 -0
  1602. package/webapp/dist/assets/release-wire-f2VuBoBF.js +1 -0
  1603. package/webapp/dist/assets/releases-Bp3CDgmo.js +2 -0
  1604. package/webapp/dist/assets/rolldown-runtime-CNOWq4Kh.js +1 -0
  1605. package/webapp/dist/assets/search-input-C0MHI8vO.js +1 -0
  1606. package/webapp/dist/assets/services-BddvcFi8.js +1 -0
  1607. package/webapp/dist/assets/settings-B3egRvbI.js +1 -0
  1608. package/webapp/dist/assets/settled-pair-B-wgSZl6.js +1 -0
  1609. package/webapp/dist/assets/shared-styles-C0vN3I7_.js +1 -0
  1610. package/webapp/dist/assets/shell-command-C3pXf1vi.js +1 -0
  1611. package/webapp/dist/assets/sign-in-9q-Nfy83.js +1 -0
  1612. package/webapp/dist/assets/skeleton-BmWDJWF9.js +1 -0
  1613. package/webapp/dist/assets/snackbar-DSPmjMyi.js +1 -0
  1614. package/webapp/dist/assets/stack-health-status-BIv2C10x.js +1 -0
  1615. package/webapp/dist/assets/stack-start-notice-BVnMOwRQ.js +1 -0
  1616. package/webapp/dist/assets/stacks-IZ1mfizi.js +1 -0
  1617. package/webapp/dist/assets/storage-CKXnhqkt.js +1 -0
  1618. package/webapp/dist/assets/store-bqUBn2A4.js +1 -0
  1619. package/webapp/dist/assets/sync-reading-CN0jPKAg.js +1 -0
  1620. package/webapp/dist/assets/system-info-BFKNM-hf.js +1 -0
  1621. package/webapp/dist/assets/table-BOWT6Y9d.js +1 -0
  1622. package/webapp/dist/assets/table-viewport-Bp4pq-c_.js +1 -0
  1623. package/webapp/dist/assets/tabs-k5NPGLnJ.js +1 -0
  1624. package/webapp/dist/assets/terminal-BrP-ENHg.css +1 -0
  1625. package/webapp/dist/assets/terminal-QWBau-Us.js +62 -0
  1626. package/webapp/dist/assets/terminal-input-b7f2VoE_.js +2 -0
  1627. package/webapp/dist/assets/topology-CPey5dP6.js +8 -0
  1628. package/webapp/dist/assets/topology-metadata-dialog-BivuU2y6.js +2 -0
  1629. package/webapp/dist/assets/topology-routes.worker-BoYrIzAH.js +1 -0
  1630. package/webapp/dist/assets/traces-By0rdfDC.js +1 -0
  1631. package/webapp/dist/assets/use-copy-to-clipboard-BWYpToS3.js +1 -0
  1632. package/webapp/dist/assets/use-polled-resource-B22hhr5L.js +1 -0
  1633. package/webapp/dist/assets/use-stack-context-UkBsF-l7.js +1 -0
  1634. package/webapp/dist/assets/webapp-BnxOVfrc.css +1 -0
  1635. package/webapp/dist/assets/webapp-D-UhjFhS.js +35 -0
  1636. package/webapp/dist/console-version.json +1 -0
  1637. package/webapp/dist/index.html +54 -7
  1638. package/dist/release/daemon-omni.d.ts +0 -41
  1639. package/dist/release/daemon-omni.d.ts.map +0 -1
  1640. package/dist/release/daemon-omni.js +0 -59
  1641. package/dist/release/daemon-omni.js.map +0 -1
  1642. package/dist/services/netron-telemetry-transport.d.ts +0 -42
  1643. package/dist/services/netron-telemetry-transport.d.ts.map +0 -1
  1644. package/dist/services/netron-telemetry-transport.js +0 -93
  1645. package/dist/services/netron-telemetry-transport.js.map +0 -1
  1646. package/webapp/dist/assets/FormControlLabel-BbSxpQwN.js +0 -1
  1647. package/webapp/dist/assets/Grid-DizFZYue.js +0 -1
  1648. package/webapp/dist/assets/Switch-Bfiqzx8l.js +0 -1
  1649. package/webapp/dist/assets/alerts-DH_RVRS3.js +0 -1
  1650. package/webapp/dist/assets/apps-B96355sz.js +0 -1
  1651. package/webapp/dist/assets/audit-CYGtbi4k.js +0 -1
  1652. package/webapp/dist/assets/client-BmqFExWT.js +0 -1
  1653. package/webapp/dist/assets/constants-veKGFkC6.js +0 -1
  1654. package/webapp/dist/assets/containers-B_TpThln.js +0 -2
  1655. package/webapp/dist/assets/daemon-memory-CCPZ4cV_.js +0 -1
  1656. package/webapp/dist/assets/dashboard-DHf2_65N.js +0 -1
  1657. package/webapp/dist/assets/dashboard-builder-CWY2pjeG.js +0 -1
  1658. package/webapp/dist/assets/deploy-release-dialog-Dp-zpSAd.js +0 -1
  1659. package/webapp/dist/assets/deployments-tJI6O3fK.js +0 -1
  1660. package/webapp/dist/assets/detail-B2zP1Hto.js +0 -8
  1661. package/webapp/dist/assets/detail-CoIrwmsy.js +0 -1
  1662. package/webapp/dist/assets/detail-DWaGaOtL.js +0 -2
  1663. package/webapp/dist/assets/formatters-BqjL73N3.js +0 -1
  1664. package/webapp/dist/assets/fs-Ccl3sAcp.js +0 -1
  1665. package/webapp/dist/assets/index-Dvo0iprx.css +0 -1
  1666. package/webapp/dist/assets/index-vMnY_4jR.js +0 -412
  1667. package/webapp/dist/assets/logs-DTRjOfX8.js +0 -12
  1668. package/webapp/dist/assets/maplibre-gl-DowHoZAx.js +0 -814
  1669. package/webapp/dist/assets/metrics-UCajtdox.js +0 -2
  1670. package/webapp/dist/assets/nodes-DuTVU0f6.js +0 -7
  1671. package/webapp/dist/assets/pipelines-C8BeDcAl.js +0 -4
  1672. package/webapp/dist/assets/projects-Dp_zFfLY.js +0 -1
  1673. package/webapp/dist/assets/react-DlmbjZJV.js +0 -1
  1674. package/webapp/dist/assets/react-apexcharts.esm-C8pn45ml.js +0 -97
  1675. package/webapp/dist/assets/release-bits-BzTKz5fM.js +0 -1
  1676. package/webapp/dist/assets/release-build-panel-DcW9YcXQ.js +0 -1
  1677. package/webapp/dist/assets/releases-B4hcr1bE.js +0 -2
  1678. package/webapp/dist/assets/rolldown-runtime-XKyaHtl9.js +0 -1
  1679. package/webapp/dist/assets/settings-DIteZTbe.js +0 -1
  1680. package/webapp/dist/assets/settled-pair-C7SjZuns.js +0 -1
  1681. package/webapp/dist/assets/sign-in-D4kMBOHp.js +0 -1
  1682. package/webapp/dist/assets/stacks-Brnf-EB7.js +0 -1
  1683. package/webapp/dist/assets/sync-reading-C3PnJ7AX.js +0 -1
  1684. package/webapp/dist/assets/system-info-CFDNVKkU.js +0 -1
  1685. package/webapp/dist/assets/topology-7WeTUsDN.js +0 -12
  1686. package/webapp/dist/assets/traces-9c3gwCN-.js +0 -1
  1687. package/webapp/dist/assets/use-stack-context-CnA5FTHu.js +0 -1
@@ -1,3 +1,10 @@
1
+ import { Errors } from '@omnitron-dev/titan/errors';
2
+ import { OWNER_CAPABILITIES } from '../daemon/execution-capabilities.js';
3
+ import { parsePoolScaleRequest, assertPoolScaleTarget } from '../shared/pool-scale.js';
4
+ import { installedEntryRevision, installedExecutable, requireInstalledBinding } from './installed-execution.js';
5
+ import { topologyRevision } from '../project/topology-plan.js';
6
+ import { createHash } from 'node:crypto';
7
+ import { stackExecutionKey, executionScopeKey, executionScopeOwns } from '../shared/dto/stack-execution.js';
1
8
  /**
2
9
  * OrchestratorService — Core orchestration logic
3
10
  *
@@ -7,7 +14,7 @@
7
14
  * - Each app gets a ProcessSupervisor via pm.supervisor(config)
8
15
  * - Supervisor manages all child lifecycle: spawn, health, metrics, crash recovery, restart
9
16
  * - Single or multi-instance (pool) — configured via ISupervisorChildConfig
10
- * - Scaling delegates to supervisor.scaleChild()
17
+ * - Runtime resizing addresses one declared topology pool
11
18
  *
12
19
  * Classic mode:
13
20
  * - child_process.fork() with manual exit handling (legacy compat)
@@ -26,13 +33,16 @@
26
33
  * → Full Titan Application inside each worker
27
34
  * → Two Netron instances: PM management plane + app HTTP data plane
28
35
  */
36
+ import { ReadinessMonitor } from '../health/readiness.js';
29
37
  import fs from 'node:fs';
30
38
  import { readDeclaredConfig, withDeclaredConfig } from '../project/declared-config.js';
31
39
  import path from 'node:path';
32
40
  import { fileURLToPath } from 'node:url';
33
- import { PoolStrategy, SupervisionStrategy, ProcessLifecycleQueue, LifecyclePreempted, computeBackoff, isAlive, discoverManagedProcesses, } from '@omnitron-dev/titan-pm';
41
+ import { PoolStrategy, SupervisionStrategy, ProcessLifecycleQueue, LifecyclePreempted, computeBackoff, RestartWindow, isAlive, killChildAndVerify, discoverManagedProcesses, } from '@omnitron-dev/titan-pm';
34
42
  import { EventEmitter } from '@omnitron-dev/eventemitter';
35
43
  import { AppHandle } from './app-handle.js';
44
+ import { verifyLaunchRelease } from '../release/runtime-provenance.js';
45
+ import { withClosureLibraryPath } from '../release/closure-library-path.js';
36
46
  import { parsePsLine, parsePsBatch } from './ps-metrics.js';
37
47
  import { launchClassic } from './classic-launcher.js';
38
48
  import { resolveStartupOrder, resolveShutdownOrder } from './dependency-resolver.js';
@@ -60,7 +70,9 @@ function qualifyChildName(appName, childName) {
60
70
  const TOPOLOGY_EXPOSE_TIMEOUT_MS = 30_000;
61
71
  const TOPOLOGY_EXPOSE_POLL_MS = 250;
62
72
  import { ServiceRouter } from './service-router.js';
63
- import { loadBootstrapConfig, clearCacheFor } from './bootstrap-loader.js';
73
+ import { ApplicationTopology } from './application-topology.js';
74
+ import { clearCacheFor } from './bootstrap-loader.js';
75
+ import { readBootstrapMetadata } from '../project/bootstrap-metadata.js';
64
76
  /** Levels a pino logger accepts. A child is spawned with nothing else. */
65
77
  const PINO_LEVELS = new Set(['fatal', 'error', 'warn', 'info', 'debug', 'trace', 'silent']);
66
78
  /**
@@ -81,6 +93,7 @@ import { collectOwnedPids } from './owned-pids.js';
81
93
  import { combineProcessHealth, notRunningHealth, poolHealth } from './app-health.js';
82
94
  import { combineProcessTraffic } from './app-traffic.js';
83
95
  import { CLI_VERSION } from '../config/defaults.js';
96
+ import { applicationBootstrapRuntime } from './application-runtime.js';
84
97
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
85
98
  // Resolve bootstrap-process path — .ts in dev (tsx), .js when compiled
86
99
  function resolveBootstrapProcessPath() {
@@ -185,6 +198,7 @@ export class OrchestratorService extends EventEmitter {
185
198
  logger;
186
199
  pm;
187
200
  stateStore;
201
+ ownerOptions;
188
202
  handles = new Map();
189
203
  /**
190
204
  * Per-name in-flight start lock (T#57). When two `startApp()` calls
@@ -197,6 +211,8 @@ export class OrchestratorService extends EventEmitter {
197
211
  * for the same name isn't permanently locked out.
198
212
  */
199
213
  startingApps = new Map();
214
+ stoppingApps = null;
215
+ stopGeneration = 0;
200
216
  /**
201
217
  * Per-app async serial-execution queue covering start / stop / restart
202
218
  * / crash-restart-timer (P0-E + P0-I + P2-B in the audit). Pre-this-
@@ -212,15 +228,18 @@ export class OrchestratorService extends EventEmitter {
212
228
  * The queue collapses all four into one primitive ordered by
213
229
  * priority (stop > restart > start > crash-restart). The same-key
214
230
  * mutex means stop ALWAYS observes a completed start, and an
215
- * explicit stop ALWAYS preempts a pending crash-restart timer.
231
+ * explicit stop cancels recovery waits before joining the queue.
216
232
  */
217
233
  lifecycleQueue = new ProcessLifecycleQueue();
218
234
  /**
219
- * Pending post-escalation cool-down timers, keyed by app name.
235
+ * Pending crash backoff and post-escalation timers, keyed by app name.
220
236
  * Held here rather than inside a lifecycle-queue slot so that a
221
237
  * crashed app still answers operator commands while it waits.
222
238
  */
223
239
  coolDownTimers = new Map();
240
+ appStopIntents = new Map();
241
+ readinessMonitor = new ReadinessMonitor();
242
+ readinessSignatures = new WeakMap();
224
243
  config = null;
225
244
  cwd;
226
245
  metricsTimer = null;
@@ -233,11 +252,12 @@ export class OrchestratorService extends EventEmitter {
233
252
  watchSelection = null;
234
253
  bootstrapSources = new Map();
235
254
  allowsWatch(entry) {
236
- return this.devMode && !this.watchDisabled && entry.watch !== false &&
255
+ return this.devMode && !this.watchDisabled && !entry.releaseRoot && entry.watch !== false &&
237
256
  (!this.watchSelection || this.watchSelection.has(entry.name));
238
257
  }
239
258
  /** One policy for both fs.watch and esbuild; disabling does not stop apps. */
240
259
  async setWatchMode(enabled, apps) {
260
+ this.devMode = enabled;
241
261
  this.watchDisabled = !enabled;
242
262
  this.watchSelection = apps ? new Set(apps.map((name) => this.resolveAppName(name) ?? name)) : null;
243
263
  for (const [name, state] of this.restartCoalescer) {
@@ -255,7 +275,7 @@ export class OrchestratorService extends EventEmitter {
255
275
  const entry = this.handles.get(name)?.entry;
256
276
  if (!this.buildService || !source)
257
277
  return;
258
- if (!entry || !this.allowsWatch(entry) || !entry.bootstrap ||
278
+ if (!entry || this.executionBusy(name) || !this.allowsWatch(entry) || !entry.bootstrap ||
259
279
  path.resolve(entry.cwd ?? this.cwd, entry.bootstrap) !== source.path) {
260
280
  const state = this.restartCoalescer.get(name);
261
281
  if (state)
@@ -269,7 +289,7 @@ export class OrchestratorService extends EventEmitter {
269
289
  void this.restartAfterChange(name).catch((error) => {
270
290
  this.logger.error({ app: name, error: error.message }, 'Restart after source change failed');
271
291
  });
272
- });
292
+ }, this.devMode);
273
293
  }
274
294
  /** Automatic triggers remain revocable while queued; manual restart is independent. */
275
295
  async restartAfterChange(name) {
@@ -329,19 +349,9 @@ export class OrchestratorService extends EventEmitter {
329
349
  */
330
350
  bootReconciled = false;
331
351
  bootReconcilePromise = null;
332
- /** Daemon's Netron instance for native service routing */
333
- daemonNetron = null;
334
- /** Daemon Unix socket path for child-to-daemon Netron connections */
335
- daemonSocketPath = null;
336
- /**
337
- * Promise that resolves once the daemon's Netron is wired up. Apps that
338
- * declare topology cannot launch until this is ready — instead of failing
339
- * with "daemon Netron not available" the launcher awaits this promise
340
- * (with a generous timeout) so transient startup-order interleavings
341
- * resolve themselves instead of becoming user-visible errors.
342
- */
343
- daemonNetronReady;
344
- resolveDaemonNetronReady = () => undefined;
352
+ topologyDirectory = null;
353
+ topologyReady;
354
+ resolveTopologyReady = () => undefined;
345
355
  /**
346
356
  * Optional metrics sink. Set by the daemon at boot via
347
357
  * `setMetricsBridge` so the orchestrator can forward janitor sweeps,
@@ -350,25 +360,32 @@ export class OrchestratorService extends EventEmitter {
350
360
  * bootstraps).
351
361
  */
352
362
  metricsBridge = null;
353
- constructor(logger, pm, stateStore, cwd) {
363
+ constructor(logger, pm, stateStore, cwd, ownerOptions = {}) {
354
364
  super();
355
365
  this.logger = logger;
356
366
  this.pm = pm;
357
367
  this.stateStore = stateStore;
368
+ this.ownerOptions = ownerOptions;
358
369
  this.cwd = cwd ?? process.cwd();
359
- this.daemonNetronReady = new Promise((resolve) => {
360
- this.resolveDaemonNetronReady = resolve;
370
+ if (pm.outputCaptureVersion === 1)
371
+ pm.on('process:output', (name, line, stream, context) => {
372
+ const app = [...this.handles.keys()].filter(key => name === key || name.startsWith(`${key}/`) || name.startsWith(`${key}-`))
373
+ .sort((a, b) => b.length - a.length)[0];
374
+ const handle = app ? this.handles.get(app) : undefined;
375
+ if (app && handle)
376
+ this.childLogForwarder(app, handle)(line, stream, context);
377
+ });
378
+ this.topologyReady = new Promise((resolve) => {
379
+ this.resolveTopologyReady = resolve;
361
380
  });
362
381
  }
363
- /**
364
- * Set the daemon Netron instance and socket path for native topology routing.
365
- * Called by the daemon after start when Netron is available.
366
- */
367
- setDaemonNetron(netron, socketPath) {
368
- this.daemonNetron = netron;
369
- this.daemonSocketPath = socketPath;
370
- this.resolveDaemonNetronReady();
371
- this.logger.info({ socketPath }, 'Daemon Netron set for native topology routing');
382
+ /** Application RPC listeners never share the owner's management namespace. */
383
+ setTopologyDirectory(directory) {
384
+ this.topologyDirectory = path.resolve(directory);
385
+ this.resolveTopologyReady();
386
+ }
387
+ async bootstrapRuntime(bootstrap) {
388
+ return applicationBootstrapRuntime(bootstrap, BOOTSTRAP_PROCESS_PATH, this.ownerOptions.allowSdklessBootstrap ?? true);
372
389
  }
373
390
  /**
374
391
  * Wire the metrics bridge. Called once during daemon bootstrap.
@@ -400,18 +417,20 @@ export class OrchestratorService extends EventEmitter {
400
417
  this.metricsBridge?.recordAppEscalated(app);
401
418
  });
402
419
  }
403
- /**
404
- * Wait until the daemon Netron is available, with a hard ceiling so we
405
- * never hang forever if `setDaemonNetron()` was never wired in.
406
- */
407
- async ensureDaemonNetronReady(timeoutMs = 30_000) {
408
- if (this.daemonNetron && this.daemonSocketPath)
420
+ async ensureTopologyReady(timeoutMs = 30_000) {
421
+ if (this.topologyDirectory)
409
422
  return;
423
+ let timer;
410
424
  const timeout = new Promise((_resolve, reject) => {
411
- const timer = setTimeout(() => reject(new Error(`Daemon Netron not initialized within ${timeoutMs}ms — wiring bug?`)), timeoutMs);
425
+ timer = setTimeout(() => reject(new Error(`Application topology directory not configured within ${timeoutMs}ms`)), timeoutMs);
412
426
  timer.unref?.();
413
427
  });
414
- await Promise.race([this.daemonNetronReady, timeout]);
428
+ try {
429
+ await Promise.race([this.topologyReady, timeout]);
430
+ }
431
+ finally {
432
+ clearTimeout(timer);
433
+ }
415
434
  }
416
435
  // ============================================================================
417
436
  // Lifecycle
@@ -567,6 +586,7 @@ export class OrchestratorService extends EventEmitter {
567
586
  if (this.janitor)
568
587
  return this.janitor;
569
588
  this.janitor = new ProcessJanitor({
589
+ reapForeignOrphans: this.ownerOptions.reapForeignOrphans ?? true,
570
590
  logger: this.logger,
571
591
  getOwnedPids: () => this.collectOwnedPids(),
572
592
  onMetrics: (m) => this.metricsBridge?.recordJanitorSweep(m),
@@ -685,14 +705,9 @@ export class OrchestratorService extends EventEmitter {
685
705
  return pids;
686
706
  }
687
707
  async startApp(entry, config) {
688
- // T#63: run the one-shot cold-start reconcile (orphan reap +
689
- // janitor arming) before ANY app spawns. Project-mode boots flow
690
- // through `projectService.startStack → orchestrator.startApp`
691
- // and historically bypassed the reap entirely — a previous
692
- // daemon's children (now reparented to init) kept their HTTP
693
- // listen ports and the fresh child failed to bind silently.
694
- // No-op after first call thanks to `bootReconciled`.
695
- await this.ensureBootReconciled(config);
708
+ const stopGeneration = this.stopGeneration;
709
+ if (this.stoppingApps)
710
+ throw new Error('Application stop is in progress; new starts are not admitted');
696
711
  // Defensive auto-namespacing — promotes a bare entry.name to the
697
712
  // canonical `${project}/${stack}/${name}` form when the env carries
698
713
  // OMNITRON_PROJECT + OMNITRON_STACK. Catches every code path that
@@ -701,8 +716,29 @@ export class OrchestratorService extends EventEmitter {
701
716
  // - legacy ecosystem configs without per-app namespace
702
717
  // - daemon startAll() flows over a not-yet-namespaced config
703
718
  entry = ensureNamespacedEntry(entry);
719
+ this.assertAppStartAllowed(this.resolveAppName(entry.name) ?? entry.name);
720
+ if (!this.appStopIntents.has(entry.name)) {
721
+ this.appStopIntents.set(entry.name, { revision: 0, stopped: false });
722
+ }
723
+ const stopRevision = this.appStopIntents.get(entry.name)?.revision;
724
+ // T#63: run the one-shot cold-start reconcile (orphan reap +
725
+ // janitor arming) before ANY app spawns. Project-mode boots flow
726
+ // through `projectService.startStack → orchestrator.startApp`
727
+ // and historically bypassed the reap entirely — a previous
728
+ // daemon's children (now reparented to init) kept their HTTP
729
+ // listen ports and the fresh child failed to bind silently.
730
+ // No-op after first call thanks to `bootReconciled`.
731
+ await this.ensureBootReconciled(config);
732
+ if (this.stoppingApps || stopGeneration !== this.stopGeneration ||
733
+ stopRevision !== this.appStopIntents.get(entry.name)?.revision) {
734
+ throw new Error('Application stop interrupted start admission');
735
+ }
736
+ const intent = this.appStopIntents.get(entry.name);
737
+ const wasStopped = intent?.stopped;
738
+ if (intent)
739
+ intent.stopped = false;
704
740
  const inflight = this.startingApps.get(entry.name);
705
- if (inflight) {
741
+ if (inflight && !wasStopped) {
706
742
  this.logger.debug({ app: entry.name }, 'Coalescing concurrent startApp into in-flight launch (T#57)');
707
743
  return inflight;
708
744
  }
@@ -711,12 +747,17 @@ export class OrchestratorService extends EventEmitter {
711
747
  // (or in-flight) now waits its turn instead of racing through
712
748
  // and leaving an orphan supervisor.
713
749
  const promise = this.lifecycleQueue.enqueue(entry.name, 'start', () => this.startAppInternal(entry, config)).finally(() => {
714
- this.startingApps.delete(entry.name);
750
+ if (this.startingApps.get(entry.name) === promise)
751
+ this.startingApps.delete(entry.name);
715
752
  });
716
753
  this.startingApps.set(entry.name, promise);
717
754
  return promise;
718
755
  }
719
- async startAppInternal(entry, config) {
756
+ async startAppInternal(entry, config, installed) {
757
+ if (!installed)
758
+ this.assertAppStartAllowed(entry.name);
759
+ else
760
+ this.assertApplicationFence(entry.name);
720
761
  // Persist ecosystem config for restartApp — stack mode passes config per-app,
721
762
  // but restartApp calls startApp without it.
722
763
  if (config && !this.config) {
@@ -759,6 +800,9 @@ export class OrchestratorService extends EventEmitter {
759
800
  // Qualified identities are separate deployments, even when their basename matches.
760
801
  if (newIsNamespaced && existingIsNamespaced)
761
802
  continue;
803
+ if (installed)
804
+ throw new Error('Installed stack start cannot displace another application');
805
+ this.assertAppStartAllowed(key);
762
806
  // A bare alias may still refer to the one qualified deployment.
763
807
  if (h.status === 'online') {
764
808
  if (newIsNamespaced && !existingIsNamespaced) {
@@ -767,7 +811,8 @@ export class OrchestratorService extends EventEmitter {
767
811
  await this.stopApp(key);
768
812
  }
769
813
  catch (err) {
770
- this.logger.warn({ stale: key, error: err.message }, 'stopApp during dedup failed — clearing handle anyway');
814
+ this.logger.error({ stale: key, error: err.message }, 'Cannot replace app registration while its previous processes remain unconfirmed');
815
+ throw new Error(`Cannot replace '${key}' with '${entry.name}': the previous application did not stop`, { cause: err });
771
816
  }
772
817
  this.handles.delete(key);
773
818
  if (key !== entry.name)
@@ -785,8 +830,7 @@ export class OrchestratorService extends EventEmitter {
785
830
  // its services are still registered on the daemon's Netron. Dropping the
786
831
  // handle here is the last moment anything knows they exist — or that its
787
832
  // processes still run: an errored app's other children and its pools.
788
- await this.releaseExposedServices(h);
789
- await this.tearDownProcesses(h);
833
+ await this.tearDownApp(h);
790
834
  this.handles.delete(key);
791
835
  // Drop any metrics that were collected under the stale alias so it
792
836
  // doesn't haunt future snapshots as a ghost offline app.
@@ -805,10 +849,13 @@ export class OrchestratorService extends EventEmitter {
805
849
  // starts, or the new one finds its own predecessor on its port: on
806
850
  // sample/test (2026-09-25) payments's crash restarts failed five times on
807
851
  // `EADDRINUSE :3004`, «held by … a child this daemon still accounts for».
808
- if (existing) {
809
- await this.releaseExposedServices(existing);
810
- await this.tearDownProcesses(existing);
852
+ if (existing && !installed) {
853
+ await this.tearDownApp(existing);
811
854
  }
855
+ // A sealed entry never inherits a former source build, including a
856
+ // bootstrap-to-classic transition. Retained resumes still reject pollution.
857
+ if (entry.releaseRoot && !installed)
858
+ await this.discardSourceBuild(entry.name);
812
859
  const mode = entry.bootstrap ? 'bootstrap' : 'classic';
813
860
  const handle = new AppHandle(entry, mode);
814
861
  // The restart budget belongs to the APP, not to this handle instance.
@@ -816,8 +863,10 @@ export class OrchestratorService extends EventEmitter {
816
863
  // can never reach `maxRestarts` — which made the budget, the escalation
817
864
  // and the cool-down unreachable even once the restart itself worked. The
818
865
  // window is enforced by the policy, not by forgetting.
819
- if (existing)
866
+ if (existing) {
820
867
  handle.restarts = existing.restarts;
868
+ handle.restartWindow = existing.restartWindow;
869
+ }
821
870
  this.handles.set(entry.name, handle);
822
871
  // Arm metrics sampling here — the one place an app enters the registry.
823
872
  //
@@ -834,16 +883,20 @@ export class OrchestratorService extends EventEmitter {
834
883
  this.ensureMetricsPolling();
835
884
  this.logger.info({ app: entry.name, mode }, 'Starting app');
836
885
  try {
837
- if (mode === 'classic') {
838
- await this.launchClassicMode(entry, handle, cfg);
839
- }
840
- else {
841
- await this.launchBootstrapMode(entry, handle, cfg);
886
+ if (entry.releaseRoot) {
887
+ // Bootstrap metadata executes application code. Authenticate the sealed
888
+ // tree before introspection on initial launches as well as resumes.
889
+ handle.release = await verifyLaunchRelease(entry, handle.generation, [installedExecutable(entry, this.cwd)]);
890
+ requireInstalledBinding(handle.release, installedEntryRevision(entry, cfg, this.cwd), installed);
842
891
  }
892
+ const launch = mode === 'classic' ? await this.launchClassicMode(entry, handle, cfg, installed)
893
+ : await this.launchBootstrapMode(entry, handle, cfg, installed);
843
894
  // «App started» only for an app that is. It was logged in the same
844
895
  // millisecond as a child's «Process failed to start», for an app whose
845
896
  // processes never all came up.
846
897
  if (handle.status === 'online') {
898
+ if (launch)
899
+ this.installedLaunches.set(handle, { binding: Object.freeze(launch), config: cfg });
847
900
  this.logger.info({ app: entry.name, pid: handle.pid, mode }, 'App started');
848
901
  }
849
902
  else {
@@ -868,11 +921,24 @@ export class OrchestratorService extends EventEmitter {
868
921
  // The counter is bumped by hand because `markErrored()` deliberately
869
922
  // does not (an app that never ran has not "restarted"), and without it
870
923
  // the budget below can never trip and the retry would be unbounded.
924
+ // A rejected topology is not a partially running application. Keep
925
+ // resource ownership if cleanup fails so a later stop can retry it.
926
+ handle.markStopping();
927
+ let failure = err;
928
+ try {
929
+ await this.tearDownApp(handle);
930
+ handle.markStopped();
931
+ }
932
+ catch (cleanupError) {
933
+ failure = new AggregateError([err, cleanupError], `Application '${entry.name}' startup failed and cleanup is incomplete: ${String(err)}; ${String(cleanupError)}`);
934
+ }
871
935
  handle.markErrored();
936
+ handle.recordExit({ code: null, signal: null, expected: false, message: String(failure) });
872
937
  handle.restarts++;
873
938
  this.persistState();
874
- this.scheduleRecovery(entry, handle, cfg);
875
- throw err;
939
+ if (!installed)
940
+ this.scheduleRecovery(entry, handle, cfg);
941
+ throw failure;
876
942
  }
877
943
  }
878
944
  /**
@@ -891,6 +957,7 @@ export class OrchestratorService extends EventEmitter {
891
957
  * half-way must not also leave the half nobody asked about.
892
958
  */
893
959
  async tearDownProcesses(handle, force = false, timeout = 10_000) {
960
+ const failures = [];
894
961
  try {
895
962
  if (handle.mode === 'bootstrap' && handle.supervisor) {
896
963
  await handle.supervisor.stop();
@@ -899,56 +966,472 @@ export class OrchestratorService extends EventEmitter {
899
966
  await this.stopChildProcess(handle, force, timeout);
900
967
  }
901
968
  }
902
- finally {
903
- for (const [name, pool] of handle.topologyPools) {
904
- try {
905
- await pool.destroy();
906
- }
907
- catch (err) {
908
- this.logger.warn({ app: handle.name, pool: name, error: err.message }, 'Destroying a topology pool failed — its workers may still run');
909
- }
969
+ catch (error) {
970
+ failures.push(error);
971
+ }
972
+ for (const [name, pool] of handle.topologyPools) {
973
+ try {
974
+ await pool.destroy();
975
+ handle.topologyPools.delete(name);
910
976
  }
911
- handle.topologyPools.clear();
977
+ catch (error) {
978
+ failures.push(error);
979
+ this.logger.error({ app: handle.name, pool: name, error: String(error) }, 'Pool termination unconfirmed; retaining ownership for retry');
980
+ }
981
+ }
982
+ if (failures.length) {
983
+ throw new AggregateError(failures, `Application stop incomplete: ${failures.map(String).join('; ')}`);
912
984
  }
913
985
  }
914
- /**
915
- * Give back every service an app exposed on the daemon's Netron.
916
- *
917
- * A registration outlives the process behind it: the daemon keeps answering
918
- * `queryInterface` with the full method list and every call through the name
919
- * fails at the socket. `takeOverExisting` rescues a name the next launch
920
- * re-exposes; one it does not stays advertised for the life of the daemon.
921
- */
986
+ /** Close only the listener and registrations owned by this launch. */
922
987
  async releaseExposedServices(handle) {
923
- if (!handle.serviceRouter)
988
+ if (!handle.topology)
924
989
  return;
990
+ await handle.topology.close();
991
+ handle.topology = null;
992
+ }
993
+ async tearDownApp(handle, force = false, timeout = 10_000) {
994
+ const failures = [];
925
995
  try {
926
- await handle.serviceRouter.releaseAll();
996
+ await this.releaseExposedServices(handle);
927
997
  }
928
- catch (err) {
929
- this.logger.warn({ app: handle.name, error: err.message }, 'Releasing exposed services failed — the daemon may still advertise them');
998
+ catch (error) {
999
+ failures.push(error);
1000
+ }
1001
+ try {
1002
+ await this.tearDownProcesses(handle, force, timeout);
1003
+ }
1004
+ catch (error) {
1005
+ failures.push(error);
1006
+ }
1007
+ if (failures.length)
1008
+ throw new AggregateError(failures, `Application '${handle.name}' stop incomplete: ${failures.map(String).join('; ')}`);
1009
+ }
1010
+ /** Historical launch identity stays private to the handle; membership changes can invalidate its live release observation. */
1011
+ installedLaunches = new WeakMap();
1012
+ executionOperations = new Map();
1013
+ getExecutionCapabilities() { return OWNER_CAPABILITIES; }
1014
+ executionBusy(name) {
1015
+ return [...this.executionOperations.keys()].some(key => name === key || name.startsWith(`${key}/`));
1016
+ }
1017
+ assertExecutionIdle(scope) {
1018
+ const key = executionScopeKey(scope);
1019
+ if ([...this.executionOperations.keys()].some(active => active === key || active.startsWith(`${key}/`) || key.startsWith(`${active}/`))) {
1020
+ throw new Error(`Execution scope '${key}' is busy; wait for its stop or reconciliation before starting another operation`);
1021
+ }
1022
+ }
1023
+ /** One in-flight boundary for whole-stack and child-scope lifecycle mutations. */
1024
+ executionOperation(scope, operationId, fingerprint, work) {
1025
+ const key = executionScopeKey(scope);
1026
+ if (typeof operationId !== 'string' || !/^[a-f0-9-]{36}$/.test(operationId))
1027
+ throw new Error('Invalid execution operation identity');
1028
+ const active = this.executionOperations.get(key);
1029
+ if (active?.id === operationId && active.fingerprint === fingerprint)
1030
+ return active.promise;
1031
+ this.assertExecutionIdle(scope);
1032
+ // Reserve before invoking work, including its synchronous checks and first write.
1033
+ const promise = Promise.resolve().then(work).finally(() => this.executionOperations.delete(key));
1034
+ this.executionOperations.set(key, { id: operationId, fingerprint, promise });
1035
+ return promise;
1036
+ }
1037
+ /**
1038
+ * Reconcile an explicitly selected graph behind its durable stop fence.
1039
+ * This neither stops nor starts a process and never deletes logs or artifacts.
1040
+ * The controller's existing release selection remains the desired-state source.
1041
+ */
1042
+ reconcileStoppedStack(request) {
1043
+ const input = structuredClone(request);
1044
+ const { plan, entries, operationId } = input;
1045
+ const key = stackExecutionKey(plan);
1046
+ if (plan.application !== undefined || plan.phase !== 'stopped') {
1047
+ throw new Error('Stack reconciliation requires a completed whole-stack stop');
1048
+ }
1049
+ if (!Array.isArray(entries))
1050
+ throw new Error('Stack reconciliation requires the complete target graph');
1051
+ const target = new Map();
1052
+ for (const entry of entries) {
1053
+ if (!entry || typeof entry.name !== 'string' || !entry.name.startsWith(`${key}/`) ||
1054
+ executionScopeKey({ ...plan, application: entry.name.slice(key.length + 1) }) !== entry.name || target.has(entry.name)) {
1055
+ throw new Error('Stack reconciliation requires unique canonical applications inside its scope');
1056
+ }
1057
+ target.set(entry.name, entry);
1058
+ }
1059
+ const fingerprint = topologyRevision({ kind: 'reconcile', ...input });
1060
+ return this.executionOperation(plan, operationId, fingerprint, async () => {
1061
+ if (topologyRevision(this.stackExecutionPlan(plan)) !== topologyRevision(plan)) {
1062
+ throw new Error('Stack changed; inspect its stopped generations before reconciling');
1063
+ }
1064
+ const retained = plan.apps.map(app => {
1065
+ const handle = this.handles.get(app.name);
1066
+ return { handle, definition: handle.definitionRevision };
1067
+ });
1068
+ const assertStopped = () => {
1069
+ if (this.stoppingApps)
1070
+ throw new Error('Global application shutdown is active; wait before reconciling the stack');
1071
+ for (const { handle, definition } of retained) {
1072
+ if (this.handles.get(handle.name) !== handle || handle.definitionRevision !== definition ||
1073
+ handle.status !== 'stopped' || handle.pid !== null || handle.childProcess || handle.supervisor ||
1074
+ handle.topology || handle.topologyPools.size || this.restartCoalescer.get(handle.name)?.inFlight) {
1075
+ throw new Error(`Application '${handle.name}' is not the reviewed, fully stopped generation`);
1076
+ }
1077
+ }
1078
+ };
1079
+ assertStopped();
1080
+ // Revoke old plans durably before changing watchers or the retained inventory.
1081
+ const intent = this.stateStore.updateStackIntent(plan, current => {
1082
+ if (current.phase !== 'stopped' || current.revision !== plan.revision || current.revision === Number.MAX_SAFE_INTEGER) {
1083
+ throw new Error('Stack stop changed before reconciliation');
1084
+ }
1085
+ return { phase: 'stopped', revision: current.revision + 1, operationId, fingerprint };
1086
+ });
1087
+ for (const { handle } of retained)
1088
+ await this.discardSourceBuild(handle.name);
1089
+ assertStopped();
1090
+ const expected = { ...plan, revision: intent.revision };
1091
+ if (topologyRevision(this.stackExecutionPlan(plan)) !== topologyRevision(expected)) {
1092
+ throw new Error('Stack changed during reconciliation; it has not been enabled');
1093
+ }
1094
+ const retired = [];
1095
+ // No await between final validation and the complete inventory change.
1096
+ for (const { handle } of retained) {
1097
+ const entry = target.get(handle.name);
1098
+ if (entry)
1099
+ handle.redefine(entry);
1100
+ else {
1101
+ this.handles.delete(handle.name);
1102
+ this.clearCoolDown(handle.name);
1103
+ this.restartCoalescer.delete(handle.name);
1104
+ this.appStopIntents.delete(handle.name);
1105
+ retired.push(handle.name);
1106
+ }
1107
+ }
1108
+ this.persistState();
1109
+ for (const name of retired) {
1110
+ this.emit('app:retired', name);
1111
+ this.metricsBridge?.evictApp(name);
1112
+ }
1113
+ await this.stateStore.flush();
1114
+ this.logger.info({ project: plan.project, stack: plan.stack, revision: intent.revision, retired }, 'Stopped stack membership reconciled');
1115
+ return { project: plan.project, stack: plan.stack, revision: intent.revision, retired,
1116
+ retained: retained.filter(({ handle }) => target.has(handle.name)).map(({ handle }) => handle.name),
1117
+ added: [...target.keys()].filter(name => !plan.apps.some(app => app.name === name)), observedAt: new Date().toISOString() };
1118
+ });
1119
+ }
1120
+ /** The owner supplies generations; backend caches cannot establish stop authority. */
1121
+ async inspectStackExecution(scope) {
1122
+ return this.stackExecutionPlan(scope);
1123
+ }
1124
+ stackExecutionPlan(scope) {
1125
+ return this.executionPlan({ project: scope.project, stack: scope.stack });
1126
+ }
1127
+ async inspectExecution(scope) {
1128
+ return this.executionPlan(scope);
1129
+ }
1130
+ executionPlan(scope) {
1131
+ const key = executionScopeKey(scope);
1132
+ const names = this.listHandleNames().filter(name => executionScopeOwns(scope, name)).sort();
1133
+ if (scope.application !== undefined && names.length !== 1)
1134
+ throw new Error(`Application '${key}' is not retained by this owner`);
1135
+ if (names.some(name => this.lifecycleQueue.isBusy(name)) ||
1136
+ [...this.startingApps.keys()].some(name => executionScopeOwns(scope, name))) {
1137
+ throw new Error(`Execution scope '${key}' has active application operations; retry after they finish`);
1138
+ }
1139
+ const { revision, phase } = this.stateStore.getExecutionIntent(scope);
1140
+ const parent = scope.application !== undefined ? this.stateStore.getStackIntent(scope) : undefined;
1141
+ if (parent?.phase === 'stopping' || parent?.phase === 'starting')
1142
+ throw new Error('Parent stack has an unfinished operation');
1143
+ return { project: scope.project, stack: scope.stack, revision, phase,
1144
+ ...(scope.application !== undefined && { application: scope.application, parentRevision: parent.revision }),
1145
+ apps: names.map(name => ({ name, generation: this.handles.get(name).generation })) };
1146
+ }
1147
+ retainedApp(name, generation) {
1148
+ const handle = this.handles.get(name);
1149
+ if (!handle || handle.generation !== generation || handle.status !== 'stopped' || handle.pid !== null ||
1150
+ handle.childProcess || handle.supervisor || handle.topology || handle.topologyPools.size) {
1151
+ throw new Error(`Application '${name}' is not the retained stopped generation`);
1152
+ }
1153
+ const bare = effectiveAppName(name);
1154
+ if (this.handles.has(bare) || this.startingApps.has(bare) || this.lifecycleQueue.isBusy(bare) ||
1155
+ this.buildResults.has(name) || !handle.entry.releaseRoot || !path.isAbsolute(handle.entry.cwd ?? '') ||
1156
+ (handle.entry.bootstrap && !handle.entry.env?.['OMNITRON_STACK'])) {
1157
+ throw new Error(`Application '${name}' requires an unambiguous precompiled installed release with retained launch configuration`);
1158
+ }
1159
+ const launch = this.installedLaunches.get(handle);
1160
+ if (!launch)
1161
+ throw new Error(`Application '${name}' has no verified installed launch recorded for its generation`);
1162
+ if (launch.binding.entrySha256 !== installedEntryRevision(handle.entry, launch.config, this.cwd)) {
1163
+ throw new Error(`Application '${name}' launch configuration changed since its verified launch`);
1164
+ }
1165
+ return { handle, ...launch };
1166
+ }
1167
+ /** A stopped intent is insufficient if its handles or their launch inputs disappeared. */
1168
+ async inspectInstalledStack(scope) {
1169
+ const plan = this.stackExecutionPlan(scope);
1170
+ if (plan.phase !== 'stopped' || !plan.apps.length)
1171
+ throw new Error('Installed stack start requires a completed stop with retained applications');
1172
+ for (const item of plan.apps)
1173
+ this.assertApplicationFence(item.name);
1174
+ const apps = [];
1175
+ for (const item of plan.apps) {
1176
+ const { handle, binding } = this.retainedApp(item.name, item.generation);
1177
+ const entry = handle.entry;
1178
+ const executable = installedExecutable(entry, this.cwd);
1179
+ const paths = [executable, ...(handle.topologyProcesses ?? []).map(child => path.resolve(path.dirname(executable), child.module))];
1180
+ const release = await verifyLaunchRelease(entry, item.generation, paths);
1181
+ requireInstalledBinding(release, binding.entrySha256, binding);
1182
+ apps.push({ ...item, installed: { ...binding } });
1183
+ }
1184
+ for (const item of plan.apps)
1185
+ this.retainedApp(item.name, item.generation);
1186
+ if (topologyRevision(this.stackExecutionPlan(scope)) !== topologyRevision(plan)) {
1187
+ throw new Error('Installed stack changed during inspection; prepare a new start');
1188
+ }
1189
+ return { ...plan, apps };
1190
+ }
1191
+ async openInstalledStack({ operationId, plan }) {
1192
+ if (typeof operationId !== 'string' || !/^[a-f0-9-]{36}$/.test(operationId))
1193
+ throw new Error('Invalid start operation identity');
1194
+ this.assertExecutionIdle(plan);
1195
+ const observed = this.stackExecutionPlan(plan);
1196
+ if (observed.phase !== 'stopped' || plan.phase !== 'stopped' || observed.revision !== plan.revision ||
1197
+ !observed.apps.length || observed.apps.length !== plan.apps.length ||
1198
+ observed.apps.some((item, index) => {
1199
+ const expected = plan.apps[index];
1200
+ if (!expected?.installed || expected.name !== item.name || expected.generation !== item.generation)
1201
+ return true;
1202
+ return topologyRevision(this.retainedApp(item.name, item.generation).binding) !== topologyRevision(expected.installed);
1203
+ }))
1204
+ throw new Error('Installed stack changed; prepare a new start');
1205
+ for (const item of plan.apps)
1206
+ this.assertApplicationFence(item.name);
1207
+ const fingerprint = topologyRevision(plan);
1208
+ this.stateStore.updateStackIntent(plan, current => {
1209
+ if (current.phase !== 'stopped' || current.revision !== plan.revision || current.revision === Number.MAX_SAFE_INTEGER) {
1210
+ throw new Error('Installed stack stop is no longer current');
1211
+ }
1212
+ return { phase: 'starting', revision: current.revision + 1, operationId, fingerprint, remaining: plan.apps.map(app => app.name) };
1213
+ });
1214
+ }
1215
+ async resumeInstalledApp({ operationId, plan, name }) {
1216
+ const app = plan.apps.find(item => item.name === name);
1217
+ if (!app?.installed || !name.startsWith(`${stackExecutionKey(plan)}/`))
1218
+ throw new Error('Application is outside the prepared installed stack');
1219
+ const expected = app.installed;
1220
+ const fingerprint = topologyRevision(plan);
1221
+ const stopGeneration = this.stopGeneration;
1222
+ const stopRevision = this.appStopIntents.get(name)?.revision;
1223
+ await this.lifecycleQueue.enqueue(name, 'start', async () => {
1224
+ const { handle, config } = this.retainedApp(name, app.generation);
1225
+ const entry = structuredClone(handle.entry);
1226
+ if (this.stoppingApps || this.stopGeneration !== stopGeneration ||
1227
+ installedEntryRevision(entry, config, this.cwd) !== expected.entrySha256) {
1228
+ throw new Error('Installed start admission changed');
1229
+ }
1230
+ // Reserve before the first effect. A crash or lost reply cannot authorize a second attempt.
1231
+ this.stateStore.updateStackIntent(plan, current => {
1232
+ if (current.phase !== 'starting' || current.operationId !== operationId || current.fingerprint !== fingerprint ||
1233
+ current.pendingApp || !current.remaining?.includes(name))
1234
+ throw new Error('Installed start is stale, busy or already consumed');
1235
+ return { ...current, pendingApp: name };
1236
+ });
1237
+ await this.ensureBootReconciled(config);
1238
+ this.retainedApp(name, app.generation);
1239
+ // Introspection loads bootstrap code. Verify it before reading the process topology;
1240
+ // the final launch verification binds the child modules discovered there.
1241
+ if (entry.bootstrap) {
1242
+ const evidence = await verifyLaunchRelease(entry, app.generation, [installedExecutable(entry, this.cwd)]);
1243
+ requireInstalledBinding(evidence, installedEntryRevision(entry, config, this.cwd), expected);
1244
+ this.retainedApp(name, app.generation);
1245
+ }
1246
+ if (this.stoppingApps || this.stopGeneration !== stopGeneration ||
1247
+ stopRevision !== this.appStopIntents.get(name)?.revision)
1248
+ throw new Error('Stop interrupted installed start admission');
1249
+ const intent = this.appStopIntents.get(name);
1250
+ if (intent)
1251
+ intent.stopped = false;
1252
+ const started = await this.startAppInternal(entry, config, expected);
1253
+ if (started.status !== 'online')
1254
+ throw new Error(`Installed application '${name}' did not come online`);
1255
+ requireInstalledBinding(started.release, installedEntryRevision(started.entry, config, this.cwd), expected);
1256
+ this.stateStore.updateStackIntent(plan, current => {
1257
+ if (current.phase !== 'starting' || current.operationId !== operationId || current.fingerprint !== fingerprint ||
1258
+ current.pendingApp !== name)
1259
+ throw new Error('Installed start was superseded');
1260
+ const remaining = current.remaining.filter(item => item !== name);
1261
+ if (!remaining.length && plan.apps.some(item => this.handles.get(item.name)?.status !== 'online')) {
1262
+ throw new Error('Installed start incomplete: previously started application is no longer online');
1263
+ }
1264
+ return remaining.length ? { phase: 'starting', revision: current.revision, operationId, fingerprint, remaining }
1265
+ : { phase: 'running', revision: current.revision };
1266
+ });
1267
+ });
1268
+ }
1269
+ async enableStackExecution(scope, options = {}) {
1270
+ return this.enableExecution({ project: scope.project, stack: scope.stack }, options);
1271
+ }
1272
+ async enableExecution(scope, options = {}) {
1273
+ const key = executionScopeKey(scope);
1274
+ this.assertExecutionIdle(scope);
1275
+ if (scope.application !== undefined && this.stateStore.getStackIntent(scope).phase !== 'running') {
1276
+ throw new Error('Parent stack must be running before admitting an application start');
1277
+ }
1278
+ this.stateStore.updateExecutionIntent(scope, current => {
1279
+ if (scope.application !== undefined && (!Number.isSafeInteger(options.expectedRevision) || options.expectedRevision !== current.revision)) {
1280
+ throw new Error('Application execution intent changed; inspect it before admitting a start');
1281
+ }
1282
+ if (current.phase === 'starting')
1283
+ throw new Error(`Stack '${key}' has an unfinished installed start; inspect and stop it before starting again`);
1284
+ if (current.phase === 'stopping')
1285
+ throw new Error(`Stack '${key}' has an unconfirmed stop; complete it before starting`);
1286
+ if (current.phase === 'running')
1287
+ return current;
1288
+ if (options.automatic)
1289
+ throw new Error(`Stack '${key}' was deliberately stopped; an explicit stack start is required`);
1290
+ if (current.revision === Number.MAX_SAFE_INTEGER)
1291
+ throw new Error('Stack execution revision exhausted');
1292
+ return { revision: current.revision + 1, phase: 'running' };
1293
+ });
1294
+ }
1295
+ stopStackExecution(request) {
1296
+ if (request.plan.application !== undefined)
1297
+ throw new Error('Use the scoped execution contract for an application stop');
1298
+ return this.stopExecution(request);
1299
+ }
1300
+ stopExecution(request) {
1301
+ const fingerprint = topologyRevision({ kind: 'stop', plan: request.plan });
1302
+ return this.executionOperation(request.plan, request.operationId, fingerprint, () => this.stopExecutionNow(request));
1303
+ }
1304
+ async stopExecutionNow({ operationId, plan }) {
1305
+ const key = executionScopeKey(plan);
1306
+ const fingerprint = createHash('sha256').update(JSON.stringify(plan)).digest('hex');
1307
+ const prior = this.stateStore.getExecutionIntent(plan);
1308
+ const retry = prior.operationId === operationId && prior.fingerprint === fingerprint;
1309
+ if (prior.operationId === operationId && !retry)
1310
+ throw new Error('Stop operation identity was reused with different arguments');
1311
+ if (!retry) {
1312
+ const observed = this.executionPlan(plan);
1313
+ if (JSON.stringify(observed) !== JSON.stringify(plan))
1314
+ throw new Error(`Stack '${key}' changed; prepare a new stop`);
1315
+ }
1316
+ // A durable stop fence also covers crash recovery and file-watch restarts.
1317
+ // No newly admitted start may pass it while this operation awaits exits.
1318
+ const assertParent = () => {
1319
+ if (plan.application === undefined)
1320
+ return;
1321
+ const parent = this.stateStore.getStackIntent(plan);
1322
+ if (parent.revision !== plan.parentRevision || parent.phase === 'starting' || parent.phase === 'stopping') {
1323
+ throw new Error('Parent stack intent changed; inspect before retrying the application operation');
1324
+ }
1325
+ };
1326
+ assertParent();
1327
+ const intent = this.stateStore.updateExecutionIntent(plan, current => {
1328
+ if (current.operationId === operationId && current.fingerprint === fingerprint)
1329
+ return current;
1330
+ if (current.revision !== plan.revision)
1331
+ throw new Error(`Stack '${key}' intent changed; prepare a new stop`);
1332
+ if (current.revision === Number.MAX_SAFE_INTEGER)
1333
+ throw new Error('Stack execution revision exhausted');
1334
+ return { revision: current.revision + 1, phase: 'stopping', operationId, fingerprint };
1335
+ });
1336
+ const failures = [];
1337
+ for (const expected of [...plan.apps].reverse()) {
1338
+ assertParent();
1339
+ const handle = this.handles.get(expected.name);
1340
+ if (!executionScopeOwns(plan, expected.name) || !handle || handle.generation !== expected.generation) {
1341
+ failures.push(new Error(`Application '${expected.name}' changed generation; inspect before retrying`));
1342
+ continue;
1343
+ }
1344
+ try {
1345
+ await this.stopApp(expected.name);
1346
+ }
1347
+ catch (error) {
1348
+ failures.push(error);
1349
+ }
1350
+ }
1351
+ const survivors = this.listHandleNames().filter(name => executionScopeOwns(plan, name) && this.handles.get(name)?.status !== 'stopped');
1352
+ if (survivors.length)
1353
+ failures.push(new Error(`Exit unconfirmed for: ${survivors.join(', ')}`));
1354
+ if (failures.length)
1355
+ throw new AggregateError(failures, `Stack '${key}' stop incomplete: ${failures.map(String).join('; ')}`);
1356
+ assertParent();
1357
+ this.stateStore.updateExecutionIntent(plan, current => {
1358
+ if (current.revision !== intent.revision || current.operationId !== operationId)
1359
+ throw new Error('Stack stop authority changed');
1360
+ return { ...current, phase: 'stopped' };
1361
+ });
1362
+ return { project: plan.project, stack: plan.stack, operationId, revision: intent.revision,
1363
+ ...(plan.application !== undefined && { application: plan.application }),
1364
+ stopped: plan.apps.map(app => app.name), observedAt: new Date().toISOString() };
1365
+ }
1366
+ assertAppStartAllowed(name) {
1367
+ const parts = name.split('/');
1368
+ // Stack stops own the whole prefix, including retained legacy nested names.
1369
+ // Admission must enforce the same boundary before recovery or watch can restart them.
1370
+ if (parts.length < 3)
1371
+ return;
1372
+ const scope = { project: parts[0], stack: parts[1] };
1373
+ this.assertExecutionIdle({ ...scope, ...(parts.length === 3 && { application: parts[2] }) });
1374
+ const phase = this.stateStore.getStackIntent(scope).phase;
1375
+ if (phase === 'starting')
1376
+ throw new Error(`Stack '${stackExecutionKey(scope)}' has an unfinished installed stack start; inspect its receipt and stop before retrying`);
1377
+ if (phase !== 'running') {
1378
+ throw new Error(`Stack '${stackExecutionKey(scope)}' is stopped or stopping; use stack start after confirming its stop`);
1379
+ }
1380
+ this.assertApplicationFence(name);
1381
+ }
1382
+ assertApplicationFence(name) {
1383
+ const parts = name.split('/');
1384
+ if (parts.length !== 3)
1385
+ return;
1386
+ const scope = { project: parts[0], stack: parts[1], application: parts[2] };
1387
+ if (this.stateStore.getExecutionIntent(scope).phase !== 'running') {
1388
+ throw new Error(`Application '${name}' is fenced; inspect and explicitly admit its start`);
930
1389
  }
931
- handle.serviceRouter = null;
932
1390
  }
933
1391
  async stopApp(name, force = false, timeout = 10_000) {
934
1392
  const canonical = this.resolveAppName(name) ?? name;
935
1393
  // Outside the queue on purpose: the operator's intent lands the
936
1394
  // moment the command arrives, not whenever the queue drains.
1395
+ // Unknown names need no retained intent. Start admission registers its
1396
+ // token before its first await, including before a handle exists.
1397
+ if (this.handles.has(canonical) || this.appStopIntents.has(canonical)) {
1398
+ this.appStopIntents.set(canonical, {
1399
+ revision: (this.appStopIntents.get(canonical)?.revision ?? 0) + 1,
1400
+ stopped: true,
1401
+ });
1402
+ }
937
1403
  this.clearCoolDown(canonical);
1404
+ const restart = this.restartCoalescer.get(canonical);
1405
+ if (restart) {
1406
+ restart.manualSerial = 0;
1407
+ restart.watchSerial = 0;
1408
+ restart.cooldownUntil = 0;
1409
+ }
938
1410
  return this.lifecycleQueue.enqueue(canonical, 'stop', async () => {
939
1411
  const handle = this.handles.get(canonical);
940
- if (!handle || handle.status === 'stopped')
1412
+ if (!handle || (handle.status === 'stopped' && !handle.topology && !handle.supervisor && !handle.childProcess && handle.topologyPools.size === 0))
941
1413
  return;
942
1414
  handle.markStopping();
943
- // Unexpose topology services from daemon Netron before stopping processes
944
- await this.releaseExposedServices(handle);
945
- await this.tearDownProcesses(handle, force, timeout);
1415
+ await this.tearDownApp(handle, force, timeout);
946
1416
  handle.markStopped();
947
1417
  this.persistState();
948
1418
  this.logger.info({ app: name }, 'App stopped');
949
1419
  });
950
1420
  }
951
- async stopAll(force = false) {
1421
+ stopAll(force = false) {
1422
+ if (this.stoppingApps)
1423
+ return this.stoppingApps;
1424
+ this.stopGeneration++;
1425
+ for (const name of this.coolDownTimers.keys())
1426
+ this.clearCoolDown(name);
1427
+ const operation = Promise.resolve().then(() => this.stopAllOnce(force));
1428
+ this.stoppingApps = operation;
1429
+ const settled = () => { if (this.stoppingApps === operation)
1430
+ this.stoppingApps = null; };
1431
+ void operation.then(settled, settled);
1432
+ return operation;
1433
+ }
1434
+ async stopAllOnce(force) {
952
1435
  if (this.metricsTimer) {
953
1436
  clearInterval(this.metricsTimer);
954
1437
  this.metricsTimer = null;
@@ -959,6 +1442,7 @@ export class OrchestratorService extends EventEmitter {
959
1442
  this.janitor.stop();
960
1443
  }
961
1444
  let count = 0;
1445
+ const failures = [];
962
1446
  // When force=true (daemon shutdown), use short timeout per app (3s SIGTERM, then SIGKILL)
963
1447
  const perAppTimeout = force ? 3_000 : 10_000;
964
1448
  // Registered projects need not belong to the daemon's root ecosystem.
@@ -995,26 +1479,28 @@ export class OrchestratorService extends EventEmitter {
995
1479
  count++;
996
1480
  }
997
1481
  catch (err) {
1482
+ failures.push(new Error(`Application '${entry.name}' stop failed: ${String(err)}`, { cause: err }));
998
1483
  this.logger.error({ app: entry.name, error: err.message }, 'Failed to stop');
999
1484
  }
1000
1485
  }));
1001
1486
  }
1002
- try {
1003
- await this.pm.shutdown({ force, timeout: force ? 5_000 : 30_000 });
1004
- }
1005
- catch {
1006
- /* PM may have nothing left to clean up */
1007
- }
1487
+ // Stop-all is a reversible application operation. The resident owner (or
1488
+ // Titan lifecycle) owns terminal ProcessManager shutdown, including workers
1489
+ // outside application handles. Keeping that boundary permits startAll later.
1008
1490
  // Dispose esbuild watch contexts
1009
1491
  if (this.buildService) {
1010
1492
  try {
1011
1493
  await this.buildService.dispose();
1494
+ this.buildService = null;
1495
+ }
1496
+ catch (error) {
1497
+ failures.push(error);
1012
1498
  }
1013
- catch { /* best-effort */ }
1014
- this.buildService = null;
1015
1499
  }
1016
1500
  this.buildResults.clear();
1017
1501
  this.bootstrapSources.clear();
1502
+ if (failures.length)
1503
+ throw new AggregateError(failures, `Application shutdown incomplete: ${failures.map(String).join('; ')}`);
1018
1504
  return count;
1019
1505
  }
1020
1506
  /**
@@ -1027,6 +1513,12 @@ export class OrchestratorService extends EventEmitter {
1027
1513
  const handle = this.handles.get(this.resolveAppName(name) ?? name);
1028
1514
  if (!handle)
1029
1515
  return false;
1516
+ const [project, stack, app] = handle.name.split('/');
1517
+ if (project && stack && app)
1518
+ this.assertExecutionIdle({ project, stack });
1519
+ if (project && stack && app && this.stateStore.getStackIntent({ project, stack }).phase === 'starting') {
1520
+ throw new Error('An installed stack start is active; its application entry cannot be changed');
1521
+ }
1030
1522
  handle.redefine(entry);
1031
1523
  if (!this.allowsWatch(entry)) {
1032
1524
  const state = this.restartCoalescer.get(handle.name);
@@ -1125,6 +1617,7 @@ export class OrchestratorService extends EventEmitter {
1125
1617
  throw new Error(`Unknown app: ${name}`);
1126
1618
  }
1127
1619
  name = canonical;
1620
+ this.assertAppStartAllowed(name);
1128
1621
  const state = this.getCoalescerState(name);
1129
1622
  if (fromExternal) {
1130
1623
  state.triggerSerial += 1;
@@ -1229,11 +1722,22 @@ export class OrchestratorService extends EventEmitter {
1229
1722
  const handle = this.handles.get(name);
1230
1723
  if (!handle)
1231
1724
  throw new Error(`Unknown app: ${name}`);
1725
+ this.assertAppStartAllowed(name);
1232
1726
  const entry = handle.entry;
1727
+ const definitionRevision = handle.definitionRevision;
1233
1728
  if (this.devMode && entry.bootstrap) {
1234
1729
  clearCacheFor(path.resolve(entry.cwd ?? this.cwd, entry.bootstrap));
1235
1730
  }
1236
- await this.stopApp(name);
1731
+ const stopped = this.stopApp(name);
1732
+ const intent = this.appStopIntents.get(name);
1733
+ const generation = this.stopGeneration;
1734
+ await stopped;
1735
+ if (this.stoppingApps || generation !== this.stopGeneration || intent !== this.appStopIntents.get(name)) {
1736
+ throw new Error('Application stop interrupted restart');
1737
+ }
1738
+ if (this.handles.get(name) !== handle || handle.definitionRevision !== definitionRevision || handle.entry !== entry) {
1739
+ throw new Error(`Application '${name}' definition changed while stopping; restart was cancelled. Inspect the current definition and start it explicitly.`);
1740
+ }
1237
1741
  return this.startApp(entry);
1238
1742
  }
1239
1743
  getCoalescerState(name) {
@@ -1314,6 +1818,7 @@ export class OrchestratorService extends EventEmitter {
1314
1818
  if (!handle)
1315
1819
  throw new Error(`Unknown app: ${name}`);
1316
1820
  name = canonical;
1821
+ this.assertAppStartAllowed(name);
1317
1822
  // Classic mode or no supervisor — cannot do zero-downtime, fall back to restart
1318
1823
  if (handle.mode !== 'bootstrap' || !handle.supervisor) {
1319
1824
  return this.restartApp(name);
@@ -1322,33 +1827,39 @@ export class OrchestratorService extends EventEmitter {
1322
1827
  if (childNames.length === 0) {
1323
1828
  return this.restartApp(name);
1324
1829
  }
1325
- this.logger.info({ app: name, children: childNames.length }, 'Zero-downtime reload starting');
1326
- // For each child process, do a rolling restart via the supervisor.
1327
- // The supervisor's restartChild stops the old child and starts a new one.
1328
- // For pool children, the pool handles draining automatically.
1329
- // We restart one child at a time to maintain availability.
1330
- for (const childName of childNames) {
1331
- this.logger.info({ app: name, child: childName }, 'Reloading child process');
1332
- try {
1333
- await handle.supervisor.restartChild(childName);
1334
- // Wait for the new child to become healthy
1335
- const health = await this.waitForChildHealth(handle, childName, 30_000);
1336
- if (!health) {
1337
- this.logger.warn({ app: name, child: childName }, 'Child did not become healthy after reload — continuing with remaining children');
1830
+ return this.lifecycleQueue.enqueue(name, 'restart', async () => {
1831
+ this.assertAppStartAllowed(name);
1832
+ if (this.handles.get(name) !== handle)
1833
+ throw new Error('Application changed while queued; retry the operation');
1834
+ this.logger.info({ app: name, children: childNames.length }, 'Zero-downtime reload starting');
1835
+ handle.invalidateRelease();
1836
+ // For each child process, do a rolling restart via the supervisor.
1837
+ // The supervisor's restartChild stops the old child and starts a new one.
1838
+ // For pool children, the pool handles draining automatically.
1839
+ // We restart one child at a time to maintain availability.
1840
+ for (const childName of childNames) {
1841
+ this.logger.info({ app: name, child: childName }, 'Reloading child process');
1842
+ try {
1843
+ await handle.supervisor.restartChild(childName);
1844
+ // Wait for the new child to become healthy
1845
+ const health = await this.waitForChildHealth(handle, childName, 30_000);
1846
+ if (!health) {
1847
+ this.logger.warn({ app: name, child: childName }, 'Child did not become healthy after reload — continuing with remaining children');
1848
+ }
1849
+ this.logger.info({ app: name, child: childName }, 'Child reloaded successfully');
1850
+ }
1851
+ catch (err) {
1852
+ // `error: err`, not `error: err.message`: the logger aliases `error`
1853
+ // onto pino's error serializer, so the object arrives with its stack
1854
+ // and a string arrives as a string with nothing behind it.
1855
+ this.logger.error({ app: name, child: childName, error: err }, 'Failed to reload child — aborting zero-downtime reload');
1856
+ throw new Error(`Zero-downtime reload failed for '${name}' at child '${childName}': ${err.message}`, { cause: err });
1338
1857
  }
1339
- this.logger.info({ app: name, child: childName }, 'Child reloaded successfully');
1340
- }
1341
- catch (err) {
1342
- // `error: err`, not `error: err.message`: the logger aliases `error`
1343
- // onto pino's error serializer, so the object arrives with its stack
1344
- // and a string arrives as a string with nothing behind it.
1345
- this.logger.error({ app: name, child: childName, error: err }, 'Failed to reload child — aborting zero-downtime reload');
1346
- throw new Error(`Zero-downtime reload failed for '${name}' at child '${childName}': ${err.message}`, { cause: err });
1347
1858
  }
1348
- }
1349
- this.logger.info({ app: name }, 'Zero-downtime reload complete');
1350
- this.persistState();
1351
- return handle;
1859
+ this.logger.info({ app: name }, 'Zero-downtime reload complete');
1860
+ this.persistState();
1861
+ return handle;
1862
+ });
1352
1863
  }
1353
1864
  /**
1354
1865
  * Wait for a child process to report healthy status within a timeout.
@@ -1375,29 +1886,58 @@ export class OrchestratorService extends EventEmitter {
1375
1886
  // ============================================================================
1376
1887
  // Scaling — delegates to PM supervisor
1377
1888
  // ============================================================================
1378
- async scaleApp(name, instances) {
1379
- const canonical = this.resolveAppName(name) ?? name;
1889
+ async scaleApp(name, instances, process) {
1890
+ const request = parsePoolScaleRequest({ name, instances, process });
1891
+ const canonical = this.resolveAppName(request.name) ?? request.name;
1892
+ assertPoolScaleTarget(this.getApp(canonical), request);
1380
1893
  const handle = this.handles.get(canonical);
1381
- if (!handle)
1382
- throw new Error(`Unknown app: ${name}`);
1383
- name = canonical;
1384
- if (!this.config)
1385
- throw new Error('Ecosystem config not loaded');
1386
- if (handle.mode !== 'bootstrap') {
1387
- this.logger.warn({ app: name }, 'Classic mode apps do not support scaling');
1894
+ const generation = handle.generation;
1895
+ this.assertAppStartAllowed(canonical);
1896
+ return this.lifecycleQueue.enqueue(canonical, 'restart', async () => {
1897
+ this.assertAppStartAllowed(canonical);
1898
+ if (this.handles.get(canonical) !== handle || handle.generation !== generation)
1899
+ throw new Error('Application changed while queued; retry the operation');
1900
+ assertPoolScaleTarget(this.getApp(canonical), request);
1901
+ if (handle.status !== 'online')
1902
+ throw Errors.conflict('Process pools can only be resized while the application is online');
1903
+ const declaration = handle.topologyProcesses.find(item => item.name === request.process);
1904
+ const pool = handle.topologyPools.get(request.process);
1905
+ if (!pool)
1906
+ throw Errors.conflict('Declared process pool is not running');
1907
+ const declared = declaration.instances;
1908
+ const automatic = declaration.scaling?.strategy === 'auto';
1909
+ const minimum = automatic ? declared : 1;
1910
+ const maximum = declaration.scaling?.maxInstances ?? (automatic ? declared * 4 : declared);
1911
+ if (!Number.isSafeInteger(declared) || declared < 2 || !Number.isSafeInteger(maximum) || maximum < declared)
1912
+ throw new Error('Process pool has invalid declared scaling limits');
1913
+ if (request.instances < minimum || request.instances > maximum)
1914
+ throw Errors.badRequest(`Process pool resize must stay within declared limits ${minimum}..${maximum}`);
1915
+ if (pool.size === request.instances)
1916
+ return handle;
1917
+ this.logger.info({ app: canonical, process: request.process, from: pool.size, to: request.instances,
1918
+ automatic, lifetime: 'until-restart' }, 'Resizing a declared process pool');
1919
+ handle.invalidateRelease();
1920
+ // PM owns membership serialization and waits for every admitted spawn/exit.
1921
+ // The source declaration and installed entry remain unchanged. Automatic
1922
+ // pools retain their policy and can subsequently resize within its limits.
1923
+ await pool.scale(request.instances);
1924
+ if (pool.size !== request.instances)
1925
+ throw new Error('Process pool resize is unconfirmed; inspect its observed membership');
1926
+ this.persistState(); // Observations only, never a durable desired-size override.
1388
1927
  return handle;
1389
- }
1390
- if (instances < 1)
1391
- throw new Error('Instance count must be at least 1');
1392
- if (instances === handle.instanceCount)
1393
- return handle;
1394
- if (!handle.supervisor)
1395
- throw new Error(`No supervisor for app: ${name}`);
1396
- this.logger.info({ app: name, from: handle.instanceCount, to: instances }, 'Scaling app');
1397
- await handle.supervisor.scaleChild(name, instances);
1398
- handle.instanceCount = instances;
1399
- this.persistState();
1400
- return handle;
1928
+ });
1929
+ }
1930
+ async restartAppChild(name, child) {
1931
+ const canonical = this.resolveAppName(name) ?? name;
1932
+ this.assertAppStartAllowed(canonical);
1933
+ await this.lifecycleQueue.enqueue(canonical, 'restart', async () => {
1934
+ this.assertAppStartAllowed(canonical);
1935
+ const supervisor = this.handles.get(canonical)?.supervisor;
1936
+ if (!supervisor)
1937
+ throw new Error(`No supervisor for '${canonical}'`);
1938
+ this.handles.get(canonical)?.invalidateRelease();
1939
+ await supervisor.restartChild(child);
1940
+ });
1401
1941
  }
1402
1942
  // ============================================================================
1403
1943
  // Information
@@ -1503,6 +2043,13 @@ export class OrchestratorService extends EventEmitter {
1503
2043
  }
1504
2044
  return result;
1505
2045
  }
2046
+ configureReadiness(declarations) {
2047
+ this.readinessMonitor.configure(declarations);
2048
+ }
2049
+ hasDeclaredReadiness(name) {
2050
+ const handle = this.getHandle(name);
2051
+ return Boolean(handle && this.readinessMonitor.isConfigured(handle.entry));
2052
+ }
1506
2053
  /**
1507
2054
  * Each app's health, asked of every process it runs — its supervisor
1508
2055
  * children and its worker pools — and combined (`app-health.ts`).
@@ -1517,12 +2064,11 @@ export class OrchestratorService extends EventEmitter {
1517
2064
  if (name !== undefined && wanted === undefined)
1518
2065
  return {};
1519
2066
  const result = {};
1520
- for (const [appName, handle] of this.handles) {
1521
- if (wanted && appName !== wanted)
1522
- continue;
2067
+ const entries = [...this.handles].filter(([appName]) => !wanted || appName === wanted);
2068
+ const measure = async ([appName, handle]) => {
1523
2069
  if (handle.status !== 'online') {
1524
2070
  result[appName] = notRunningHealth(handle.status);
1525
- continue;
2071
+ return;
1526
2072
  }
1527
2073
  if (handle.mode === 'bootstrap' && handle.supervisor) {
1528
2074
  const supervisor = handle.supervisor;
@@ -1530,14 +2076,40 @@ export class OrchestratorService extends EventEmitter {
1530
2076
  for (const [pool, instance] of handle.topologyPools) {
1531
2077
  answers.push([pool, poolHealth(instance.metrics)]);
1532
2078
  }
1533
- const health = answers.length > 0 ? combineProcessHealth(answers) : handle.lastHealth;
2079
+ if (handle.entry && this.readinessMonitor.isConfigured(handle.entry))
2080
+ answers.push(['readiness', await this.readinessMonitor.check(handle, handle.entry, handle.healthRunId)]);
2081
+ const health = handle.status !== 'online' ? notRunningHealth(handle.status)
2082
+ : answers.length > 0 ? combineProcessHealth(answers) : handle.lastHealth;
1534
2083
  handle.lastHealth = health;
1535
2084
  result[appName] = health;
1536
2085
  }
1537
2086
  else {
1538
- result[appName] = handle.lastHealth;
2087
+ const runId = handle.healthRunId;
2088
+ const declaration = handle.entry;
2089
+ const measured = await this.readinessMonitor.check(handle, declaration, runId);
2090
+ if (runId !== handle.healthRunId || declaration !== handle.entry) {
2091
+ result[appName] = { timestamp: Date.now(), status: 'degraded', checks: [{ name: 'readiness', status: 'warn', message: 'measurement_superseded: application restarted or its declaration changed during this probe; request a fresh measurement.' }] };
2092
+ return;
2093
+ }
2094
+ const health = handle.status === 'online' ? measured : notRunningHealth(handle.status);
2095
+ handle.lastHealth = health;
2096
+ result[appName] = health;
2097
+ const signature = JSON.stringify([health.status, health.checks.map(c => [c.name, c.status, c.status === 'pass' ? '' : c.message])]);
2098
+ if (this.readinessSignatures.get(handle) !== signature) {
2099
+ this.readinessSignatures.set(handle, signature);
2100
+ const details = { event: 'application.readiness.changed', app: appName, status: health.status, checks: health.checks };
2101
+ if (health.status === 'healthy')
2102
+ this.logger.info(details, 'Application readiness verified');
2103
+ else if (health.status === 'degraded')
2104
+ this.logger.warn(details, 'Application readiness needs attention');
2105
+ else
2106
+ this.logger.error(details, 'Application readiness failed');
2107
+ }
1539
2108
  }
1540
- }
2109
+ };
2110
+ // Keep a fleet of failed endpoints from serializing the entire health response.
2111
+ for (let offset = 0; offset < entries.length; offset += 4)
2112
+ await Promise.all(entries.slice(offset, offset + 4).map(measure));
1541
2113
  return result;
1542
2114
  }
1543
2115
  /**
@@ -1626,8 +2198,11 @@ export class OrchestratorService extends EventEmitter {
1626
2198
  // ============================================================================
1627
2199
  // Private — Launch
1628
2200
  // ============================================================================
1629
- async launchClassicMode(entry, handle, config) {
1630
- const child = await launchClassic(entry, handle, this.cwd, this.logger, this.appLogHandlers);
2201
+ async launchClassicMode(entry, handle, config, installed) {
2202
+ handle.release = await verifyLaunchRelease(entry, handle.generation, [installedExecutable(entry, this.cwd)]);
2203
+ const launch = entry.releaseRoot || installed || handle.release.state === 'confirmed'
2204
+ ? requireInstalledBinding(handle.release, installedEntryRevision(entry, config, this.cwd), installed) : undefined;
2205
+ const child = await launchClassic(entry, handle, this.cwd, this.logger, this.appLogHandlers, Boolean(installed));
1631
2206
  child.on('exit', (code, signal) => {
1632
2207
  if (handle.status === 'stopping') {
1633
2208
  handle.markStopped();
@@ -1639,6 +2214,7 @@ export class OrchestratorService extends EventEmitter {
1639
2214
  }
1640
2215
  this.persistState();
1641
2216
  });
2217
+ return launch;
1642
2218
  }
1643
2219
  /**
1644
2220
  * Launch bootstrap app via PM ProcessSupervisor.
@@ -1647,7 +2223,7 @@ export class OrchestratorService extends EventEmitter {
1647
2223
  * all topology children (server + worker pools) and wires IPC relay between them.
1648
2224
  * Otherwise, creates a single bootstrap-process as before.
1649
2225
  */
1650
- async launchBootstrapMode(entry, handle, config) {
2226
+ async launchBootstrapMode(entry, handle, config, installed) {
1651
2227
  handle.markStarting();
1652
2228
  const bootstrapAbsPath = path.resolve(entry.cwd ?? this.cwd, entry.bootstrap);
1653
2229
  // Load bootstrap definition to check for process topology and requirements.
@@ -1661,7 +2237,9 @@ export class OrchestratorService extends EventEmitter {
1661
2237
  let topology;
1662
2238
  let definition;
1663
2239
  try {
1664
- definition = await loadBootstrapConfig(bootstrapAbsPath, { devMode: this.devMode, freshModuleGraph: true });
2240
+ const captured = await readBootstrapMetadata(bootstrapAbsPath, this.devMode && !entry.releaseRoot, 60_000);
2241
+ definition = captured.definition;
2242
+ handle.bootstrapMetadata = captured.metadata;
1665
2243
  topology = definition.processes;
1666
2244
  }
1667
2245
  catch (err) {
@@ -1703,7 +2281,7 @@ export class OrchestratorService extends EventEmitter {
1703
2281
  }
1704
2282
  // Resolve infrastructure config and inject as env vars.
1705
2283
  // Skip if already injected by project.service.ts (stack flow sets OMNITRON_STACK).
1706
- const alreadyResolved = !!(entry.env?.['OMNITRON_STACK'] && entry.env?.['DATABASE_URL']);
2284
+ const alreadyResolved = !!entry.env?.['OMNITRON_STACK'];
1707
2285
  if (!alreadyResolved && (definition?.requires || definition?.omnitronConfig)) {
1708
2286
  try {
1709
2287
  const { resolveStack, resolvedConfigToEnv } = await import('../project/config-resolver.js');
@@ -1719,7 +2297,7 @@ export class OrchestratorService extends EventEmitter {
1719
2297
  if (appConfig) {
1720
2298
  const envVars = resolvedConfigToEnv(appConfig, entry.name, stackName);
1721
2299
  if (Object.keys(envVars).length > 0) {
1722
- entry.env = { ...entry.env, ...envVars };
2300
+ entry.env = { ...envVars, ...entry.env };
1723
2301
  this.logger.debug({ app: entry.name, envCount: Object.keys(envVars).length }, 'Injected resolved infrastructure config as env vars');
1724
2302
  }
1725
2303
  }
@@ -1730,23 +2308,44 @@ export class OrchestratorService extends EventEmitter {
1730
2308
  }
1731
2309
  // Build all entry points via esbuild (dev mode bundles from source .ts)
1732
2310
  //
1733
- if (definition)
2311
+ if (installed && this.buildResults.has(entry.name)) {
2312
+ throw new Error('Installed stack start cannot use a development build');
2313
+ }
2314
+ if (definition && !installed)
1734
2315
  await this.prepareBootstrapBuild(entry, bootstrapAbsPath, definition);
1735
2316
  const buildResult = this.buildResults.get(entry.name);
1736
2317
  // Use bundled bootstrap path for topology import when available
1737
2318
  const effectiveBootstrapPath = buildResult?.bootstrapPath ?? bootstrapAbsPath;
2319
+ handle.release = buildResult
2320
+ ? { state: 'unreported', reason: 'This launch uses a generated build; an installed release receipt cannot identify that executable.' }
2321
+ : await verifyLaunchRelease(entry, handle.generation, [bootstrapAbsPath, ...(topology ?? []).map(process => path.resolve(path.dirname(bootstrapAbsPath), process.module))]);
2322
+ const launch = entry.releaseRoot || installed || handle.release.state === 'confirmed'
2323
+ ? requireInstalledBinding(handle.release, installedEntryRevision(entry, config, this.cwd), installed) : undefined;
1738
2324
  if (topology && topology.length > 0) {
1739
2325
  await this.launchTopology(entry, handle, config, effectiveBootstrapPath, topology, buildResult);
1740
2326
  }
1741
2327
  else {
1742
2328
  await this.launchSingleProcess(entry, handle, config, effectiveBootstrapPath, buildResult);
1743
2329
  }
2330
+ return launch;
2331
+ }
2332
+ async discardSourceBuild(name) {
2333
+ const state = this.restartCoalescer.get(name);
2334
+ if (state)
2335
+ state.watchSerial = 0;
2336
+ await this.buildService?.unwatchApp(name);
2337
+ this.buildResults.delete(name);
2338
+ this.bootstrapSources.delete(name);
1744
2339
  }
1745
2340
  async prepareBootstrapBuild(entry, bootstrapAbsPath, definition) {
1746
2341
  const sourceTopology = /\.(?:[cm]?ts|tsx)$/.test(bootstrapAbsPath) ||
1747
2342
  definition.processes.some((process) => /\.(?:[cm]?ts|tsx)$/.test(process.module));
1748
- if (!this.devMode && !sourceTopology)
2343
+ if (entry.releaseRoot || (!this.devMode && !sourceTopology)) {
2344
+ // A prior source launch under this name must not redirect a prebuilt
2345
+ // release to a stale generated executable or leave its watcher active.
2346
+ await this.discardSourceBuild(entry.name);
1749
2347
  return;
2348
+ }
1750
2349
  try {
1751
2350
  this.buildService ??= new BuildService(this.devMode, {
1752
2351
  onEsbuildReset: (info) => this.metricsBridge?.recordResilientHandleReset(info),
@@ -1755,13 +2354,13 @@ export class OrchestratorService extends EventEmitter {
1755
2354
  const existing = this.buildResults.get(entry.name);
1756
2355
  const current = this.handles.get(entry.name)?.entry ?? entry;
1757
2356
  const reusable = existing && this.allowsWatch(current) && this.buildService.isWatching(entry.name) &&
1758
- this.buildService.canReuseBuild(existing, bootstrapAbsPath, definition);
2357
+ this.buildService.canReuseBuild(existing, bootstrapAbsPath, definition, this.devMode);
1759
2358
  if (!reusable) {
1760
2359
  // A manual restart with watch:false deliberately compiles the current
1761
2360
  // sources. It must not reuse an artifact that stopped being maintained.
1762
2361
  await this.buildService.unwatchApp(entry.name);
1763
2362
  this.buildResults.delete(entry.name);
1764
- this.buildResults.set(entry.name, await this.buildService.buildApp(entry.name, bootstrapAbsPath, definition));
2363
+ this.buildResults.set(entry.name, await this.buildService.buildApp(entry.name, bootstrapAbsPath, definition, this.devMode));
1765
2364
  this.logger.info({ app: entry.name }, 'Built entry points via esbuild');
1766
2365
  }
1767
2366
  this.bootstrapSources.set(entry.name, { path: bootstrapAbsPath, definition });
@@ -1779,30 +2378,34 @@ export class OrchestratorService extends EventEmitter {
1779
2378
  * The BootstrapProcess finds its own entry, imports the module, and wires transports.
1780
2379
  *
1781
2380
  * Processes with `instances > 1` are launched as PM pools with load balancing.
1782
- * Processes with `topology.access` get Netron-native proxies via daemon socket.
1783
- * Processes with `topology.expose` auto-expose their @Service on daemon Netron.
2381
+ * Processes with `topology.access` get native Netron proxies within this application.
2382
+ * Processes with `topology.expose` publish their @Service on its private listener.
1784
2383
  *
1785
2384
  * Service metadata is auto-discovered from pool workers — no manual `exports`
1786
2385
  * config needed. The @Service decorator on the worker IS the source of truth.
1787
2386
  */
1788
2387
  async launchTopology(entry, handle, config, bootstrapAbsPath, topology, buildResult) {
2388
+ // One fresh, aligned adapter for every pool and single process in this
2389
+ // application generation. Resolve before allocating topology resources.
2390
+ const runtime = await this.bootstrapRuntime(bootstrapAbsPath);
1789
2391
  const policy = buildRestartPolicy(entry, config);
1790
- // Wait for daemon Netron to be wired up. Cheap no-op if already ready;
1791
- // otherwise blocks (with timeout) instead of immediately failing — the
1792
- // race between daemon startup and stack auto-resume is benign and just
1793
- // needs a single rendezvous.
1794
- await this.ensureDaemonNetronReady();
1795
- const serviceRouter = new ServiceRouter(this.daemonNetron, this.logger);
1796
- const daemonSocketUrl = `unix://${this.daemonSocketPath}`;
2392
+ const spawnEnv = withClosureLibraryPath(entry.env, [entry.releaseRoot, entry.cwd, bootstrapAbsPath]);
2393
+ const needsRouting = topology.some(proc => proc.topology?.expose === true || proc.topology?.access?.length);
2394
+ handle.deferStartup();
2395
+ if (needsRouting) {
2396
+ await this.ensureTopologyReady();
2397
+ handle.topology = await ApplicationTopology.allocate(this.topologyDirectory, entry.name, this.logger);
2398
+ await handle.topology.start();
2399
+ }
2400
+ const serviceRouter = handle.topology?.router;
2401
+ const topologySocketUrl = handle.topology?.url;
1797
2402
  // Topology startup order: providers (topology.expose) before consumers (topology.access).
1798
- // Providers register their @Service on daemon Netron via ServiceRouter.
1799
- // Consumers connect to daemon and queryInterface() for those services.
1800
- // Currently only pool processes support topology.expose (ServiceRouter wraps pool.execute).
2403
+ // Each application's private namespace contains both pool and single providers.
1801
2404
  const poolEntries = topology.filter((p) => (p.instances ?? 1) > 1);
1802
2405
  const singleEntries = topology.filter((p) => (p.instances ?? 1) <= 1);
1803
2406
  // Step 1: Create PM pools — must complete before Step 2 so services are available
1804
2407
  // Pools with topology.expose auto-discover @Service metadata from the first
1805
- // worker via getExposedServices() and register on daemon Netron via ServiceRouter.
2408
+ // worker via getExposedServices() and publish within this application's namespace.
1806
2409
  const poolNames = [];
1807
2410
  for (const procEntry of poolEntries) {
1808
2411
  const instances = procEntry.instances;
@@ -1826,14 +2429,15 @@ export class OrchestratorService extends EventEmitter {
1826
2429
  allMethodsPublic: true,
1827
2430
  ...(handle.appLogLevel && { logLevel: handle.appLogLevel }),
1828
2431
  startupTimeout: procEntry.startupTimeout ?? entry.startupTimeout ?? DEFAULT_CHILD_STARTUP_TIMEOUT,
1829
- ...(entry.env && { env: entry.env }),
1830
- ...(entry.cwd && { cwd: entry.cwd }),
2432
+ ...(spawnEnv && { env: spawnEnv }),
2433
+ cwd: entry.cwd ?? this.cwd,
1831
2434
  dependencies: {
1832
2435
  bootstrapPath: bootstrapAbsPath,
1833
2436
  processName: procEntry.name,
1834
2437
  ...(bundledModulePath && { bundledModulePath }),
1835
2438
  ...(topologyAccess.length > 0 && {
1836
- __daemonSocketUrl: daemonSocketUrl,
2439
+ // Retain the bootstrap wire key for previously sealed SDKs.
2440
+ __daemonSocketUrl: topologySocketUrl,
1837
2441
  __topologyConnects: topologyAccess,
1838
2442
  }),
1839
2443
  },
@@ -1876,7 +2480,7 @@ export class OrchestratorService extends EventEmitter {
1876
2480
  };
1877
2481
  this.logger.info({ app: entry.name, process: procEntry.name, instances }, 'Creating topology process pool');
1878
2482
  // pm.pool() returns a Proxy wrapping ProcessPool — execute() dispatches to pool workers
1879
- const pool = await this.pm.pool(BOOTSTRAP_PROCESS_PATH, poolOptions);
2483
+ const pool = await this.pm.pool(runtime, poolOptions);
1880
2484
  poolNames.push(procEntry.name);
1881
2485
  // Track the pool on the AppHandle so `getInfo()` can report the
1882
2486
  // actual worker count for pool-managed topology entries. Without
@@ -1884,56 +2488,15 @@ export class OrchestratorService extends EventEmitter {
1884
2488
  // which returns null for pool workers (they aren't supervisor
1885
2489
  // children) and the entry is mis-reported as `status: 'stopped'`.
1886
2490
  handle.topologyPools.set(procEntry.name, pool);
2491
+ this.observePoolReleaseMembership(handle, pool);
1887
2492
  this.attachPoolLogCapture(entry.name, procEntry.name, handle, pool);
1888
2493
  // Auto-discover @Service metadata from pool workers and expose via ServiceRouter.
1889
2494
  // No manual `exports` needed — @Service decorator IS the source of truth.
1890
2495
  // Requires explicit `topology: { expose: true }` — opt-in for security.
1891
2496
  if (procEntry.topology?.expose === true) {
1892
- try {
1893
- // A pool worker reports ready before its Application has started, and
1894
- // `@Service` classes are exposed to Netron during start — so asking
1895
- // once, or once more 500ms later, asks a worker that is still booting.
1896
- // What it answers then is an empty list, or a service whose method
1897
- // list has not been filled in yet, and both used to end the same way:
1898
- // nothing registered on the daemon, the consumer process starting
1899
- // seconds later, querying, and being told the service does not exist.
1900
- // The consumer resolves its topology proxy exactly once, so that
1901
- // answer disabled the feature for the life of the process — in the
1902
- // case that surfaced this, every OHLCV candle aggregation.
1903
- //
1904
- // Poll instead, and treat "a service with no methods" as not ready
1905
- // rather than as a service, because an empty method list produces a
1906
- // proxy that can do nothing.
1907
- const usable = (list) => Array.isArray(list) && list.length > 0 && list.some((svc) => svc.methods?.length > 0);
1908
- let services = await pool.execute('getExposedServices');
1909
- const deadline = Date.now() + TOPOLOGY_EXPOSE_TIMEOUT_MS;
1910
- while (!usable(services) && Date.now() < deadline) {
1911
- await new Promise((r) => setTimeout(r, TOPOLOGY_EXPOSE_POLL_MS));
1912
- services = await pool.execute('getExposedServices');
1913
- }
1914
- if (!usable(services)) {
1915
- this.logger.warn({
1916
- app: entry.name,
1917
- process: procEntry.name,
1918
- waitedMs: TOPOLOGY_EXPOSE_TIMEOUT_MS,
1919
- reported: services?.map((svc) => `${svc.name}(${svc.methods?.length ?? 0})`) ?? [],
1920
- }, 'No usable @Service found on pool worker — topology.expose has no effect, and any ' +
1921
- 'process declaring topology.access on it will start without a proxy');
1922
- }
1923
- for (const svc of services ?? []) {
1924
- if (svc.methods.length === 0) {
1925
- // Silently skipped before. A consumer then failed to find a
1926
- // service its own declaration named, with nothing anywhere
1927
- // connecting the two facts.
1928
- this.logger.warn({ app: entry.name, process: procEntry.name, service: svc.name }, 'Pool service exposes no methods — not registered on the daemon');
1929
- continue;
1930
- }
1931
- await serviceRouter.exposePoolService(procEntry.name, svc.name, svc.version ?? '1.0.0', pool, svc.methods);
1932
- this.logger.info({ app: entry.name, process: procEntry.name, service: svc.name, methods: svc.methods.length }, 'Auto-discovered and exposed pool service on daemon Netron');
1933
- }
1934
- }
1935
- catch (err) {
1936
- this.logger.error({ app: entry.name, process: procEntry.name, error: err.message }, 'Failed to auto-discover/expose pool services');
2497
+ const services = await this.discoverTopologyServices(entry.name, procEntry.name, () => pool.execute('getExposedServices'));
2498
+ for (const svc of services) {
2499
+ await serviceRouter.exposePoolService(procEntry.name, svc.name, svc.version ?? '1.0.0', pool, svc.methods);
1937
2500
  }
1938
2501
  }
1939
2502
  }
@@ -1950,14 +2513,14 @@ export class OrchestratorService extends EventEmitter {
1950
2513
  // path beside it has always stated one. See CHILD_REQUEST_TIMEOUT.
1951
2514
  requestTimeout: CHILD_REQUEST_TIMEOUT,
1952
2515
  startupTimeout: procEntry.startupTimeout ?? entry.startupTimeout ?? DEFAULT_CHILD_STARTUP_TIMEOUT,
1953
- ...(entry.env && { env: entry.env }),
1954
- ...(entry.cwd && { cwd: entry.cwd }),
2516
+ ...(spawnEnv && { env: spawnEnv }),
2517
+ cwd: entry.cwd ?? this.cwd,
1955
2518
  dependencies: {
1956
2519
  bootstrapPath: bootstrapAbsPath,
1957
2520
  processName: procEntry.name,
1958
2521
  ...(bundledModulePath && { bundledModulePath }),
1959
2522
  ...(topologyAccess.length > 0 && {
1960
- __daemonSocketUrl: daemonSocketUrl,
2523
+ __daemonSocketUrl: topologySocketUrl,
1961
2524
  __topologyConnects: topologyAccess,
1962
2525
  }),
1963
2526
  },
@@ -1971,7 +2534,7 @@ export class OrchestratorService extends EventEmitter {
1971
2534
  };
1972
2535
  children.push({
1973
2536
  name: `${entry.name}/${procEntry.name}`,
1974
- process: BOOTSTRAP_PROCESS_PATH,
2537
+ process: runtime,
1975
2538
  spawnOptions: spawnOpts,
1976
2539
  critical: procEntry.critical ?? entry.critical ?? false,
1977
2540
  });
@@ -1979,7 +2542,7 @@ export class OrchestratorService extends EventEmitter {
1979
2542
  // Step 3: Create supervisor for single-instance children
1980
2543
  const supervisorConfig = {
1981
2544
  strategy: mapStrategy(config.supervision.strategy),
1982
- maxRestarts: policy.maxRestarts ?? config.supervision.maxRestarts,
2545
+ maxRestarts: policy.enabled === false ? 0 : policy.maxRestarts ?? config.supervision.maxRestarts,
1983
2546
  window: policy.window ?? config.supervision.window,
1984
2547
  backoff: policy.backoff ?? config.supervision.backoff,
1985
2548
  children,
@@ -1999,7 +2562,6 @@ export class OrchestratorService extends EventEmitter {
1999
2562
  this.onChildStarted(entry, handle, supervisor);
2000
2563
  // Set supervisor on handle BEFORE start so attachLogCapture can access it
2001
2564
  handle.supervisor = supervisor;
2002
- handle.serviceRouter = serviceRouter;
2003
2565
  handle.instanceCount = entry.instances ?? 1;
2004
2566
  handle.topologyProcesses = topology;
2005
2567
  this.wireSupervisorEvents(entry, handle, supervisor);
@@ -2019,57 +2581,47 @@ export class OrchestratorService extends EventEmitter {
2019
2581
  // A consumer among these children may therefore start before the service
2020
2582
  // is registered; consumers re-resolve their proxy on use for exactly that
2021
2583
  // reason (see quotes's `OhlcvSchedulerService`).
2022
- await this.exposeChildTopologyServices(entry, supervisor, serviceRouter, singleEntries);
2584
+ if (serviceRouter)
2585
+ await this.exposeChildTopologyServices(entry, supervisor, serviceRouter, singleEntries);
2586
+ if (handle.finishStartup())
2587
+ this.announceOnline(entry.name, handle);
2588
+ }
2589
+ /** Shared discovery contract for pools and supervisor children. */
2590
+ async discoverTopologyServices(application, provider, ask) {
2591
+ const deadline = Date.now() + TOPOLOGY_EXPOSE_TIMEOUT_MS;
2592
+ let reported;
2593
+ while (true) {
2594
+ try {
2595
+ reported = await ask();
2596
+ }
2597
+ catch (error) {
2598
+ throw new Error(`Application '${application}' topology provider '${provider}' discovery failed: ${String(error)}`, { cause: error });
2599
+ }
2600
+ if (Array.isArray(reported) && reported.length) {
2601
+ if (reported.some(service => !service || typeof service.name !== 'string' || !service.name ||
2602
+ (service.version !== undefined && typeof service.version !== 'string') ||
2603
+ !Array.isArray(service.methods) || service.methods.some((method) => typeof method !== 'string' || !method))) {
2604
+ throw new Error(`Application '${application}' topology provider '${provider}' returned invalid service metadata`);
2605
+ }
2606
+ const services = reported.filter(service => service.methods.length > 0);
2607
+ if (services.length)
2608
+ return services;
2609
+ }
2610
+ if (Date.now() >= deadline) {
2611
+ throw new Error(`Application '${application}' topology provider '${provider}' exposed no callable services within ${TOPOLOGY_EXPOSE_TIMEOUT_MS}ms`);
2612
+ }
2613
+ await new Promise(resolve => setTimeout(resolve, TOPOLOGY_EXPOSE_POLL_MS));
2614
+ }
2023
2615
  }
2024
- /**
2025
- * Register each single process's `@Service` classes on the daemon.
2026
- *
2027
- * Mirrors the pool path above, including its poll: a child reports ready
2028
- * before its Application has started, and `@Service` classes are exposed to
2029
- * Netron during start, so asking once asks a process that is still booting
2030
- * and gets an empty list back.
2031
- */
2616
+ /** Publish each single provider after its supervisor has started. */
2032
2617
  async exposeChildTopologyServices(entry, supervisor, serviceRouter, singleEntries) {
2033
2618
  for (const procEntry of singleEntries) {
2034
2619
  if (procEntry.topology?.expose !== true)
2035
2620
  continue;
2036
- const childName = `${entry.name}/${procEntry.name}`;
2037
- const getProxy = () => supervisor.getChildProxy(childName);
2038
- try {
2039
- const usable = (list) => Array.isArray(list) && list.length > 0 && list.some((svc) => svc.methods?.length > 0);
2040
- const ask = async () => {
2041
- const child = getProxy();
2042
- if (!child?.getExposedServices)
2043
- return undefined;
2044
- return (await child.getExposedServices());
2045
- };
2046
- let services = await ask();
2047
- const deadline = Date.now() + TOPOLOGY_EXPOSE_TIMEOUT_MS;
2048
- while (!usable(services) && Date.now() < deadline) {
2049
- await new Promise((r) => setTimeout(r, TOPOLOGY_EXPOSE_POLL_MS));
2050
- services = await ask();
2051
- }
2052
- if (!usable(services)) {
2053
- this.logger.warn({
2054
- app: entry.name,
2055
- process: procEntry.name,
2056
- waitedMs: TOPOLOGY_EXPOSE_TIMEOUT_MS,
2057
- reported: services?.map((svc) => `${svc.name}(${svc.methods?.length ?? 0})`) ?? [],
2058
- }, 'No usable @Service found on this process — topology.expose has no effect, and any ' +
2059
- 'process declaring topology.access on it will start without a proxy');
2060
- continue;
2061
- }
2062
- for (const svc of services ?? []) {
2063
- if (svc.methods.length === 0) {
2064
- this.logger.warn({ app: entry.name, process: procEntry.name, service: svc.name }, 'Process service exposes no methods — not registered on the daemon');
2065
- continue;
2066
- }
2067
- await serviceRouter.exposeChildService(procEntry.name, svc.name, svc.version ?? '1.0.0', getProxy, svc.methods);
2068
- this.logger.info({ app: entry.name, process: procEntry.name, service: svc.name, methods: svc.methods.length }, 'Auto-discovered and exposed process service on daemon Netron');
2069
- }
2070
- }
2071
- catch (err) {
2072
- this.logger.error({ app: entry.name, process: procEntry.name, error: err.message }, "Failed to auto-discover/expose this process's services");
2621
+ const getProxy = () => supervisor.getChildProxy(`${entry.name}/${procEntry.name}`);
2622
+ const services = await this.discoverTopologyServices(entry.name, procEntry.name, async () => getProxy()?.getExposedServices?.());
2623
+ for (const svc of services) {
2624
+ await serviceRouter.exposeChildService(procEntry.name, svc.name, svc.version ?? '1.0.0', getProxy, svc.methods);
2073
2625
  }
2074
2626
  }
2075
2627
  }
@@ -2079,6 +2631,7 @@ export class OrchestratorService extends EventEmitter {
2079
2631
  async launchSingleProcess(entry, handle, config, bootstrapAbsPath, buildResult) {
2080
2632
  const instances = entry.instances ?? 1;
2081
2633
  const policy = buildRestartPolicy(entry, config);
2634
+ const spawnEnv = withClosureLibraryPath(entry.env, [entry.releaseRoot, entry.cwd, bootstrapAbsPath]);
2082
2635
  // For single-process apps, use the first (only) process entry's bundled module
2083
2636
  const firstProcessName = buildResult?.modulePaths.keys().next().value;
2084
2637
  const bundledModulePath = firstProcessName
@@ -2087,9 +2640,12 @@ export class OrchestratorService extends EventEmitter {
2087
2640
  const spawnOpts = {
2088
2641
  name: entry.name,
2089
2642
  version: '1.0.0',
2643
+ // The execution owner's sealed runtime is never the application's
2644
+ // implicit working directory. Titan PM forwards this to native fork.
2645
+ cwd: entry.cwd ?? this.cwd,
2090
2646
  // As above: a single child's client otherwise runs on netron's default.
2091
2647
  requestTimeout: CHILD_REQUEST_TIMEOUT,
2092
- ...(entry.env && { env: entry.env }),
2648
+ ...(spawnEnv && { env: spawnEnv }),
2093
2649
  dependencies: {
2094
2650
  bootstrapPath: bootstrapAbsPath,
2095
2651
  ...(bundledModulePath && { bundledModulePath }),
@@ -2114,7 +2670,7 @@ export class OrchestratorService extends EventEmitter {
2114
2670
  };
2115
2671
  const childConfig = {
2116
2672
  name: entry.name,
2117
- process: BOOTSTRAP_PROCESS_PATH,
2673
+ process: await this.bootstrapRuntime(bootstrapAbsPath),
2118
2674
  spawnOptions: spawnOpts,
2119
2675
  critical: entry.critical ?? false,
2120
2676
  };
@@ -2123,6 +2679,7 @@ export class OrchestratorService extends EventEmitter {
2123
2679
  size: instances,
2124
2680
  strategy: PoolStrategy.ROUND_ROBIN,
2125
2681
  metrics: true,
2682
+ spawnOptions: spawnOpts,
2126
2683
  // See the note on the other pool: `replaceUnhealthy` is declared by
2127
2684
  // titan-pm and read by nothing.
2128
2685
  healthCheck: {
@@ -2131,25 +2688,16 @@ export class OrchestratorService extends EventEmitter {
2131
2688
  },
2132
2689
  spawnOptionsFactory: (index) => ({
2133
2690
  name: `${entry.name}-${index}`,
2134
- ...(entry.env && { env: entry.env }),
2135
- ...(entry.startupTimeout != null && { startupTimeout: entry.startupTimeout }),
2136
2691
  dependencies: {
2137
- bootstrapPath: bootstrapAbsPath,
2138
- ...(bundledModulePath && { bundledModulePath }),
2692
+ ...spawnOpts.dependencies,
2139
2693
  portOffset: index,
2140
2694
  },
2141
- health: {
2142
- enabled: true,
2143
- interval: config.monitoring.healthCheck.interval,
2144
- timeout: config.monitoring.healthCheck.timeout,
2145
- },
2146
- observability: { metrics: true },
2147
2695
  }),
2148
2696
  };
2149
2697
  }
2150
2698
  const supervisorConfig = {
2151
2699
  strategy: mapStrategy(config.supervision.strategy),
2152
- maxRestarts: policy.maxRestarts ?? config.supervision.maxRestarts,
2700
+ maxRestarts: policy.enabled === false ? 0 : policy.maxRestarts ?? config.supervision.maxRestarts,
2153
2701
  window: policy.window ?? config.supervision.window,
2154
2702
  backoff: policy.backoff ?? config.supervision.backoff,
2155
2703
  children: [childConfig],
@@ -2196,10 +2744,15 @@ export class OrchestratorService extends EventEmitter {
2196
2744
  this.persistState();
2197
2745
  if (!whole)
2198
2746
  return;
2199
- this.startPostOnlineCooldown(entry.name);
2200
- this.emit('app:online', entry.name);
2747
+ this.announceOnline(entry.name, handle);
2201
2748
  });
2202
2749
  }
2750
+ announceOnline(name, handle) {
2751
+ handle.clearLastExit();
2752
+ this.startPostOnlineCooldown(name);
2753
+ this.persistState();
2754
+ this.emit('app:online', name);
2755
+ }
2203
2756
  /**
2204
2757
  * Wire common supervisor events (crash, restart, escalate) and log capture.
2205
2758
  */
@@ -2210,7 +2763,8 @@ export class OrchestratorService extends EventEmitter {
2210
2763
  // The app re-entered a live state — drop the previous crash
2211
2764
  // context so a future `omnitron inspect` shows the *next*
2212
2765
  // crash, not the last one.
2213
- handle.clearLastExit();
2766
+ if (handle.status === 'online')
2767
+ handle.clearLastExit();
2214
2768
  });
2215
2769
  // A child that is down leaves the app partial until it is back — a
2216
2770
  // sibling's restart must not bring the app `online` around it.
@@ -2293,20 +2847,19 @@ export class OrchestratorService extends EventEmitter {
2293
2847
  // module that throws on import does — so the streams below are often
2294
2848
  // empty and the only account of what happened is on the error.
2295
2849
  this.persistChildFailure(entry.name, childName, error);
2296
- this.persistChildOutput(entry.name, childName, details?.stdout, 'stdout');
2297
- this.persistChildOutput(entry.name, childName, details?.stderr, 'stderr');
2850
+ if (this.pm.outputCaptureVersion !== 1) {
2851
+ this.persistChildOutput(entry.name, childName, details?.stdout, 'stdout');
2852
+ this.persistChildOutput(entry.name, childName, details?.stderr, 'stderr');
2853
+ }
2298
2854
  handle.recordExit({
2299
2855
  code: null,
2300
2856
  signal: null,
2301
2857
  expected: false,
2302
2858
  message: error.message,
2303
2859
  });
2304
- // The supervisor gives up on a non-critical child whose start failed (a
2305
- // critical one throws, and `startApp` says so). That went unseen while
2306
- // the first child's start made the app `online`; now the app would wait
2307
- // for a child that is not coming, in `starting` — which `omnitron start`
2308
- // takes for a start in progress and leaves alone. A declared process
2309
- // that did not start is an app that did not start.
2860
+ // The supervisor retries within its configured budget. Until a real
2861
+ // ready event arrives, the application is unavailable, not still booting.
2862
+ handle.childGone(childName);
2310
2863
  if (handle.status === 'starting')
2311
2864
  handle.markErrored();
2312
2865
  this.logger.error({ app: entry.name, child: childName, err: error.message }, 'Process failed to start');
@@ -2317,6 +2870,12 @@ export class OrchestratorService extends EventEmitter {
2317
2870
  this.logger.info({ app: entry.name, child: childName, attempt }, 'Process restarting');
2318
2871
  this.emit('app:restart', entry.name, attempt);
2319
2872
  });
2873
+ supervisor.on('child:recovery-stopped', (childName, error) => {
2874
+ handle.status = 'crashed';
2875
+ this.logger.error({ app: entry.name, child: childName, reason: error.message }, 'Process recovery stopped by restart policy; inspect the last failure before retrying');
2876
+ this.persistState();
2877
+ this.emit('app:escalated', entry.name, childName);
2878
+ });
2320
2879
  supervisor.on('escalate', (childName, _error) => {
2321
2880
  handle.status = 'crashed';
2322
2881
  this.logger.error({ app: entry.name, child: childName }, 'App exceeded max restarts — escalated');
@@ -2329,6 +2888,8 @@ export class OrchestratorService extends EventEmitter {
2329
2888
  * Routes child stdout/stderr lines to AppHandle ring buffer for `getLogs()`.
2330
2889
  */
2331
2890
  attachLogCapture(appName, childName, handle) {
2891
+ if (this.pm.outputCaptureVersion === 1)
2892
+ return;
2332
2893
  const supervisor = handle.supervisor;
2333
2894
  if (!supervisor)
2334
2895
  return;
@@ -2340,6 +2901,21 @@ export class OrchestratorService extends EventEmitter {
2340
2901
  return;
2341
2902
  workerHandle.onLog(this.childLogForwarder(appName, handle));
2342
2903
  }
2904
+ /** Pool initialization is complete; every later membership change supersedes this launch proof. */
2905
+ observePoolReleaseMembership(handle, pool) {
2906
+ const invalidate = () => handle.invalidateRelease();
2907
+ for (const event of ['worker:spawned', 'worker:shutdown', 'worker:replaced', 'pool:scaled', 'pool:destroyed'])
2908
+ pool.on(event, invalidate);
2909
+ // A crash precedes the pool's health check and replacement; stop confirming
2910
+ // the old membership as soon as the initial worker reports its exit.
2911
+ for (const id of pool.getWorkerIds()) {
2912
+ const worker = pool.getWorkerHandle(id);
2913
+ if (worker?.onExit)
2914
+ worker.onExit(invalidate);
2915
+ else
2916
+ invalidate();
2917
+ }
2918
+ }
2343
2919
  /**
2344
2920
  * Attach log capture to the workers of a topology POOL.
2345
2921
  *
@@ -2355,6 +2931,8 @@ export class OrchestratorService extends EventEmitter {
2355
2931
  * alternative is an event this package does not expose yet.
2356
2932
  */
2357
2933
  attachPoolLogCapture(appName, processName, handle, pool) {
2934
+ if (this.pm.outputCaptureVersion === 1)
2935
+ return;
2358
2936
  const forward = this.childLogForwarder(appName, handle);
2359
2937
  let attached = 0;
2360
2938
  for (const workerId of pool.getWorkerIds()) {
@@ -2368,8 +2946,12 @@ export class OrchestratorService extends EventEmitter {
2368
2946
  }
2369
2947
  /** The one place a child's line becomes an app's line. */
2370
2948
  childLogForwarder(appName, handle) {
2371
- return (line, stream) => {
2949
+ return (line, stream, context) => {
2372
2950
  // In-memory ring buffer (for live CLI tailing)
2951
+ // Accept durable capture before updating volatile views: a retry keeps
2952
+ // the same ID and must not duplicate the diagnostic ring.
2953
+ for (const handler of this.appLogHandlers)
2954
+ handler(appName, line, context);
2373
2955
  handle.appendLog(line);
2374
2956
  // Separate stderr ring — feeds `lastExit.stderrTail` on death.
2375
2957
  // Without this, the operator running `omnitron inspect` after
@@ -2377,15 +2959,6 @@ export class OrchestratorService extends EventEmitter {
2377
2959
  if (stream === 'stderr') {
2378
2960
  handle.appendStderr(line);
2379
2961
  }
2380
- // Persist to disk via registered log handlers (LogManager)
2381
- for (const handler of this.appLogHandlers) {
2382
- try {
2383
- handler(appName, line);
2384
- }
2385
- catch {
2386
- // Log handler failure must not break the app
2387
- }
2388
- }
2389
2962
  };
2390
2963
  }
2391
2964
  /**
@@ -2495,46 +3068,11 @@ export class OrchestratorService extends EventEmitter {
2495
3068
  // ============================================================================
2496
3069
  async stopChildProcess(handle, force, timeout) {
2497
3070
  const child = handle.childProcess;
2498
- if (!child || !child.pid)
3071
+ if (!child)
2499
3072
  return;
2500
- const pid = child.pid;
2501
- // P0-D — Signal the whole process group, not just the direct
2502
- // child. classic-launcher spawns with `detached: true` so the
2503
- // child becomes group leader (pgid === pid). `process.kill(-pid)`
2504
- // delivers the signal to every process in the group, reaping
2505
- // grandchildren (ffmpeg, docker, worker pools …) that ignore the
2506
- // direct-child kill. Falls back to `child.kill` when the negative-
2507
- // pid call fails (test environments, restricted permissions, the
2508
- // child wasn't started detached — bootstrap-mode currently isn't).
2509
- const sendSignal = (sig) => {
2510
- try {
2511
- process.kill(-pid, sig);
2512
- return;
2513
- }
2514
- catch (err) {
2515
- const code = err.code;
2516
- if (code !== 'ESRCH' && code !== 'EPERM') {
2517
- // ESRCH/EPERM = group already gone or not a group leader.
2518
- // Anything else (EINVAL etc.) → log via best-effort.
2519
- this.logger.debug({ app: handle.name, pid, sig, code }, 'process.kill(-pid) fallback');
2520
- }
2521
- }
2522
- try {
2523
- child.kill(sig);
2524
- }
2525
- catch { /* best-effort */ }
2526
- };
2527
- await new Promise((resolve) => {
2528
- const timer = setTimeout(() => {
2529
- sendSignal('SIGKILL');
2530
- resolve();
2531
- }, timeout);
2532
- child.once('exit', () => {
2533
- clearTimeout(timer);
2534
- resolve();
2535
- });
2536
- sendSignal(force ? 'SIGKILL' : 'SIGTERM');
2537
- });
3073
+ const stopped = await killChildAndVerify(child, this.logger, { app: handle.name }, timeout, { force, processGroup: true });
3074
+ if (!stopped)
3075
+ throw new Error(`Application '${handle.name}' (pid ${child.pid}) did not confirm process-group exit`);
2538
3076
  }
2539
3077
  /**
2540
3078
  * Cancel a pending crash cool-down for `name`, if one is armed.
@@ -2549,131 +3087,63 @@ export class OrchestratorService extends EventEmitter {
2549
3087
  }
2550
3088
  }
2551
3089
  async scheduleRecovery(entry, handle, config) {
3090
+ const generation = this.stopGeneration;
3091
+ const revision = this.appStopIntents.get(entry.name)?.revision;
3092
+ const eligible = () => !this.stoppingApps && generation === this.stopGeneration &&
3093
+ revision === this.appStopIntents.get(entry.name)?.revision &&
3094
+ !this.appStopIntents.get(entry.name)?.stopped &&
3095
+ this.handles.get(entry.name) === handle &&
3096
+ (handle.status === 'crashed' || handle.status === 'errored');
3097
+ if (!eligible())
3098
+ return;
2552
3099
  const policy = buildRestartPolicy(entry, config);
3100
+ const maxRestarts = policy.maxRestarts ?? 5;
2553
3101
  if (!policy.enabled)
2554
3102
  return;
2555
- if (handle.restarts >= (policy.maxRestarts ?? 5)) {
3103
+ if (maxRestarts <= 0) {
2556
3104
  handle.status = 'crashed';
2557
- this.logger.error({ app: entry.name }, 'Max restarts exceeded');
2558
3105
  this.emit('app:escalated', entry.name);
2559
- // P1-I — auto-recovery after a cool-down. pm2 has this as
2560
- // `restart_delay` + a fresh attempt window; pre-fix omnitron
2561
- // left the app permanently 'crashed' until human intervention.
2562
- // We reset the counter + schedule one fresh attempt 10 minutes
2563
- // out. If THAT attempt also crashes through maxRestarts we
2564
- // land back here and pause another 10 minutes — bounded
2565
- // self-healing without thrashing.
2566
- //
2567
- // The wait happens OUTSIDE the lifecycle queue, and that is the
2568
- // whole point. It used to be a queued `crash-restart` whose
2569
- // `run()` slept for the entire cool-down — but `enqueue` will
2570
- // not preempt a RUNNING head, and with an empty queue the
2571
- // sleeper always became the head immediately. So the `onPreempt`
2572
- // hook meant to cancel it could never fire, and an operator's
2573
- // `stop` or `restart` simply queued behind ten minutes of sleep:
2574
- // the CLI's RPC timed out after 60s while the op stayed queued,
2575
- // to fire whenever the cool-down finally elapsed. An app that
2576
- // exhausted its restart budget was unreachable by every command
2577
- // the CLI offers — `restart` hung, `stop` hung, `stack start`
2578
- // skipped it — and the only recovery was restarting the daemon.
2579
- const COOL_DOWN_MS = 10 * 60_000;
2580
- this.clearCoolDown(entry.name);
2581
- const timer = setTimeout(() => {
2582
- this.coolDownTimers.delete(entry.name);
2583
- // Re-read the handle: every start replaces it (see
2584
- // `startAppInternal`), so the one captured above is stale the
2585
- // moment anything restarts this app. Only a still-crashed app
2586
- // wants this attempt — an operator who started it meanwhile
2587
- // has already settled the question.
2588
- const current = this.handles.get(entry.name);
2589
- if (!current || current.status !== 'crashed')
2590
- return;
2591
- this.logger.info({ app: entry.name }, 'Cool-down elapsed — attempting fresh recovery');
2592
- current.restarts = 0; // fresh attempt window
2593
- current.status = 'stopped';
2594
- void this.lifecycleQueue
2595
- .enqueue(entry.name, 'crash-restart', () => this.startAppInternal(entry, config))
2596
- .catch((err) => {
2597
- if (err instanceof LifecyclePreempted)
2598
- return;
2599
- this.logger.error({ app: entry.name, err: err.message }, 'Cool-down recovery failed');
2600
- });
2601
- }, COOL_DOWN_MS);
2602
- timer.unref?.();
2603
- this.coolDownTimers.set(entry.name, timer);
2604
3106
  return;
2605
3107
  }
2606
- const backoff = policy.backoff ?? config.supervision.backoff;
2607
- const delay = this.calculateBackoff(handle.restarts, backoff);
2608
- this.logger.info({ app: entry.name, delay, attempt: handle.restarts + 1 }, 'Scheduling restart');
2609
- // P0-I — schedule the crash-restart through the lifecycle queue
2610
- // so an explicit stop preempts the pending restart before it
2611
- // fires. The setTimeout is still the timing source, but the
2612
- // queue.enqueue with `onPreempt` guarantees the timer is cleared
2613
- // (and the promise rejected with LifecyclePreempted) the moment a
2614
- // higher-priority op for the same app arrives. Pre-fix the timer
2615
- // could fire during stopApp's `await stopChild(...)` window and
2616
- // spawn a zombie under the same handle.
2617
- let timer = null;
2618
- const restartPromise = this.lifecycleQueue.enqueue(entry.name, 'crash-restart', () => new Promise((resolve, reject) => {
2619
- timer = setTimeout(async () => {
2620
- timer = null;
2621
- // Guard: don't restart if orchestrator was stopped during backoff
2622
- if (handle.status === 'stopping' || handle.status === 'stopped') {
2623
- resolve();
2624
- return;
2625
- }
2626
- try {
2627
- handle.status = 'stopped';
2628
- // `startAppInternal`, not `startApp`.
2629
- //
2630
- // This task holds the lifecycle-queue slot for `entry.name`.
2631
- // `startApp` enqueues 'start' on that same key, and the queue
2632
- // cannot run it until this task returns — so the await never
2633
- // settles and the restart silently never happens. Measured:
2634
- // `startApp:enter` with no matching exit, and the app left in
2635
- // whatever state the crash put it in.
2636
- //
2637
- // This is why the whole policy below — bounded attempts,
2638
- // exponential backoff, the ten-minute cool-down described in its
2639
- // own comment as "bounded self-healing" — had never restarted
2640
- // anything. The queue was introduced (P0-I) to stop a restart
2641
- // timer racing a stop; it also made the restart unreachable, and
2642
- // nothing failed loudly enough to say so.
2643
- await this.startAppInternal(entry, config);
2644
- resolve();
2645
- }
2646
- catch (err) {
2647
- const message = err.message;
2648
- this.logger.error({ app: entry.name, error: message }, 'Restart failed');
2649
- // Said separately and after, because reading the process table
2650
- // takes a moment and the failure itself must not wait for it.
2651
- void this.explainPortConflict(message).then((held) => {
2652
- if (held)
2653
- this.logger.error({ app: entry.name }, `Restart failed — ${held}`);
2654
- });
2655
- reject(err);
2656
- }
2657
- }, delay);
2658
- }), () => {
2659
- // onPreempt — explicit stop / restart arrived. Cancel the
2660
- // pending timer so the restart never fires.
2661
- if (timer) {
2662
- clearTimeout(timer);
2663
- timer = null;
2664
- }
2665
- });
2666
- // Swallow LifecyclePreempted — that's the explicit-stop happy
2667
- // path, not an error. Anything else gets logged.
2668
- restartPromise.catch((err) => {
2669
- if (err instanceof LifecyclePreempted)
3108
+ const window = handle.restartWindow ??= new RestartWindow();
3109
+ const recent = window.recent(policy.window);
3110
+ const exhausted = recent >= maxRestarts;
3111
+ if (exhausted) {
3112
+ handle.status = 'crashed';
3113
+ this.logger.error({ app: entry.name }, 'Max restarts exceeded');
3114
+ this.emit('app:escalated', entry.name);
3115
+ }
3116
+ const delay = exhausted ? 10 * 60_000 : this.calculateBackoff(recent, policy.backoff ?? config.supervision.backoff);
3117
+ this.logger.info({ app: entry.name, delay, attempt: exhausted ? 1 : recent + 1 }, 'Scheduling restart');
3118
+ this.clearCoolDown(entry.name);
3119
+ // Waiting must not occupy the lifecycle queue: a running queue head
3120
+ // cannot be preempted. Only the actual launch takes the queue slot.
3121
+ const timer = setTimeout(() => {
3122
+ this.coolDownTimers.delete(entry.name);
3123
+ if (!eligible())
2670
3124
  return;
2671
- this.logger.warn({ app: entry.name, err: err.message }, 'Crash restart task rejected');
2672
- });
2673
- // Legacy field — callers still poke handle.crashRestartTimer to
2674
- // check "is a restart pending"; keep it in sync with the queued
2675
- // timer so existing inspect / status code paths don't break.
2676
- handle.crashRestartTimer = timer;
3125
+ void this.lifecycleQueue.enqueue(entry.name, 'crash-restart', async () => {
3126
+ // A stop can arrive after the timer fires but before this job runs.
3127
+ if (!eligible())
3128
+ return;
3129
+ if (exhausted)
3130
+ window.clear();
3131
+ window.record(policy.window);
3132
+ handle.status = 'stopped';
3133
+ await this.startAppInternal(entry, config);
3134
+ }).catch((err) => {
3135
+ if (err instanceof LifecyclePreempted)
3136
+ return;
3137
+ const message = err.message;
3138
+ this.logger.error({ app: entry.name, error: message }, 'Restart failed');
3139
+ void this.explainPortConflict(message).then((held) => {
3140
+ if (held)
3141
+ this.logger.error({ app: entry.name }, `Restart failed — ${held}`);
3142
+ });
3143
+ });
3144
+ }, delay);
3145
+ timer.unref?.();
3146
+ this.coolDownTimers.set(entry.name, timer);
2677
3147
  }
2678
3148
  calculateBackoff(attempt, backoff) {
2679
3149
  // Delegate to the shared backoff library in titan-pm. Pre-fix the
@@ -2964,6 +3434,7 @@ export class OrchestratorService extends EventEmitter {
2964
3434
  }
2965
3435
  const info = {
2966
3436
  name: handle.name,
3437
+ generation: handle.generation,
2967
3438
  pid: handle.pid,
2968
3439
  status,
2969
3440
  cpu: handle.cpu,
@@ -2973,6 +3444,7 @@ export class OrchestratorService extends EventEmitter {
2973
3444
  instances: handle.instanceCount,
2974
3445
  port: handle.port,
2975
3446
  mode: handle.mode,
3447
+ release: handle.release,
2976
3448
  critical: handle.entry.critical ?? false,
2977
3449
  };
2978
3450
  // Include sub-process topology if present