@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,538 @@
1
+ /**
2
+ * Execution state tracker with write-through DB persistence.
3
+ *
4
+ * Aggregates job/step status updates from agents and persists execution
5
+ * history to PostgreSQL. Maintains in-memory state for fast lookups
6
+ * (job name resolution, run completion detection) with write-through
7
+ * to the execution_runs/execution_jobs/execution_steps tables.
8
+ *
9
+ * Overall run status follows locked decision:
10
+ * - success ONLY if ALL jobs succeed
11
+ * - failed if ANY job fails
12
+ * - cancelled if ANY job is cancelled (and none failed)
13
+ */
14
+ import { type Kysely } from 'kysely';
15
+ import type { Database } from '../db/types.js';
16
+ import { ExecutionRunStatus } from '@kici-dev/engine';
17
+ import type { ObserverRegistry } from '../ws/observer-registry.js';
18
+ import type { LogStorage } from './log-storage.js';
19
+ import type { JobQueue } from '../queue/job-queue.js';
20
+ /** Context passed to onExecutionComplete for commit status updates. */
21
+ export interface ExecutionContext {
22
+ workflowName: string;
23
+ provider: string;
24
+ repoIdentifier: string;
25
+ sha: string;
26
+ installationId?: number;
27
+ requestId?: string;
28
+ routingKey?: string;
29
+ /** Git branch or tag (e.g. "main", "feature/foo"). */
30
+ ref?: string;
31
+ /** Trigger event type (e.g. "push", "pr:open"). */
32
+ triggerEvent?: string;
33
+ /** First line of the commit message. */
34
+ commitMessage?: string;
35
+ /** Parent run ID for re-run lineage (null/undefined for original runs). */
36
+ parentRunId?: string | null;
37
+ /** Root ancestor run ID for re-run lineage (null/undefined for original runs). */
38
+ originalRunId?: string | null;
39
+ /** User identity that triggered this re-run (null/undefined for webhook-triggered). */
40
+ triggeredBy?: string | null;
41
+ /** Workflow-level concurrency config from the lock file. */
42
+ concurrency?: {
43
+ cancelInProgress?: boolean;
44
+ max?: number;
45
+ };
46
+ }
47
+ /** Data passed to the onWorkflowComplete callback. */
48
+ interface WorkflowCompleteCallbackData {
49
+ runId: string;
50
+ workflowName: string;
51
+ status: string;
52
+ duration: number;
53
+ jobResults: Array<{
54
+ name: string;
55
+ status: string;
56
+ }>;
57
+ routingKey?: string;
58
+ repo: string;
59
+ }
60
+ /** Data passed to the onJobComplete callback. */
61
+ interface JobCompleteCallbackData {
62
+ runId: string;
63
+ jobId: string;
64
+ jobName: string;
65
+ status: string;
66
+ routingKey?: string;
67
+ repo: string;
68
+ workflowName: string;
69
+ }
70
+ export interface ExecutionTrackerDeps {
71
+ db: Kysely<Database>;
72
+ /** Optional observer registry for broadcasting status/step/log events to CLI observers. */
73
+ observerRegistry?: ObserverRegistry;
74
+ /** Optional callback when execution reaches terminal state. */
75
+ onExecutionComplete?: (runId: string, status: Extract<ExecutionRunStatus, 'success' | 'failed' | 'cancelled'>, context: ExecutionContext, description?: string) => void;
76
+ /** Optional callback to forward step status to Platform. */
77
+ onStepStatusForward?: (runId: string, jobId: string, jobName: string, stepIndex: number, stepName: string, state: string, timestamp: number, data?: Record<string, unknown>, requestId?: string) => void;
78
+ /** Optional callback when a completed run is pruned from memory. */
79
+ onRunPruned?: (runId: string) => void;
80
+ /** Optional callback when a workflow run reaches terminal state (for system event emission). */
81
+ onWorkflowComplete?: (data: WorkflowCompleteCallbackData) => void;
82
+ /** Optional callback when a job reaches terminal state (for system event emission). */
83
+ onJobComplete?: (data: JobCompleteCallbackData) => void;
84
+ /**
85
+ * Optional callback to forward execution status changes to Platform.
86
+ * Fires at run start (status=pending), on first job running, and run completion.
87
+ * Used by Platform StaleOrchDetector to track active runs.
88
+ */
89
+ onExecutionStatusChange?: (runId: string, status: ExecutionRunStatus, context: ExecutionContext, jobCount: number, startedAt: number, completedAt?: number, durationMs?: number, failureReason?: string,
90
+ /**
91
+ * Total raw log bytes accumulated across the run (sum of per-job totals).
92
+ * Set on terminal run states only. Powers the operator-side
93
+ * `kici_org_log_bytes` capacity-planning gauge on the Platform.
94
+ */
95
+ logBytes?: number) => void;
96
+ /** Optional callback to forward job status changes to Platform.
97
+ * Fires on every job state transition (pending->running, running->success, etc.).
98
+ * Used to populate Platform's execution_jobs projection table. */
99
+ onJobStatusChange?: (runId: string, jobId: string, jobName: string, status: string, timestamp: number, startedAt?: number, completedAt?: number, durationMs?: number, errorMessage?: string, agentId?: string, runsOnLabels?: string[],
100
+ /**
101
+ * Total raw log bytes accumulated across the job (sum of per-step totals).
102
+ * Set on terminal job states only.
103
+ */
104
+ logBytes?: number) => void;
105
+ /**
106
+ * Optional callback to emit run.event messages to Platform.
107
+ * Fires at orchestrator lifecycle points (dispatch, agent assignment, job start/complete).
108
+ *
109
+ * SECURITY: this payload MUST NOT carry an `orgId` (or any tenant identifier).
110
+ * The Platform always uses `authState.orgId` for tenant attribution; trusting
111
+ * a wire-supplied field is a cross-tenant injection primitive. See
112
+ * `docs/architecture/security/ws-tenant-isolation.md`.
113
+ */
114
+ onRunEventEmit?: (event: {
115
+ runId: string;
116
+ eventType: string;
117
+ timestampMs: number;
118
+ sourceService: 'orchestrator' | 'agent';
119
+ jobId?: string | null;
120
+ metadata?: Record<string, unknown>;
121
+ durationMs?: number | null;
122
+ }) => void;
123
+ /** Optional log storage for writing per-job orchestration logs (JSONL). */
124
+ logStorage?: LogStorage;
125
+ /** Org ID for this orchestrator instance (used in run.event emission). */
126
+ orgId?: string;
127
+ /** Optional job queue for cascading run failures to dispatch_queue entries. */
128
+ jobQueue?: JobQueue;
129
+ }
130
+ export declare class ExecutionTracker {
131
+ private readonly db;
132
+ private readonly observerRegistry?;
133
+ private readonly onExecutionComplete?;
134
+ private readonly onStepStatusForward?;
135
+ private readonly onRunPruned?;
136
+ private readonly onWorkflowComplete?;
137
+ private readonly onJobComplete?;
138
+ private readonly onExecutionStatusChange?;
139
+ private readonly onJobStatusChange?;
140
+ private readonly onRunEventEmit?;
141
+ private readonly logStorage?;
142
+ private readonly orgId?;
143
+ private readonly jobQueue?;
144
+ private readonly runs;
145
+ /** Tracks which runs are test runs for observer broadcasting. */
146
+ private readonly testRunIds;
147
+ /**
148
+ * Per-(run, job) raw log byte accumulator.
149
+ *
150
+ * Populated from the agent-reported `logBytesStreamed` field on terminal
151
+ * `step.status` messages and folded into `execution_jobs.log_bytes` when
152
+ * the job reaches terminal state. The per-run total is then computed by
153
+ * summing the per-job entries and written into `execution_runs.log_bytes`
154
+ * at run completion. Deleted on run prune to avoid Map growth.
155
+ *
156
+ * Map shape: runId -> jobId -> bytes.
157
+ */
158
+ private readonly jobLogBytes;
159
+ /** Callback fired when a job's needs are satisfied and it's ready for dispatch. */
160
+ onJobReadyCallback?: (runId: string, jobName: string) => Promise<void>;
161
+ constructor(deps: ExecutionTrackerDeps);
162
+ /**
163
+ * Register a callback fired when a job's needs become satisfied.
164
+ * The processor sets this to dispatch newly-ready jobs to agents.
165
+ */
166
+ setOnJobReadyCallback(cb: (runId: string, jobName: string) => Promise<void>): void;
167
+ /**
168
+ * Record a new execution run with its initial jobs.
169
+ *
170
+ * Inserts execution_runs and execution_jobs rows in the DB and
171
+ * sets up in-memory tracking state.
172
+ */
173
+ onExecutionStarted(runId: string, workflowName: string, provider: string, repoIdentifier: string, ref: string, sha: string, deliveryId: string | null, providerContext: Record<string, unknown>, triggerDecision: Record<string, unknown> | null, jobs: Array<{
174
+ jobId: string;
175
+ jobName: string;
176
+ matrixValues?: Record<string, unknown>;
177
+ runsOnLabels?: string[];
178
+ }>, routingKey?: string,
179
+ /** Secret context names dispatched with jobs (for context-disable job lookup). */
180
+ dispatchedContexts?: string[],
181
+ /** Trigger event type (e.g. "push", "pr:open") for dashboard display. */
182
+ triggerEvent?: string,
183
+ /** First line of commit message for dashboard display. */
184
+ commitMessage?: string,
185
+ /** Parent run ID for re-run lineage. */
186
+ parentRunId?: string | null,
187
+ /** User identity that triggered this re-run. */
188
+ triggeredBy?: string | null,
189
+ /** Root ancestor run ID for re-run lineage. */
190
+ originalRunId?: string | null,
191
+ /** Workflow-level concurrency config from the lock file. */
192
+ concurrency?: {
193
+ cancelInProgress?: boolean;
194
+ max?: number;
195
+ }): Promise<void>;
196
+ /**
197
+ * Add additional jobs to an already-started execution run.
198
+ * Used when build jobs are tracked early and regular jobs are dispatched later.
199
+ */
200
+ /**
201
+ * Find the synthetic needs-pending job ID for a given job name in a run.
202
+ * Used by dispatchReadyJob to locate the placeholder entry before replacing it.
203
+ *
204
+ * Cluster correctness: the synthetic row is inserted by the peer that
205
+ * ingested the webhook. In an HA cluster `dispatchReadyJob` can fire on a
206
+ * different peer whose in-memory map has no entry for this run. Fall back
207
+ * to the DB so the leftover synthetic row gets cleaned up regardless of
208
+ * which peer owns the downstream dispatch.
209
+ */
210
+ findSyntheticJobId(runId: string, jobName: string): Promise<string | undefined>;
211
+ addJobsToRun(runId: string, jobs: Array<{
212
+ jobId: string;
213
+ jobName: string;
214
+ matrixValues?: Record<string, unknown>;
215
+ runsOnLabels?: string[];
216
+ }>, dispatchedContexts?: string[],
217
+ /** Synthetic job ID to replace (e.g. needs-pending-deploy-{uuid}). */
218
+ replaceSyntheticId?: string): Promise<void>;
219
+ /**
220
+ * Mark a run as a test run for observer broadcasting.
221
+ * Called by the test pipeline after creating the execution run.
222
+ */
223
+ markTestRun(runId: string): void;
224
+ /**
225
+ * Check if a run is a test run.
226
+ */
227
+ isTestRun(runId: string): boolean;
228
+ /**
229
+ * Update job status within a run.
230
+ *
231
+ * On terminal states (success/failed/cancelled), checks if ALL jobs
232
+ * in the run are terminal. If so, computes overall run status and
233
+ * fires the onExecutionComplete callback.
234
+ */
235
+ onJobStatus(runId: string, jobId: string, state: string, timestamp: number, agentId?: string, data?: Record<string, unknown>): Promise<void>;
236
+ /**
237
+ * Phase 1a: recover run state from the DB when in-memory tracking is empty.
238
+ * Returns the rehydrated RunState or null if the run is unknown to the DB
239
+ * (in which case the caller skips this status update entirely).
240
+ */
241
+ private recoverRunFromDb;
242
+ /**
243
+ * Phase 1b: recover job state from the dispatch_queue and add it to the
244
+ * run's in-memory map. Returns the freshly-inserted job entry.
245
+ */
246
+ private recoverJobFromDispatchQueue;
247
+ /**
248
+ * Phase 2: build the upsert payload for execution_jobs and execute it.
249
+ * Returns the per-job log byte total when the job reached a terminal state
250
+ * (used downstream by the run-completion phase to populate run.log_bytes).
251
+ */
252
+ private persistJobStatusUpdate;
253
+ /**
254
+ * Phase 3a: transition run from pending -> running when the first job
255
+ * starts executing.
256
+ */
257
+ private maybeTransitionRunToRunning;
258
+ /**
259
+ * Phase 3b: when an agent reports 'cancelling', transition the run-level
260
+ * status too. 'cancelling' means "graceful cancel in progress, hooks
261
+ * running" — the run should reflect this intermediate state.
262
+ */
263
+ private maybeTransitionRunToCancelling;
264
+ /**
265
+ * Phase 4: emit run.event and orchestration log entries at job lifecycle
266
+ * points (job started / agent assigned / job terminal).
267
+ */
268
+ private emitJobLifecycleEvents;
269
+ /**
270
+ * Phase 5: fire the onJobStatusChange callback for Platform forwarding.
271
+ */
272
+ private fireJobStatusChangeCallback;
273
+ /**
274
+ * Phase 6: reconcile orphaned steps. If a job reaches terminal state but
275
+ * some steps are still 'running' (because a step.complete IPC message was
276
+ * lost), mark them as the job's terminal state. Without this safety net,
277
+ * the dashboard shows "running" with an ever-growing duration for the lost
278
+ * step.
279
+ */
280
+ private reconcileOrphanedSteps;
281
+ /**
282
+ * Phase 7: drift report handling.
283
+ * When an agent reports droppedJobs, transition those sibling jobs to
284
+ * drift_dropped. drift_dropped is a terminal state, so the scheduler hook
285
+ * (Phase 8) will propagate failures to any downstreams.
286
+ */
287
+ private handleDriftDroppedJobs;
288
+ /**
289
+ * Phase 8: needs-aware scheduler hook.
290
+ * When a job reaches terminal state, evaluate its downstreams for dispatch.
291
+ * The DAG is acyclic (validated at compile time L1 and eval time L2),
292
+ * so recursive skip propagation terminates naturally.
293
+ */
294
+ private runSchedulerHook;
295
+ /**
296
+ * Phase 9: stuck-jobs invariant check ( Layer 3).
297
+ * Before declaring a run complete, verify no stuck jobs exist. If any are
298
+ * found, fail them via recursive onJobStatus calls and signal the caller to
299
+ * stop (returns true) — the recursive calls will re-enter and re-check
300
+ * completion with fresh state.
301
+ */
302
+ private enforceSchedulerInvariantOrFail;
303
+ /**
304
+ * Phase 10: finalize run completion. Computes overall status, writes the
305
+ * execution_runs row, fires Platform-forwarding + workflow-complete +
306
+ * observer callbacks, and schedules in-memory pruning.
307
+ */
308
+ private finalizeRunCompletion;
309
+ /**
310
+ * Mark a run as failed when its build fails (timeout or error).
311
+ *
312
+ * Called by the processor when a build job was tracked early via
313
+ * onExecutionStarted but the build subsequently fails. Without this,
314
+ * the execution_runs row would stay in a non-terminal state.
315
+ */
316
+ onBuildFailed(runId: string): Promise<void>;
317
+ /**
318
+ * Create a failed execution run when the build timed out before onExecutionStarted
319
+ * had a chance to insert the row (buildJobTrackedEarly was false).
320
+ *
321
+ * Inserts a minimal execution_runs row with status='failed' directly so the E2E
322
+ * test (and dashboard) can observe the failure instead of a missing run.
323
+ */
324
+ onBuildFailedBeforeTracking(runId: string, workflowName: string, provider: string, repoIdentifier: string, ref: string, sha: string, deliveryId: string | null, providerContext: Record<string, unknown>, routingKey: string, triggerEvent?: string, commitMessage?: string, failureReason?: string): Promise<void>;
325
+ /**
326
+ * Mark a run as failed immediately with a reason message.
327
+ *
328
+ * Used when no agents are available to dispatch any jobs (e.g. cron-triggered
329
+ * runs on a cluster leader without matching local agents and no reachable peers).
330
+ * Instead of leaving the run in 'running' for OrphanRecovery to catch after 5 min,
331
+ * this fails it right away.
332
+ */
333
+ failRun(runId: string, reason: string): Promise<void>;
334
+ /**
335
+ * Update step status within a job.
336
+ *
337
+ * Upserts execution_steps row with timing information. On 'running',
338
+ * sets started_at. On terminal state, sets completed_at, duration_ms,
339
+ * exit_code. Also constructs log_path and forwards to Platform.
340
+ *
341
+ * @param logBytesStreamed Raw byte total reported by the agent's
342
+ * LogStreamer at terminal step time. Accumulated into a per-(run, job)
343
+ * counter that lands in `execution_jobs.log_bytes` and
344
+ * `execution_runs.log_bytes` when the job and run reach terminal state,
345
+ * feeding the operator-side `kici_org_log_bytes` capacity-planning gauge
346
+ * on the Platform.
347
+ */
348
+ onStepStatus(runId: string, jobId: string, stepIndex: number, stepName: string, state: string, timestamp: number, data?: Record<string, unknown>, logBytesStreamed?: number): Promise<void>;
349
+ /**
350
+ * Check if all tracked jobs in a run have reached terminal state.
351
+ */
352
+ isRunComplete(runId: string): boolean;
353
+ /**
354
+ * Get the current overall status of a run.
355
+ */
356
+ getRunStatus(runId: string): Extract<ExecutionRunStatus, 'running' | 'success' | 'failed' | 'cancelled'>;
357
+ /**
358
+ * Look up a job name from in-memory state.
359
+ * Used by LogWriter to construct log paths.
360
+ */
361
+ getJobName(runId: string, jobId: string): string | undefined;
362
+ /**
363
+ * Get execution context for a run from in-memory state.
364
+ * Used by commit status reporting to access provider/repo/sha info.
365
+ */
366
+ getExecutionContext(runId: string): ExecutionContext | undefined;
367
+ /**
368
+ * Update the heartbeat timestamp for a running job.
369
+ *
370
+ * Uses optimistic WHERE status='running' so completed jobs are not updated.
371
+ * Called when the agent sends a job.heartbeat message.
372
+ */
373
+ updateJobHeartbeat(runId: string, jobId: string): Promise<void>;
374
+ /**
375
+ * Get the count of active (non-completed) runs in memory.
376
+ */
377
+ getActiveRunCount(): number;
378
+ /**
379
+ * Get a summary of all active runs for the cluster health API.
380
+ * Returns run ID, workflow name, status, and job routing counts.
381
+ */
382
+ getActiveRuns(): Array<{
383
+ runId: string;
384
+ workflowName: string;
385
+ status: string;
386
+ jobs: {
387
+ total: number;
388
+ completed: number;
389
+ failed: number;
390
+ running: number;
391
+ };
392
+ }>;
393
+ /**
394
+ * Get replay data for all in-memory runs (both active and recently completed).
395
+ * Used to send a state.replay message to Platform on reconnection so the Platform
396
+ * can reconcile its execution_runs and execution_jobs projection tables.
397
+ */
398
+ getReplayData(): Array<{
399
+ runId: string;
400
+ workflowName: string;
401
+ status: ExecutionRunStatus;
402
+ routingKey?: string;
403
+ repoIdentifier?: string;
404
+ sha?: string;
405
+ ref?: string;
406
+ triggerEvent?: string;
407
+ commitMessage?: string;
408
+ parentRunId?: string | null;
409
+ originalRunId?: string | null;
410
+ triggeredBy?: string | null;
411
+ failureReason?: string;
412
+ jobCount: number;
413
+ startedAt: number;
414
+ completedAt?: number;
415
+ durationMs?: number;
416
+ jobs: Array<{
417
+ jobId: string;
418
+ jobName: string;
419
+ status: string;
420
+ startedAt?: number;
421
+ completedAt?: number;
422
+ runsOnLabels?: string[];
423
+ }>;
424
+ }>;
425
+ /**
426
+ * Replay data merged with terminal runs read from the orchestrator's local DB.
427
+ *
428
+ * `getReplayData()` only sees runs still in memory. After an orchestrator
429
+ * crash/restart, in-memory state is empty until new webhooks arrive — but
430
+ * any run that completed before the crash still lives in `execution_runs`
431
+ * on disk. Without re-emitting those, Platform's mirror table (and the
432
+ * `kici_org_executions_count` operator-aggregate gauge) silently undercounts.
433
+ *
434
+ * This wrapper fills that gap: it returns the in-memory replay items first,
435
+ * then unions in any terminal-state runs from the local DB completed within
436
+ * `windowHours` (default 24h) that aren't already covered. Order is preserved
437
+ * for in-memory entries (callers may rely on that for active-run metadata);
438
+ * DB-backed entries are appended in `completed_at ASC` order.
439
+ *
440
+ * Idempotent: Platform's `state.replay` handler upserts on `run_id`, so
441
+ * re-emitting an already-mirrored run is a no-op for billing and dashboard
442
+ * state alike.
443
+ */
444
+ getReplayDataWithDb(windowHours?: number): Promise<ReturnType<ExecutionTracker['getReplayData']>>;
445
+ /**
446
+ * Update a job's in-memory status without touching the DB.
447
+ * Used by StaleRunDetector which does direct DB updates and only needs
448
+ * the in-memory state kept in sync for run completion detection.
449
+ */
450
+ updateInMemoryJob(runId: string, jobId: string, status: string): void;
451
+ /**
452
+ * Forward a terminal job status to Platform via the onJobStatusChange callback.
453
+ * Used by StaleRunDetector and OrphanRecovery which update the DB directly
454
+ * but need to notify Platform so its execution_jobs projection stays in sync.
455
+ */
456
+ forwardJobTerminalStatus(runId: string, jobId: string, jobName: string, status: string, errorMessage?: string): void;
457
+ /**
458
+ * Emit a run.event message via the onRunEventEmit callback.
459
+ * Public wrapper for use by StaleRunDetector and OrphanRecovery.
460
+ */
461
+ emitInfraEvent(runId: string, eventType: string, opts?: {
462
+ jobId?: string;
463
+ metadata?: Record<string, unknown>;
464
+ durationMs?: number;
465
+ }): void;
466
+ /**
467
+ * Cancel all non-terminal steps for a job.
468
+ *
469
+ * When a job is terminated by infrastructure (stale detection, orphan recovery,
470
+ * recovery timeout), any in-progress steps remain with status='running' in the DB.
471
+ * This method marks them as 'cancelled' so the dashboard doesn't show stale
472
+ * running indicators for steps that are no longer executing.
473
+ */
474
+ cancelStepsForJob(runId: string, jobId: string, reason: string): Promise<void>;
475
+ /**
476
+ * Check if all jobs for a run are terminal, and if so, complete the run.
477
+ * Works with in-memory state (normal operation) or falls back to DB query
478
+ * (crash recovery / pruned runs). Called by StaleRunDetector after marking
479
+ * stale jobs.
480
+ */
481
+ completeRunIfAllJobsTerminal(runId: string): Promise<void>;
482
+ /**
483
+ * Path A helper: complete a run using in-memory state. Called by the
484
+ * stale detector when memRun is still tracked locally — writes the
485
+ * execution_runs terminal row, fires Platform-forwarding +
486
+ * workflow-complete callbacks, and schedules in-memory pruning.
487
+ */
488
+ private completeRunFromMemoryState;
489
+ /**
490
+ * Path B helper: complete a run using DB rows only (crash recovery /
491
+ * pruned runs). Loads jobs + run row from execution_jobs/execution_runs,
492
+ * checks the all-terminal predicate + run-state guard, then writes the
493
+ * terminal row and fires Platform-forwarding callbacks.
494
+ */
495
+ private completeRunFromDbFallback;
496
+ /**
497
+ * Emit a run.event message to Platform via the onRunEventEmit callback.
498
+ * Called at orchestrator lifecycle points for infrastructure event tracking.
499
+ */
500
+ private emitRunEvent;
501
+ /**
502
+ * Emit a scaler lifecycle event for a job.
503
+ * Stores the event in the event_log table via the existing run.event pipeline
504
+ * and writes a log line to the provisioning JSONL file.
505
+ *
506
+ * @param runId - The run this event belongs to
507
+ * @param jobId - The job this event belongs to
508
+ * @param event - The scaler event with type, detail, and timestamp
509
+ */
510
+ emitScalerEvent(runId: string, jobId: string, event: {
511
+ agentId: string;
512
+ eventType: string;
513
+ detail: string;
514
+ timestampMs: number;
515
+ }): void;
516
+ /**
517
+ * Append a line to a per-job orchestration log file via LogStorage.
518
+ * Log format is JSONL for structured parsing on the frontend.
519
+ * Path convention: executions/{runId}/jobs/{jobId}/orchestration.jsonl
520
+ */
521
+ private writeOrchLog;
522
+ /**
523
+ * Build a human-readable description for a completed run.
524
+ * Lists failed job names for non-success outcomes.
525
+ */
526
+ private buildRunDescription;
527
+ /**
528
+ * Compute the overall run status from job statuses.
529
+ *
530
+ * Per locked decision:
531
+ * - success ONLY if ALL jobs pass (skipped jobs count as success)
532
+ * - failed if ANY job failed or timed_out_stale
533
+ * - cancelled if ANY job cancelled (and none failed)
534
+ */
535
+ private computeRunStatus;
536
+ }
537
+ export {};
538
+ //# sourceMappingURL=execution-tracker.d.ts.map
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Filesystem-backed log storage.
3
+ *
4
+ * Stores execution logs as files on disk. No TTL -- logs persist indefinitely.
5
+ * Supports append-only writes (JSONL accumulation) and cursor-based pagination.
6
+ *
7
+ * File layout:
8
+ * {basePath}/executions/{runId}/job-{name}/step-{index}.log
9
+ */
10
+ import type { LogReadOptions, LogReadResult, LogStorage } from './log-storage.js';
11
+ interface FilesystemLogStorageOptions {
12
+ basePath: string;
13
+ }
14
+ export declare class FilesystemLogStorage implements LogStorage {
15
+ private readonly basePath;
16
+ constructor(options: FilesystemLogStorageOptions);
17
+ private fullPath;
18
+ /**
19
+ * Ensure the directory for a given file path exists.
20
+ */
21
+ private ensureDir;
22
+ /**
23
+ * Check if a file exists on disk.
24
+ */
25
+ private fileExists;
26
+ /**
27
+ * Get the size of a file in bytes. Returns 0 if the file doesn't exist.
28
+ */
29
+ private fileSize;
30
+ /**
31
+ * Recursively list all files under a directory, returning paths relative
32
+ * to the base path.
33
+ */
34
+ private listRecursive;
35
+ append(path: string, data: string): Promise<void>;
36
+ read(path: string, options?: LogReadOptions): Promise<LogReadResult>;
37
+ exists(path: string): Promise<boolean>;
38
+ list(prefix: string): Promise<string[]>;
39
+ }
40
+ export {};
41
+ //# sourceMappingURL=fs-log-storage.d.ts.map
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Handler for log pull protocol messages on the orchestrator side.
3
+ *
4
+ * Responds to Platform requests for historical logs (log.request).
5
+ * Reads from LogStorage, supports pagination via cursor/limit,
6
+ * and filtering by jobName/stepIndex.
7
+ *
8
+ * Live logs flow via the push-based log.chunk -> BrowserFanOut path
9
+ * and are not handled here.
10
+ */
11
+ import type { LogStorage } from './log-storage.js';
12
+ import type { ExecutionTracker } from './execution-tracker.js';
13
+ export interface LogPullHandlerDeps {
14
+ logStorage: LogStorage;
15
+ executionTracker: ExecutionTracker;
16
+ /** Callback to send response messages back over WS */
17
+ send: (message: unknown) => void;
18
+ }
19
+ export declare class LogPullHandler {
20
+ private readonly deps;
21
+ constructor(deps: LogPullHandlerDeps);
22
+ /**
23
+ * Handle log.request -- read logs from storage and respond.
24
+ * Supports filtering by jobName and stepIndex, pagination via cursor/limit.
25
+ */
26
+ handleRequest(msg: {
27
+ messageId: string;
28
+ executionId: string;
29
+ jobName?: string;
30
+ stepIndex?: number;
31
+ cursor?: number;
32
+ limit?: number;
33
+ }): Promise<void>;
34
+ }
35
+ //# sourceMappingURL=log-pull-handler.d.ts.map
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Log storage abstraction for the orchestrator.
3
+ *
4
+ * Provides a pluggable backend interface for persisting execution logs.
5
+ * Unlike CacheStorage, log storage has NO TTL semantics -- logs persist
6
+ * indefinitely and the customer manages their own storage lifecycle.
7
+ *
8
+ * Backends: FilesystemLogStorage, S3LogStorage
9
+ *
10
+ * Log file layout: executions/{runId}/job-{name}/step-{index}.log
11
+ * Format: JSONL (one JSON object per line with timestamp, level, message, metadata)
12
+ */
13
+ /**
14
+ * Read result from LogStorage.read().
15
+ * Supports cursor-based pagination for large log files.
16
+ */
17
+ export interface LogReadResult {
18
+ /** The log content for this page */
19
+ data: string;
20
+ /** Byte offset cursor for the next read (pass to options.cursor) */
21
+ cursor: number;
22
+ /** True if the entire file has been read (cursor >= file size) */
23
+ complete: boolean;
24
+ }
25
+ /**
26
+ * Options for LogStorage.read().
27
+ */
28
+ export interface LogReadOptions {
29
+ /** Byte offset to start reading from (0-based). Default: 0 */
30
+ cursor?: number;
31
+ /** Maximum number of bytes to read. Default: read all remaining */
32
+ limit?: number;
33
+ }
34
+ /**
35
+ * Pluggable log storage interface.
36
+ *
37
+ * All operations are async. No TTL -- logs persist indefinitely.
38
+ */
39
+ export interface LogStorage {
40
+ /** Append lines to a log file. Creates the file (and directories) if it doesn't exist. */
41
+ append(path: string, data: string): Promise<void>;
42
+ /** Read log file content. Returns { data, cursor, complete } for pagination. */
43
+ read(path: string, options?: LogReadOptions): Promise<LogReadResult>;
44
+ /** Check if a log file exists. */
45
+ exists(path: string): Promise<boolean>;
46
+ /** List files matching a prefix (directory listing). */
47
+ list(prefix: string): Promise<string[]>;
48
+ }
49
+ /**
50
+ * Configuration for creating a log storage backend.
51
+ */
52
+ type LogStorageConfig = {
53
+ type: 'filesystem';
54
+ basePath: string;
55
+ } | {
56
+ type: 's3';
57
+ bucket: string;
58
+ prefix: string;
59
+ region?: string;
60
+ /** Custom endpoint URL for S3-compatible services (e.g., SeaweedFS, LocalStack) */
61
+ endpoint?: string;
62
+ /** Use path-style access instead of virtual-hosted-style (required for most S3-compatible services) */
63
+ forcePathStyle?: boolean;
64
+ };
65
+ /**
66
+ * Factory function to create the appropriate LogStorage backend.
67
+ */
68
+ export declare function createLogStorage(config: LogStorageConfig): LogStorage;
69
+ export {};
70
+ //# sourceMappingURL=log-storage.d.ts.map