@omnitron-dev/omnitron 0.2.0 → 0.3.0

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 (1247) hide show
  1. package/dist/BUILD.json +5 -0
  2. package/dist/cli/omnitron.js +351 -29
  3. package/dist/cli/omnitron.js.map +1 -1
  4. package/dist/cluster/cluster.rpc-service.d.ts +40 -0
  5. package/dist/cluster/cluster.rpc-service.d.ts.map +1 -1
  6. package/dist/cluster/cluster.rpc-service.js +49 -3
  7. package/dist/cluster/cluster.rpc-service.js.map +1 -1
  8. package/dist/cluster/config-sync.d.ts.map +1 -1
  9. package/dist/cluster/config-sync.js.map +1 -1
  10. package/dist/cluster/leader-election.d.ts +90 -2
  11. package/dist/cluster/leader-election.d.ts.map +1 -1
  12. package/dist/cluster/leader-election.js +176 -22
  13. package/dist/cluster/leader-election.js.map +1 -1
  14. package/dist/cluster/mesh-link.d.ts +136 -0
  15. package/dist/cluster/mesh-link.d.ts.map +1 -0
  16. package/dist/cluster/mesh-link.js +212 -0
  17. package/dist/cluster/mesh-link.js.map +1 -0
  18. package/dist/cluster/mesh.d.ts +59 -0
  19. package/dist/cluster/mesh.d.ts.map +1 -0
  20. package/dist/cluster/mesh.js +117 -0
  21. package/dist/cluster/mesh.js.map +1 -0
  22. package/dist/cluster/slave-connector.d.ts +193 -9
  23. package/dist/cluster/slave-connector.d.ts.map +1 -1
  24. package/dist/cluster/slave-connector.js +409 -37
  25. package/dist/cluster/slave-connector.js.map +1 -1
  26. package/dist/commands/audit.d.ts +65 -0
  27. package/dist/commands/audit.d.ts.map +1 -0
  28. package/dist/commands/audit.js +233 -0
  29. package/dist/commands/audit.js.map +1 -0
  30. package/dist/commands/backup.d.ts +4 -0
  31. package/dist/commands/backup.d.ts.map +1 -1
  32. package/dist/commands/backup.js +255 -33
  33. package/dist/commands/backup.js.map +1 -1
  34. package/dist/commands/cluster.d.ts.map +1 -1
  35. package/dist/commands/cluster.js +78 -47
  36. package/dist/commands/cluster.js.map +1 -1
  37. package/dist/commands/daemon-cmd.d.ts +7 -1
  38. package/dist/commands/daemon-cmd.d.ts.map +1 -1
  39. package/dist/commands/daemon-cmd.js +87 -21
  40. package/dist/commands/daemon-cmd.js.map +1 -1
  41. package/dist/commands/daemon-required.d.ts +34 -0
  42. package/dist/commands/daemon-required.d.ts.map +1 -0
  43. package/dist/commands/daemon-required.js +92 -0
  44. package/dist/commands/daemon-required.js.map +1 -0
  45. package/dist/commands/deploy.d.ts +70 -8
  46. package/dist/commands/deploy.d.ts.map +1 -1
  47. package/dist/commands/deploy.js +99 -64
  48. package/dist/commands/deploy.js.map +1 -1
  49. package/dist/commands/discover.d.ts +25 -4
  50. package/dist/commands/discover.d.ts.map +1 -1
  51. package/dist/commands/discover.js +155 -102
  52. package/dist/commands/discover.js.map +1 -1
  53. package/dist/commands/doctor.d.ts +293 -0
  54. package/dist/commands/doctor.d.ts.map +1 -0
  55. package/dist/commands/doctor.js +1706 -0
  56. package/dist/commands/doctor.js.map +1 -0
  57. package/dist/commands/env.d.ts +8 -1
  58. package/dist/commands/env.d.ts.map +1 -1
  59. package/dist/commands/env.js +13 -8
  60. package/dist/commands/env.js.map +1 -1
  61. package/dist/commands/exec.d.ts.map +1 -1
  62. package/dist/commands/exec.js +3 -2
  63. package/dist/commands/exec.js.map +1 -1
  64. package/dist/commands/fleet-asking.d.ts +87 -0
  65. package/dist/commands/fleet-asking.d.ts.map +1 -0
  66. package/dist/commands/fleet-asking.js +176 -0
  67. package/dist/commands/fleet-asking.js.map +1 -0
  68. package/dist/commands/fleet.d.ts +18 -0
  69. package/dist/commands/fleet.d.ts.map +1 -1
  70. package/dist/commands/fleet.js +314 -74
  71. package/dist/commands/fleet.js.map +1 -1
  72. package/dist/commands/health-check.d.ts +8 -6
  73. package/dist/commands/health-check.d.ts.map +1 -1
  74. package/dist/commands/health-check.js +26 -23
  75. package/dist/commands/health-check.js.map +1 -1
  76. package/dist/commands/health.d.ts.map +1 -1
  77. package/dist/commands/health.js +22 -8
  78. package/dist/commands/health.js.map +1 -1
  79. package/dist/commands/infra.d.ts +42 -1
  80. package/dist/commands/infra.d.ts.map +1 -1
  81. package/dist/commands/infra.js +418 -49
  82. package/dist/commands/infra.js.map +1 -1
  83. package/dist/commands/init.d.ts.map +1 -1
  84. package/dist/commands/init.js +21 -36
  85. package/dist/commands/init.js.map +1 -1
  86. package/dist/commands/inspect-graph.d.ts.map +1 -1
  87. package/dist/commands/inspect-graph.js +2 -6
  88. package/dist/commands/inspect-graph.js.map +1 -1
  89. package/dist/commands/inspect.d.ts.map +1 -1
  90. package/dist/commands/inspect.js +110 -14
  91. package/dist/commands/inspect.js.map +1 -1
  92. package/dist/commands/k8s.d.ts.map +1 -1
  93. package/dist/commands/k8s.js +23 -18
  94. package/dist/commands/k8s.js.map +1 -1
  95. package/dist/commands/kb.d.ts.map +1 -1
  96. package/dist/commands/kb.js +88 -29
  97. package/dist/commands/kb.js.map +1 -1
  98. package/dist/commands/list.d.ts.map +1 -1
  99. package/dist/commands/list.js +21 -9
  100. package/dist/commands/list.js.map +1 -1
  101. package/dist/commands/log-health.d.ts +120 -0
  102. package/dist/commands/log-health.d.ts.map +1 -0
  103. package/dist/commands/log-health.js +212 -0
  104. package/dist/commands/log-health.js.map +1 -0
  105. package/dist/commands/logs.d.ts +96 -2
  106. package/dist/commands/logs.d.ts.map +1 -1
  107. package/dist/commands/logs.js +522 -196
  108. package/dist/commands/logs.js.map +1 -1
  109. package/dist/commands/metrics.d.ts.map +1 -1
  110. package/dist/commands/metrics.js +35 -17
  111. package/dist/commands/metrics.js.map +1 -1
  112. package/dist/commands/monit.d.ts.map +1 -1
  113. package/dist/commands/monit.js +3 -2
  114. package/dist/commands/monit.js.map +1 -1
  115. package/dist/commands/node.d.ts +68 -0
  116. package/dist/commands/node.d.ts.map +1 -1
  117. package/dist/commands/node.js +285 -68
  118. package/dist/commands/node.js.map +1 -1
  119. package/dist/commands/output.d.ts +10 -0
  120. package/dist/commands/output.d.ts.map +1 -1
  121. package/dist/commands/output.js +41 -1
  122. package/dist/commands/output.js.map +1 -1
  123. package/dist/commands/pipeline.d.ts.map +1 -1
  124. package/dist/commands/pipeline.js +26 -19
  125. package/dist/commands/pipeline.js.map +1 -1
  126. package/dist/commands/project.d.ts +19 -0
  127. package/dist/commands/project.d.ts.map +1 -1
  128. package/dist/commands/project.js +125 -27
  129. package/dist/commands/project.js.map +1 -1
  130. package/dist/commands/release-store.d.ts +28 -0
  131. package/dist/commands/release-store.d.ts.map +1 -0
  132. package/dist/commands/release-store.js +158 -0
  133. package/dist/commands/release-store.js.map +1 -0
  134. package/dist/commands/release.d.ts +61 -0
  135. package/dist/commands/release.d.ts.map +1 -0
  136. package/dist/commands/release.js +555 -0
  137. package/dist/commands/release.js.map +1 -0
  138. package/dist/commands/reload.d.ts +16 -0
  139. package/dist/commands/reload.d.ts.map +1 -1
  140. package/dist/commands/reload.js +21 -5
  141. package/dist/commands/reload.js.map +1 -1
  142. package/dist/commands/remote.d.ts +40 -0
  143. package/dist/commands/remote.d.ts.map +1 -1
  144. package/dist/commands/remote.js +146 -35
  145. package/dist/commands/remote.js.map +1 -1
  146. package/dist/commands/restart.d.ts +16 -0
  147. package/dist/commands/restart.d.ts.map +1 -1
  148. package/dist/commands/restart.js +21 -5
  149. package/dist/commands/restart.js.map +1 -1
  150. package/dist/commands/scale.d.ts.map +1 -1
  151. package/dist/commands/scale.js +4 -3
  152. package/dist/commands/scale.js.map +1 -1
  153. package/dist/commands/secret.d.ts +54 -0
  154. package/dist/commands/secret.d.ts.map +1 -1
  155. package/dist/commands/secret.js +236 -34
  156. package/dist/commands/secret.js.map +1 -1
  157. package/dist/commands/service-units.d.ts +181 -0
  158. package/dist/commands/service-units.d.ts.map +1 -0
  159. package/dist/commands/service-units.js +291 -0
  160. package/dist/commands/service-units.js.map +1 -0
  161. package/dist/commands/service.d.ts +39 -0
  162. package/dist/commands/service.d.ts.map +1 -0
  163. package/dist/commands/service.js +370 -0
  164. package/dist/commands/service.js.map +1 -0
  165. package/dist/commands/spinner.d.ts +29 -0
  166. package/dist/commands/spinner.d.ts.map +1 -0
  167. package/dist/commands/spinner.js +44 -0
  168. package/dist/commands/spinner.js.map +1 -0
  169. package/dist/commands/stack.d.ts +49 -1
  170. package/dist/commands/stack.d.ts.map +1 -1
  171. package/dist/commands/stack.js +325 -12
  172. package/dist/commands/stack.js.map +1 -1
  173. package/dist/commands/start.d.ts +16 -0
  174. package/dist/commands/start.d.ts.map +1 -1
  175. package/dist/commands/start.js +20 -3
  176. package/dist/commands/start.js.map +1 -1
  177. package/dist/commands/status.d.ts +9 -0
  178. package/dist/commands/status.d.ts.map +1 -1
  179. package/dist/commands/status.js +45 -29
  180. package/dist/commands/status.js.map +1 -1
  181. package/dist/commands/stop.d.ts +16 -0
  182. package/dist/commands/stop.d.ts.map +1 -1
  183. package/dist/commands/stop.js +34 -6
  184. package/dist/commands/stop.js.map +1 -1
  185. package/dist/commands/tor.d.ts +14 -7
  186. package/dist/commands/tor.d.ts.map +1 -1
  187. package/dist/commands/tor.js +113 -33
  188. package/dist/commands/tor.js.map +1 -1
  189. package/dist/commands/up.d.ts +85 -1
  190. package/dist/commands/up.d.ts.map +1 -1
  191. package/dist/commands/up.js +180 -32
  192. package/dist/commands/up.js.map +1 -1
  193. package/dist/commands/webapp.d.ts.map +1 -1
  194. package/dist/commands/webapp.js +2 -1
  195. package/dist/commands/webapp.js.map +1 -1
  196. package/dist/config/defaults.d.ts +16 -0
  197. package/dist/config/defaults.d.ts.map +1 -1
  198. package/dist/config/defaults.js +26 -3
  199. package/dist/config/defaults.js.map +1 -1
  200. package/dist/config/define-ecosystem.d.ts.map +1 -1
  201. package/dist/config/define-ecosystem.js +2 -0
  202. package/dist/config/define-ecosystem.js.map +1 -1
  203. package/dist/config/index.d.ts +1 -1
  204. package/dist/config/index.d.ts.map +1 -1
  205. package/dist/config/index.js +1 -1
  206. package/dist/config/index.js.map +1 -1
  207. package/dist/config/loader.d.ts +45 -1
  208. package/dist/config/loader.d.ts.map +1 -1
  209. package/dist/config/loader.js +64 -6
  210. package/dist/config/loader.js.map +1 -1
  211. package/dist/config/omnitron-config.schema.d.ts.map +1 -1
  212. package/dist/config/omnitron-config.schema.js +16 -0
  213. package/dist/config/omnitron-config.schema.js.map +1 -1
  214. package/dist/config/types.d.ts +411 -42
  215. package/dist/config/types.d.ts.map +1 -1
  216. package/dist/daemon/config-reload.d.ts +27 -0
  217. package/dist/daemon/config-reload.d.ts.map +1 -0
  218. package/dist/daemon/config-reload.js +42 -0
  219. package/dist/daemon/config-reload.js.map +1 -0
  220. package/dist/daemon/daemon-client.d.ts +136 -2
  221. package/dist/daemon/daemon-client.d.ts.map +1 -1
  222. package/dist/daemon/daemon-client.js +307 -21
  223. package/dist/daemon/daemon-client.js.map +1 -1
  224. package/dist/daemon/daemon-entry.js +90 -30
  225. package/dist/daemon/daemon-entry.js.map +1 -1
  226. package/dist/daemon/daemon-scheduler.d.ts +4 -0
  227. package/dist/daemon/daemon-scheduler.d.ts.map +1 -1
  228. package/dist/daemon/daemon-scheduler.js +137 -7
  229. package/dist/daemon/daemon-scheduler.js.map +1 -1
  230. package/dist/daemon/daemon-state-store.service.d.ts +263 -0
  231. package/dist/daemon/daemon-state-store.service.d.ts.map +1 -0
  232. package/dist/daemon/daemon-state-store.service.js +446 -0
  233. package/dist/daemon/daemon-state-store.service.js.map +1 -0
  234. package/dist/daemon/daemon.d.ts +205 -1
  235. package/dist/daemon/daemon.d.ts.map +1 -1
  236. package/dist/daemon/daemon.js +1139 -139
  237. package/dist/daemon/daemon.js.map +1 -1
  238. package/dist/daemon/daemon.module.d.ts.map +1 -1
  239. package/dist/daemon/daemon.module.js +163 -83
  240. package/dist/daemon/daemon.module.js.map +1 -1
  241. package/dist/daemon/daemon.rpc-service.d.ts +90 -1
  242. package/dist/daemon/daemon.rpc-service.d.ts.map +1 -1
  243. package/dist/daemon/daemon.rpc-service.js +438 -96
  244. package/dist/daemon/daemon.rpc-service.js.map +1 -1
  245. package/dist/daemon/pid-manager.d.ts +16 -3
  246. package/dist/daemon/pid-manager.d.ts.map +1 -1
  247. package/dist/daemon/pid-manager.js +31 -4
  248. package/dist/daemon/pid-manager.js.map +1 -1
  249. package/dist/daemon/spawn-daemon.d.ts +73 -0
  250. package/dist/daemon/spawn-daemon.d.ts.map +1 -0
  251. package/dist/daemon/spawn-daemon.js +101 -0
  252. package/dist/daemon/spawn-daemon.js.map +1 -0
  253. package/dist/daemon/state-store.d.ts +65 -3
  254. package/dist/daemon/state-store.d.ts.map +1 -1
  255. package/dist/daemon/state-store.js +100 -58
  256. package/dist/daemon/state-store.js.map +1 -1
  257. package/dist/database/connection.d.ts +71 -0
  258. package/dist/database/connection.d.ts.map +1 -0
  259. package/dist/database/connection.js +129 -0
  260. package/dist/database/connection.js.map +1 -0
  261. package/dist/database/dialect.d.ts +60 -0
  262. package/dist/database/dialect.d.ts.map +1 -0
  263. package/dist/database/dialect.js +80 -0
  264. package/dist/database/dialect.js.map +1 -0
  265. package/dist/database/migrate.d.ts +5 -2
  266. package/dist/database/migrate.d.ts.map +1 -1
  267. package/dist/database/migrate.js +23 -33
  268. package/dist/database/migrate.js.map +1 -1
  269. package/dist/database/migration-runner.d.ts +50 -0
  270. package/dist/database/migration-runner.d.ts.map +1 -0
  271. package/dist/database/migration-runner.js +143 -0
  272. package/dist/database/migration-runner.js.map +1 -0
  273. package/dist/database/migrations/006_login_throttle.d.ts +17 -0
  274. package/dist/database/migrations/006_login_throttle.d.ts.map +1 -0
  275. package/dist/database/migrations/006_login_throttle.js +33 -0
  276. package/dist/database/migrations/006_login_throttle.js.map +1 -0
  277. package/dist/database/migrations/007_sync_ingested.d.ts +21 -0
  278. package/dist/database/migrations/007_sync_ingested.d.ts.map +1 -0
  279. package/dist/database/migrations/007_sync_ingested.js +39 -0
  280. package/dist/database/migrations/007_sync_ingested.js.map +1 -0
  281. package/dist/database/migrations/008_node_health_version_text.d.ts +24 -0
  282. package/dist/database/migrations/008_node_health_version_text.d.ts.map +1 -0
  283. package/dist/database/migrations/008_node_health_version_text.js +35 -0
  284. package/dist/database/migrations/008_node_health_version_text.js.map +1 -0
  285. package/dist/database/migrations/009_node_health_unmeasured.d.ts +40 -0
  286. package/dist/database/migrations/009_node_health_unmeasured.d.ts.map +1 -0
  287. package/dist/database/migrations/009_node_health_unmeasured.js +63 -0
  288. package/dist/database/migrations/009_node_health_unmeasured.js.map +1 -0
  289. package/dist/database/migrations/010_metrics_raw_had_no_reader.d.ts +22 -0
  290. package/dist/database/migrations/010_metrics_raw_had_no_reader.d.ts.map +1 -0
  291. package/dist/database/migrations/010_metrics_raw_had_no_reader.js +26 -0
  292. package/dist/database/migrations/010_metrics_raw_had_no_reader.js.map +1 -0
  293. package/dist/database/migrations/011_alerts_nobody_had_to_write.d.ts +56 -0
  294. package/dist/database/migrations/011_alerts_nobody_had_to_write.d.ts.map +1 -0
  295. package/dist/database/migrations/011_alerts_nobody_had_to_write.js +79 -0
  296. package/dist/database/migrations/011_alerts_nobody_had_to_write.js.map +1 -0
  297. package/dist/database/migrations/012_a_disk_nobody_watched.d.ts +26 -0
  298. package/dist/database/migrations/012_a_disk_nobody_watched.d.ts.map +1 -0
  299. package/dist/database/migrations/012_a_disk_nobody_watched.js +40 -0
  300. package/dist/database/migrations/012_a_disk_nobody_watched.js.map +1 -0
  301. package/dist/database/migrations/013_an_alarm_delivered.d.ts +14 -0
  302. package/dist/database/migrations/013_an_alarm_delivered.d.ts.map +1 -0
  303. package/dist/database/migrations/013_an_alarm_delivered.js +28 -0
  304. package/dist/database/migrations/013_an_alarm_delivered.js.map +1 -0
  305. package/dist/database/migrations/index.d.ts +21 -0
  306. package/dist/database/migrations/index.d.ts.map +1 -0
  307. package/dist/database/migrations/index.js +47 -0
  308. package/dist/database/migrations/index.js.map +1 -0
  309. package/dist/database/schema.d.ts +27 -11
  310. package/dist/database/schema.d.ts.map +1 -1
  311. package/dist/database/sqlite-date-binding.d.ts +71 -0
  312. package/dist/database/sqlite-date-binding.d.ts.map +1 -0
  313. package/dist/database/sqlite-date-binding.js +174 -0
  314. package/dist/database/sqlite-date-binding.js.map +1 -0
  315. package/dist/execution/data-channel.d.ts +48 -0
  316. package/dist/execution/data-channel.d.ts.map +1 -0
  317. package/dist/execution/data-channel.js +55 -0
  318. package/dist/execution/data-channel.js.map +1 -0
  319. package/dist/execution/execution.service.d.ts +139 -0
  320. package/dist/execution/execution.service.d.ts.map +1 -1
  321. package/dist/execution/execution.service.js +273 -10
  322. package/dist/execution/execution.service.js.map +1 -1
  323. package/dist/index.d.ts +1 -1
  324. package/dist/index.d.ts.map +1 -1
  325. package/dist/infrastructure/bare-metal-plan.d.ts +208 -0
  326. package/dist/infrastructure/bare-metal-plan.d.ts.map +1 -0
  327. package/dist/infrastructure/bare-metal-plan.js +363 -0
  328. package/dist/infrastructure/bare-metal-plan.js.map +1 -0
  329. package/dist/infrastructure/bare-metal-runner.d.ts +65 -0
  330. package/dist/infrastructure/bare-metal-runner.d.ts.map +1 -0
  331. package/dist/infrastructure/bare-metal-runner.js +354 -0
  332. package/dist/infrastructure/bare-metal-runner.js.map +1 -0
  333. package/dist/infrastructure/config-payload.d.ts +149 -0
  334. package/dist/infrastructure/config-payload.d.ts.map +1 -0
  335. package/dist/infrastructure/config-payload.js +235 -0
  336. package/dist/infrastructure/config-payload.js.map +1 -0
  337. package/dist/infrastructure/container-runtime.d.ts +169 -1
  338. package/dist/infrastructure/container-runtime.d.ts.map +1 -1
  339. package/dist/infrastructure/container-runtime.js +525 -33
  340. package/dist/infrastructure/container-runtime.js.map +1 -1
  341. package/dist/infrastructure/gateway-reachability.d.ts +85 -0
  342. package/dist/infrastructure/gateway-reachability.d.ts.map +1 -0
  343. package/dist/infrastructure/gateway-reachability.js +116 -0
  344. package/dist/infrastructure/gateway-reachability.js.map +1 -0
  345. package/dist/infrastructure/gateway-redis-db.d.ts +29 -0
  346. package/dist/infrastructure/gateway-redis-db.d.ts.map +1 -0
  347. package/dist/infrastructure/gateway-redis-db.js +32 -0
  348. package/dist/infrastructure/gateway-redis-db.js.map +1 -0
  349. package/dist/infrastructure/host-inspection.d.ts +223 -0
  350. package/dist/infrastructure/host-inspection.d.ts.map +1 -0
  351. package/dist/infrastructure/host-inspection.js +501 -0
  352. package/dist/infrastructure/host-inspection.js.map +1 -0
  353. package/dist/infrastructure/infrastructure-gate.d.ts.map +1 -1
  354. package/dist/infrastructure/infrastructure.service.d.ts +206 -6
  355. package/dist/infrastructure/infrastructure.service.d.ts.map +1 -1
  356. package/dist/infrastructure/infrastructure.service.js +415 -89
  357. package/dist/infrastructure/infrastructure.service.js.map +1 -1
  358. package/dist/infrastructure/known-machines.d.ts +76 -0
  359. package/dist/infrastructure/known-machines.d.ts.map +1 -0
  360. package/dist/infrastructure/known-machines.js +94 -0
  361. package/dist/infrastructure/known-machines.js.map +1 -0
  362. package/dist/infrastructure/node-credentials.d.ts +45 -0
  363. package/dist/infrastructure/node-credentials.d.ts.map +1 -0
  364. package/dist/infrastructure/node-credentials.js +80 -0
  365. package/dist/infrastructure/node-credentials.js.map +1 -0
  366. package/dist/infrastructure/orphan-containers.d.ts +99 -0
  367. package/dist/infrastructure/orphan-containers.d.ts.map +1 -0
  368. package/dist/infrastructure/orphan-containers.js +106 -0
  369. package/dist/infrastructure/orphan-containers.js.map +1 -0
  370. package/dist/infrastructure/phantom-endpoint-janitor.d.ts +20 -0
  371. package/dist/infrastructure/phantom-endpoint-janitor.d.ts.map +1 -1
  372. package/dist/infrastructure/phantom-endpoint-janitor.js +56 -6
  373. package/dist/infrastructure/phantom-endpoint-janitor.js.map +1 -1
  374. package/dist/infrastructure/presets/gateway-openresty.d.ts.map +1 -1
  375. package/dist/infrastructure/presets/gateway-openresty.js +29 -3
  376. package/dist/infrastructure/presets/gateway-openresty.js.map +1 -1
  377. package/dist/infrastructure/presets/minio.d.ts.map +1 -1
  378. package/dist/infrastructure/presets/minio.js +36 -3
  379. package/dist/infrastructure/presets/minio.js.map +1 -1
  380. package/dist/infrastructure/presets/postgres.d.ts.map +1 -1
  381. package/dist/infrastructure/presets/postgres.js +69 -2
  382. package/dist/infrastructure/presets/postgres.js.map +1 -1
  383. package/dist/infrastructure/presets/redis.d.ts.map +1 -1
  384. package/dist/infrastructure/presets/redis.js +13 -0
  385. package/dist/infrastructure/presets/redis.js.map +1 -1
  386. package/dist/infrastructure/presets/registry.d.ts.map +1 -1
  387. package/dist/infrastructure/presets/registry.js +81 -12
  388. package/dist/infrastructure/presets/registry.js.map +1 -1
  389. package/dist/infrastructure/presets/tor.d.ts +38 -0
  390. package/dist/infrastructure/presets/tor.d.ts.map +1 -1
  391. package/dist/infrastructure/presets/tor.js +78 -69
  392. package/dist/infrastructure/presets/tor.js.map +1 -1
  393. package/dist/infrastructure/presets/torrc.d.ts +54 -0
  394. package/dist/infrastructure/presets/torrc.d.ts.map +1 -0
  395. package/dist/infrastructure/presets/torrc.js +153 -0
  396. package/dist/infrastructure/presets/torrc.js.map +1 -0
  397. package/dist/infrastructure/presets/types.d.ts +17 -0
  398. package/dist/infrastructure/presets/types.d.ts.map +1 -1
  399. package/dist/infrastructure/provisioning-outcome.d.ts +85 -0
  400. package/dist/infrastructure/provisioning-outcome.d.ts.map +1 -0
  401. package/dist/infrastructure/provisioning-outcome.js +122 -0
  402. package/dist/infrastructure/provisioning-outcome.js.map +1 -0
  403. package/dist/infrastructure/server-registry.d.ts +27 -0
  404. package/dist/infrastructure/server-registry.d.ts.map +1 -1
  405. package/dist/infrastructure/server-registry.js +60 -5
  406. package/dist/infrastructure/server-registry.js.map +1 -1
  407. package/dist/infrastructure/service-binding.d.ts +60 -0
  408. package/dist/infrastructure/service-binding.d.ts.map +1 -0
  409. package/dist/infrastructure/service-binding.js +90 -0
  410. package/dist/infrastructure/service-binding.js.map +1 -0
  411. package/dist/infrastructure/service-credentials.d.ts +105 -0
  412. package/dist/infrastructure/service-credentials.d.ts.map +1 -0
  413. package/dist/infrastructure/service-credentials.js +141 -0
  414. package/dist/infrastructure/service-credentials.js.map +1 -0
  415. package/dist/infrastructure/service-resolver.d.ts +160 -12
  416. package/dist/infrastructure/service-resolver.d.ts.map +1 -1
  417. package/dist/infrastructure/service-resolver.js +463 -53
  418. package/dist/infrastructure/service-resolver.js.map +1 -1
  419. package/dist/infrastructure/shipped-config.d.ts +43 -0
  420. package/dist/infrastructure/shipped-config.d.ts.map +1 -0
  421. package/dist/infrastructure/shipped-config.js +159 -0
  422. package/dist/infrastructure/shipped-config.js.map +1 -0
  423. package/dist/infrastructure/stack-infra-manager.d.ts +6 -0
  424. package/dist/infrastructure/stack-infra-manager.d.ts.map +1 -1
  425. package/dist/infrastructure/stack-infra-manager.js +31 -13
  426. package/dist/infrastructure/stack-infra-manager.js.map +1 -1
  427. package/dist/infrastructure/types.d.ts +261 -6
  428. package/dist/infrastructure/types.d.ts.map +1 -1
  429. package/dist/mcp/mcp-bridge.d.ts.map +1 -1
  430. package/dist/mcp/mcp-bridge.js.map +1 -1
  431. package/dist/mcp/tool-groups/apps.tools.d.ts +2 -1
  432. package/dist/mcp/tool-groups/apps.tools.d.ts.map +1 -1
  433. package/dist/mcp/tool-groups/apps.tools.js +2 -2
  434. package/dist/mcp/tool-groups/apps.tools.js.map +1 -1
  435. package/dist/mcp/tool-groups/infra.tools.d.ts +16 -2
  436. package/dist/mcp/tool-groups/infra.tools.d.ts.map +1 -1
  437. package/dist/mcp/tool-groups/infra.tools.js +51 -41
  438. package/dist/mcp/tool-groups/infra.tools.js.map +1 -1
  439. package/dist/mcp/tool-groups/kb.tools.d.ts.map +1 -1
  440. package/dist/mcp/tool-groups/kb.tools.js +4 -6
  441. package/dist/mcp/tool-groups/kb.tools.js.map +1 -1
  442. package/dist/mcp/tool-groups/management.tools.d.ts +20 -3
  443. package/dist/mcp/tool-groups/management.tools.d.ts.map +1 -1
  444. package/dist/mcp/tool-groups/management.tools.js +158 -125
  445. package/dist/mcp/tool-groups/management.tools.js.map +1 -1
  446. package/dist/mcp/tool-groups/monitoring.tools.d.ts +10 -1
  447. package/dist/mcp/tool-groups/monitoring.tools.d.ts.map +1 -1
  448. package/dist/mcp/tool-groups/monitoring.tools.js +65 -18
  449. package/dist/mcp/tool-groups/monitoring.tools.js.map +1 -1
  450. package/dist/mcp/unavailable-tools.d.ts +35 -0
  451. package/dist/mcp/unavailable-tools.d.ts.map +1 -0
  452. package/dist/mcp/unavailable-tools.js +59 -0
  453. package/dist/mcp/unavailable-tools.js.map +1 -0
  454. package/dist/monitoring/app-health.indicator.d.ts.map +1 -1
  455. package/dist/monitoring/app-health.indicator.js +12 -0
  456. package/dist/monitoring/app-health.indicator.js.map +1 -1
  457. package/dist/monitoring/desktop-notifier.d.ts +26 -0
  458. package/dist/monitoring/desktop-notifier.d.ts.map +1 -0
  459. package/dist/monitoring/desktop-notifier.js +49 -0
  460. package/dist/monitoring/desktop-notifier.js.map +1 -0
  461. package/dist/monitoring/docker-health.indicator.d.ts +17 -1
  462. package/dist/monitoring/docker-health.indicator.d.ts.map +1 -1
  463. package/dist/monitoring/docker-health.indicator.js +38 -8
  464. package/dist/monitoring/docker-health.indicator.js.map +1 -1
  465. package/dist/monitoring/event-loop-stall.indicator.d.ts +26 -0
  466. package/dist/monitoring/event-loop-stall.indicator.d.ts.map +1 -0
  467. package/dist/monitoring/event-loop-stall.indicator.js +47 -0
  468. package/dist/monitoring/event-loop-stall.indicator.js.map +1 -0
  469. package/dist/monitoring/event-loop-watch.d.ts +124 -0
  470. package/dist/monitoring/event-loop-watch.d.ts.map +1 -0
  471. package/dist/monitoring/event-loop-watch.js +179 -0
  472. package/dist/monitoring/event-loop-watch.js.map +1 -0
  473. package/dist/monitoring/host-disk.d.ts +6 -0
  474. package/dist/monitoring/host-disk.d.ts.map +1 -0
  475. package/dist/monitoring/host-disk.js +26 -0
  476. package/dist/monitoring/host-disk.js.map +1 -0
  477. package/dist/monitoring/log-line.d.ts +188 -0
  478. package/dist/monitoring/log-line.d.ts.map +1 -0
  479. package/dist/monitoring/log-line.js +458 -0
  480. package/dist/monitoring/log-line.js.map +1 -0
  481. package/dist/monitoring/log-manager.d.ts +89 -8
  482. package/dist/monitoring/log-manager.d.ts.map +1 -1
  483. package/dist/monitoring/log-manager.js +246 -77
  484. package/dist/monitoring/log-manager.js.map +1 -1
  485. package/dist/observability/metrics-bridge.d.ts.map +1 -1
  486. package/dist/observability/metrics-server.d.ts.map +1 -1
  487. package/dist/orchestrator/app-handle.d.ts +157 -2
  488. package/dist/orchestrator/app-handle.d.ts.map +1 -1
  489. package/dist/orchestrator/app-handle.js +165 -3
  490. package/dist/orchestrator/app-handle.js.map +1 -1
  491. package/dist/orchestrator/app-health.d.ts +33 -0
  492. package/dist/orchestrator/app-health.d.ts.map +1 -0
  493. package/dist/orchestrator/app-health.js +74 -0
  494. package/dist/orchestrator/app-health.js.map +1 -0
  495. package/dist/orchestrator/app-traffic.d.ts +14 -0
  496. package/dist/orchestrator/app-traffic.d.ts.map +1 -0
  497. package/dist/orchestrator/app-traffic.js +33 -0
  498. package/dist/orchestrator/app-traffic.js.map +1 -0
  499. package/dist/orchestrator/bootstrap-loader-child.d.ts +19 -0
  500. package/dist/orchestrator/bootstrap-loader-child.d.ts.map +1 -0
  501. package/dist/orchestrator/bootstrap-loader-child.js +43 -0
  502. package/dist/orchestrator/bootstrap-loader-child.js.map +1 -0
  503. package/dist/orchestrator/bootstrap-loader.d.ts +72 -0
  504. package/dist/orchestrator/bootstrap-loader.d.ts.map +1 -1
  505. package/dist/orchestrator/bootstrap-loader.js +350 -5
  506. package/dist/orchestrator/bootstrap-loader.js.map +1 -1
  507. package/dist/orchestrator/bootstrap-process.d.ts +99 -4
  508. package/dist/orchestrator/bootstrap-process.d.ts.map +1 -1
  509. package/dist/orchestrator/bootstrap-process.js +330 -19
  510. package/dist/orchestrator/bootstrap-process.js.map +1 -1
  511. package/dist/orchestrator/build-service.d.ts.map +1 -1
  512. package/dist/orchestrator/build-service.js.map +1 -1
  513. package/dist/orchestrator/call-exposed-service.d.ts +7 -0
  514. package/dist/orchestrator/call-exposed-service.d.ts.map +1 -0
  515. package/dist/orchestrator/call-exposed-service.js +50 -0
  516. package/dist/orchestrator/call-exposed-service.js.map +1 -0
  517. package/dist/orchestrator/classic-launcher.d.ts +1 -0
  518. package/dist/orchestrator/classic-launcher.d.ts.map +1 -1
  519. package/dist/orchestrator/classic-launcher.js +34 -3
  520. package/dist/orchestrator/classic-launcher.js.map +1 -1
  521. package/dist/orchestrator/file-watcher.d.ts +78 -1
  522. package/dist/orchestrator/file-watcher.d.ts.map +1 -1
  523. package/dist/orchestrator/file-watcher.js +181 -6
  524. package/dist/orchestrator/file-watcher.js.map +1 -1
  525. package/dist/orchestrator/module-worker-process.d.ts.map +1 -1
  526. package/dist/orchestrator/module-worker-process.js +10 -0
  527. package/dist/orchestrator/module-worker-process.js.map +1 -1
  528. package/dist/orchestrator/orchestrator.service.d.ts +371 -11
  529. package/dist/orchestrator/orchestrator.service.d.ts.map +1 -1
  530. package/dist/orchestrator/orchestrator.service.js +1602 -269
  531. package/dist/orchestrator/orchestrator.service.js.map +1 -1
  532. package/dist/orchestrator/owned-pids.d.ts +83 -0
  533. package/dist/orchestrator/owned-pids.d.ts.map +1 -0
  534. package/dist/orchestrator/owned-pids.js +93 -0
  535. package/dist/orchestrator/owned-pids.js.map +1 -0
  536. package/dist/orchestrator/port-conflict.d.ts +102 -0
  537. package/dist/orchestrator/port-conflict.d.ts.map +1 -0
  538. package/dist/orchestrator/port-conflict.js +131 -0
  539. package/dist/orchestrator/port-conflict.js.map +1 -0
  540. package/dist/orchestrator/process-janitor.d.ts +78 -4
  541. package/dist/orchestrator/process-janitor.d.ts.map +1 -1
  542. package/dist/orchestrator/process-janitor.js +246 -30
  543. package/dist/orchestrator/process-janitor.js.map +1 -1
  544. package/dist/orchestrator/ps-metrics.d.ts +37 -0
  545. package/dist/orchestrator/ps-metrics.d.ts.map +1 -0
  546. package/dist/orchestrator/ps-metrics.js +60 -0
  547. package/dist/orchestrator/ps-metrics.js.map +1 -0
  548. package/dist/orchestrator/service-router.d.ts +58 -2
  549. package/dist/orchestrator/service-router.d.ts.map +1 -1
  550. package/dist/orchestrator/service-router.js +157 -25
  551. package/dist/orchestrator/service-router.js.map +1 -1
  552. package/dist/orchestrator/topology-query.d.ts +49 -0
  553. package/dist/orchestrator/topology-query.d.ts.map +1 -0
  554. package/dist/orchestrator/topology-query.js +54 -0
  555. package/dist/orchestrator/topology-query.js.map +1 -0
  556. package/dist/project/artifact-builder.d.ts +174 -3
  557. package/dist/project/artifact-builder.d.ts.map +1 -1
  558. package/dist/project/artifact-builder.js +454 -42
  559. package/dist/project/artifact-builder.js.map +1 -1
  560. package/dist/project/build-decision.d.ts +58 -0
  561. package/dist/project/build-decision.d.ts.map +1 -0
  562. package/dist/project/build-decision.js +59 -0
  563. package/dist/project/build-decision.js.map +1 -0
  564. package/dist/project/config-resolver.d.ts +6 -4
  565. package/dist/project/config-resolver.d.ts.map +1 -1
  566. package/dist/project/config-resolver.js +128 -74
  567. package/dist/project/config-resolver.js.map +1 -1
  568. package/dist/project/declared-config.d.ts +42 -0
  569. package/dist/project/declared-config.d.ts.map +1 -0
  570. package/dist/project/declared-config.js +60 -0
  571. package/dist/project/declared-config.js.map +1 -0
  572. package/dist/project/dependency-analyzer.d.ts.map +1 -1
  573. package/dist/project/dependency-analyzer.js.map +1 -1
  574. package/dist/project/deploy-phases.d.ts +35 -0
  575. package/dist/project/deploy-phases.d.ts.map +1 -0
  576. package/dist/project/deploy-phases.js +75 -0
  577. package/dist/project/deploy-phases.js.map +1 -0
  578. package/dist/project/exec-in-group.d.ts +49 -0
  579. package/dist/project/exec-in-group.d.ts.map +1 -0
  580. package/dist/project/exec-in-group.js +100 -0
  581. package/dist/project/exec-in-group.js.map +1 -0
  582. package/dist/project/node-app-config.d.ts +101 -0
  583. package/dist/project/node-app-config.d.ts.map +1 -0
  584. package/dist/project/node-app-config.js +134 -0
  585. package/dist/project/node-app-config.js.map +1 -0
  586. package/dist/project/node-app-health.d.ts +76 -0
  587. package/dist/project/node-app-health.d.ts.map +1 -0
  588. package/dist/project/node-app-health.js +119 -0
  589. package/dist/project/node-app-health.js.map +1 -0
  590. package/dist/project/operator-account.d.ts +287 -0
  591. package/dist/project/operator-account.d.ts.map +1 -0
  592. package/dist/project/operator-account.js +373 -0
  593. package/dist/project/operator-account.js.map +1 -0
  594. package/dist/project/registry.d.ts +45 -8
  595. package/dist/project/registry.d.ts.map +1 -1
  596. package/dist/project/registry.js +217 -49
  597. package/dist/project/registry.js.map +1 -1
  598. package/dist/project/requirements-scanner.d.ts +1 -0
  599. package/dist/project/requirements-scanner.d.ts.map +1 -1
  600. package/dist/project/requirements-scanner.js +28 -3
  601. package/dist/project/requirements-scanner.js.map +1 -1
  602. package/dist/project/stack-env.d.ts +37 -0
  603. package/dist/project/stack-env.d.ts.map +1 -0
  604. package/dist/project/stack-env.js +85 -0
  605. package/dist/project/stack-env.js.map +1 -0
  606. package/dist/project/stand-containers.d.ts +4 -0
  607. package/dist/project/stand-containers.d.ts.map +1 -0
  608. package/dist/project/stand-containers.js +27 -0
  609. package/dist/project/stand-containers.js.map +1 -0
  610. package/dist/project/working-tree.d.ts +62 -0
  611. package/dist/project/working-tree.d.ts.map +1 -0
  612. package/dist/project/working-tree.js +101 -0
  613. package/dist/project/working-tree.js.map +1 -0
  614. package/dist/release/artifact-store.d.ts +360 -0
  615. package/dist/release/artifact-store.d.ts.map +1 -0
  616. package/dist/release/artifact-store.js +1040 -0
  617. package/dist/release/artifact-store.js.map +1 -0
  618. package/dist/release/attest-on-node.d.ts +92 -0
  619. package/dist/release/attest-on-node.d.ts.map +1 -0
  620. package/dist/release/attest-on-node.js +207 -0
  621. package/dist/release/attest-on-node.js.map +1 -0
  622. package/dist/release/attest.d.ts +135 -0
  623. package/dist/release/attest.d.ts.map +1 -0
  624. package/dist/release/attest.js +199 -0
  625. package/dist/release/attest.js.map +1 -0
  626. package/dist/release/build-run.d.ts +151 -0
  627. package/dist/release/build-run.d.ts.map +1 -0
  628. package/dist/release/build-run.js +609 -0
  629. package/dist/release/build-run.js.map +1 -0
  630. package/dist/release/builder.d.ts +57 -0
  631. package/dist/release/builder.d.ts.map +1 -0
  632. package/dist/release/builder.js +120 -0
  633. package/dist/release/builder.js.map +1 -0
  634. package/dist/release/daemon-omni.d.ts +41 -0
  635. package/dist/release/daemon-omni.d.ts.map +1 -0
  636. package/dist/release/daemon-omni.js +59 -0
  637. package/dist/release/daemon-omni.js.map +1 -0
  638. package/dist/release/definition-inputs.d.ts +34 -0
  639. package/dist/release/definition-inputs.d.ts.map +1 -0
  640. package/dist/release/definition-inputs.js +90 -0
  641. package/dist/release/definition-inputs.js.map +1 -0
  642. package/dist/release/delivered.d.ts +53 -0
  643. package/dist/release/delivered.d.ts.map +1 -0
  644. package/dist/release/delivered.js +81 -0
  645. package/dist/release/delivered.js.map +1 -0
  646. package/dist/release/layout.d.ts +61 -0
  647. package/dist/release/layout.d.ts.map +1 -0
  648. package/dist/release/layout.js +114 -0
  649. package/dist/release/layout.js.map +1 -0
  650. package/dist/release/load.d.ts +44 -0
  651. package/dist/release/load.d.ts.map +1 -0
  652. package/dist/release/load.js +84 -0
  653. package/dist/release/load.js.map +1 -0
  654. package/dist/release/manifest.d.ts +299 -0
  655. package/dist/release/manifest.d.ts.map +1 -0
  656. package/dist/release/manifest.js +176 -0
  657. package/dist/release/manifest.js.map +1 -0
  658. package/dist/release/migrations.d.ts +32 -0
  659. package/dist/release/migrations.d.ts.map +1 -0
  660. package/dist/release/migrations.js +51 -0
  661. package/dist/release/migrations.js.map +1 -0
  662. package/dist/release/publish.d.ts +71 -0
  663. package/dist/release/publish.d.ts.map +1 -0
  664. package/dist/release/publish.js +102 -0
  665. package/dist/release/publish.js.map +1 -0
  666. package/dist/release/store.d.ts +174 -0
  667. package/dist/release/store.d.ts.map +1 -0
  668. package/dist/release/store.js +257 -0
  669. package/dist/release/store.js.map +1 -0
  670. package/dist/services/alert.rpc-service.d.ts +11 -15
  671. package/dist/services/alert.rpc-service.d.ts.map +1 -1
  672. package/dist/services/alert.rpc-service.js +29 -14
  673. package/dist/services/alert.rpc-service.js.map +1 -1
  674. package/dist/services/alert.service.d.ts +96 -59
  675. package/dist/services/alert.service.d.ts.map +1 -1
  676. package/dist/services/alert.service.js +455 -70
  677. package/dist/services/alert.service.js.map +1 -1
  678. package/dist/services/anonymous-input.d.ts +26 -0
  679. package/dist/services/anonymous-input.d.ts.map +1 -0
  680. package/dist/services/anonymous-input.js +44 -0
  681. package/dist/services/anonymous-input.js.map +1 -0
  682. package/dist/services/audit.rpc-service.d.ts +27 -0
  683. package/dist/services/audit.rpc-service.d.ts.map +1 -0
  684. package/dist/services/audit.rpc-service.js +57 -0
  685. package/dist/services/audit.rpc-service.js.map +1 -0
  686. package/dist/services/audit.service.d.ts +165 -0
  687. package/dist/services/audit.service.d.ts.map +1 -0
  688. package/dist/services/audit.service.js +242 -0
  689. package/dist/services/audit.service.js.map +1 -0
  690. package/dist/services/auth-context.d.ts +21 -1
  691. package/dist/services/auth-context.d.ts.map +1 -1
  692. package/dist/services/auth-context.js +51 -5
  693. package/dist/services/auth-context.js.map +1 -1
  694. package/dist/services/auth.rpc-service.d.ts +0 -1
  695. package/dist/services/auth.rpc-service.d.ts.map +1 -1
  696. package/dist/services/auth.rpc-service.js +23 -9
  697. package/dist/services/auth.rpc-service.js.map +1 -1
  698. package/dist/services/auth.service.d.ts +47 -33
  699. package/dist/services/auth.service.d.ts.map +1 -1
  700. package/dist/services/auth.service.js +155 -23
  701. package/dist/services/auth.service.js.map +1 -1
  702. package/dist/services/backup-pipeline.d.ts +97 -0
  703. package/dist/services/backup-pipeline.d.ts.map +1 -0
  704. package/dist/services/backup-pipeline.js +286 -0
  705. package/dist/services/backup-pipeline.js.map +1 -0
  706. package/dist/services/backup-schedule.d.ts +69 -0
  707. package/dist/services/backup-schedule.d.ts.map +1 -0
  708. package/dist/services/backup-schedule.js +132 -0
  709. package/dist/services/backup-schedule.js.map +1 -0
  710. package/dist/services/backup.rpc-service.d.ts +31 -2
  711. package/dist/services/backup.rpc-service.d.ts.map +1 -1
  712. package/dist/services/backup.rpc-service.js +53 -0
  713. package/dist/services/backup.rpc-service.js.map +1 -1
  714. package/dist/services/backup.service.d.ts +458 -14
  715. package/dist/services/backup.service.d.ts.map +1 -1
  716. package/dist/services/backup.service.js +1368 -170
  717. package/dist/services/backup.service.js.map +1 -1
  718. package/dist/services/bundle-build-worker.d.ts +19 -0
  719. package/dist/services/bundle-build-worker.d.ts.map +1 -0
  720. package/dist/services/bundle-build-worker.js +40 -0
  721. package/dist/services/bundle-build-worker.js.map +1 -0
  722. package/dist/services/bundle-builder.d.ts +487 -0
  723. package/dist/services/bundle-builder.d.ts.map +1 -0
  724. package/dist/services/bundle-builder.js +1083 -0
  725. package/dist/services/bundle-builder.js.map +1 -0
  726. package/dist/services/bundle-worker-protocol.d.ts +19 -0
  727. package/dist/services/bundle-worker-protocol.d.ts.map +1 -0
  728. package/dist/services/bundle-worker-protocol.js +32 -0
  729. package/dist/services/bundle-worker-protocol.js.map +1 -0
  730. package/dist/services/deploy.rpc-service.d.ts +4 -1
  731. package/dist/services/deploy.rpc-service.d.ts.map +1 -1
  732. package/dist/services/deploy.rpc-service.js +10 -0
  733. package/dist/services/deploy.rpc-service.js.map +1 -1
  734. package/dist/services/deploy.service.d.ts +14 -24
  735. package/dist/services/deploy.service.d.ts.map +1 -1
  736. package/dist/services/deploy.service.js +46 -5
  737. package/dist/services/deploy.service.js.map +1 -1
  738. package/dist/services/discovery.rpc-service.d.ts +2 -1
  739. package/dist/services/discovery.rpc-service.d.ts.map +1 -1
  740. package/dist/services/discovery.rpc-service.js.map +1 -1
  741. package/dist/services/discovery.service.d.ts +32 -28
  742. package/dist/services/discovery.service.d.ts.map +1 -1
  743. package/dist/services/discovery.service.js +108 -133
  744. package/dist/services/discovery.service.js.map +1 -1
  745. package/dist/services/event-broadcaster.rpc-service.d.ts +36 -23
  746. package/dist/services/event-broadcaster.rpc-service.d.ts.map +1 -1
  747. package/dist/services/event-broadcaster.rpc-service.js +70 -32
  748. package/dist/services/event-broadcaster.rpc-service.js.map +1 -1
  749. package/dist/services/event-broadcaster.service.d.ts.map +1 -1
  750. package/dist/services/event-broadcaster.service.js.map +1 -1
  751. package/dist/services/fleet.rpc-service.d.ts +2 -1
  752. package/dist/services/fleet.rpc-service.d.ts.map +1 -1
  753. package/dist/services/fleet.rpc-service.js +3 -1
  754. package/dist/services/fleet.rpc-service.js.map +1 -1
  755. package/dist/services/fleet.service.d.ts +32 -34
  756. package/dist/services/fleet.service.d.ts.map +1 -1
  757. package/dist/services/fleet.service.js +66 -10
  758. package/dist/services/fleet.service.js.map +1 -1
  759. package/dist/services/health-check.rpc-service.d.ts +2 -1
  760. package/dist/services/health-check.rpc-service.d.ts.map +1 -1
  761. package/dist/services/health-check.rpc-service.js.map +1 -1
  762. package/dist/services/health-check.service.d.ts +50 -36
  763. package/dist/services/health-check.service.d.ts.map +1 -1
  764. package/dist/services/health-check.service.js +179 -182
  765. package/dist/services/health-check.service.js.map +1 -1
  766. package/dist/services/infrastructure.rpc-service.d.ts +297 -2
  767. package/dist/services/infrastructure.rpc-service.d.ts.map +1 -1
  768. package/dist/services/infrastructure.rpc-service.js +523 -11
  769. package/dist/services/infrastructure.rpc-service.js.map +1 -1
  770. package/dist/services/kubernetes.rpc-service.d.ts +2 -1
  771. package/dist/services/kubernetes.rpc-service.d.ts.map +1 -1
  772. package/dist/services/kubernetes.rpc-service.js.map +1 -1
  773. package/dist/services/kubernetes.service.d.ts +5 -39
  774. package/dist/services/kubernetes.service.d.ts.map +1 -1
  775. package/dist/services/kubernetes.service.js +29 -5
  776. package/dist/services/kubernetes.service.js.map +1 -1
  777. package/dist/services/local-bundle.d.ts +151 -0
  778. package/dist/services/local-bundle.d.ts.map +1 -0
  779. package/dist/services/local-bundle.js +233 -0
  780. package/dist/services/local-bundle.js.map +1 -0
  781. package/dist/services/lockout.d.ts +28 -0
  782. package/dist/services/lockout.d.ts.map +1 -0
  783. package/dist/services/lockout.js +41 -0
  784. package/dist/services/lockout.js.map +1 -0
  785. package/dist/services/log-collector.rpc-service.d.ts +16 -0
  786. package/dist/services/log-collector.rpc-service.d.ts.map +1 -1
  787. package/dist/services/log-collector.rpc-service.js +16 -0
  788. package/dist/services/log-collector.rpc-service.js.map +1 -1
  789. package/dist/services/log-collector.service.d.ts +172 -54
  790. package/dist/services/log-collector.service.d.ts.map +1 -1
  791. package/dist/services/log-collector.service.js +492 -102
  792. package/dist/services/log-collector.service.js.map +1 -1
  793. package/dist/services/log-retention.d.ts +50 -0
  794. package/dist/services/log-retention.d.ts.map +1 -0
  795. package/dist/services/log-retention.js +52 -0
  796. package/dist/services/log-retention.js.map +1 -0
  797. package/dist/services/maintenance-lock.d.ts +162 -0
  798. package/dist/services/maintenance-lock.d.ts.map +1 -0
  799. package/dist/services/maintenance-lock.js +316 -0
  800. package/dist/services/maintenance-lock.js.map +1 -0
  801. package/dist/services/master-address.d.ts +107 -0
  802. package/dist/services/master-address.d.ts.map +1 -0
  803. package/dist/services/master-address.js +154 -0
  804. package/dist/services/master-address.js.map +1 -0
  805. package/dist/services/migration-output.d.ts +16 -0
  806. package/dist/services/migration-output.d.ts.map +1 -0
  807. package/dist/services/migration-output.js +22 -0
  808. package/dist/services/migration-output.js.map +1 -0
  809. package/dist/services/netron-telemetry-transport.d.ts.map +1 -1
  810. package/dist/services/netron-telemetry-transport.js.map +1 -1
  811. package/dist/services/node-deploy-lease.d.ts +154 -0
  812. package/dist/services/node-deploy-lease.d.ts.map +1 -0
  813. package/dist/services/node-deploy-lease.js +386 -0
  814. package/dist/services/node-deploy-lease.js.map +1 -0
  815. package/dist/services/node-health.repository.d.ts +63 -4
  816. package/dist/services/node-health.repository.d.ts.map +1 -1
  817. package/dist/services/node-health.repository.js +108 -67
  818. package/dist/services/node-health.repository.js.map +1 -1
  819. package/dist/services/node-manager.rpc-service.d.ts +355 -10
  820. package/dist/services/node-manager.rpc-service.d.ts.map +1 -1
  821. package/dist/services/node-manager.rpc-service.js +730 -34
  822. package/dist/services/node-manager.rpc-service.js.map +1 -1
  823. package/dist/services/node-manager.service.d.ts +267 -95
  824. package/dist/services/node-manager.service.d.ts.map +1 -1
  825. package/dist/services/node-manager.service.js +805 -103
  826. package/dist/services/node-manager.service.js.map +1 -1
  827. package/dist/services/node-upgrade.d.ts +129 -0
  828. package/dist/services/node-upgrade.d.ts.map +1 -0
  829. package/dist/services/node-upgrade.js +161 -0
  830. package/dist/services/node-upgrade.js.map +1 -0
  831. package/dist/services/node-upgrade.service.d.ts +232 -0
  832. package/dist/services/node-upgrade.service.d.ts.map +1 -0
  833. package/dist/services/node-upgrade.service.js +468 -0
  834. package/dist/services/node-upgrade.service.js.map +1 -0
  835. package/dist/services/pipeline.rpc-service.d.ts +2 -1
  836. package/dist/services/pipeline.rpc-service.d.ts.map +1 -1
  837. package/dist/services/pipeline.rpc-service.js.map +1 -1
  838. package/dist/services/pipeline.service.d.ts +15 -46
  839. package/dist/services/pipeline.service.d.ts.map +1 -1
  840. package/dist/services/pipeline.service.js +72 -9
  841. package/dist/services/pipeline.service.js.map +1 -1
  842. package/dist/services/project.rpc-service.d.ts +133 -5
  843. package/dist/services/project.rpc-service.d.ts.map +1 -1
  844. package/dist/services/project.rpc-service.js +249 -22
  845. package/dist/services/project.rpc-service.js.map +1 -1
  846. package/dist/services/project.service.d.ts +677 -15
  847. package/dist/services/project.service.d.ts.map +1 -1
  848. package/dist/services/project.service.js +2798 -304
  849. package/dist/services/project.service.js.map +1 -1
  850. package/dist/services/redeploy-decision.d.ts +176 -0
  851. package/dist/services/redeploy-decision.d.ts.map +1 -0
  852. package/dist/services/redeploy-decision.js +142 -0
  853. package/dist/services/redeploy-decision.js.map +1 -0
  854. package/dist/services/release.rpc-service.d.ts +159 -0
  855. package/dist/services/release.rpc-service.d.ts.map +1 -0
  856. package/dist/services/release.rpc-service.js +395 -0
  857. package/dist/services/release.rpc-service.js.map +1 -0
  858. package/dist/services/release.service.d.ts +114 -0
  859. package/dist/services/release.service.d.ts.map +1 -0
  860. package/dist/services/release.service.js +208 -0
  861. package/dist/services/release.service.js.map +1 -0
  862. package/dist/services/remote-deployer.service.d.ts +569 -8
  863. package/dist/services/remote-deployer.service.d.ts.map +1 -1
  864. package/dist/services/remote-deployer.service.js +1618 -169
  865. package/dist/services/remote-deployer.service.js.map +1 -1
  866. package/dist/services/remote-ops.service.d.ts +51 -9
  867. package/dist/services/remote-ops.service.d.ts.map +1 -1
  868. package/dist/services/remote-ops.service.js +235 -39
  869. package/dist/services/remote-ops.service.js.map +1 -1
  870. package/dist/services/remote-provisioner.d.ts +122 -0
  871. package/dist/services/remote-provisioner.d.ts.map +1 -0
  872. package/dist/services/remote-provisioner.js +258 -0
  873. package/dist/services/remote-provisioner.js.map +1 -0
  874. package/dist/services/secrets.rpc-service.d.ts +51 -2
  875. package/dist/services/secrets.rpc-service.d.ts.map +1 -1
  876. package/dist/services/secrets.rpc-service.js +81 -2
  877. package/dist/services/secrets.rpc-service.js.map +1 -1
  878. package/dist/services/secrets.service.d.ts +108 -9
  879. package/dist/services/secrets.service.d.ts.map +1 -1
  880. package/dist/services/secrets.service.js +313 -48
  881. package/dist/services/secrets.service.js.map +1 -1
  882. package/dist/services/slave-storage.service.d.ts +107 -0
  883. package/dist/services/slave-storage.service.d.ts.map +1 -1
  884. package/dist/services/slave-storage.service.js +171 -2
  885. package/dist/services/slave-storage.service.js.map +1 -1
  886. package/dist/services/static-carry-forward.d.ts +85 -0
  887. package/dist/services/static-carry-forward.d.ts.map +1 -0
  888. package/dist/services/static-carry-forward.js +159 -0
  889. package/dist/services/static-carry-forward.js.map +1 -0
  890. package/dist/services/sync-policy.d.ts +167 -0
  891. package/dist/services/sync-policy.d.ts.map +1 -0
  892. package/dist/services/sync-policy.js +161 -0
  893. package/dist/services/sync-policy.js.map +1 -0
  894. package/dist/services/sync-summary.d.ts +39 -0
  895. package/dist/services/sync-summary.d.ts.map +1 -0
  896. package/dist/services/sync-summary.js +62 -0
  897. package/dist/services/sync-summary.js.map +1 -0
  898. package/dist/services/sync.rpc-service.d.ts +19 -7
  899. package/dist/services/sync.rpc-service.d.ts.map +1 -1
  900. package/dist/services/sync.rpc-service.js +36 -5
  901. package/dist/services/sync.rpc-service.js.map +1 -1
  902. package/dist/services/sync.service.d.ts +350 -18
  903. package/dist/services/sync.service.d.ts.map +1 -1
  904. package/dist/services/sync.service.js +864 -116
  905. package/dist/services/sync.service.js.map +1 -1
  906. package/dist/services/system-info.rpc-service.d.ts +2 -1
  907. package/dist/services/system-info.rpc-service.d.ts.map +1 -1
  908. package/dist/services/system-info.rpc-service.js.map +1 -1
  909. package/dist/services/system-info.service.d.ts +56 -68
  910. package/dist/services/system-info.service.d.ts.map +1 -1
  911. package/dist/services/system-info.service.js +240 -127
  912. package/dist/services/system-info.service.js.map +1 -1
  913. package/dist/services/telemetry.rpc-service.d.ts.map +1 -1
  914. package/dist/services/telemetry.rpc-service.js +9 -3
  915. package/dist/services/telemetry.rpc-service.js.map +1 -1
  916. package/dist/services/telemetry.service.d.ts +4 -2
  917. package/dist/services/telemetry.service.d.ts.map +1 -1
  918. package/dist/services/telemetry.service.js +4 -2
  919. package/dist/services/telemetry.service.js.map +1 -1
  920. package/dist/services/trace-collector.rpc-service.d.ts +2 -1
  921. package/dist/services/trace-collector.rpc-service.d.ts.map +1 -1
  922. package/dist/services/trace-collector.rpc-service.js.map +1 -1
  923. package/dist/services/trace-collector.service.d.ts +2 -41
  924. package/dist/services/trace-collector.service.d.ts.map +1 -1
  925. package/dist/services/trace-collector.service.js +27 -7
  926. package/dist/services/trace-collector.service.js.map +1 -1
  927. package/dist/services/wait-for-postgres.d.ts +28 -0
  928. package/dist/services/wait-for-postgres.d.ts.map +1 -0
  929. package/dist/services/wait-for-postgres.js +77 -0
  930. package/dist/services/wait-for-postgres.js.map +1 -0
  931. package/dist/shared/alert-expression.d.ts +60 -0
  932. package/dist/shared/alert-expression.d.ts.map +1 -0
  933. package/dist/shared/alert-expression.js +124 -0
  934. package/dist/shared/alert-expression.js.map +1 -0
  935. package/dist/shared/audit-outcome.d.ts +39 -0
  936. package/dist/shared/audit-outcome.d.ts.map +1 -0
  937. package/dist/shared/audit-outcome.js +45 -0
  938. package/dist/shared/audit-outcome.js.map +1 -0
  939. package/dist/shared/build-freshness.d.ts +59 -0
  940. package/dist/shared/build-freshness.d.ts.map +1 -0
  941. package/dist/shared/build-freshness.js +113 -0
  942. package/dist/shared/build-freshness.js.map +1 -0
  943. package/dist/shared/build-stamp.d.ts +26 -0
  944. package/dist/shared/build-stamp.d.ts.map +1 -0
  945. package/dist/shared/build-stamp.js +36 -0
  946. package/dist/shared/build-stamp.js.map +1 -0
  947. package/dist/shared/describe-error.d.ts +22 -0
  948. package/dist/shared/describe-error.d.ts.map +1 -0
  949. package/dist/shared/describe-error.js +39 -0
  950. package/dist/shared/describe-error.js.map +1 -0
  951. package/dist/shared/dto/alerts.d.ts +101 -0
  952. package/dist/shared/dto/alerts.d.ts.map +1 -0
  953. package/dist/shared/dto/alerts.js +9 -0
  954. package/dist/shared/dto/alerts.js.map +1 -0
  955. package/dist/shared/dto/auth.d.ts +49 -0
  956. package/dist/shared/dto/auth.d.ts.map +1 -0
  957. package/dist/shared/dto/auth.js +14 -0
  958. package/dist/shared/dto/auth.js.map +1 -0
  959. package/dist/shared/dto/backups.d.ts +16 -0
  960. package/dist/shared/dto/backups.d.ts.map +1 -0
  961. package/dist/shared/dto/backups.js +9 -0
  962. package/dist/shared/dto/backups.js.map +1 -0
  963. package/dist/shared/dto/deploy.d.ts +28 -0
  964. package/dist/shared/dto/deploy.d.ts.map +1 -0
  965. package/dist/shared/dto/deploy.js +8 -0
  966. package/dist/shared/dto/deploy.js.map +1 -0
  967. package/dist/shared/dto/discovery.d.ts +24 -0
  968. package/dist/shared/dto/discovery.d.ts.map +1 -0
  969. package/dist/shared/dto/discovery.js +9 -0
  970. package/dist/shared/dto/discovery.js.map +1 -0
  971. package/dist/shared/dto/fleet.d.ts +35 -0
  972. package/dist/shared/dto/fleet.d.ts.map +1 -0
  973. package/dist/shared/dto/fleet.js +8 -0
  974. package/dist/shared/dto/fleet.js.map +1 -0
  975. package/dist/shared/dto/health.d.ts +26 -0
  976. package/dist/shared/dto/health.d.ts.map +1 -0
  977. package/dist/shared/dto/health.js +9 -0
  978. package/dist/shared/dto/health.js.map +1 -0
  979. package/dist/shared/dto/kubernetes.d.ts +44 -0
  980. package/dist/shared/dto/kubernetes.d.ts.map +1 -0
  981. package/dist/shared/dto/kubernetes.js +9 -0
  982. package/dist/shared/dto/kubernetes.js.map +1 -0
  983. package/dist/shared/dto/logs.d.ts +77 -0
  984. package/dist/shared/dto/logs.d.ts.map +1 -0
  985. package/dist/shared/dto/logs.js +10 -0
  986. package/dist/shared/dto/logs.js.map +1 -0
  987. package/dist/shared/dto/metrics.d.ts +65 -0
  988. package/dist/shared/dto/metrics.d.ts.map +1 -0
  989. package/dist/shared/dto/metrics.js +17 -0
  990. package/dist/shared/dto/metrics.js.map +1 -0
  991. package/dist/shared/dto/nodes.d.ts +347 -0
  992. package/dist/shared/dto/nodes.d.ts.map +1 -0
  993. package/dist/shared/dto/nodes.js +8 -0
  994. package/dist/shared/dto/nodes.js.map +1 -0
  995. package/dist/shared/dto/pipelines.d.ts +53 -0
  996. package/dist/shared/dto/pipelines.d.ts.map +1 -0
  997. package/dist/shared/dto/pipelines.js +9 -0
  998. package/dist/shared/dto/pipelines.js.map +1 -0
  999. package/dist/shared/dto/project.d.ts +142 -8
  1000. package/dist/shared/dto/project.d.ts.map +1 -1
  1001. package/dist/shared/dto/services.d.ts +831 -7
  1002. package/dist/shared/dto/services.d.ts.map +1 -1
  1003. package/dist/shared/dto/system-info.d.ts +93 -0
  1004. package/dist/shared/dto/system-info.d.ts.map +1 -0
  1005. package/dist/shared/dto/system-info.js +9 -0
  1006. package/dist/shared/dto/system-info.js.map +1 -0
  1007. package/dist/shared/dto/traces.d.ts +49 -0
  1008. package/dist/shared/dto/traces.d.ts.map +1 -0
  1009. package/dist/shared/dto/traces.js +9 -0
  1010. package/dist/shared/dto/traces.js.map +1 -0
  1011. package/dist/shared/env-config.d.ts +74 -0
  1012. package/dist/shared/env-config.d.ts.map +1 -0
  1013. package/dist/shared/env-config.js +99 -0
  1014. package/dist/shared/env-config.js.map +1 -0
  1015. package/dist/shared/events.d.ts +45 -39
  1016. package/dist/shared/events.d.ts.map +1 -1
  1017. package/dist/shared/events.js +6 -0
  1018. package/dist/shared/events.js.map +1 -1
  1019. package/dist/shared/format.d.ts +1 -1
  1020. package/dist/shared/format.d.ts.map +1 -1
  1021. package/dist/shared/format.js +4 -0
  1022. package/dist/shared/format.js.map +1 -1
  1023. package/dist/shared/local-infra-host.d.ts +28 -0
  1024. package/dist/shared/local-infra-host.d.ts.map +1 -0
  1025. package/dist/shared/local-infra-host.js +28 -0
  1026. package/dist/shared/local-infra-host.js.map +1 -0
  1027. package/dist/shared/node-check.d.ts +37 -0
  1028. package/dist/shared/node-check.d.ts.map +1 -0
  1029. package/dist/shared/node-check.js +41 -0
  1030. package/dist/shared/node-check.js.map +1 -0
  1031. package/dist/shared/paths.d.ts +29 -0
  1032. package/dist/shared/paths.d.ts.map +1 -0
  1033. package/dist/shared/paths.js +54 -0
  1034. package/dist/shared/paths.js.map +1 -0
  1035. package/dist/shared/pnpm.d.ts +29 -0
  1036. package/dist/shared/pnpm.d.ts.map +1 -0
  1037. package/dist/shared/pnpm.js +57 -0
  1038. package/dist/shared/pnpm.js.map +1 -0
  1039. package/dist/shared/private-files.d.ts +29 -0
  1040. package/dist/shared/private-files.d.ts.map +1 -0
  1041. package/dist/shared/private-files.js +109 -0
  1042. package/dist/shared/private-files.js.map +1 -0
  1043. package/dist/shared/redact-env.d.ts +24 -0
  1044. package/dist/shared/redact-env.d.ts.map +1 -0
  1045. package/dist/shared/redact-env.js +36 -0
  1046. package/dist/shared/redact-env.js.map +1 -0
  1047. package/dist/shared/release-reading.d.ts +85 -0
  1048. package/dist/shared/release-reading.d.ts.map +1 -0
  1049. package/dist/shared/release-reading.js +81 -0
  1050. package/dist/shared/release-reading.js.map +1 -0
  1051. package/dist/shared/roles.d.ts +58 -3
  1052. package/dist/shared/roles.d.ts.map +1 -1
  1053. package/dist/shared/roles.js +55 -0
  1054. package/dist/shared/roles.js.map +1 -1
  1055. package/dist/shared/rpcauth.d.ts +13 -0
  1056. package/dist/shared/rpcauth.d.ts.map +1 -0
  1057. package/dist/shared/rpcauth.js +23 -0
  1058. package/dist/shared/rpcauth.js.map +1 -0
  1059. package/dist/shared/shell-escape.d.ts +9 -0
  1060. package/dist/shared/shell-escape.d.ts.map +1 -0
  1061. package/dist/shared/shell-escape.js +11 -0
  1062. package/dist/shared/shell-escape.js.map +1 -0
  1063. package/dist/shared/sync-reading.d.ts +45 -0
  1064. package/dist/shared/sync-reading.d.ts.map +1 -0
  1065. package/dist/shared/sync-reading.js +42 -0
  1066. package/dist/shared/sync-reading.js.map +1 -0
  1067. package/dist/shared/tokens.d.ts +19 -0
  1068. package/dist/shared/tokens.d.ts.map +1 -1
  1069. package/dist/shared/tokens.js +28 -0
  1070. package/dist/shared/tokens.js.map +1 -1
  1071. package/dist/webapp/webapp.service.d.ts +33 -2
  1072. package/dist/webapp/webapp.service.d.ts.map +1 -1
  1073. package/dist/webapp/webapp.service.js +143 -31
  1074. package/dist/webapp/webapp.service.js.map +1 -1
  1075. package/dist/workers/health-monitor-process.d.ts.map +1 -1
  1076. package/dist/workers/health-monitor-process.js +10 -0
  1077. package/dist/workers/health-monitor-process.js.map +1 -1
  1078. package/dist/workers/health-monitor.service.d.ts +45 -3
  1079. package/dist/workers/health-monitor.service.d.ts.map +1 -1
  1080. package/dist/workers/health-monitor.service.js +152 -25
  1081. package/dist/workers/health-monitor.service.js.map +1 -1
  1082. package/dist/workers/system-worker-manager.d.ts +43 -0
  1083. package/dist/workers/system-worker-manager.d.ts.map +1 -1
  1084. package/dist/workers/system-worker-manager.js +150 -3
  1085. package/dist/workers/system-worker-manager.js.map +1 -1
  1086. package/dist/workers/types.d.ts +8 -2
  1087. package/dist/workers/types.d.ts.map +1 -1
  1088. package/package.json +64 -30
  1089. package/webapp/dist/BUILD.json +5 -0
  1090. package/webapp/dist/assets/FormControlLabel-BrH2diyl.js +1 -0
  1091. package/webapp/dist/assets/Grid-BZ7xhoHQ.js +1 -0
  1092. package/webapp/dist/assets/Switch-DGSAxQPM.js +1 -0
  1093. package/webapp/dist/assets/alerts-sXqHJbsa.js +1 -0
  1094. package/webapp/dist/assets/apps-B_Ah8Flh.js +1 -0
  1095. package/webapp/dist/assets/audit-YXihwyui.js +1 -0
  1096. package/webapp/dist/assets/client-CGbBvy9k.js +1 -0
  1097. package/webapp/dist/assets/constants-veKGFkC6.js +1 -0
  1098. package/webapp/dist/assets/containers-Di4NOTLf.js +2 -0
  1099. package/webapp/dist/assets/daemon-memory-CCPZ4cV_.js +1 -0
  1100. package/webapp/dist/assets/dashboard-Cfuf95N3.js +1 -0
  1101. package/webapp/dist/assets/dashboard-builder-CowaYb-M.js +1 -0
  1102. package/webapp/dist/assets/deploy-release-dialog-D6C-XcKY.js +1 -0
  1103. package/webapp/dist/assets/deployments-ChTq5kCw.js +1 -0
  1104. package/webapp/dist/assets/detail-BsGWv7Dj.js +1 -0
  1105. package/webapp/dist/assets/detail-CyVf_cw5.js +2 -0
  1106. package/webapp/dist/assets/detail-D027j6aO.js +8 -0
  1107. package/webapp/dist/assets/formatters-BqjL73N3.js +1 -0
  1108. package/webapp/dist/assets/index-B8AHIPc-.css +1 -0
  1109. package/webapp/dist/assets/index-DiZbrwxT.js +414 -0
  1110. package/webapp/dist/assets/logs-L2b8Oqmo.js +12 -0
  1111. package/webapp/dist/assets/maplibre-gl-MlmG2kbn.js +801 -0
  1112. package/webapp/dist/assets/metrics-CQgjz2Lz.js +2 -0
  1113. package/webapp/dist/assets/nodes-Nwia2Ty6.js +7 -0
  1114. package/webapp/dist/assets/pipelines-DCu_rXOr.js +4 -0
  1115. package/webapp/dist/assets/projects-Bb4aV76h.js +1 -0
  1116. package/webapp/dist/assets/react-CwJFpaho.js +1 -0
  1117. package/webapp/dist/assets/react-apexcharts.esm-Dy0Fez42.js +1956 -0
  1118. package/webapp/dist/assets/release-bits-Dj4EOhhb.js +1 -0
  1119. package/webapp/dist/assets/release-build-panel-D6OCVlhT.js +1 -0
  1120. package/webapp/dist/assets/releases-CnAt3yO6.js +2 -0
  1121. package/webapp/dist/assets/rolldown-runtime-hePW80VL.js +1 -0
  1122. package/webapp/dist/assets/settings-DU-mjiwb.js +1 -0
  1123. package/webapp/dist/assets/settled-pair-C7SjZuns.js +1 -0
  1124. package/webapp/dist/assets/sign-in-Bcvjrr4C.js +1 -0
  1125. package/webapp/dist/assets/stacks-B-e8p50I.js +1 -0
  1126. package/webapp/dist/assets/sync-reading-C3PnJ7AX.js +1 -0
  1127. package/webapp/dist/assets/system-info-BtE3dgfw.js +1 -0
  1128. package/webapp/dist/assets/topology-Cwch-uF1.js +12 -0
  1129. package/webapp/dist/assets/topology-DLioOiRN.css +1 -0
  1130. package/webapp/dist/assets/traces-BbShR-4P.js +1 -0
  1131. package/webapp/dist/assets/use-stack-context-CZUgPq88.js +1 -0
  1132. package/webapp/dist/index.html +6 -6
  1133. package/dist/commands/dev.d.ts +0 -23
  1134. package/dist/commands/dev.d.ts.map +0 -1
  1135. package/dist/commands/dev.js +0 -76
  1136. package/dist/commands/dev.js.map +0 -1
  1137. package/dist/config/define-app.d.ts +0 -6
  1138. package/dist/config/define-app.d.ts.map +0 -1
  1139. package/dist/config/define-app.js +0 -38
  1140. package/dist/config/define-app.js.map +0 -1
  1141. package/dist/infrastructure/gateway-generator.d.ts +0 -63
  1142. package/dist/infrastructure/gateway-generator.d.ts.map +0 -1
  1143. package/dist/infrastructure/gateway-generator.js +0 -253
  1144. package/dist/infrastructure/gateway-generator.js.map +0 -1
  1145. package/dist/monitoring/health.service.d.ts +0 -14
  1146. package/dist/monitoring/health.service.d.ts.map +0 -1
  1147. package/dist/monitoring/health.service.js +0 -50
  1148. package/dist/monitoring/health.service.js.map +0 -1
  1149. package/dist/monitoring/metrics.service.d.ts +0 -14
  1150. package/dist/monitoring/metrics.service.d.ts.map +0 -1
  1151. package/dist/monitoring/metrics.service.js +0 -40
  1152. package/dist/monitoring/metrics.service.js.map +0 -1
  1153. package/dist/orchestrator/bootstrap-runner.d.ts +0 -15
  1154. package/dist/orchestrator/bootstrap-runner.d.ts.map +0 -1
  1155. package/dist/orchestrator/bootstrap-runner.js +0 -152
  1156. package/dist/orchestrator/bootstrap-runner.js.map +0 -1
  1157. package/dist/orchestrator/topology-proxy.d.ts +0 -65
  1158. package/dist/orchestrator/topology-proxy.d.ts.map +0 -1
  1159. package/dist/orchestrator/topology-proxy.js +0 -209
  1160. package/dist/orchestrator/topology-proxy.js.map +0 -1
  1161. package/dist/orchestrator/topology-relay.d.ts +0 -111
  1162. package/dist/orchestrator/topology-relay.d.ts.map +0 -1
  1163. package/dist/orchestrator/topology-relay.js +0 -255
  1164. package/dist/orchestrator/topology-relay.js.map +0 -1
  1165. package/dist/services/auth-middleware.d.ts +0 -47
  1166. package/dist/services/auth-middleware.d.ts.map +0 -1
  1167. package/dist/services/auth-middleware.js +0 -158
  1168. package/dist/services/auth-middleware.js.map +0 -1
  1169. package/dist/services/environment.rpc-service.d.ts +0 -22
  1170. package/dist/services/environment.rpc-service.d.ts.map +0 -1
  1171. package/dist/services/environment.rpc-service.js +0 -65
  1172. package/dist/services/environment.rpc-service.js.map +0 -1
  1173. package/dist/services/environment.service.d.ts +0 -87
  1174. package/dist/services/environment.service.d.ts.map +0 -1
  1175. package/dist/services/environment.service.js +0 -220
  1176. package/dist/services/environment.service.js.map +0 -1
  1177. package/dist/services/metrics-collector.service.d.ts +0 -103
  1178. package/dist/services/metrics-collector.service.d.ts.map +0 -1
  1179. package/dist/services/metrics-collector.service.js +0 -235
  1180. package/dist/services/metrics-collector.service.js.map +0 -1
  1181. package/dist/services/metrics.rpc-service.d.ts +0 -41
  1182. package/dist/services/metrics.rpc-service.d.ts.map +0 -1
  1183. package/dist/services/metrics.rpc-service.js +0 -90
  1184. package/dist/services/metrics.rpc-service.js.map +0 -1
  1185. package/dist/services/metrics.service.d.ts +0 -72
  1186. package/dist/services/metrics.service.d.ts.map +0 -1
  1187. package/dist/services/metrics.service.js +0 -185
  1188. package/dist/services/metrics.service.js.map +0 -1
  1189. package/dist/supervisor/omnitron-supervisor.d.ts +0 -21
  1190. package/dist/supervisor/omnitron-supervisor.d.ts.map +0 -1
  1191. package/dist/supervisor/omnitron-supervisor.js +0 -43
  1192. package/dist/supervisor/omnitron-supervisor.js.map +0 -1
  1193. package/dist/webapp/static-server.d.ts +0 -24
  1194. package/dist/webapp/static-server.d.ts.map +0 -1
  1195. package/dist/webapp/static-server.js +0 -152
  1196. package/dist/webapp/static-server.js.map +0 -1
  1197. package/webapp/dist/assets/Badge-D2ZBP5iK.js +0 -1
  1198. package/webapp/dist/assets/Card-vO88g06B.js +0 -1
  1199. package/webapp/dist/assets/CardActions-C9h7Q2wW.js +0 -1
  1200. package/webapp/dist/assets/CardContent-BA_Xmmhk.js +0 -1
  1201. package/webapp/dist/assets/CardHeader-ceIs__6x.js +0 -1
  1202. package/webapp/dist/assets/Chip-Ckk0xUhK.js +0 -1
  1203. package/webapp/dist/assets/DialogActions-BhHM7hov.js +0 -1
  1204. package/webapp/dist/assets/DialogContentText-BT2JQRmK.js +0 -1
  1205. package/webapp/dist/assets/FormControlLabel-CcQByVS8.js +0 -1
  1206. package/webapp/dist/assets/Grid-14PETRQW.js +0 -1
  1207. package/webapp/dist/assets/InputAdornment-B8aHIsQ7.js +0 -1
  1208. package/webapp/dist/assets/Skeleton-B74-Ds6O.js +0 -37
  1209. package/webapp/dist/assets/Switch-DvWD2wh4.js +0 -1
  1210. package/webapp/dist/assets/SwitchBase-CDU4nY8O.js +0 -1
  1211. package/webapp/dist/assets/Tab-DcCOYYp5.js +0 -1
  1212. package/webapp/dist/assets/TableContainer-CzTh4mu-.js +0 -1
  1213. package/webapp/dist/assets/TableRow-BySEreZR.js +0 -2
  1214. package/webapp/dist/assets/TextField-BLf-BHz2.js +0 -1
  1215. package/webapp/dist/assets/alerts-DnRbT41C.js +0 -1
  1216. package/webapp/dist/assets/apps-CdR0VH2d.js +0 -1
  1217. package/webapp/dist/assets/chunk-DtcAfS_W.js +0 -1
  1218. package/webapp/dist/assets/client-DU8I_lDc.js +0 -2
  1219. package/webapp/dist/assets/constants-BgnT-Xdy.js +0 -1
  1220. package/webapp/dist/assets/containers-Dw-rRXV1.js +0 -1
  1221. package/webapp/dist/assets/dashboard-CzgB0uZz.js +0 -1
  1222. package/webapp/dist/assets/dashboard-builder-DsA0yg33.js +0 -1
  1223. package/webapp/dist/assets/deployments-DtQAoIcQ.js +0 -1
  1224. package/webapp/dist/assets/detail-BJR-G7JG.js +0 -1
  1225. package/webapp/dist/assets/detail-nlCeSltl.js +0 -8
  1226. package/webapp/dist/assets/formatters-Do41SRmE.js +0 -1
  1227. package/webapp/dist/assets/index-ByQDwp2r.js +0 -566
  1228. package/webapp/dist/assets/index-CHVXOsTS.css +0 -1
  1229. package/webapp/dist/assets/isMuiElement-DwF2naaF.js +0 -1
  1230. package/webapp/dist/assets/logs-Kn8o4H7k.js +0 -11
  1231. package/webapp/dist/assets/metrics-DN8Zu5wT.js +0 -2
  1232. package/webapp/dist/assets/nodes-Bgch7AtN.js +0 -7
  1233. package/webapp/dist/assets/pipelines-Cry3qm-S.js +0 -4
  1234. package/webapp/dist/assets/popper-BJFSj6rc.js +0 -1
  1235. package/webapp/dist/assets/preload-helper-DSXbuxSR.js +0 -1
  1236. package/webapp/dist/assets/projects-Dym2GI1U.js +0 -1
  1237. package/webapp/dist/assets/react-apexcharts.esm-CSGK5Cxn.js +0 -958
  1238. package/webapp/dist/assets/react-apexcharts.esm-DEAWOwx5.js +0 -1003
  1239. package/webapp/dist/assets/settings-va3zTcow.js +0 -1
  1240. package/webapp/dist/assets/sign-in-ik35umbp.js +0 -1
  1241. package/webapp/dist/assets/stacks-CVFOnxbF.js +0 -1
  1242. package/webapp/dist/assets/system-info-npIXAjX2.js +0 -1
  1243. package/webapp/dist/assets/topology-CHpVij2M.css +0 -1
  1244. package/webapp/dist/assets/topology-bDe70vLs.js +0 -12
  1245. package/webapp/dist/assets/traces-DIIcT8DF.js +0 -1
  1246. package/webapp/dist/assets/use-stack-context-DHLwZv1r.js +0 -1
  1247. /package/webapp/dist/assets/{fs-CgZLtHiQ.js → fs-Ccl3sAcp.js} +0 -0
@@ -5,29 +5,146 @@
5
5
  * - Every slave daemon collects ALL metrics, logs, events, alerts locally
6
6
  * - Data is buffered in a local append-only WAL (write-ahead log) in omnitron-pg
7
7
  * - Periodically, slave attempts to push buffered data to master via Netron TCP
8
- * - On success: WAL entries marked as synced
9
- * - On failure: exponential backoff, retry later — data is NEVER lost
10
- * - All sync batches are idempotent (safe to retry)
8
+ * - On success: the entries the master confirms are marked as synced
9
+ * - On failure: exponential backoff, retry later — the entries stay pending
10
+ * - Sync batches are idempotent: the master keeps a ledger of what it took
11
11
  *
12
12
  * Guarantees:
13
- * 1. Zero data loss — local WAL persists through daemon restarts
13
+ * 1. No loss on delivery failure — an entry is released only once the master
14
+ * has confirmed it holds it. Bounded by (5): when the buffer is over
15
+ * budget, undelivered entries are dropped oldest-first, loudly.
14
16
  * 2. Autonomous operation — slave works normally without master
15
17
  * 3. Eventual consistency — master sees all data when connectivity restores
16
18
  * 4. Conflict-free — operational data is append-only, config uses master-wins
17
19
  * 5. Bounded buffer — oldest entries evicted when maxBufferSize reached
18
20
  *
21
+ * Four of these were stated here long before anything implemented them, and
22
+ * every one of the failures was silent: replication that drops data still
23
+ * reports a successful cycle, because what would have noticed is what was
24
+ * missing. Guarantee 1 said "zero data loss" while both transports discarded
25
+ * whatever the master rejected; the batches were called idempotent with
26
+ * `batchId` used only inside log strings; and `maxBufferSize` was read from
27
+ * config, defaulted to 500 MB, and never referenced again.
28
+ *
29
+ * Guarantee 1 is now stated as what it can be. "Zero data loss" was not
30
+ * achievable alongside a bounded buffer, and writing it down did not make it
31
+ * so — a slave that cannot reach its master eventually has to choose between
32
+ * dropping data and filling the disk. It drops, oldest first, at warning
33
+ * level with a count. See `sync-policy.ts`.
34
+ *
19
35
  * WAL table: `sync_buffer` in slave's local omnitron-pg
20
36
  * Each entry: { id, category, payload (jsonb), createdAt, syncedAt (null until synced) }
37
+ * Dedup ledger (master side): `sync_ingested`, keyed on (nodeId, slave entry id)
21
38
  */
39
+ import { toIsoUtc } from '../database/sqlite-date-binding.js';
40
+ import { describeError } from '../shared/describe-error.js';
41
+ import { classifyIngestFailure, deliveredIds, sweepMadeProgress, planEviction, SYNCED_RETENTION_MS, LEDGER_WINDOW_DAYS, LEDGER_FIRST_PASS_DELAY_MS, LEDGER_INTERVAL_MS, LEDGER_BACKLOG_INTERVAL_MS, } from './sync-policy.js';
42
+ import { planRetention, batchesPerPass } from './log-retention.js';
22
43
  /** Max batches per node per minute */
23
44
  const RATE_LIMIT_PER_MINUTE = 60;
45
+ /**
46
+ * The most parameters one statement binds.
47
+ *
48
+ * Postgres takes 65 535 and SQLite 32 766 (better-sqlite3 13.0.3 / SQLite
49
+ * 3.53.4, measured: 32 767 is refused with «too many SQL variables»). This
50
+ * service writes to both — a master on Postgres, a slave on SQLite — so the
51
+ * smaller one bounds every statement it builds from a list, with room.
52
+ */
53
+ const MAX_BOUND_PARAMETERS = 30_000;
54
+ /** Rows split into statements that each stay within `MAX_BOUND_PARAMETERS`. */
55
+ function statementsOf(rows) {
56
+ if (rows.length === 0)
57
+ return [];
58
+ const perRow = Math.max(1, Object.keys(rows[0]).length);
59
+ const size = Math.max(1, Math.floor(MAX_BOUND_PARAMETERS / perRow));
60
+ const parts = [];
61
+ for (let i = 0; i < rows.length; i += size)
62
+ parts.push(rows.slice(i, i + size));
63
+ return parts;
64
+ }
65
+ function logRow(nodeId, entry) {
66
+ return {
67
+ timestamp: entry.payload['timestamp'] ?? entry.createdAt,
68
+ nodeId,
69
+ app: entry.payload['app'] ?? 'unknown',
70
+ level: entry.payload['level'] ?? 'info',
71
+ message: entry.payload['message'] ?? '',
72
+ labels: JSON.stringify(entry.payload['labels'] ?? {}),
73
+ traceId: entry.payload['traceId'] ?? null,
74
+ spanId: entry.payload['spanId'] ?? null,
75
+ metadata: entry.payload['metadata'] ? JSON.stringify(entry.payload['metadata']) : null,
76
+ };
77
+ }
78
+ /**
79
+ * A remote alert, with the machine that raised it.
80
+ *
81
+ * `nodeId` was `_nodeId` here: accepted and discarded. `alert_events` has
82
+ * no node column, so it goes into `annotations`, which is the jsonb this
83
+ * table already carries context in — an alert that says "disk above 90%"
84
+ * and cannot say whose disk is an alert an operator cannot act on.
85
+ *
86
+ * `ruleId` keeps its `?? 'unknown'` only so the shape is unchanged; the
87
+ * column is a `uuid` with a foreign key to `alert_rules`, so that literal
88
+ * is refused by the database and the entry is now discarded by
89
+ * `classifyIngestFailure` instead of being offered forever. A slave's
90
+ * rules are its own, so the same is true of any real ruleId the master
91
+ * does not share — which is what makes the permanent-failure path the
92
+ * important half of this.
93
+ */
94
+ function alertRow(nodeId, entry) {
95
+ const annotations = {
96
+ ...entry.payload['annotations'],
97
+ node: nodeId,
98
+ };
99
+ return {
100
+ ruleId: entry.payload['ruleId'] ?? 'unknown',
101
+ status: entry.payload['status'] ?? 'firing',
102
+ value: entry.payload['value'] != null ? String(entry.payload['value']) : null,
103
+ annotations: JSON.stringify(annotations),
104
+ firedAt: entry.payload['firedAt'] ?? entry.createdAt,
105
+ resolvedAt: entry.payload['resolvedAt'] ?? null,
106
+ acknowledgedAt: null,
107
+ acknowledgedBy: null,
108
+ };
109
+ }
110
+ /**
111
+ * A remote span, with the machine that produced it.
112
+ *
113
+ * The node went into `tags` as `entry.payload['tags'] ?? { nodeId }` — a
114
+ * fallback, so it was recorded ONLY for a span that carried no tags at
115
+ * all, and dropped for every span that carried any. The `??` fires exactly
116
+ * when there is nothing to lose and is skipped exactly when there is.
117
+ * Merged now, and the node wins the key, because the span's own view of
118
+ * which node it ran on is the one thing about it the master can check.
119
+ */
120
+ function traceRow(nodeId, entry) {
121
+ return {
122
+ traceId: entry.payload['traceId'] ?? 'unknown',
123
+ spanId: entry.payload['spanId'] ?? 'unknown',
124
+ parentSpanId: entry.payload['parentSpanId'] ?? null,
125
+ operationName: entry.payload['operationName'] ?? 'unknown',
126
+ serviceName: entry.payload['serviceName'] ?? 'unknown',
127
+ startTime: entry.payload['startTime'] ?? entry.createdAt,
128
+ endTime: entry.payload['endTime'] ?? entry.createdAt,
129
+ duration: Number(entry.payload['duration'] ?? 0),
130
+ status: entry.payload['status'] ?? 'ok',
131
+ tags: JSON.stringify({ ...entry.payload['tags'], node: nodeId }),
132
+ logs: entry.payload['logs'] ? JSON.stringify(entry.payload['logs']) : null,
133
+ };
134
+ }
24
135
  export class SyncService {
25
136
  db;
26
137
  logger;
27
138
  nodeId;
28
139
  role;
140
+ /** Set on a master; see `setMetricsSink`. */
141
+ metricsSink = null;
29
142
  config;
30
143
  syncTimer = null;
144
+ /** The master's ledger pruning, re-armed after each pass. See `pruneLedger`. */
145
+ ledgerTimer = null;
146
+ /** Whether this database keeps the buffer's figures; null until asked. See `keptBufferStats`. */
147
+ bufferStatsKept = null;
31
148
  isSyncing = false;
32
149
  backoff = { attempt: 0, nextRetryAt: 0 };
33
150
  lastSyncAt = null;
@@ -60,22 +177,31 @@ export class SyncService {
60
177
  // ===========================================================================
61
178
  /**
62
179
  * Start the sync loop.
63
- * Only runs on slave daemons — master is a no-op.
180
+ *
181
+ * On a slave, the buffer's pass: bound it, then try to drain it. On a
182
+ * master, the ledger's: `sync_ingested` pruned to its dedup window. The
183
+ * master used to return here, and its half of the pipeline was never
184
+ * maintained at all.
64
185
  */
65
186
  start() {
66
- if (this.role !== 'slave') {
67
- this.logger.debug({ role: this.role }, 'Sync not needed for this daemon role');
187
+ if (this.role === 'master') {
188
+ this.scheduleLedgerPrune(LEDGER_FIRST_PASS_DELAY_MS);
68
189
  return;
69
190
  }
70
191
  this.logger.info({ interval: this.config.interval, batchSize: this.config.batchSize, categories: this.config.categories }, 'Starting sync service');
71
192
  this.syncTimer = setInterval(() => {
72
- this.syncCycle().catch((err) => {
193
+ this.syncTick().catch((err) => {
73
194
  this.logger.error({ error: err.message }, 'Sync cycle failed');
74
195
  });
75
196
  }, this.config.interval);
76
197
  this.syncTimer.unref();
77
- // Initial sync attempt
78
- this.syncCycle().catch(() => { });
198
+ // Initial sync attempt — reported like every other one. The recurring
199
+ // call four lines above logs its failure; this one swallowed it, and it
200
+ // is the more informative of the two: it is the first evidence that a
201
+ // slave can reach its master at all.
202
+ this.syncTick().catch((err) => {
203
+ this.logger.error({ error: err.message }, 'Initial sync cycle failed');
204
+ });
79
205
  }
80
206
  /**
81
207
  * Stop the sync loop and flush remaining buffer.
@@ -86,6 +212,10 @@ export class SyncService {
86
212
  clearInterval(this.syncTimer);
87
213
  this.syncTimer = null;
88
214
  }
215
+ if (this.ledgerTimer) {
216
+ clearTimeout(this.ledgerTimer);
217
+ this.ledgerTimer = null;
218
+ }
89
219
  // Final sync attempt before shutdown
90
220
  if (this.role === 'slave' && this.masterInvoke) {
91
221
  try {
@@ -132,9 +262,26 @@ export class SyncService {
132
262
  }).execute();
133
263
  }
134
264
  catch (err) {
135
- this.logger.warn({ category: entry.category, error: err.message }, 'Failed to buffer sync entry');
265
+ this.logger.error({ nodeId: this.nodeId, category: entry.category, error: err.message }, 'Failed to buffer sync entry — it will not reach the master');
136
266
  }
137
267
  }
268
+ /**
269
+ * Where ingested remote metrics are recorded, on a master.
270
+ *
271
+ * Set by the daemon to `MetricsService.recordTyped` — the store the
272
+ * console's charts read, with the node as a label. It is the only place a
273
+ * remote metric goes: the `metrics_raw` table it was also written to had
274
+ * no reader and no pruning (migration 010). Without a sink, remote metrics
275
+ * are claimed and go nowhere.
276
+ *
277
+ * A sink rather than a constructor dependency: this service is built by
278
+ * hand in `daemon.ts` with five positional arguments, and a sixth is a
279
+ * change every caller has to get right at runtime rather than at compile
280
+ * time.
281
+ */
282
+ setMetricsSink(sink) {
283
+ this.metricsSink = sink;
284
+ }
138
285
  /**
139
286
  * Buffer multiple entries at once (batch optimization).
140
287
  */
@@ -151,28 +298,79 @@ export class SyncService {
151
298
  }))).execute();
152
299
  }
153
300
  catch (err) {
154
- this.logger.warn({ count: entries.length, error: err.message }, 'Failed to buffer sync batch');
301
+ // ERROR, with the node and the size. A buffer that refuses is data
302
+ // this node will never replicate, and on the master it looks exactly
303
+ // like a node that had nothing to say — someone reads an empty screen
304
+ // and draws a conclusion about the system rather than about the pipe.
305
+ this.logger.error({ nodeId: this.nodeId, count: filteredEntries.length, category: filteredEntries[0]?.category, error: err.message }, 'Failed to buffer sync batch — these entries will not reach the master');
155
306
  }
156
307
  }
157
308
  // ===========================================================================
158
309
  // Pull API (master pulls buffered data from slave)
159
310
  // ===========================================================================
160
311
  /**
161
- * Drain pending buffer entries — called by master via RPC.
162
- * Returns a batch of unsynced entries and marks them as synced.
163
- * Idempotent: entries are only drained once.
312
+ * Hand pending entries to the master — called by the master via RPC.
313
+ *
314
+ * This used to mark the entries synced before returning them, and called
315
+ * that idempotent. It is the opposite: a response lost in transit, a
316
+ * checksum mismatch or a rate-limit rejection left the data marked
317
+ * delivered on the slave and absent on the master, to be evicted twenty-
318
+ * four hours later. The caller logged the failure at debug level.
319
+ *
320
+ * Entries are released only by `ackDrained`, after the master has them.
321
+ * Re-draining before that returns the same entries, which is correct and
322
+ * is what the deduplication ledger on the master side is for.
164
323
  */
165
324
  async drainBuffer(limit) {
166
- const batch = await this.fetchPendingBatch(limit);
167
- if (batch.entries.length > 0) {
168
- await this.markSynced(batch.entries.map((e) => e.id));
169
- this.lastSyncAt = Date.now();
170
- }
171
- return batch;
325
+ return this.fetchPendingBatch(limit);
326
+ }
327
+ /**
328
+ * Release entries the master has confirmed it holds.
329
+ *
330
+ * Called after `receiveBatch` succeeds. Split from `drainBuffer` so that
331
+ * everything between the two — the network, the checksum, the ingestion —
332
+ * can fail without the slave forgetting the data.
333
+ */
334
+ async ackDrained(ids) {
335
+ if (ids.length === 0)
336
+ return { released: 0 };
337
+ await this.markSynced(ids);
338
+ this.lastSyncAt = Date.now();
339
+ return { released: ids.length };
172
340
  }
173
341
  // ===========================================================================
174
342
  // Sync Cycle (push to master — legacy, kept for backward compatibility)
175
343
  // ===========================================================================
344
+ /**
345
+ * One scheduled pass: bound the buffer, then try to drain it.
346
+ *
347
+ * The order is the whole point. `enforceBufferBounds` used to be the last
348
+ * statement of `syncCycle`'s `try`, which meant it ran on a SUCCESSFUL
349
+ * cycle and on nothing else — and a successful cycle is the one case where
350
+ * the buffer is being drained and needs no bound. Every path that leaves it
351
+ * growing skipped it:
352
+ *
353
+ * - no master configured at all → `syncCycle` returns at its second line;
354
+ * - master unreachable → the push throws and control leaves via `catch`;
355
+ * - and then the backoff, which saturates at five minutes, returns at the
356
+ * third line for most ticks after that.
357
+ *
358
+ * So the guarantee in this file's header — "bounded buffer, oldest entries
359
+ * evicted when maxBufferSize is reached" — held only while it was not
360
+ * needed. A slave that lost its master still buffered until the disk filled,
361
+ * which is the exact failure the bound was written to prevent and the
362
+ * reason it is not read as a replication bug when it happens: what fills is
363
+ * the disk, and what breaks is everything else sharing it.
364
+ *
365
+ * The bound is a local database operation. It needs no master, so it does
366
+ * not belong behind a check for one.
367
+ */
368
+ async syncTick() {
369
+ if (this.disposed)
370
+ return;
371
+ await this.enforceBufferBounds();
372
+ await this.syncCycle();
373
+ }
176
374
  async syncCycle() {
177
375
  if (this.disposed || this.isSyncing)
178
376
  return;
@@ -184,14 +382,27 @@ export class SyncService {
184
382
  this.isSyncing = true;
185
383
  try {
186
384
  let totalSynced = 0;
385
+ let totalRefused = 0;
386
+ const seenThisCycle = new Set();
187
387
  // Sync in batches until no more pending entries
188
388
  while (true) {
189
389
  const batch = await this.fetchPendingBatch();
190
390
  if (batch.entries.length === 0)
191
391
  break;
192
- await this.pushBatch(batch);
193
- await this.markSynced(batch.entries.map((e) => e.id));
194
- totalSynced += batch.entries.length;
392
+ const outcome = await this.pushBatch(batch);
393
+ const delivered = deliveredIds(outcome);
394
+ await this.markSynced(delivered);
395
+ totalSynced += delivered.length;
396
+ totalRefused += outcome.failed.length;
397
+ // Entries the master rejected stay pending, so the next fetch
398
+ // returns them again. Stop the sweep when a page yields nothing new
399
+ // — otherwise a permanently unacceptable entry loops here forever.
400
+ if (!sweepMadeProgress(seenThisCycle, batch.entries.map((e) => e.id))) {
401
+ this.logger.warn({ nodeId: this.nodeId, pending: batch.entries.length }, 'Sync sweep stalled — the master is rejecting the oldest pending entries');
402
+ break;
403
+ }
404
+ for (const e of batch.entries)
405
+ seenThisCycle.add(e.id);
195
406
  // Don't monopolize — yield after each batch
196
407
  if (totalSynced >= this.config.batchSize * 5)
197
408
  break;
@@ -199,25 +410,49 @@ export class SyncService {
199
410
  if (totalSynced > 0) {
200
411
  this.logger.info({ synced: totalSynced }, 'Sync cycle completed');
201
412
  }
413
+ // A cycle that delivered NOTHING and was refused everything is not a
414
+ // success, even though nothing threw.
415
+ //
416
+ // Only one of the two ways to fail used to reach the backoff. An
417
+ // unreachable master makes the push throw, and the `catch` below grows
418
+ // the delay to five minutes. But a master that ANSWERS and says no to
419
+ // every entry returns normally — and control arrived here, at a reset
420
+ // of a backoff that had never been set. That is how 1000 entries were
421
+ // offered 94 times in 37 minutes while the master's own Postgres was
422
+ // down behind a stopped Docker: the RPC succeeded on every attempt,
423
+ // and only the ingest failed. The configured delay (5 s, doubling, to
424
+ // 300 s) would have made that about a dozen attempts; it was never
425
+ // consulted.
426
+ if (totalSynced === 0 && totalRefused > 0) {
427
+ this.noteSyncFailure(`master refused every entry (${totalRefused})`);
428
+ return;
429
+ }
202
430
  // Reset backoff on success
203
431
  this.backoff = { attempt: 0, nextRetryAt: 0 };
204
432
  this.lastSyncAt = Date.now();
205
433
  this.lastError = null;
206
- // Evict old synced entries
207
- await this.evictSynced();
208
434
  }
209
435
  catch (err) {
210
- const message = err.message;
211
- this.lastError = message;
212
- this.backoff.attempt++;
213
- const delay = Math.min(this.config.backoff.initial * Math.pow(this.config.backoff.factor, this.backoff.attempt), this.config.backoff.max);
214
- this.backoff.nextRetryAt = Date.now() + delay;
215
- this.logger.warn({ error: message, attempt: this.backoff.attempt, nextRetryMs: delay }, 'Sync failed — will retry');
436
+ this.noteSyncFailure(describeError(err));
216
437
  }
217
438
  finally {
218
439
  this.isSyncing = false;
219
440
  }
220
441
  }
442
+ /**
443
+ * Grow the retry delay and record why.
444
+ *
445
+ * Shared by both ways a cycle can fail — a master that cannot be reached,
446
+ * and a master that answers no — because the buffer does not care which
447
+ * one it was, and neither does the disk it is filling.
448
+ */
449
+ noteSyncFailure(message) {
450
+ this.lastError = message;
451
+ this.backoff.attempt++;
452
+ const delay = Math.min(this.config.backoff.initial * Math.pow(this.config.backoff.factor, this.backoff.attempt), this.config.backoff.max);
453
+ this.backoff.nextRetryAt = Date.now() + delay;
454
+ this.logger.warn({ error: message, attempt: this.backoff.attempt, nextRetryMs: delay }, 'Sync failed — will retry');
455
+ }
221
456
  async fetchPendingBatch(limit) {
222
457
  const rows = await this.db
223
458
  .selectFrom('sync_buffer')
@@ -231,7 +466,9 @@ export class SyncService {
231
466
  id: String(r.id),
232
467
  category: r.category,
233
468
  payload: (typeof r.payload === 'string' ? JSON.parse(r.payload) : r.payload),
234
- createdAt: r.createdAt instanceof Date ? r.createdAt.toISOString() : String(r.createdAt),
469
+ // Whatever spelling the local column holds, the master receives a
470
+ // timestamp that states its zone. See `toIsoUtc`.
471
+ createdAt: toIsoUtc(r.createdAt),
235
472
  }));
236
473
  // Compute integrity checksum
237
474
  const checksum = await this.computeChecksum(entries);
@@ -243,10 +480,32 @@ export class SyncService {
243
480
  hash.update(JSON.stringify(entries));
244
481
  return hash.digest('hex');
245
482
  }
483
+ /**
484
+ * Push a batch and report what the master kept.
485
+ *
486
+ * The return value used to be discarded, and `receiveBatch` swallows
487
+ * per-entry ingestion failures into a warning — so the caller marked every
488
+ * entry delivered whether or not any of them arrived. A master response
489
+ * without the id lists is treated as "all delivered", which is what an
490
+ * older master would mean by it; that is the only reading that does not
491
+ * silently retry everything against a peer that cannot tell us otherwise.
492
+ */
246
493
  async pushBatch(batch) {
247
494
  if (!this.masterInvoke)
248
495
  throw new Error('No master connection');
249
- await this.masterInvoke('OmnitronSync', 'receiveBatch', [batch]);
496
+ const response = (await this.masterInvoke('OmnitronSync', 'receiveBatch', [batch]));
497
+ const allIds = batch.entries.map((e) => e.id);
498
+ if (!response || !Array.isArray(response.acceptedIds)) {
499
+ return { accepted: allIds, duplicates: [], failed: [], discarded: [] };
500
+ }
501
+ return {
502
+ accepted: response.acceptedIds,
503
+ duplicates: Array.isArray(response.duplicateIds) ? response.duplicateIds : [],
504
+ failed: Array.isArray(response.failedIds) ? response.failedIds : [],
505
+ // An older master answers without this field. Treating a missing list
506
+ // as an empty one is right: it discarded nothing.
507
+ discarded: Array.isArray(response.discardedIds) ? response.discardedIds : [],
508
+ };
250
509
  }
251
510
  async markSynced(ids) {
252
511
  if (ids.length === 0)
@@ -258,19 +517,193 @@ export class SyncService {
258
517
  .execute();
259
518
  }
260
519
  /**
261
- * Evict synced entries older than 24h to keep WAL bounded.
520
+ * Keep the WAL inside `maxBufferSize`.
521
+ *
522
+ * Guarantee 5 in the header of this file — "bounded buffer, oldest entries
523
+ * evicted when maxBufferSize reached" — had no implementation:
524
+ * `maxBufferSize` was read from config, defaulted to 500 MB, and never
525
+ * referenced again. The only eviction was of *synced* rows older than a
526
+ * day, so a slave that lost its master buffered until the disk filled. The
527
+ * failure lands on everything else sharing that disk, which is why it
528
+ * would never have been read as a replication bug.
529
+ *
530
+ * Two passes. The routine one removes delivered entries past their
531
+ * retention. The overflow one runs only when the table is still over
532
+ * budget and removes oldest-first regardless of delivery — at which point
533
+ * data is being dropped, so it is said at warning level with the count.
262
534
  */
263
- async evictSynced() {
535
+ async enforceBufferBounds() {
264
536
  try {
265
- const cutoff = new Date(Date.now() - 24 * 60 * 60 * 1000);
537
+ const cutoff = new Date(Date.now() - SYNCED_RETENTION_MS);
266
538
  await this.db
267
539
  .deleteFrom('sync_buffer')
268
540
  .where('syncedAt', 'is not', null)
269
541
  .where('syncedAt', '<', cutoff)
270
542
  .execute();
543
+ const stats = await this.bufferStats();
544
+ if (!stats)
545
+ return;
546
+ const plan = planEviction({
547
+ totalBytes: stats.totalBytes,
548
+ maxBytes: this.config.maxBufferSize,
549
+ totalRows: stats.totalRows,
550
+ syncedRows: stats.syncedRows,
551
+ });
552
+ if (plan.overflowRows === 0)
553
+ return;
554
+ // Delivered before undelivered, oldest first within each — so an
555
+ // overflow small enough to be absorbed by rows the master already has
556
+ // costs nothing.
557
+ const delivered = await this.dropOldest('delivered', plan.overflowRows);
558
+ const undelivered = delivered < plan.overflowRows ? await this.dropOldest('undelivered', plan.overflowRows - delivered) : 0;
559
+ const dropped = delivered + undelivered;
560
+ if (dropped === 0)
561
+ return;
562
+ // Counted, not predicted: the level follows what was actually dropped.
563
+ const level = undelivered > 0 ? 'warn' : 'info';
564
+ this.logger[level]({
565
+ dropped,
566
+ undelivered,
567
+ totalBytes: stats.totalBytes,
568
+ maxBytes: this.config.maxBufferSize,
569
+ }, undelivered > 0
570
+ ? 'Sync buffer over budget — dropped entries the master never received'
571
+ : 'Sync buffer over budget — dropped delivered entries');
271
572
  }
272
- catch {
273
- // Non-critical
573
+ catch (err) {
574
+ // Losing a retention pass is survivable; losing it in silence is how
575
+ // the unbounded growth stayed invisible in the first place.
576
+ this.logger.warn({ error: err.message }, 'Sync buffer retention pass failed');
577
+ }
578
+ }
579
+ /**
580
+ * Delete up to `limit` of the oldest rows of one kind; say how many went.
581
+ *
582
+ * By a subquery, not by a list. The ids used to be read into memory and
583
+ * deleted with `WHERE id IN (…)` — one bound parameter per row, where
584
+ * SQLite takes 32 766. So the pass worked for a small overflow and refused
585
+ * exactly the large one, which is the only kind a buffer cut off from its
586
+ * master produces. Measured on the test node, 2026-09-22: «too many SQL
587
+ * variables» on 558 passes in a row, 13:03–17:42 UTC, against 4 019 288
588
+ * rows and 555 MB of payload over a 500 MB budget. The bound bounded
589
+ * nothing, and said so every thirty seconds in a log nobody on the master
590
+ * reads.
591
+ *
592
+ * Two queries rather than one ordered `syncedAt DESC`, which put NULLs —
593
+ * the undelivered rows — last on SQLite and FIRST on Postgres, and among
594
+ * the delivered took the most recently delivered first, against the
595
+ * comment above it. Both of these are served by `idx_sync_pending
596
+ * (syncedAt, createdAt)`: delivered rows in the order they were delivered,
597
+ * which is the order the routine pass retires them in, only sooner; and
598
+ * undelivered ones in the order they were buffered.
599
+ */
600
+ async dropOldest(which, limit) {
601
+ const oldest = which === 'delivered'
602
+ ? this.db
603
+ .selectFrom('sync_buffer')
604
+ .select('id')
605
+ .where('syncedAt', 'is not', null)
606
+ .orderBy('syncedAt', 'asc')
607
+ .orderBy('createdAt', 'asc')
608
+ .limit(limit)
609
+ : this.db
610
+ .selectFrom('sync_buffer')
611
+ .select('id')
612
+ .where('syncedAt', 'is', null)
613
+ .orderBy('createdAt', 'asc')
614
+ .limit(limit);
615
+ const result = await this.db.deleteFrom('sync_buffer').where('id', 'in', oldest).executeTakeFirst();
616
+ return Number(result.numDeletedRows);
617
+ }
618
+ /**
619
+ * Size and row counts of the WAL, or null when the database cannot say.
620
+ *
621
+ * This asked `pg_total_relation_size('sync_buffer')` — a Postgres function,
622
+ * about the one table that only ever exists where the database is SQLite.
623
+ * A slave buffers and a master receives, so the measurement the bound above
624
+ * depends on threw `no such function: pg_total_relation_size` on every
625
+ * pass, on every slave. Observed on a provisioned node, every thirty
626
+ * seconds, immediately behind the `Date`-binding fix that let the pass get
627
+ * this far:
628
+ *
629
+ * 05:58:48 Sync buffer retention pass failed
630
+ * error: "no such function: pg_total_relation_size"
631
+ *
632
+ * Three defects stacked on one guarantee: the bound ran only on the cycle
633
+ * that did not need it, then could not bind its own cutoff, and then could
634
+ * not measure. Each fix revealed the next, and only the last one makes
635
+ * "bounded buffer" true. The routine delete of synced rows sits before this
636
+ * call and was unaffected throughout.
637
+ *
638
+ * The replacement measures the same quantity in the same terms on both
639
+ * dialects: the bytes of the buffered payloads. That is deliberately not
640
+ * the relation's on-disk footprint — it excludes indexes, row headers and
641
+ * Postgres's TOAST compression — because one definition of `maxBufferSize`
642
+ * that means the same thing on a master and on a slave is worth more than
643
+ * two that each drift by whatever their storage engine adds. The payload is
644
+ * the term that grows.
645
+ *
646
+ * `cast(payload as text)` is required by both: the column is `jsonb` on
647
+ * Postgres, where `length()` has no jsonb form, and TEXT on SQLite, where
648
+ * the cast costs nothing. `octet_length` rather than `length` because the
649
+ * second counts CHARACTERS — a buffer of Cyrillic log lines measures at
650
+ * half its size, and a budget is about bytes. Verified against both engines
651
+ * (postgres:17-alpine, better-sqlite3 13.0.3 / SQLite 3.53.4).
652
+ */
653
+ async bufferStats() {
654
+ const kept = await this.keptBufferStats();
655
+ if (kept)
656
+ return kept;
657
+ const { sql } = await import('kysely');
658
+ const row = await sql `
659
+ SELECT coalesce(sum(octet_length(cast(payload as text))), 0) AS total_bytes,
660
+ count(*) AS total_rows,
661
+ count(*) FILTER (WHERE "syncedAt" IS NOT NULL) AS synced_rows
662
+ FROM sync_buffer
663
+ `.execute(this.db);
664
+ const first = row.rows[0];
665
+ if (!first)
666
+ return null;
667
+ return {
668
+ totalBytes: Number(first.total_bytes),
669
+ totalRows: Number(first.total_rows),
670
+ syncedRows: Number(first.synced_rows),
671
+ };
672
+ }
673
+ /**
674
+ * The buffer's figures as its triggers keep them, or null when this
675
+ * database keeps none (see `SlaveStorageService.createBufferStats`).
676
+ *
677
+ * One row instead of a pass over the table: 395–399 ms on the test node's
678
+ * 4 million rows, every thirty seconds, on the daemon's event loop. Null
679
+ * sends `bufferStats` back to that pass, and is remembered, so a database
680
+ * without the row — one this service did not create — costs one refused
681
+ * query per process rather than one per pass.
682
+ */
683
+ async keptBufferStats() {
684
+ if (this.bufferStatsKept === false)
685
+ return null;
686
+ try {
687
+ const { sql } = await import('kysely');
688
+ const row = await sql `
689
+ SELECT totalBytes, totalRows, syncedRows FROM sync_buffer_stats WHERE id = 1
690
+ `.execute(this.db);
691
+ const first = row.rows[0];
692
+ this.bufferStatsKept = Boolean(first);
693
+ if (!first)
694
+ return null;
695
+ return {
696
+ totalBytes: Number(first.totalBytes),
697
+ totalRows: Number(first.totalRows),
698
+ syncedRows: Number(first.syncedRows),
699
+ };
700
+ }
701
+ catch (err) {
702
+ // Remembered only when the table is not there. Any other refusal is
703
+ // this pass's, and the next one asks again.
704
+ if (/no such table|does not exist/i.test(describeError(err)))
705
+ this.bufferStatsKept = false;
706
+ return null;
274
707
  }
275
708
  }
276
709
  // ===========================================================================
@@ -285,6 +718,16 @@ export class SyncService {
285
718
  if (this.role !== 'master') {
286
719
  throw new Error('Only master daemon can receive sync batches');
287
720
  }
721
+ // A batch has to say which node it came from, and this is the only place
722
+ // that can insist. Everything downstream labels the data with `nodeId`:
723
+ // logs are stored under it, and metrics are recorded with it as a label
724
+ // that separates this node's readings from the master's own. An empty or
725
+ // missing value does not fail there — it quietly merges two machines into
726
+ // one, and a chart then shows the sum of both under a single name.
727
+ // Refused by name rather than defaulted.
728
+ if (typeof batch.nodeId !== 'string' || batch.nodeId.trim() === '') {
729
+ throw new Error('Sync batch rejected: `nodeId` is required and must be a non-empty string.');
730
+ }
288
731
  // Rate limiting — prevent flood from misbehaving slaves
289
732
  if (!this.checkRateLimit(batch.nodeId)) {
290
733
  throw new Error(`Rate limit exceeded for node ${batch.nodeId}. Max ${RATE_LIMIT_PER_MINUTE} batches/min.`);
@@ -294,92 +737,397 @@ export class SyncService {
294
737
  if (!batch.checksum || batch.checksum !== expectedChecksum) {
295
738
  throw new Error(`Checksum mismatch for batch ${batch.batchId}. Expected ${expectedChecksum}, got ${batch.checksum}. Batch rejected.`);
296
739
  }
297
- let accepted = 0;
298
- for (const entry of batch.entries) {
740
+ const { outcome, causes } = await this.ingest(batch.nodeId, batch.entries);
741
+ if (outcome.failed.length > 0) {
742
+ this.logger.warn({
743
+ nodeId: batch.nodeId,
744
+ batchId: batch.batchId,
745
+ failed: outcome.failed.length,
746
+ total: batch.entries.length,
747
+ causes: [...causes.entries()].map(([cause, count]) => `${cause} ×${count}`),
748
+ }, 'Sync batch partially ingested');
749
+ }
750
+ else {
751
+ this.logger.debug({
752
+ nodeId: batch.nodeId,
753
+ batchId: batch.batchId,
754
+ accepted: outcome.accepted.length,
755
+ duplicates: outcome.duplicates.length,
756
+ total: batch.entries.length,
757
+ }, 'Sync batch received');
758
+ }
759
+ return {
760
+ // Kept as a number for the existing RPC contract; the id lists are
761
+ // what the slave needs to know which entries it may release.
762
+ accepted: outcome.accepted.length,
763
+ duplicates: outcome.duplicates.length,
764
+ acceptedIds: outcome.accepted,
765
+ duplicateIds: outcome.duplicates,
766
+ failedIds: outcome.failed,
767
+ // Released, not stored. The slave must let these go or it offers them
768
+ // forever; the ERROR beside each one is the only record that they
769
+ // existed.
770
+ discardedIds: outcome.discarded,
771
+ };
772
+ }
773
+ /**
774
+ * Take a batch: as one transaction, or — when the database refuses it as
775
+ * a whole — one entry at a time, which is what finds the entry it refused.
776
+ *
777
+ * Every batch used to take the second road. Each entry was claimed and
778
+ * ingested in a transaction of its own, so that one entry the database
779
+ * refuses costs that entry and not its thousand neighbours — and so every
780
+ * batch cost a thousand `BEGIN … COMMIT`s, on a master whose omnitron-pg
781
+ * runs `synchronous_commit = on`: a WAL flush per entry, a thousand per
782
+ * pull. While the machine was idle that was 800–1 100 entries a second
783
+ * against 38 produced on the test node. Under load a pull outlasted the
784
+ * 15 s heartbeat, and the next heartbeat started another over the same
785
+ * entries (see `pullSyncData`). Measured 2026-09-22: nine pulls of the
786
+ * same 7 918 entries finishing within 122 ms of each other.
787
+ *
788
+ * The isolation is kept, and paid for only where it buys something: a
789
+ * batch the database refuses — a malformed uuid, a foreign key the master
790
+ * does not have — is retried entry by entry, and that path classifies
791
+ * each refusal exactly as it always has. The fast path is never worse
792
+ * than the old one; it falls back to it.
793
+ */
794
+ async ingest(nodeId, entries) {
795
+ try {
796
+ return { outcome: await this.ingestAsOne(nodeId, entries), causes: new Map() };
797
+ }
798
+ catch (err) {
799
+ // Debug: the path below says, per entry and at the right level, what
800
+ // was refused and why. That the batch had to take it is not news.
801
+ this.logger.debug({ nodeId, entries: entries.length, error: describeError(err) }, 'Sync batch refused as a whole — ingesting it entry by entry');
802
+ return this.ingestEntryByEntry(nodeId, entries);
803
+ }
804
+ }
805
+ /**
806
+ * The whole batch in one transaction: the claims in one statement, each
807
+ * destination table's rows in one more.
808
+ *
809
+ * An id that appears twice in a batch is taken once and its second
810
+ * occurrence reported a duplicate — what the per-entry path does, because
811
+ * there the first occurrence's claim is committed before the second's is
812
+ * tried.
813
+ */
814
+ async ingestAsOne(nodeId, entries) {
815
+ const outcome = { accepted: [], duplicates: [], failed: [], discarded: [] };
816
+ const taken = [];
817
+ await this.db.transaction().execute(async (trx) => {
818
+ const claimed = await this.claimAll(trx, nodeId, entries.map((e) => e.id));
819
+ for (const entry of entries) {
820
+ if (claimed.delete(entry.id)) {
821
+ outcome.accepted.push(entry.id);
822
+ taken.push(entry);
823
+ }
824
+ else {
825
+ outcome.duplicates.push(entry.id);
826
+ }
827
+ }
828
+ await this.writeRows(trx, nodeId, taken);
829
+ });
830
+ this.recordMetrics(nodeId, taken);
831
+ return outcome;
832
+ }
833
+ /**
834
+ * One transaction per entry: the road for a batch the database refused.
835
+ *
836
+ * Slow on purpose. Each entry succeeds or fails on its own, so the one the
837
+ * database will never store is named, discarded and released, and a
838
+ * failure that may pass is left for the next pull — while everything else
839
+ * in the batch is taken.
840
+ */
841
+ async ingestEntryByEntry(nodeId, entries) {
842
+ const outcome = { accepted: [], duplicates: [], failed: [], discarded: [] };
843
+ // Why entries were refused, and how many times each reason came up. A
844
+ // thousand entries failing on one dead database is ONE event; naming the
845
+ // reason per entry buried the cause under its own repetitions.
846
+ const causes = new Map();
847
+ for (const entry of entries) {
299
848
  try {
300
- switch (entry.category) {
301
- case 'metrics':
302
- await this.ingestMetric(batch.nodeId, entry);
303
- break;
304
- case 'logs':
305
- await this.ingestLog(batch.nodeId, entry);
306
- break;
307
- case 'alerts':
308
- await this.ingestAlert(batch.nodeId, entry);
309
- break;
310
- case 'traces':
311
- await this.ingestTrace(batch.nodeId, entry);
312
- break;
313
- case 'events':
314
- case 'state':
315
- // Events and state changes stored as logs with category label
316
- await this.ingestLog(batch.nodeId, { ...entry, payload: { ...entry.payload, _category: entry.category } });
317
- break;
318
- default:
319
- this.logger.debug({ category: entry.category }, 'Unknown sync category — skipping');
320
- break;
849
+ // Claim the entry, then ingest it, in one transaction. A failure
850
+ // rolls the claim back, so the entry is retried rather than recorded
851
+ // as taken; a conflicting claim means this batch repeats one already
852
+ // applied, which is what "idempotent" was always supposed to mean.
853
+ const result = await this.claimAndIngest(nodeId, entry);
854
+ if (result === 'duplicate')
855
+ outcome.duplicates.push(entry.id);
856
+ else if (result === 'discarded')
857
+ outcome.discarded.push(entry.id);
858
+ else {
859
+ outcome.accepted.push(entry.id);
860
+ this.recordMetrics(nodeId, [entry]);
321
861
  }
322
- accepted++;
323
862
  }
324
863
  catch (err) {
325
- this.logger.warn({ nodeId: batch.nodeId, category: entry.category, error: err.message }, 'Failed to ingest sync entry');
864
+ // Not marked delivered. The slave keeps it and offers it again —
865
+ // previously this warning was the only trace of an entry that had
866
+ // just been dropped on both sides.
867
+ outcome.failed.push(entry.id);
868
+ // `(err as Error).message` was the empty string for the commonest
869
+ // failure of all — an unreachable database arrives as an
870
+ // `AggregateError` whose reasons live in `.errors`. 76 659 records in
871
+ // one hour carried `error: ""`, while the cause was named in three
872
+ // lines of the file next to it.
873
+ const cause = describeError(err);
874
+ causes.set(cause, (causes.get(cause) ?? 0) + 1);
875
+ this.logger.debug({ nodeId, entryId: entry.id, category: entry.category, error: cause }, 'Failed to ingest sync entry — left unacknowledged for retry');
876
+ }
877
+ }
878
+ return { outcome, causes };
879
+ }
880
+ /**
881
+ * Claim entries for this node; the ids that come back are the new ones.
882
+ *
883
+ * Sorted, so that two transactions claiming overlapping batches take the
884
+ * ledger's rows in the same order and cannot deadlock on each other.
885
+ */
886
+ async claimAll(db, nodeId, ids) {
887
+ const rows = [...new Set(ids)].sort().map((entryId) => ({ nodeId, entryId }));
888
+ const claimed = new Set();
889
+ for (const part of statementsOf(rows)) {
890
+ const taken = await db
891
+ .insertInto('sync_ingested')
892
+ .values(part)
893
+ .onConflict((oc) => oc.columns(['nodeId', 'entryId']).doNothing())
894
+ .returning('entryId')
895
+ .execute();
896
+ for (const row of taken)
897
+ claimed.add(String(row.entryId));
898
+ }
899
+ return claimed;
900
+ }
901
+ /**
902
+ * Store claimed entries in the tables the console reads, one statement per
903
+ * table (per `MAX_BOUND_PARAMETERS` rows). Both roads write through here,
904
+ * so an entry lands as the same row whichever one took it.
905
+ */
906
+ async writeRows(db, nodeId, entries) {
907
+ const logs = [];
908
+ const alerts = [];
909
+ const traces = [];
910
+ const unknown = [];
911
+ for (const entry of entries) {
912
+ switch (entry.category) {
913
+ case 'metrics':
914
+ // No row: a metric's only store is the sink, after the claim
915
+ // commits (`recordMetrics`). Its claim is what stops a retry from
916
+ // recording it twice.
917
+ break;
918
+ case 'logs':
919
+ logs.push(logRow(nodeId, entry));
920
+ break;
921
+ case 'alerts':
922
+ alerts.push(alertRow(nodeId, entry));
923
+ break;
924
+ case 'traces':
925
+ traces.push(traceRow(nodeId, entry));
926
+ break;
927
+ case 'events':
928
+ case 'state':
929
+ // Stored as logs. The category itself is not kept: `logs` has no
930
+ // column for it, and the `_category` this path once added to the
931
+ // payload reached none.
932
+ logs.push(logRow(nodeId, entry));
933
+ break;
934
+ default:
935
+ unknown.push(entry);
936
+ break;
326
937
  }
327
938
  }
328
- this.logger.debug({ nodeId: batch.nodeId, batchId: batch.batchId, accepted, total: batch.entries.length }, 'Sync batch received');
329
- return { accepted };
939
+ for (const part of statementsOf(logs))
940
+ await db.insertInto('logs').values(part).execute();
941
+ for (const part of statementsOf(alerts))
942
+ await db.insertInto('alert_events').values(part).execute();
943
+ for (const part of statementsOf(traces))
944
+ await db.insertInto('traces').values(part).execute();
945
+ if (unknown.length > 0) {
946
+ // An unknown category is not a failure to retry — retrying cannot make
947
+ // it known. It is claimed and dropped, so the slave releases it, and
948
+ // said at warning level rather than debug: a category the master does
949
+ // not understand means the two are out of step.
950
+ this.logger.warn({
951
+ nodeId,
952
+ entries: unknown.length,
953
+ categories: [...new Set(unknown.map((e) => e.category))],
954
+ firstEntryId: unknown[0].id,
955
+ }, 'Unknown sync category — entries discarded');
956
+ }
957
+ }
958
+ /**
959
+ * Hand claimed remote metrics to the store the console reads.
960
+ *
961
+ * The sink records each sample into titan-metrics, which is what the
962
+ * console's `getSnapshot` and `querySeries` read, tagged with `node` so a
963
+ * remote reading is a label dimension rather than a second table. The
964
+ * `metrics_raw` table these were also written to was kept «until the
965
+ * console is observed showing the label»; it was observed (2026-09-23: 19
966
+ * series labelled with the test node), and the table — written ~0.93
967
+ * million rows a day, read and pruned by nothing — is gone (migration 010).
968
+ * History now lives in titan-metrics' store (in memory, 7 days, lost with a
969
+ * master restart); how long it should be kept is that store's question.
970
+ *
971
+ * AFTER the commit. The sink is not part of the transaction, and it used to
972
+ * be called inside it, before the row was written: an entry whose write
973
+ * then failed was recorded anyway, and recorded again by the retry that
974
+ * stored it. With a batch rolled back and retried entry by entry, that
975
+ * would have been every metric in it.
976
+ */
977
+ recordMetrics(nodeId, entries) {
978
+ if (!this.metricsSink)
979
+ return;
980
+ try {
981
+ for (const entry of entries) {
982
+ if (entry.category !== 'metrics')
983
+ continue;
984
+ this.metricsSink({
985
+ node: nodeId,
986
+ name: String(entry.payload['name'] ?? 'unknown'),
987
+ app: String(entry.payload['app'] ?? 'unknown'),
988
+ labels: (entry.payload['labels'] ?? {}),
989
+ value: Number(entry.payload['value'] ?? 0),
990
+ });
991
+ }
992
+ }
993
+ catch (err) {
994
+ // The entries are stored and will be acknowledged; a sink that throws
995
+ // must not turn that into a retry the ledger then calls a duplicate.
996
+ this.logger.warn({ nodeId, error: describeError(err) }, 'Stored remote metrics could not be recorded for the console');
997
+ }
998
+ }
999
+ /**
1000
+ * Record the entry as taken and ingest it, atomically.
1001
+ *
1002
+ * Returns `'duplicate'` when the master already holds it — a retry after a
1003
+ * lost acknowledgement, which is delivery, not failure. Throws when
1004
+ * ingestion fails, leaving nothing recorded.
1005
+ */
1006
+ async claimAndIngest(nodeId, entry) {
1007
+ try {
1008
+ return await this.claimAndIngestOnce(nodeId, entry);
1009
+ }
1010
+ catch (err) {
1011
+ if (classifyIngestFailure(err) !== 'permanent')
1012
+ throw err;
1013
+ // The database says this entry can never be stored. Leaving it
1014
+ // unacknowledged would offer it again on every sweep, forever, with
1015
+ // everything behind it in the buffer waiting — and the only symptom is
1016
+ // one "Sync pull stalled" line per pull.
1017
+ //
1018
+ // The claim is made in its own transaction because the one above rolled
1019
+ // back with the failure, taking the claim with it. Claiming it here is
1020
+ // what stops it coming back.
1021
+ await this.db
1022
+ .insertInto('sync_ingested')
1023
+ .values({ nodeId, entryId: entry.id })
1024
+ .onConflict((oc) => oc.columns(['nodeId', 'entryId']).doNothing())
1025
+ .execute()
1026
+ .catch(() => undefined);
1027
+ // ERROR, with everything needed to find the entry: this is data that
1028
+ // will never arrive, and the node has been told to forget it.
1029
+ this.logger.error({ nodeId, entryId: entry.id, category: entry.category, error: err.message }, 'Sync entry rejected permanently — discarded so the buffer can drain');
1030
+ return 'discarded';
1031
+ }
1032
+ }
1033
+ async claimAndIngestOnce(nodeId, entry) {
1034
+ return this.db.transaction().execute(async (trx) => {
1035
+ const claim = await trx
1036
+ .insertInto('sync_ingested')
1037
+ .values({ nodeId, entryId: entry.id })
1038
+ .onConflict((oc) => oc.columns(['nodeId', 'entryId']).doNothing())
1039
+ .returning('entryId')
1040
+ .executeTakeFirst();
1041
+ if (!claim)
1042
+ return 'duplicate';
1043
+ await this.writeRows(trx, nodeId, [entry]);
1044
+ return 'accepted';
1045
+ });
330
1046
  }
331
1047
  // ===========================================================================
332
- // Master-Side: Data Ingestion
1048
+ // Master-Side: the ledger's window
333
1049
  // ===========================================================================
334
- async ingestMetric(nodeId, entry) {
335
- await this.db.insertInto('metrics_raw').values({
336
- timestamp: entry.createdAt,
337
- nodeId,
338
- app: entry.payload['app'] ?? 'unknown',
339
- name: entry.payload['name'] ?? 'unknown',
340
- value: Number(entry.payload['value'] ?? 0),
341
- labels: JSON.stringify(entry.payload['labels'] ?? {}),
342
- }).execute();
343
- }
344
- async ingestLog(nodeId, entry) {
345
- await this.db.insertInto('logs').values({
346
- timestamp: entry.payload['timestamp'] ?? entry.createdAt,
347
- nodeId,
348
- app: entry.payload['app'] ?? 'unknown',
349
- level: entry.payload['level'] ?? 'info',
350
- message: entry.payload['message'] ?? '',
351
- labels: JSON.stringify(entry.payload['labels'] ?? {}),
352
- traceId: entry.payload['traceId'] ?? null,
353
- spanId: entry.payload['spanId'] ?? null,
354
- metadata: entry.payload['metadata'] ? JSON.stringify(entry.payload['metadata']) : null,
355
- }).execute();
356
- }
357
- async ingestAlert(_nodeId, entry) {
358
- await this.db.insertInto('alert_events').values({
359
- ruleId: entry.payload['ruleId'] ?? 'unknown',
360
- status: entry.payload['status'] ?? 'firing',
361
- value: entry.payload['value'] != null ? String(entry.payload['value']) : null,
362
- annotations: entry.payload['annotations'] ? JSON.stringify(entry.payload['annotations']) : null,
363
- firedAt: entry.payload['firedAt'] ?? entry.createdAt,
364
- resolvedAt: entry.payload['resolvedAt'] ?? null,
365
- acknowledgedAt: null,
366
- acknowledgedBy: null,
367
- }).execute();
368
- }
369
- async ingestTrace(_nodeId, entry) {
370
- await this.db.insertInto('traces').values({
371
- traceId: entry.payload['traceId'] ?? 'unknown',
372
- spanId: entry.payload['spanId'] ?? 'unknown',
373
- parentSpanId: entry.payload['parentSpanId'] ?? null,
374
- operationName: entry.payload['operationName'] ?? 'unknown',
375
- serviceName: entry.payload['serviceName'] ?? 'unknown',
376
- startTime: entry.payload['startTime'] ?? entry.createdAt,
377
- endTime: entry.payload['endTime'] ?? entry.createdAt,
378
- duration: Number(entry.payload['duration'] ?? 0),
379
- status: entry.payload['status'] ?? 'ok',
380
- tags: JSON.stringify(entry.payload['tags'] ?? { nodeId: _nodeId }),
381
- logs: entry.payload['logs'] ? JSON.stringify(entry.payload['logs']) : null,
382
- }).execute();
1050
+ /**
1051
+ * Arm the next ledger pass: in an hour, or in a minute when the last one
1052
+ * hit its ceiling and more is waiting. Chained rather than an interval, so
1053
+ * the cadence is decided with the last pass's result in hand.
1054
+ */
1055
+ scheduleLedgerPrune(delayMs) {
1056
+ if (this.ledgerTimer)
1057
+ clearTimeout(this.ledgerTimer);
1058
+ if (this.disposed)
1059
+ return;
1060
+ this.ledgerTimer = setTimeout(() => {
1061
+ void this.pruneLedger().then((removed) => {
1062
+ if (this.disposed)
1063
+ return;
1064
+ const plan = planRetention(LEDGER_WINDOW_DAYS);
1065
+ this.scheduleLedgerPrune(plan && removed >= plan.maxThisPass ? LEDGER_BACKLOG_INTERVAL_MS : LEDGER_INTERVAL_MS);
1066
+ });
1067
+ }, delayMs);
1068
+ this.ledgerTimer.unref();
1069
+ }
1070
+ /**
1071
+ * Forget claims older than the dedup window (`LEDGER_WINDOW_DAYS`), in
1072
+ * bounded batches, and say how many went.
1073
+ *
1074
+ * `sync_ingested` was written on every entry and pruned by nothing: 9.9
1075
+ * million rows, 2.2 GB, and ~3.3 million more a day per node, beside an
1076
+ * index on `ingestedAt` whose migration says it is there «for pruning». A
1077
+ * claim is needed only while its node may offer the entry again — see the
1078
+ * window's own comment for why a day covers that.
1079
+ *
1080
+ * By a subquery on the key, like the buffer's eviction, so no statement
1081
+ * binds a parameter per row; `batchSize` rows at a time, so no statement
1082
+ * holds the ingest path's inserts behind it for long.
1083
+ *
1084
+ * Said at info whenever it removed something, with the oldest claim left:
1085
+ * a month from now, «the ledger is stable» must be tellable from «the
1086
+ * pruner never ran» by reading the log rather than the code.
1087
+ */
1088
+ async pruneLedger(plan = planRetention(LEDGER_WINDOW_DAYS)) {
1089
+ if (!plan || this.disposed)
1090
+ return 0;
1091
+ let removed = 0;
1092
+ try {
1093
+ for (let i = 0; i < batchesPerPass(plan); i++) {
1094
+ if (this.disposed)
1095
+ break;
1096
+ const oldest = this.db
1097
+ .selectFrom('sync_ingested')
1098
+ .select(['nodeId', 'entryId'])
1099
+ .where('ingestedAt', '<', plan.cutoff)
1100
+ .limit(plan.batchSize);
1101
+ const result = await this.db
1102
+ .deleteFrom('sync_ingested')
1103
+ .where(({ eb, refTuple }) => eb(refTuple('nodeId', 'entryId'), 'in', oldest.$asTuple('nodeId', 'entryId')))
1104
+ .executeTakeFirst();
1105
+ const n = Number(result.numDeletedRows);
1106
+ removed += n;
1107
+ if (n < plan.batchSize)
1108
+ break;
1109
+ }
1110
+ if (removed > 0) {
1111
+ const left = await this.db
1112
+ .selectFrom('sync_ingested')
1113
+ .select((eb) => eb.fn.min('ingestedAt').as('oldest'))
1114
+ .executeTakeFirst();
1115
+ this.logger.info({
1116
+ removed,
1117
+ cutoff: plan.cutoff.toISOString(),
1118
+ oldestKept: left?.oldest ? toIsoUtc(left.oldest) : null,
1119
+ windowDays: LEDGER_WINDOW_DAYS,
1120
+ }, 'Pruned sync ledger claims past the dedup window');
1121
+ }
1122
+ else {
1123
+ this.logger.debug({ cutoff: plan.cutoff.toISOString() }, 'Sync ledger holds nothing past the dedup window');
1124
+ }
1125
+ }
1126
+ catch (err) {
1127
+ // A pruner that keeps failing is the ledger growing again, quietly.
1128
+ this.logger.error({ error: describeError(err), removed }, 'Sync ledger prune failed');
1129
+ }
1130
+ return removed;
383
1131
  }
384
1132
  // ===========================================================================
385
1133
  // Rate Limiting (master-side)