@kici-dev/orchestrator 0.0.0 → 0.1.1

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 (342) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +1 -6
  3. package/dist/__test-helpers__/mock-db.d.ts +103 -0
  4. package/dist/__test-helpers__/mock-ws.d.ts +13 -0
  5. package/dist/agent/dispatcher.d.ts +231 -0
  6. package/dist/agent/ownership-tracker.d.ts +46 -0
  7. package/dist/agent/registry.d.ts +255 -0
  8. package/dist/agent/token-store.d.ts +96 -0
  9. package/dist/app.d.ts +234 -0
  10. package/dist/audit/access-log.d.ts +92 -0
  11. package/dist/audit/sampling-rate-limiter.d.ts +41 -0
  12. package/dist/cache/build-coordinator.d.ts +42 -0
  13. package/dist/cache/dep-cache.d.ts +51 -0
  14. package/dist/cache/index.d.ts +16 -0
  15. package/dist/cache/pending-builds.d.ts +14 -0
  16. package/dist/cache/pending-dynamics.d.ts +15 -0
  17. package/dist/cache/pending-inits.d.ts +19 -0
  18. package/dist/cache/pending-tracker.d.ts +65 -0
  19. package/dist/cache/source-cache.d.ts +30 -0
  20. package/dist/cli/api-client.d.ts +411 -0
  21. package/dist/cli/commands/access-log.d.ts +30 -0
  22. package/dist/cli/commands/agent-service/index.d.ts +15 -0
  23. package/dist/cli/commands/agent-service/install.d.ts +9 -0
  24. package/dist/cli/commands/agent-service/logs.d.ts +9 -0
  25. package/dist/cli/commands/agent-service/restart.d.ts +8 -0
  26. package/dist/cli/commands/agent-service/start.d.ts +8 -0
  27. package/dist/cli/commands/agent-service/status.d.ts +10 -0
  28. package/dist/cli/commands/agent-service/stop.d.ts +8 -0
  29. package/dist/cli/commands/agent-service/uninstall.d.ts +9 -0
  30. package/dist/cli/commands/agent-service/upgrade.d.ts +11 -0
  31. package/dist/cli/commands/agent.d.ts +10 -0
  32. package/dist/cli/commands/api-key.d.ts +12 -0
  33. package/dist/cli/commands/audit.d.ts +9 -0
  34. package/dist/cli/commands/backend.d.ts +17 -0
  35. package/dist/cli/commands/cold-store-impl.d.ts +101 -0
  36. package/dist/cli/commands/cold-store.d.ts +30 -0
  37. package/dist/cli/commands/config.d.ts +16 -0
  38. package/dist/cli/commands/db.d.ts +19 -0
  39. package/dist/cli/commands/debug-bundle.d.ts +16 -0
  40. package/dist/cli/commands/diagnose.d.ts +15 -0
  41. package/dist/cli/commands/environment.d.ts +24 -0
  42. package/dist/cli/commands/event-dlq.d.ts +19 -0
  43. package/dist/cli/commands/event-log.d.ts +27 -0
  44. package/dist/cli/commands/event.d.ts +4 -0
  45. package/dist/cli/commands/execution.d.ts +17 -0
  46. package/dist/cli/commands/inspect-bundle.d.ts +16 -0
  47. package/dist/cli/commands/maintenance.d.ts +4 -0
  48. package/dist/cli/commands/orchestrator-service/index.d.ts +12 -0
  49. package/dist/cli/commands/orchestrator-service/install.d.ts +10 -0
  50. package/dist/cli/commands/orchestrator-service/logs.d.ts +10 -0
  51. package/dist/cli/commands/orchestrator-service/restart.d.ts +8 -0
  52. package/dist/cli/commands/orchestrator-service/start.d.ts +8 -0
  53. package/dist/cli/commands/orchestrator-service/status.d.ts +10 -0
  54. package/dist/cli/commands/orchestrator-service/stop.d.ts +8 -0
  55. package/dist/cli/commands/orchestrator-service/uninstall.d.ts +9 -0
  56. package/dist/cli/commands/orchestrator-service/upgrade.d.ts +12 -0
  57. package/dist/cli/commands/org-settings.d.ts +17 -0
  58. package/dist/cli/commands/peer.d.ts +13 -0
  59. package/dist/cli/commands/queue.d.ts +16 -0
  60. package/dist/cli/commands/registration.d.ts +18 -0
  61. package/dist/cli/commands/rotate.d.ts +9 -0
  62. package/dist/cli/commands/runs.d.ts +34 -0
  63. package/dist/cli/commands/secret.d.ts +12 -0
  64. package/dist/cli/commands/shared/db.d.ts +16 -0
  65. package/dist/cli/commands/shared/versioned-upgrade.d.ts +38 -0
  66. package/dist/cli/commands/source.d.ts +24 -0
  67. package/dist/cli/commands/token.d.ts +10 -0
  68. package/dist/cli/commands/workflow.d.ts +31 -0
  69. package/dist/cli/join.d.ts +14 -0
  70. package/dist/cli/kici-admin.d.ts +13 -0
  71. package/dist/cli/lazy-deps/cache.d.ts +17 -0
  72. package/dist/cli/lazy-deps/downloader.d.ts +33 -0
  73. package/dist/cli/lazy-deps/registry.d.ts +43 -0
  74. package/dist/cli/service/compose.d.ts +25 -0
  75. package/dist/cli/service/index.d.ts +24 -0
  76. package/dist/cli/service/launchd.d.ts +34 -0
  77. package/dist/cli/service/platform-detect.d.ts +59 -0
  78. package/dist/cli/service/systemd.d.ts +41 -0
  79. package/dist/cli/service/types.d.ts +91 -0
  80. package/dist/cli/service/windows.d.ts +20 -0
  81. package/dist/cli/wizard/agent-wizard.d.ts +24 -0
  82. package/dist/cli/wizard/orchestrator-wizard.d.ts +38 -0
  83. package/dist/cli/wizard/prompts.d.ts +23 -0
  84. package/dist/cli.js +11435 -0
  85. package/dist/cluster/cluster-identity.d.ts +59 -0
  86. package/dist/cluster/coordinator.d.ts +204 -0
  87. package/dist/cluster/health-api.d.ts +30 -0
  88. package/dist/cluster/index.d.ts +24 -0
  89. package/dist/cluster/join-client.d.ts +75 -0
  90. package/dist/cluster/join-handler.d.ts +58 -0
  91. package/dist/cluster/join-token.d.ts +94 -0
  92. package/dist/cluster/orphan-recovery.d.ts +67 -0
  93. package/dist/cluster/peer-client.d.ts +190 -0
  94. package/dist/cluster/peer-credentials.d.ts +108 -0
  95. package/dist/cluster/peer-crypto.d.ts +57 -0
  96. package/dist/cluster/peer-handler.d.ts +97 -0
  97. package/dist/cluster/peer-registry.d.ts +186 -0
  98. package/dist/cluster/raft-state.d.ts +36 -0
  99. package/dist/cluster/raft.d.ts +140 -0
  100. package/dist/cold-store/load-access-log-range.d.ts +73 -0
  101. package/dist/cold-store/load-event-log-range.d.ts +62 -0
  102. package/dist/cold-store/load-secret-audit-log-range.d.ts +38 -0
  103. package/dist/cold-store/orchestrator-cold-store.d.ts +58 -0
  104. package/dist/cold-store/tables/access-log.d.ts +80 -0
  105. package/dist/cold-store/tables/event-log.d.ts +70 -0
  106. package/dist/cold-store/tables/execution-jobs.d.ts +63 -0
  107. package/dist/cold-store/tables/execution-runs.d.ts +81 -0
  108. package/dist/cold-store/tables/execution-steps.d.ts +65 -0
  109. package/dist/cold-store/tables/secret-audit-log.d.ts +77 -0
  110. package/dist/concurrency/dispatch-next-queued.d.ts +63 -0
  111. package/dist/concurrency/group-tracker.d.ts +51 -0
  112. package/dist/concurrency/index.d.ts +3 -0
  113. package/dist/concurrency/queue-manager.d.ts +68 -0
  114. package/dist/concurrency/waiters.d.ts +58 -0
  115. package/dist/config/encryption.d.ts +82 -0
  116. package/dist/config/env-overlay.d.ts +45 -0
  117. package/dist/config/index.d.ts +16 -0
  118. package/dist/config/loader.d.ts +26 -0
  119. package/dist/config/reload.d.ts +113 -0
  120. package/dist/config/resolver.d.ts +47 -0
  121. package/dist/config/schema.d.ts +210 -0
  122. package/dist/config/shared-store.d.ts +142 -0
  123. package/dist/config/types.d.ts +218 -0
  124. package/dist/config.d.ts +249 -0
  125. package/dist/cron/cron-scheduler.d.ts +78 -0
  126. package/dist/cron/cron-store.d.ts +38 -0
  127. package/dist/dashboard/handler.d.ts +243 -0
  128. package/dist/db/client.d.ts +13 -0
  129. package/dist/db/migration-provider.d.ts +9 -0
  130. package/dist/db/migrations/001_initial.d.ts +8 -0
  131. package/dist/db/migrations/002_config_versions_key_version.d.ts +16 -0
  132. package/dist/db/migrations/003_access_log.d.ts +26 -0
  133. package/dist/db/migrations/004_rename_bundle_to_source.d.ts +19 -0
  134. package/dist/db/migrations/005_cold_store_chunk_counter.d.ts +19 -0
  135. package/dist/db/migrations/006_runs_jobs_steps_archived_at.d.ts +38 -0
  136. package/dist/db/migrations/007_audit_logs_archived_at.d.ts +42 -0
  137. package/dist/db/migrations/008_event_log_archived_at.d.ts +40 -0
  138. package/dist/db/migrations/009_access_log_trigram.d.ts +15 -0
  139. package/dist/db/migrations/010_cold_store_chunks.d.ts +34 -0
  140. package/dist/db/migrations/011_drop_source_secrets_notify.d.ts +21 -0
  141. package/dist/db/migrations/012_peer_credentials_active_uniq.d.ts +28 -0
  142. package/dist/db/migrations/013_execution_log_bytes.d.ts +21 -0
  143. package/dist/db/migrations/014_kici_events_lease_retry.d.ts +36 -0
  144. package/dist/db/migrations/015_org_settings_customer_scoped.d.ts +30 -0
  145. package/dist/db/migrations/016_org_settings_allow_http_npm.d.ts +15 -0
  146. package/dist/db/migrations/017_org_id_widen.d.ts +4 -0
  147. package/dist/db/migrations/018_org_id_prefix_backfill.d.ts +4 -0
  148. package/dist/db/migrator.d.ts +32 -0
  149. package/dist/db/types.d.ts +1266 -0
  150. package/dist/diagnostics/bundle-reader.d.ts +48 -0
  151. package/dist/diagnostics/bundle-writer.d.ts +57 -0
  152. package/dist/diagnostics/checks/agents.d.ts +10 -0
  153. package/dist/diagnostics/checks/certs.d.ts +9 -0
  154. package/dist/diagnostics/checks/config.d.ts +10 -0
  155. package/dist/diagnostics/checks/db.d.ts +9 -0
  156. package/dist/diagnostics/checks/disk.d.ts +9 -0
  157. package/dist/diagnostics/checks/index.d.ts +17 -0
  158. package/dist/diagnostics/checks/ws.d.ts +9 -0
  159. package/dist/diagnostics/index.d.ts +13 -0
  160. package/dist/diagnostics/runner.d.ts +23 -0
  161. package/dist/diagnostics/types.d.ts +38 -0
  162. package/dist/entry-helpers.d.ts +93 -0
  163. package/dist/environments/binding-store.d.ts +27 -0
  164. package/dist/environments/environment-store.d.ts +74 -0
  165. package/dist/environments/held-runs.d.ts +64 -0
  166. package/dist/environments/index.d.ts +10 -0
  167. package/dist/environments/protection/branch-gate.d.ts +5 -0
  168. package/dist/environments/protection/concurrency-gate.d.ts +7 -0
  169. package/dist/environments/protection/pipeline.d.ts +18 -0
  170. package/dist/environments/protection/reviewer-gate.d.ts +7 -0
  171. package/dist/environments/protection/trust-gate.d.ts +7 -0
  172. package/dist/environments/protection/wait-timer-gate.d.ts +7 -0
  173. package/dist/environments/variable-store.d.ts +39 -0
  174. package/dist/events/circuit-breaker.d.ts +33 -0
  175. package/dist/events/event-emitter.d.ts +55 -0
  176. package/dist/events/event-retry-scanner.d.ts +52 -0
  177. package/dist/events/event-router.d.ts +183 -0
  178. package/dist/events/event-store.d.ts +157 -0
  179. package/dist/events/trust-store.d.ts +54 -0
  180. package/dist/events/types.d.ts +61 -0
  181. package/dist/helpers/ip-extraction.d.ts +29 -0
  182. package/dist/helpers/rate-limiter.d.ts +23 -0
  183. package/dist/index.d.ts +7 -0
  184. package/dist/index.js +772 -0
  185. package/dist/lockfile-cache.d.ts +39 -0
  186. package/dist/metrics/agent-metrics-aggregator.d.ts +116 -0
  187. package/dist/metrics/metrics-reporter.d.ts +40 -0
  188. package/dist/metrics/prometheus.d.ts +261 -0
  189. package/dist/metrics/scheduled-jobs.d.ts +20 -0
  190. package/dist/orchestrator-core.d.ts +193 -0
  191. package/dist/pipeline/dispatch-matched-workflow.d.ts +102 -0
  192. package/dist/pipeline/inline-eval.d.ts +28 -0
  193. package/dist/pipeline/install-secrets-resolver.d.ts +73 -0
  194. package/dist/pipeline/manual-schedule.d.ts +21 -0
  195. package/dist/pipeline/needs-scheduler.d.ts +85 -0
  196. package/dist/pipeline/process-webhook.d.ts +38 -0
  197. package/dist/pipeline/processor.d.ts +326 -0
  198. package/dist/pipeline/rerun.d.ts +79 -0
  199. package/dist/pipeline/test-pipeline.d.ts +110 -0
  200. package/dist/provider-registry.d.ts +122 -0
  201. package/dist/providers/generic/index.d.ts +23 -0
  202. package/dist/providers/generic/normalizer.d.ts +112 -0
  203. package/dist/providers/generic/verification.d.ts +47 -0
  204. package/dist/providers/github/auth.d.ts +60 -0
  205. package/dist/providers/github/changed-files.d.ts +51 -0
  206. package/dist/providers/github/check-status-poster.d.ts +35 -0
  207. package/dist/providers/github/contributor-resolver.d.ts +30 -0
  208. package/dist/providers/github/index.d.ts +20 -0
  209. package/dist/providers/github/lock-file.d.ts +32 -0
  210. package/dist/providers/github/normalizer.d.ts +103 -0
  211. package/dist/providers/github/repo-url.d.ts +35 -0
  212. package/dist/providers/internal/index.d.ts +32 -0
  213. package/dist/providers/internal/lock-file-fetcher.d.ts +34 -0
  214. package/dist/providers/internal/normalizer.d.ts +89 -0
  215. package/dist/providers/internal/repo-url-builder.d.ts +42 -0
  216. package/dist/providers/universal-git/changed-files.d.ts +42 -0
  217. package/dist/providers/universal-git/clone-token.d.ts +83 -0
  218. package/dist/providers/universal-git/config.d.ts +192 -0
  219. package/dist/providers/universal-git/index.d.ts +55 -0
  220. package/dist/providers/universal-git/lock-file.d.ts +71 -0
  221. package/dist/providers/universal-git/normalizer.d.ts +90 -0
  222. package/dist/providers/universal-git/repo-url.d.ts +50 -0
  223. package/dist/providers/universal-git/ssh-auth.d.ts +94 -0
  224. package/dist/queue/bootstrap.d.ts +50 -0
  225. package/dist/queue/cleanup.d.ts +41 -0
  226. package/dist/queue/depth-refresher.d.ts +65 -0
  227. package/dist/queue/job-queue.d.ts +343 -0
  228. package/dist/queue/scheduled-job.d.ts +91 -0
  229. package/dist/registration/extractor.d.ts +44 -0
  230. package/dist/registration/registration-index.d.ts +162 -0
  231. package/dist/registration/registration-store.d.ts +111 -0
  232. package/dist/reporting/check-run-summary.d.ts +102 -0
  233. package/dist/reporting/commit-status.d.ts +382 -0
  234. package/dist/reporting/execution-tracker.d.ts +538 -0
  235. package/dist/reporting/fs-log-storage.d.ts +41 -0
  236. package/dist/reporting/log-pull-handler.d.ts +35 -0
  237. package/dist/reporting/log-storage.d.ts +70 -0
  238. package/dist/reporting/log-writer.d.ts +45 -0
  239. package/dist/reporting/s3-log-storage.d.ts +42 -0
  240. package/dist/reporting/step-log-buffer.d.ts +57 -0
  241. package/dist/routes/admin-access-log.d.ts +34 -0
  242. package/dist/routes/admin-backends.d.ts +28 -0
  243. package/dist/routes/admin-config.d.ts +57 -0
  244. package/dist/routes/admin-db.d.ts +20 -0
  245. package/dist/routes/admin-environments.d.ts +42 -0
  246. package/dist/routes/admin-errors.d.ts +4 -0
  247. package/dist/routes/admin-event-dlq.d.ts +39 -0
  248. package/dist/routes/admin-event-log.d.ts +42 -0
  249. package/dist/routes/admin-events.d.ts +46 -0
  250. package/dist/routes/admin-maintenance.d.ts +22 -0
  251. package/dist/routes/admin-org-settings.d.ts +29 -0
  252. package/dist/routes/admin-queue-execution.d.ts +27 -0
  253. package/dist/routes/admin-registrations.d.ts +37 -0
  254. package/dist/routes/admin-runs.d.ts +57 -0
  255. package/dist/routes/admin-scheduled-jobs.d.ts +36 -0
  256. package/dist/routes/admin-sources.d.ts +18 -0
  257. package/dist/routes/admin.d.ts +103 -0
  258. package/dist/routes/capabilities.d.ts +24 -0
  259. package/dist/routes/diagnostics.d.ts +16 -0
  260. package/dist/routes/health.d.ts +20 -0
  261. package/dist/routes/test-trigger.d.ts +41 -0
  262. package/dist/routes/uploads.d.ts +38 -0
  263. package/dist/routes/webhooks.d.ts +36 -0
  264. package/dist/scaler/bare-metal-backend.d.ts +107 -0
  265. package/dist/scaler/config.d.ts +303 -0
  266. package/dist/scaler/container-backend.d.ts +125 -0
  267. package/dist/scaler/file-tail.d.ts +23 -0
  268. package/dist/scaler/firecracker-api.d.ts +100 -0
  269. package/dist/scaler/firecracker-backend.d.ts +263 -0
  270. package/dist/scaler/index.d.ts +24 -0
  271. package/dist/scaler/ip-allocator.d.ts +177 -0
  272. package/dist/scaler/label-matcher.d.ts +73 -0
  273. package/dist/scaler/log-forwarder.d.ts +54 -0
  274. package/dist/scaler/machine-ledger.d.ts +160 -0
  275. package/dist/scaler/manager.d.ts +338 -0
  276. package/dist/scaler/nftables.d.ts +85 -0
  277. package/dist/scaler/types.d.ts +388 -0
  278. package/dist/scaler/warm-pool.d.ts +81 -0
  279. package/dist/secrets/audit-logger.d.ts +65 -0
  280. package/dist/secrets/backend-health.d.ts +60 -0
  281. package/dist/secrets/backend-registry.d.ts +68 -0
  282. package/dist/secrets/backend-sync.d.ts +40 -0
  283. package/dist/secrets/cleanup.d.ts +40 -0
  284. package/dist/secrets/config.d.ts +51 -0
  285. package/dist/secrets/crypto.d.ts +49 -0
  286. package/dist/secrets/ephemeral-keys.d.ts +49 -0
  287. package/dist/secrets/index.d.ts +17 -0
  288. package/dist/secrets/pg-secret-store.d.ts +105 -0
  289. package/dist/secrets/rbac.d.ts +47 -0
  290. package/dist/secrets/secret-output-store.d.ts +46 -0
  291. package/dist/secrets/secret-resolver.d.ts +137 -0
  292. package/dist/secrets/source-credentials.d.ts +61 -0
  293. package/dist/secrets/token-manager.d.ts +63 -0
  294. package/dist/secrets/vault-secret-store.d.ts +85 -0
  295. package/dist/security/comment-handler.d.ts +67 -0
  296. package/dist/security/contributor-cache.d.ts +75 -0
  297. package/dist/security/global-workflow-policy.d.ts +72 -0
  298. package/dist/security/lock-source.d.ts +34 -0
  299. package/dist/security/trust-resolver.d.ts +108 -0
  300. package/dist/security/workflow-diff.d.ts +26 -0
  301. package/dist/server.d.ts +17 -0
  302. package/dist/server.js +48055 -0
  303. package/dist/sources/index.d.ts +10 -0
  304. package/dist/sources/source-manager.d.ts +63 -0
  305. package/dist/sources/source-store.d.ts +79 -0
  306. package/dist/sources/source-validator.d.ts +16 -0
  307. package/dist/stale-detector/stale-run-detector.d.ts +109 -0
  308. package/dist/standalone.d.ts +20 -0
  309. package/dist/standalone.js +41546 -0
  310. package/dist/storage/blob-routes.d.ts +20 -0
  311. package/dist/storage/filesystem.d.ts +60 -0
  312. package/dist/storage/index.d.ts +20 -0
  313. package/dist/storage/s3.d.ts +68 -0
  314. package/dist/storage/sign-url.d.ts +45 -0
  315. package/dist/storage/types.d.ts +98 -0
  316. package/dist/webhook/dedup.d.ts +44 -0
  317. package/dist/webhook/event-log.d.ts +83 -0
  318. package/dist/webhook/generic-sources.d.ts +169 -0
  319. package/dist/webhook/handler.d.ts +23 -0
  320. package/dist/webhook/relay-buffer.d.ts +96 -0
  321. package/dist/webhook/verify-inbound.d.ts +78 -0
  322. package/dist/worker/in-memory-execution-tracker.d.ts +94 -0
  323. package/dist/worker/in-memory-job-queue.d.ts +74 -0
  324. package/dist/worker/static-agent-token-store.d.ts +58 -0
  325. package/dist/worker/worker-status.d.ts +36 -0
  326. package/dist/worker-core.d.ts +74 -0
  327. package/dist/ws/agent-api-registry.d.ts +49 -0
  328. package/dist/ws/agent-handler.d.ts +176 -0
  329. package/dist/ws/agent-heartbeat.d.ts +45 -0
  330. package/dist/ws/dashboard-backends-handler.d.ts +51 -0
  331. package/dist/ws/dashboard-diagnostics-handler.d.ts +56 -0
  332. package/dist/ws/dashboard-env-handler.d.ts +107 -0
  333. package/dist/ws/dashboard-global-workflows-handler.d.ts +72 -0
  334. package/dist/ws/dashboard-registrations-handler.d.ts +84 -0
  335. package/dist/ws/event-buffer.d.ts +16 -0
  336. package/dist/ws/observer-handler.d.ts +42 -0
  337. package/dist/ws/observer-registry.d.ts +88 -0
  338. package/dist/ws/platform-client.d.ts +270 -0
  339. package/dist/ws/server-options.d.ts +15 -0
  340. package/package.json +87 -6
  341. package/sbom.spdx.json +14370 -0
  342. package/index.js +0 -3
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Cluster identity validation for split-brain prevention.
3
+ *
4
+ * In geo-distributed setups, orchestrators may use different connection strings
5
+ * for the same logical DB and S3. URL comparison would falsely flag them as
6
+ * different resources. cluster_id validates that orchestrators share the same
7
+ * logical DB, and the S3 sentinel validates they share the same logical bucket.
8
+ */
9
+ import type { Kysely } from 'kysely';
10
+ interface ClusterIdentityS3Client {
11
+ getObject(bucket: string, key: string): Promise<string | null>;
12
+ putObject(bucket: string, key: string, body: string): Promise<void>;
13
+ }
14
+ export interface ClusterIdentityDeps {
15
+ db: Kysely<any>;
16
+ s3Client?: ClusterIdentityS3Client;
17
+ storageBucket?: string;
18
+ /**
19
+ * Optional storage prefix (mirrors `KICI_STORAGE_PREFIX`). When set, the
20
+ * sentinel lives under that prefix (`<prefix>/.kici-cluster-id`) so multiple
21
+ * clusters can share the same physical bucket as long as they use distinct
22
+ * prefixes. When empty, the sentinel is at the bucket root.
23
+ */
24
+ storagePrefix?: string;
25
+ /**
26
+ * E2E escape hatch — when true, validateS3Sentinel logs a warning and
27
+ * returns early. Mirrors the orchestrator's
28
+ * `config.skipS3SentinelValidation` (KICI_SKIP_S3_SENTINEL_VALIDATION).
29
+ */
30
+ skipSentinelValidation?: boolean;
31
+ }
32
+ /**
33
+ * Build the S3 key for the cluster identity sentinel under an optional prefix.
34
+ * Strips any trailing slash from the prefix so callers can pass either form.
35
+ */
36
+ export declare function clusterSentinelKey(prefix?: string): string;
37
+ export declare class ClusterIdentity {
38
+ private readonly deps;
39
+ constructor(deps: ClusterIdentityDeps);
40
+ /** Read cluster_id from DB. Throws if not found (migration not run). */
41
+ getClusterId(): Promise<string>;
42
+ /**
43
+ * Validate S3 sentinel file matches DB cluster_id.
44
+ * - If no S3 configured, skip (filesystem-only deployment).
45
+ * - If sentinel doesn't exist, write it (first orch to use this bucket).
46
+ * - If sentinel exists and matches, success.
47
+ * - If sentinel exists and doesn't match, throw error (different DB/bucket mismatch).
48
+ */
49
+ validateS3Sentinel(): Promise<void>;
50
+ /**
51
+ * Validate cluster identity at startup.
52
+ * Logs cluster_id and instance_id for operational visibility, then runs
53
+ * S3 sentinel check. Throws on misconfiguration (e.g., different cluster
54
+ * using same DB/S3).
55
+ */
56
+ validateAtStartup(instanceId: string): Promise<string>;
57
+ }
58
+ export {};
59
+ //# sourceMappingURL=cluster-identity.d.ts.map
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Run coordinator for multi-orchestrator job routing.
3
+ *
4
+ * The receiving orchestrator becomes the run coordinator: it claims jobs
5
+ * it can dispatch locally and reroutes others to peers based on agent
6
+ * inventory. Per locked decisions:
7
+ * - "One orchestrator coordinates per webhook run"
8
+ * - "Claim-based splitting"
9
+ * - "Coordinator handles ALL check run reporting"
10
+ * - "Peers report step-by-step progress back to coordinator"
11
+ * - "Cancel mode: graceful -- finish current step, cancel remaining"
12
+ */
13
+ import type { JobReroute, JobProgress, PeerToPeerMessage, ResourceRequest } from '@kici-dev/engine';
14
+ import type { PeerRegistry } from './peer-registry.js';
15
+ import type { PeerClient } from './peer-client.js';
16
+ import type { Dispatcher } from '../agent/dispatcher.js';
17
+ import type { ExecutionTracker } from '../reporting/execution-tracker.js';
18
+ import type { CommitStatusReporter } from '../reporting/commit-status.js';
19
+ export interface RunContext {
20
+ runId: string;
21
+ deliveryId: string;
22
+ routingKey: string;
23
+ event: string;
24
+ action: string | null;
25
+ provider: string;
26
+ payload: Record<string, unknown>;
27
+ repoIdentifier: string;
28
+ sha: string;
29
+ ref: string;
30
+ workflowName: string;
31
+ installationId?: number;
32
+ requestId?: string;
33
+ traceId?: string;
34
+ /** Pre-resolved clone token for workers without provider credentials. */
35
+ cloneToken?: string;
36
+ }
37
+ export interface JobToRoute {
38
+ jobName: string;
39
+ runsOnLabels: string[][];
40
+ jobConfig: Record<string, unknown>;
41
+ repoUrl: string;
42
+ ref: string;
43
+ sha: string;
44
+ sourceTarUrl?: string;
45
+ sourceTarHash?: string;
46
+ depsUrl?: string;
47
+ depsHash?: string;
48
+ /** Labels that the dispatched agent must NOT have. */
49
+ excludeLabels?: string[];
50
+ /**
51
+ * Per-job resource request and limit (K8s-style). Forwarded to
52
+ * `Dispatcher.dispatch()` so the scaler's per-scaler / per-orchestrator /
53
+ * per-machine cap accounting sees the typed value rather than relying on
54
+ * the `jobConfig.resources` JSON blob (which the dispatcher does not parse).
55
+ */
56
+ resources?: ResourceRequest;
57
+ }
58
+ export interface RouteResult {
59
+ localJobs: Array<{
60
+ jobName: string;
61
+ jobId: string;
62
+ }>;
63
+ /**
64
+ * Rerouted jobs include the pre-allocated jobId so the caller can
65
+ * register the execution_runs / execution_jobs rows under the same id
66
+ * the worker will report progress against.
67
+ */
68
+ reroutedJobs: Array<{
69
+ jobName: string;
70
+ peerId: string;
71
+ jobId: string;
72
+ }>;
73
+ failedJobs: Array<{
74
+ jobName: string;
75
+ reason: string;
76
+ }>;
77
+ }
78
+ export interface RunCoordinatorDeps {
79
+ instanceId: string;
80
+ peerRegistry: PeerRegistry;
81
+ dispatcher: Dispatcher;
82
+ executionTracker?: ExecutionTracker;
83
+ commitStatusReporter?: CommitStatusReporter;
84
+ getPeerClient: (instanceId: string) => PeerClient | undefined;
85
+ /** Fallback: send job.reroute via server-side (incoming) peer connection and wait for ACK. */
86
+ sendAndWaitAckViaHandler?: (targetInstanceId: string, msg: JobReroute, timeoutMs: number) => Promise<boolean>;
87
+ /** Fallback: send a message via server-side (incoming) peer connection (fire-and-forget). */
88
+ sendToPeerViaHandler?: (targetInstanceId: string, msg: PeerToPeerMessage) => boolean;
89
+ ackTimeoutMs?: number;
90
+ /** Stale peer timeout in ms. Default: 60000 (60s). */
91
+ staleTimeoutMs?: number;
92
+ }
93
+ export declare class RunCoordinator {
94
+ private readonly instanceId;
95
+ private readonly peerRegistry;
96
+ private readonly dispatcher;
97
+ private readonly executionTracker?;
98
+ private readonly commitStatusReporter?;
99
+ private readonly getPeerClient;
100
+ private readonly sendAndWaitAckViaHandler?;
101
+ private readonly sendToPeerViaHandler?;
102
+ private readonly ackTimeoutMs;
103
+ /**
104
+ * Tracks which jobs have been rerouted to which peers, keyed by runId.
105
+ * Used for cancel propagation and progress tracking.
106
+ */
107
+ private readonly reroutedJobs;
108
+ /**
109
+ * NAK tracking per peer: count of consecutive NAKs and backoff-until timestamp.
110
+ * Peers that repeatedly NAK are deprioritized via exponential backoff.
111
+ */
112
+ private readonly nakTracker;
113
+ /** Stale eviction timer handle. */
114
+ private staleEvictionTimer;
115
+ constructor(deps: RunCoordinatorDeps);
116
+ /**
117
+ * Route jobs for a webhook run. Claims jobs that local agents can handle,
118
+ * reroutes the rest to peers with matching capacity.
119
+ *
120
+ * Parallel fan-out: jobs targeting different peers are rerouted concurrently.
121
+ */
122
+ routeJobs(runContext: RunContext, jobs: JobToRoute[]): Promise<RouteResult>;
123
+ /**
124
+ * Handle a job reroute request received from a peer (this instance is the worker).
125
+ * Checks loop prevention, then attempts to dispatch locally.
126
+ */
127
+ handleIncomingReroute(msg: JobReroute): Promise<{
128
+ accepted: boolean;
129
+ reason?: string;
130
+ }>;
131
+ /**
132
+ * Handle peer job/step progress updates from a worker (or coord) peer.
133
+ *
134
+ * The discriminator `msg.kind` decides which downstream tracker call to
135
+ * make: 'job' updates feed `onJobStatus` (the path that drives run-level
136
+ * state transitions and the rerouted-job cleanup); 'step' updates feed
137
+ * `onStepStatus` (which only persists `execution_steps` rows). Without
138
+ * this split, every job-level event was silently funnelled into
139
+ * `onStepStatus` and the run stayed in `running` forever.
140
+ */
141
+ onPeerJobProgress(msg: JobProgress): void;
142
+ /**
143
+ * Handle peer job completion. Updates ExecutionTracker.
144
+ * The execution tracker's onJobStatus fires the needs-aware scheduler hook,
145
+ * which evaluates downstream jobs and dispatches newly-ready ones via onJobReadyCallback.
146
+ * The data parameter carries droppedJobs for drift reporting.
147
+ */
148
+ onPeerJobComplete(runId: string, jobId: string, status: string, timestamp: number, data?: Record<string, unknown>): void;
149
+ /**
150
+ * Cancel all rerouted jobs for a run. Sends peer.job.cancel to all
151
+ * peers that have jobs for this run.
152
+ *
153
+ * Per locked decision: "graceful -- finish current step, cancel remaining."
154
+ */
155
+ cancelRun(runId: string, reason: string): void;
156
+ /**
157
+ * Check if the peer registry has any connected peers.
158
+ */
159
+ hasConnectedPeers(): boolean;
160
+ /**
161
+ * Start the stale eviction timer. Calls peerRegistry.evictStalePeers()
162
+ * every staleTimeoutMs/2 to detect and remove stale peers.
163
+ */
164
+ startStaleEvictionTimer(staleTimeoutMs: number): void;
165
+ /**
166
+ * Stop the stale eviction timer.
167
+ */
168
+ stopStaleEvictionTimer(): void;
169
+ /**
170
+ * Get the NAK count for a peer (used in tests).
171
+ */
172
+ getNakCount(peerId: string): number;
173
+ /**
174
+ * Get the backoff-until timestamp for a peer (used in tests).
175
+ */
176
+ getBackoffUntil(peerId: string): number;
177
+ /**
178
+ * Attempt to reroute a job to a peer with matching capacity.
179
+ * Tries peers in order of available capacity (most capacity first).
180
+ * Returns on first successful ACK.
181
+ */
182
+ private rerouteJob;
183
+ /**
184
+ * Sort peers by available capacity for the given label sets.
185
+ * Peers with more available capacity come first.
186
+ */
187
+ private sortPeersByCapacity;
188
+ /**
189
+ * Compute total available capacity across matching agents on a peer.
190
+ *
191
+ * Applies the same `mandatoryLabels` gate the local label matcher
192
+ * applies — a gated agent only contributes capacity for label sets that
193
+ * include every gate label. Without it, the coordinator would route a
194
+ * job to a peer based on a gated agent's labels, and the peer would
195
+ * then refuse the dispatch in `AgentRegistry.findAvailable` because the
196
+ * agent's gate is not satisfied.
197
+ */
198
+ private computeAvailableCapacity;
199
+ /**
200
+ * Track a rerouted job for cancel propagation.
201
+ */
202
+ private trackReroutedJob;
203
+ }
204
+ //# sourceMappingURL=coordinator.d.ts.map
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Cluster health HTTP endpoints.
3
+ *
4
+ * Provides visibility into cluster state for monitoring and debugging:
5
+ * - GET /cluster/health -- overall cluster health status
6
+ * - GET /cluster/peers -- per-peer details including connectivity
7
+ * - GET /cluster/runs -- active execution runs with job counts
8
+ *
9
+ * Follows the existing Hono route factory pattern from routes/health.ts.
10
+ */
11
+ import { Hono } from 'hono';
12
+ import type { RaftNode } from './raft.js';
13
+ import type { PeerRegistry } from './peer-registry.js';
14
+ import type { ExecutionTracker } from '../reporting/execution-tracker.js';
15
+ import type { AgentRegistry } from '../agent/registry.js';
16
+ export interface ClusterHealthRoutesDeps {
17
+ instanceId: string;
18
+ raft: RaftNode;
19
+ peerRegistry: PeerRegistry;
20
+ executionTracker: ExecutionTracker;
21
+ agentRegistry: AgentRegistry;
22
+ }
23
+ /**
24
+ * Create cluster health routes.
25
+ *
26
+ * @param deps - Dependencies for cluster state introspection
27
+ * @returns Hono app with /cluster/health, /cluster/peers, /cluster/runs endpoints
28
+ */
29
+ export declare function createClusterHealthRoutes(deps: ClusterHealthRoutesDeps): Hono;
30
+ //# sourceMappingURL=health-api.d.ts.map
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Barrel export for the cluster coordination module.
3
+ *
4
+ * All cluster-related functionality is exported from this single entry point
5
+ * for clean imports in server.ts and standalone.ts.
6
+ */
7
+ export { PeerRegistry } from './peer-registry.js';
8
+ export type { PeerInfo, PeerAgentInfo, PeerRegistryOptions } from './peer-registry.js';
9
+ export { PeerClient } from './peer-client.js';
10
+ export type { PeerClientOptions } from './peer-client.js';
11
+ export { createPeerHandler } from './peer-handler.js';
12
+ export type { PeerHandlerDeps } from './peer-handler.js';
13
+ export { PeerCredentialStore, readCredentialFile, writeCredentialFile, } from './peer-credentials.js';
14
+ export type { PeerCredential, CredentialFileData } from './peer-credentials.js';
15
+ export { RaftNode } from './raft.js';
16
+ export type { RaftRole } from './raft.js';
17
+ export { RaftStateStore } from './raft-state.js';
18
+ export type { RaftPersistentState } from './raft-state.js';
19
+ export { OrphanRecovery } from './orphan-recovery.js';
20
+ export { RunCoordinator } from './coordinator.js';
21
+ export type { RunContext, JobToRoute, RouteResult } from './coordinator.js';
22
+ export { createClusterHealthRoutes } from './health-api.js';
23
+ export type { ClusterHealthRoutesDeps } from './health-api.js';
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Join client for zero-knowledge cluster bootstrap.
3
+ *
4
+ * Provides the joiner-side logic for `kici-admin join`:
5
+ * 1. Connect to Platform relay (WS) or direct peer (HTTP POST)
6
+ * 2. Send join.request with the join token
7
+ * 3. Receive join.response with encrypted config bundle
8
+ * 4. Decrypt bundle using token-derived AES-256-GCM key
9
+ * 5. Write decrypted config as local YAML file
10
+ *
11
+ * The token carries routing info (cleartext for Platform relay) and a secret
12
+ * (used for HKDF key derivation). Only the joiner and the token creator
13
+ * can derive the encryption key -- the Platform relay sees only ciphertext.
14
+ */
15
+ import { type JoinRequest, type JoinResponse } from '@kici-dev/engine';
16
+ import type { ConfigBundle } from './join-handler.js';
17
+ interface JoinClientOptions {
18
+ token: string;
19
+ /** Platform WebSocket URL for relay mode (e.g., wss://platform.kici.dev/ws) */
20
+ platformUrl?: string;
21
+ /** Peer HTTP URL for direct mode (e.g., https://orch-1:8080) */
22
+ peerUrl?: string;
23
+ /** API key for Platform authentication (required for --platform mode) */
24
+ apiKey?: string;
25
+ /** Path to write the resulting local config YAML */
26
+ configPath?: string;
27
+ }
28
+ /**
29
+ * Local config structure written by the join client.
30
+ * Compatible with loadLocalConfig() from config/loader.ts.
31
+ */
32
+ interface JoinLocalConfig {
33
+ database: {
34
+ url: string;
35
+ };
36
+ storage?: ConfigBundle['storage'];
37
+ secrets?: {
38
+ key: string;
39
+ };
40
+ }
41
+ /**
42
+ * Decrypt a base64-encoded encrypted config bundle using a derived encryption key.
43
+ */
44
+ export declare function decryptAndParseBundle(encryptedB64: string, encryptionKey: Buffer): ConfigBundle;
45
+ /**
46
+ * Build a JoinLocalConfig from a decrypted ConfigBundle.
47
+ * Maps bundle fields to the structure expected by loadLocalConfig().
48
+ */
49
+ export declare function buildLocalConfig(bundle: ConfigBundle): JoinLocalConfig;
50
+ /**
51
+ * Write a local config object to a YAML file.
52
+ */
53
+ export declare function writeConfigFile(path: string, config: Record<string, unknown>): Promise<void>;
54
+ export declare class JoinClient {
55
+ private readonly options;
56
+ constructor(options: JoinClientOptions);
57
+ /**
58
+ * Execute the join flow:
59
+ * 1. Send join.request with token to Platform relay or direct peer
60
+ * 2. Receive join.response with encrypted config bundle
61
+ * 3. Decrypt bundle using token-derived key
62
+ * 4. Write local config YAML
63
+ */
64
+ join(): Promise<void>;
65
+ /**
66
+ * Join via Platform relay: connect WS, authenticate, send join.request, receive join.response.
67
+ */
68
+ joinViaPlatform(request: JoinRequest): Promise<JoinResponse>;
69
+ /**
70
+ * Join via direct peer: POST to peer's join endpoint.
71
+ */
72
+ joinViaPeer(request: JoinRequest): Promise<JoinResponse>;
73
+ }
74
+ export {};
75
+ //# sourceMappingURL=join-client.d.ts.map
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Join handler for processing join requests from new orchestrators.
3
+ *
4
+ * Supports both Platform relay and direct peer transport. When a new orchestrator
5
+ * sends a join.request with a kici_join_v1 token, this handler:
6
+ * 1. Validates the token (exists in DB, not expired, not consumed)
7
+ * 2. Builds a config bundle (DB URL, S3 config, secrets key, cluster ID)
8
+ * 3. Encrypts the bundle with the token-derived AES-256-GCM key
9
+ * 4. Consumes the token (one-time use)
10
+ * 5. Returns the encrypted bundle to the joiner
11
+ *
12
+ * The Platform relay sees only routing metadata and ciphertext -- zero-knowledge.
13
+ */
14
+ import type { JoinRequest, JoinResponse } from '@kici-dev/engine';
15
+ import type { Kysely } from 'kysely';
16
+ import type { ClusterIdentity } from './cluster-identity.js';
17
+ import type { SharedConfigStore } from '../config/shared-store.js';
18
+ interface JoinHandlerDeps {
19
+ db: Kysely<any>;
20
+ sharedConfigStore: SharedConfigStore;
21
+ clusterIdentity: ClusterIdentity;
22
+ databaseUrl: string;
23
+ }
24
+ /**
25
+ * Config bundle distributed to new orchestrators via join token.
26
+ * Contains everything needed to configure and start an orchestrator instance.
27
+ */
28
+ export interface ConfigBundle {
29
+ databaseUrl: string;
30
+ storage?: {
31
+ type?: 's3';
32
+ bucket?: string;
33
+ prefix?: string;
34
+ region?: string;
35
+ endpoint?: string;
36
+ forcePathStyle?: boolean;
37
+ logBucket?: string;
38
+ };
39
+ secretKey?: string;
40
+ clusterId: string;
41
+ }
42
+ export declare class JoinHandler {
43
+ private readonly deps;
44
+ private readonly tokenManager;
45
+ constructor(deps: JoinHandlerDeps);
46
+ /**
47
+ * Handle a join request from a new orchestrator.
48
+ * Validates token, builds config bundle, encrypts with token-derived key, consumes token.
49
+ * Echoes messageId from request for Platform relay correlation.
50
+ */
51
+ handleJoinRequest(request: JoinRequest): Promise<JoinResponse>;
52
+ /**
53
+ * Build the config bundle from SharedConfig + local config.
54
+ */
55
+ buildConfigBundle(): Promise<ConfigBundle>;
56
+ }
57
+ export {};
58
+ //# sourceMappingURL=join-handler.d.ts.map
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Join token manager for zero-knowledge cluster bootstrap.
3
+ *
4
+ * Token format: kici_join_v1.<base64url(routing_json)>.<random_256bit_hex>
5
+ * - Routing JSON: { orgId, routingKey, expiry } (cleartext for Platform relay routing)
6
+ * - Secret: 32 random bytes as hex (used for key derivation)
7
+ *
8
+ * Key derivation:
9
+ * - encryption_key = HKDF-SHA256(secret, salt="kici-join-encrypt", info="v1", length=32)
10
+ * - validation_hash = SHA-256(secret) (stored in DB for lookup)
11
+ *
12
+ * Config bundle encryption: AES-256-GCM with random 12-byte IV.
13
+ * Wire format: <12-byte IV><16-byte auth tag><ciphertext>
14
+ */
15
+ import type { Kysely } from 'kysely';
16
+ /**
17
+ * Silence the module-level logger (e.g. when a CLI is emitting JSON on stdout
18
+ * and a stray log line would break the contract).
19
+ */
20
+ export declare function silenceJoinTokenLogger(): void;
21
+ interface TokenRouting {
22
+ orgId: string;
23
+ routingKey: string;
24
+ expiry: number;
25
+ role: 'coordinator' | 'worker';
26
+ }
27
+ interface DerivedKeys {
28
+ encryptionKey: Buffer;
29
+ validationHash: string;
30
+ }
31
+ interface JoinTokenManagerDeps {
32
+ db: Kysely<any>;
33
+ }
34
+ export declare class JoinTokenManager {
35
+ private readonly deps;
36
+ constructor(deps: JoinTokenManagerDeps);
37
+ /**
38
+ * Create a new join token.
39
+ * Returns the full token string (only available at creation time).
40
+ */
41
+ createToken(opts: {
42
+ orgId: string;
43
+ routingKey: string;
44
+ createdBy: string;
45
+ role?: 'coordinator' | 'worker';
46
+ expiryMs?: number;
47
+ }): Promise<string>;
48
+ /**
49
+ * Validate a token: check hash exists in DB, not expired, not consumed.
50
+ * Returns routing info and derived keys on success.
51
+ */
52
+ validateToken(token: string): Promise<{
53
+ routing: TokenRouting;
54
+ keys: DerivedKeys;
55
+ }>;
56
+ /**
57
+ * Mark token as consumed (one-time use).
58
+ */
59
+ consumeToken(validationHash: string, consumedBy: string): Promise<void>;
60
+ }
61
+ /**
62
+ * Narrow detector for the "already been used" error thrown by validateToken().
63
+ * Used by peer-handler.ts to branch into the idempotent recovery path on
64
+ * legitimate mesh-join races (sibling peer-clients on the same peer identity
65
+ * racing on a shared join token across a multi-coordinator shared-DB mesh).
66
+ * Other validation failures (expired, not found, bad parse) MUST NOT be
67
+ * treated as recoverable.
68
+ */
69
+ export declare function isTokenAlreadyUsedError(err: unknown): boolean;
70
+ /**
71
+ * Parse a join token string into routing info and secret hex.
72
+ */
73
+ export declare function parseToken(token: string): {
74
+ routing: TokenRouting;
75
+ secretHex: string;
76
+ };
77
+ /**
78
+ * Derive encryption key and validation hash from a token secret.
79
+ * - encryptionKey: HKDF-SHA256 with salt="kici-join-encrypt", info="v1"
80
+ * - validationHash: SHA-256 of secret (stored in DB for lookup)
81
+ */
82
+ export declare function deriveKeys(secret: Buffer): DerivedKeys;
83
+ /**
84
+ * Encrypt a config bundle with the derived encryption key.
85
+ * Format: <12-byte IV><16-byte auth tag><ciphertext>
86
+ */
87
+ export declare function encryptBundle(plaintext: object, encryptionKey: Buffer): Buffer;
88
+ /**
89
+ * Decrypt a config bundle with the derived encryption key.
90
+ * Expects format: <12-byte IV><16-byte auth tag><ciphertext>
91
+ */
92
+ export declare function decryptBundle(data: Buffer, encryptionKey: Buffer): object;
93
+ export {};
94
+ //# sourceMappingURL=join-token.d.ts.map
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Leader-only orphan run cleanup.
3
+ *
4
+ * Periodically scans for execution runs stuck in 'running' state whose
5
+ * coordinator orchestrator has crashed. Only the Raft leader runs recovery
6
+ * to prevent multiple orchestrators from racing to recover the same run.
7
+ *
8
+ * Recovery logic:
9
+ * 1. Find runs with status='running' and stale last update (> threshold)
10
+ * 2. Check if the coordinator is still a connected peer
11
+ * 3. If coordinator is disconnected/unknown, this is an orphan run
12
+ * 4. Check job statuses: terminal jobs stay, stuck jobs get marked failed
13
+ * 5. Finalize the run with computed overall status
14
+ */
15
+ import type { Kysely } from 'kysely';
16
+ import type { Database } from '../db/types.js';
17
+ import type { RaftNode } from './raft.js';
18
+ import type { PeerRegistry } from './peer-registry.js';
19
+ import type { ExecutionTracker } from '../reporting/execution-tracker.js';
20
+ interface OrphanRecoveryDeps {
21
+ db: Kysely<Database>;
22
+ raft: RaftNode;
23
+ peerRegistry: PeerRegistry;
24
+ executionTracker: ExecutionTracker;
25
+ /** Scan interval in ms. Default: 60000 (1 minute). */
26
+ scanIntervalMs?: number;
27
+ /** How long a run must be stale before considered orphaned. Default: 5 minutes. */
28
+ staleThresholdMs?: number;
29
+ /** How long a stuck job must have no heartbeat before marking as failed. Default: 3 minutes. */
30
+ jobStuckThresholdMs?: number;
31
+ }
32
+ export declare class OrphanRecovery {
33
+ private readonly db;
34
+ private readonly raft;
35
+ private readonly peerRegistry;
36
+ private readonly executionTracker;
37
+ private readonly scanIntervalMs;
38
+ private readonly staleThresholdMs;
39
+ private readonly jobStuckThresholdMs;
40
+ private scanTimer;
41
+ constructor(deps: OrphanRecoveryDeps);
42
+ /**
43
+ * Start periodic orphan recovery scans.
44
+ * Only runs recovery logic when this node is the Raft leader.
45
+ */
46
+ start(): void;
47
+ /**
48
+ * Stop periodic orphan recovery scans.
49
+ */
50
+ stop(): void;
51
+ /**
52
+ * Scan for orphaned runs and recover them.
53
+ * Only runs when this node is the Raft leader.
54
+ */
55
+ scanForOrphans(): Promise<void>;
56
+ /**
57
+ * Attempt to recover a single potentially orphaned run.
58
+ */
59
+ private recoverRun;
60
+ /**
61
+ * Check if a coordinator with the given routing key is still connected
62
+ * as a peer in the cluster.
63
+ */
64
+ private isCoordinatorStillConnected;
65
+ }
66
+ export {};
67
+ //# sourceMappingURL=orphan-recovery.d.ts.map