@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,103 @@
1
+ /**
2
+ * Shared mock Kysely database builder for orchestrator tests.
3
+ *
4
+ * Provides a configurable `createMockDb()` that constructs a chainable
5
+ * mock supporting the common query patterns used by the orchestrator:
6
+ *
7
+ * - selectFrom().selectAll().where()...execute() / executeTakeFirst()
8
+ * - selectFrom().select().where()...execute() / executeTakeFirst() / executeTakeFirstOrThrow()
9
+ * - insertInto().values().execute() / returning().executeTakeFirstOrThrow()
10
+ * - insertInto().values().onConflict(cb).execute()
11
+ * - insertInto().values().returningAll().executeTakeFirstOrThrow()
12
+ * - updateTable().set().where()...execute() / executeTakeFirst()
13
+ * - deleteFrom().where()...execute() / executeTakeFirst()
14
+ * - transaction().execute(async (trx) => { ... })
15
+ *
16
+ * Each test can configure return values via options and access the
17
+ * underlying vi.fn() mocks for assertions via the `mocks` property.
18
+ */
19
+ import { vi } from 'vitest';
20
+ export interface MockDbOptions {
21
+ /** Rows returned by selectAll/select chains ending in .execute(). Default: [] */
22
+ selectRows?: unknown[];
23
+ /** Row returned by select chains ending in .executeTakeFirst(). Default: undefined */
24
+ selectFirstRow?: unknown | undefined;
25
+ /** Row returned by insert chains ending in .returningAll().executeTakeFirstOrThrow(). Default: { id: 'mock-id' } */
26
+ insertedRow?: unknown;
27
+ /** Row returned by insert chains ending in .returning().executeTakeFirstOrThrow(). Default: { id: 'mock-id' } */
28
+ insertReturning?: unknown;
29
+ /** Row returned by update chains ending in .returningAll().executeTakeFirstOrThrow() or executeTakeFirst(). Default: undefined */
30
+ updatedRow?: unknown;
31
+ /** Result for update .execute() calls. Default: { numUpdatedRows: 0n } */
32
+ updateResult?: {
33
+ numUpdatedRows: bigint;
34
+ };
35
+ /** Result for delete .executeTakeFirst() calls. Default: { numDeletedRows: 0n } */
36
+ deleteResult?: {
37
+ numDeletedRows: bigint;
38
+ };
39
+ /** Result for count queries (fn.countAll). Default: { count: 0 } */
40
+ countResult?: {
41
+ count: number;
42
+ };
43
+ /** Result for insert chains ending in .executeTakeFirst(). Default: undefined */
44
+ insertResult?: {
45
+ numInsertedOrUpdatedRows: bigint;
46
+ };
47
+ }
48
+ export interface MockDb {
49
+ db: any;
50
+ mocks: MockDbMocks;
51
+ }
52
+ export interface MockDbMocks {
53
+ selectFrom: ReturnType<typeof vi.fn>;
54
+ selectAll: ReturnType<typeof vi.fn>;
55
+ select: ReturnType<typeof vi.fn>;
56
+ selectWhere: ReturnType<typeof vi.fn>;
57
+ selectOrderBy: ReturnType<typeof vi.fn>;
58
+ selectLimit: ReturnType<typeof vi.fn>;
59
+ selectExecute: ReturnType<typeof vi.fn>;
60
+ selectExecuteTakeFirst: ReturnType<typeof vi.fn>;
61
+ selectExecuteTakeFirstOrThrow: ReturnType<typeof vi.fn>;
62
+ selectForUpdate: ReturnType<typeof vi.fn>;
63
+ selectSkipLocked: ReturnType<typeof vi.fn>;
64
+ insertInto: ReturnType<typeof vi.fn>;
65
+ insertValues: ReturnType<typeof vi.fn>;
66
+ insertReturning: ReturnType<typeof vi.fn>;
67
+ insertReturningAll: ReturnType<typeof vi.fn>;
68
+ insertExecute: ReturnType<typeof vi.fn>;
69
+ insertExecuteTakeFirstOrThrow: ReturnType<typeof vi.fn>;
70
+ onConflict: ReturnType<typeof vi.fn>;
71
+ updateTable: ReturnType<typeof vi.fn>;
72
+ updateSet: ReturnType<typeof vi.fn>;
73
+ updateWhere: ReturnType<typeof vi.fn>;
74
+ updateReturningAll: ReturnType<typeof vi.fn>;
75
+ updateExecute: ReturnType<typeof vi.fn>;
76
+ updateExecuteTakeFirst: ReturnType<typeof vi.fn>;
77
+ updateExecuteTakeFirstOrThrow: ReturnType<typeof vi.fn>;
78
+ deleteFrom: ReturnType<typeof vi.fn>;
79
+ deleteWhere: ReturnType<typeof vi.fn>;
80
+ deleteExecute: ReturnType<typeof vi.fn>;
81
+ deleteExecuteTakeFirst: ReturnType<typeof vi.fn>;
82
+ transaction: ReturnType<typeof vi.fn>;
83
+ transactionExecute: ReturnType<typeof vi.fn>;
84
+ countAll: ReturnType<typeof vi.fn>;
85
+ countAs: ReturnType<typeof vi.fn>;
86
+ countExecuteTakeFirst: ReturnType<typeof vi.fn>;
87
+ }
88
+ /**
89
+ * Create a mock Kysely DB instance for orchestrator unit tests.
90
+ *
91
+ * All query chains are fully wired and return sensible defaults.
92
+ * Override specific return values via the `options` parameter.
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * const { db, mocks } = createMockDb({ selectRows: [row1, row2] });
97
+ * const store = new SomeStore(db);
98
+ * await store.list();
99
+ * expect(mocks.selectFrom).toHaveBeenCalledWith('my_table');
100
+ * ```
101
+ */
102
+ export declare function createMockDb(options?: MockDbOptions): MockDb;
103
+ //# sourceMappingURL=mock-db.d.ts.map
@@ -0,0 +1,13 @@
1
+ import type { WsLike } from '../agent/registry.js';
2
+ import type { ObserverWsLike } from '../ws/observer-registry.js';
3
+ /**
4
+ * Create a mock WsLike with vi.fn() spies on send/close.
5
+ * Used across agent registry, dispatcher, heartbeat, and WS handler tests.
6
+ */
7
+ export declare function mockWs(): WsLike;
8
+ /**
9
+ * Create a mock ObserverWsLike with vi.fn() spies on send/close.
10
+ * Used by observer-registry tests.
11
+ */
12
+ export declare function mockObserverWs(): ObserverWsLike;
13
+ //# sourceMappingURL=mock-ws.d.ts.map
@@ -0,0 +1,231 @@
1
+ import type { AgentRegistry } from './registry.js';
2
+ import { type JobQueue, type QueuedJob, type QueuedJobInput } from '../queue/job-queue.js';
3
+ import type { ScaleResult } from '../scaler/types.js';
4
+ import type { ResourceRequest } from '@kici-dev/engine';
5
+ /**
6
+ * Metrics interface for dispatch operations.
7
+ * Allows the dispatcher to update Prometheus counters without
8
+ * directly importing the metrics module (dependency injection).
9
+ */
10
+ export interface DispatchMetrics {
11
+ /** Increment the jobs dispatched counter by status. */
12
+ incJobsDispatched(status: 'dispatched' | 'queued' | 'rejected'): void;
13
+ /** Set the queue depth gauge. */
14
+ setQueueDepth(depth: number): void;
15
+ }
16
+ /**
17
+ * Result of a dispatch attempt.
18
+ */
19
+ type DispatchResult = {
20
+ status: 'dispatched';
21
+ agentId: string;
22
+ jobId: string;
23
+ } | {
24
+ status: 'queued';
25
+ jobId: string;
26
+ } | {
27
+ status: 'queued-no-backend';
28
+ jobId: string;
29
+ } | {
30
+ status: 'rejected';
31
+ reason: string;
32
+ };
33
+ /**
34
+ * Dispatch coordinator connecting the agent registry and job queue.
35
+ *
36
+ * Routes incoming jobs to matching agents based on label requirements,
37
+ * falling back to the persistent queue when no agent is available.
38
+ * Handles agent lifecycle events (connect, disconnect, job completion).
39
+ *
40
+ * The dispatcher does NOT directly access WebSocket connections --
41
+ * it uses the onDispatch callback provided at construction. The caller
42
+ * (app.ts or server.ts) provides an onDispatch that looks up the agent's
43
+ * WS from the registry and sends the job.dispatch message.
44
+ */
45
+ export declare class Dispatcher {
46
+ private readonly registry;
47
+ private readonly queue;
48
+ private readonly metrics;
49
+ private readonly onDispatch;
50
+ private readonly onNoMatchingAgent?;
51
+ /**
52
+ * Tracks which jobs are dispatched to which agents.
53
+ * Used for marking jobs as failed on agent disconnect.
54
+ */
55
+ private readonly agentJobs;
56
+ /** Reverse map: jobId -> agentId, for cancel-run lookups. */
57
+ private readonly jobToAgent;
58
+ /**
59
+ * Grace window for recently completed jobs.
60
+ * Allows late messages (log.chunk, step.status) to be accepted for a short
61
+ * period after job completion, preventing false ownership violations.
62
+ */
63
+ private readonly completedJobs;
64
+ /** Cap on completedJobs map to prevent unbounded growth. */
65
+ private static readonly COMPLETED_JOBS_CAP;
66
+ /** Grace window duration in milliseconds (30 seconds). */
67
+ private static readonly GRACE_WINDOW_MS;
68
+ /** Interval for cleaning up expired grace window entries (10 seconds). */
69
+ private static readonly GRACE_CLEANUP_INTERVAL_MS;
70
+ /** Timer for periodic grace cleanup. */
71
+ private graceCleanupTimer;
72
+ /** Max reconnection delay from agent config, used to derive grace period. */
73
+ private readonly maxReconnectDelayMs;
74
+ /** Callback when a recovery timer expires and the job is permanently failed. */
75
+ private readonly onRecoveryTimeout?;
76
+ /** Callback when a job enters recovery (starts timer). */
77
+ private readonly onRecoveryStarted?;
78
+ /**
79
+ * Per-job recovery timers for jobs in 'recovering' state.
80
+ * When an agent disconnects with in-flight jobs, each job gets a timer.
81
+ * If the agent reconnects before the timer fires, the timer is cancelled.
82
+ */
83
+ private readonly recoveringJobs;
84
+ /** Grace period = 2x max reconnection delay. */
85
+ private get gracePeriodMs();
86
+ constructor(deps: {
87
+ registry: AgentRegistry;
88
+ queue: JobQueue;
89
+ metrics: DispatchMetrics;
90
+ onDispatch: (agentId: string, job: QueuedJob) => void | Promise<void>;
91
+ /** Optional hook called when no agent matches the job's labels.
92
+ * When set, receives the per-job `resources` so the scaler can apply
93
+ * per-scaler / per-orchestrator / per-machine caps before spawning. */
94
+ onNoMatchingAgent?: (labels: string[], jobId: string, excludeLabels: string[], resources?: ResourceRequest) => Promise<ScaleResult>;
95
+ /** Max reconnection delay from agent config (default 60s). Used to derive grace period. */
96
+ maxReconnectDelayMs?: number;
97
+ /** Callback when a recovery timer expires and the job is permanently failed. */
98
+ onRecoveryTimeout?: (agentId: string, jobId: string, runId: string) => void;
99
+ /** Callback when a job enters recovery (starts timer). */
100
+ onRecoveryStarted?: (agentId: string, jobId: string) => void;
101
+ });
102
+ /**
103
+ * Dispatch a job to a matching agent, or queue it if none available.
104
+ *
105
+ * Flow:
106
+ * 1. Find available agents matching job's runsOnLabels.
107
+ * 2. If agent found: increment activeJobs, call onDispatch, return 'dispatched'.
108
+ * 3. If no agent: enqueue in queue, return 'queued'.
109
+ * 4. If queue full: return 'rejected'.
110
+ */
111
+ dispatch(job: QueuedJobInput): Promise<DispatchResult>;
112
+ /**
113
+ * Eagerly dispatch a specific bound job to a freshly-registered
114
+ * scaler-managed agent.
115
+ *
116
+ * Called by the agent-handler immediately after a scaler-managed agent
117
+ * registers, when the scaler had bound a queued jobId to that agent at
118
+ * spawn time. Atomically claims the job from the queue (validating it's
119
+ * still pending and the agent's labels still satisfy it), marks it
120
+ * dispatched, and sends it to the agent.
121
+ *
122
+ * Returns true if dispatched, false if the bound job was already claimed
123
+ * elsewhere, expired, or the agent isn't registered. The caller falls
124
+ * back to the generic onAgentAvailable() drain in either case.
125
+ */
126
+ dispatchBoundJob(agentId: string, jobId: string): Promise<boolean>;
127
+ /**
128
+ * Try draining the queue for a specific agent.
129
+ * Called when an agent registers or completes a job.
130
+ *
131
+ * Dequeues matching jobs from the queue while the agent has capacity,
132
+ * calling onDispatch for each.
133
+ */
134
+ onAgentAvailable(agentId: string): Promise<void>;
135
+ /**
136
+ * Handle agent disconnect. Starts per-job recovery timers instead of
137
+ * immediately failing jobs, giving the agent a grace period to reconnect.
138
+ * If no in-flight jobs, performs a clean disconnect.
139
+ *
140
+ * Returns empty array (no immediately failed jobs -- failures happen
141
+ * asynchronously when recovery timers expire).
142
+ */
143
+ onAgentDisconnect(agentId: string): Promise<string[]>;
144
+ /**
145
+ * Called when an agent completes a job (success or failure).
146
+ * Decrements active jobs and moves the job to the grace window
147
+ * (instead of immediately removing it) so that late messages
148
+ * (e.g. final log chunks) are still accepted.
149
+ */
150
+ onJobComplete(agentId: string, jobId: string): void;
151
+ /**
152
+ * Check if a job is owned by the given agent.
153
+ * Returns true if the job is actively dispatched to the agent,
154
+ * in recovery (agent disconnected but within grace period),
155
+ * or in the grace window (completed within the last 30 seconds).
156
+ */
157
+ isJobOwnedByAgent(agentId: string, jobId: string): boolean;
158
+ /**
159
+ * Resolve which agent a dispatched job was sent to.
160
+ * Used by the cancel-run API. Returns null if the job is not tracked (e.g. already completed).
161
+ */
162
+ getAgentIdForJob(jobId: string): string | null;
163
+ /**
164
+ * Start periodic cleanup of expired grace window entries.
165
+ * Should be called during server startup.
166
+ */
167
+ startGraceCleanup(): void;
168
+ /**
169
+ * Stop periodic grace cleanup.
170
+ * Should be called during server shutdown.
171
+ */
172
+ stopGraceCleanup(): void;
173
+ /**
174
+ * Claim a recovering job back for a reconnected agent.
175
+ * Cancels the recovery timer and returns true if the job was in recovery
176
+ * for this agent. Returns false if the job is not recovering or belongs
177
+ * to a different agent.
178
+ */
179
+ claimRecovery(jobId: string, agentId: string): boolean;
180
+ /**
181
+ * Full reconciliation of a recovering job for a reconnected agent.
182
+ * Claims the recovery timer, transitions DB status back to dispatched,
183
+ * and restores in-memory tracking. Returns true if reconciled.
184
+ */
185
+ reconcileRecovery(jobId: string, agentId: string): Promise<boolean>;
186
+ /**
187
+ * Get recovery info for a job (for structured logging).
188
+ */
189
+ getRecoveryInfo(jobId: string): {
190
+ disconnectedAt: number;
191
+ agentId: string;
192
+ } | null;
193
+ /**
194
+ * Get all recovering job IDs for a specific agent.
195
+ * Used during reconnection reconciliation.
196
+ */
197
+ getRecoveringJobsForAgent(agentId: string): string[];
198
+ /**
199
+ * Restore a reconciled job into the dispatcher's in-memory tracking.
200
+ * Called when an agent reconnects and claims a recovering job.
201
+ */
202
+ restoreJobForAgent(agentId: string, jobId: string): void;
203
+ /**
204
+ * Start a recovery timer for a job found in 'dispatched' state on startup.
205
+ * Called by server.ts/standalone.ts to create recovery timers for jobs
206
+ * from a previous orchestrator instance.
207
+ */
208
+ startRecoveryTimer(jobId: string, agentId: string, runId: string): Promise<void>;
209
+ /**
210
+ * Stop all recovery timers. Called during graceful shutdown.
211
+ */
212
+ stopRecoveryTimers(): void;
213
+ /**
214
+ * Handle recovery timer expiry for a single job.
215
+ * Extracted so that both onAgentDisconnect and startRecoveryTimer share the same logic,
216
+ * and the caller can `.catch()` to prevent unhandled rejections in setTimeout.
217
+ */
218
+ private handleRecoveryExpiry;
219
+ /** Remove expired entries from the completedJobs grace window map. */
220
+ private cleanupExpiredGraceEntries;
221
+ private trackJobForAgent;
222
+ /**
223
+ * Cancel a queued job (mark as failed in the dispatch queue).
224
+ * Used by the coordinator to clean up local fallback entries when a peer
225
+ * accepts the rerouted job.
226
+ */
227
+ cancelQueuedJob(jobId: string, reason: string): Promise<void>;
228
+ private updateQueueDepthMetric;
229
+ }
230
+ export {};
231
+ //# sourceMappingURL=dispatcher.d.ts.map
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Job ownership tracker for agent message validation.
3
+ *
4
+ * Validates that agents only send messages (job.status, log.chunk, step.status,
5
+ * job.heartbeat, cache.upload.request, cache.upload.complete) for jobs that were
6
+ * actually dispatched to them.
7
+ *
8
+ * Includes:
9
+ * - Ownership check via dispatcher's isJobOwnedByAgent
10
+ * - Violation counting with sliding window (default: 5 violations in 60s)
11
+ * - Escalation: disconnect agent after threshold violations
12
+ */
13
+ interface OwnershipTrackerOpts {
14
+ /** Check if a job is owned by the given agent (active or in grace window). */
15
+ isJobOwnedByAgent: (agentId: string, jobId: string) => boolean;
16
+ /** Callback to disconnect an agent after escalation. */
17
+ onDisconnect: (agentId: string, reason: string) => void;
18
+ /** Number of violations before escalation (default: 5). */
19
+ violationThreshold?: number;
20
+ /** Window in ms for counting violations (default: 60_000). */
21
+ violationWindowMs?: number;
22
+ }
23
+ export declare class OwnershipTracker {
24
+ private readonly isJobOwnedByAgent;
25
+ private readonly onDisconnect;
26
+ private readonly violationThreshold;
27
+ private readonly violationWindowMs;
28
+ private readonly violations;
29
+ constructor(opts: OwnershipTrackerOpts);
30
+ /**
31
+ * Check if an agent owns a job. Returns true if ownership is valid.
32
+ * On violation: logs warning, records violation, may escalate to disconnect.
33
+ */
34
+ checkOwnership(agentId: string, jobId: string, messageType: string): boolean;
35
+ /**
36
+ * Record a violation for an agent. If threshold is exceeded within the
37
+ * violation window, triggers disconnect escalation.
38
+ */
39
+ private recordViolation;
40
+ /**
41
+ * Clean up violation tracking for a disconnected agent.
42
+ */
43
+ cleanup(agentId: string): void;
44
+ }
45
+ export {};
46
+ //# sourceMappingURL=ownership-tracker.d.ts.map
@@ -0,0 +1,255 @@
1
+ /**
2
+ * In-memory agent registry with label-based lookup and capacity tracking.
3
+ *
4
+ * Follows the Platform ConnectionRegistry dual-map pattern:
5
+ * - Primary map: agentId -> AgentEntry (direct agent lookup)
6
+ * - Secondary map: label -> Set<agentId> (reverse index for label-based dispatch queries)
7
+ * - WS reverse map: ws -> agentId (fast lookup on WS events)
8
+ *
9
+ * No persistence needed -- agents re-register on reconnect.
10
+ */
11
+ import type { WsLike } from '@kici-dev/engine';
12
+ export type { WsLike } from '@kici-dev/engine';
13
+ /**
14
+ * A single tracked agent connection.
15
+ */
16
+ export interface AgentEntry {
17
+ /** Unique agent identifier. */
18
+ agentId: string;
19
+ /** The underlying WebSocket (or mock). */
20
+ ws: WsLike;
21
+ /** Set of labels this agent provides (e.g., "linux", "gpu", "docker"). */
22
+ labels: Set<string>;
23
+ /**
24
+ * Kubernetes-taint-style mandatory labels inherited from the scaler that
25
+ * spawned this agent. A job is only dispatched to this agent when every
26
+ * label in `mandatoryLabels` appears in `runsOnLabels` (in addition to the
27
+ * existing subset/exclusion checks).
28
+ *
29
+ * Empty for static agents and warm-pool replenishment spawns — those have
30
+ * no opt-in gate and behave exactly as before. Populated only when the
31
+ * spawning scaler declared a `mandatoryLabels` block; the value is a copy
32
+ * of the scaler's gate (the scaler-side gate in `findBackendForLabels` is
33
+ * not enough — once the agent registers, the queue-drain path
34
+ * (`onAgentAvailable` → `dequeueForLabels`) sees only the agent's labels
35
+ * and would otherwise pull a queued job whose `runsOn` is a subset of the
36
+ * agent's labels but does not satisfy the gate).
37
+ */
38
+ mandatoryLabels: Set<string>;
39
+ /** Number of jobs currently executing on this agent. */
40
+ activeJobs: number;
41
+ /** Maximum concurrent jobs this agent can handle (default 1). */
42
+ maxConcurrency: number;
43
+ /** Unix epoch ms of the last heartbeat received. */
44
+ lastHeartbeatAt: number;
45
+ /** Agent platform (os.platform(), e.g. 'linux', 'darwin', 'win32'). */
46
+ platform: string;
47
+ /** Agent architecture (os.arch(), e.g. 'x64', 'arm64'). */
48
+ arch: string;
49
+ /** Unix epoch ms when the agent registered. */
50
+ registeredAt: number;
51
+ /** Self-reported agent version (e.g. "0.0.1"). Null if not reported. */
52
+ version: string | null;
53
+ /**
54
+ * The `agent_tokens.id` row used to authenticate this connection, or
55
+ * `null` when auth mode is `none`. Indexed by `tokenIdIndex` so a
56
+ * synchronous revocation kick can enumerate every WS authenticated by
57
+ * a given token. in the pentest catalog.
58
+ */
59
+ tokenId: string | null;
60
+ hostname: string | null;
61
+ osRelease: string | null;
62
+ osVersion: string | null;
63
+ totalMemoryMb: number | null;
64
+ cpuCount: number | null;
65
+ nodeVersion: string | null;
66
+ runningAsUser: string | null;
67
+ runningAsUid: number | null;
68
+ memoryUsedMb: number | null;
69
+ memoryAvailableMb: number | null;
70
+ uptimeSeconds: number | null;
71
+ }
72
+ /** Optional static metadata from the agent.register message. */
73
+ interface AgentMetadata {
74
+ hostname?: string;
75
+ osRelease?: string;
76
+ osVersion?: string;
77
+ totalMemoryMb?: number;
78
+ cpuCount?: number;
79
+ nodeVersion?: string;
80
+ runningAsUser?: string;
81
+ runningAsUid?: number;
82
+ /**
83
+ * The `agent_tokens.id` row used to authenticate this connection.
84
+ * `null` when auth mode is `none` (no token-based auth applied).
85
+ * Indexed for `disconnectByTokenId(...)` revocation kicks.
86
+ */
87
+ tokenId?: string | null;
88
+ /**
89
+ * Kubernetes-taint-style mandatory labels inherited from the scaler that
90
+ * spawned this agent. Empty / undefined for static agents (no opt-in
91
+ * gate). Populated by `agent-handler.ts` from the scaler manager's
92
+ * `onAgentRegistered(...)` return value.
93
+ */
94
+ mandatoryLabels?: string[];
95
+ }
96
+ export declare class AgentRegistry {
97
+ /** Primary: agentId -> AgentEntry */
98
+ private readonly agents;
99
+ /** Secondary: label -> Set<agentId> (reverse index for label-based queries) */
100
+ private readonly labelIndex;
101
+ /** Reverse: ws -> agentId (for fast lookup on WS events) */
102
+ private readonly wsToAgentId;
103
+ /**
104
+ * Reverse: tokenId -> Set<agentId> (for synchronous revocation kicks).
105
+ *
106
+ * Populated when `register()` is called with a non-null `tokenId`,
107
+ * cleaned up by `removeFromIndexes()` on `unregister()` /
108
+ * re-registration. `disconnectByTokenId(tokenId)` walks the matching
109
+ * set, closes each WS, and unregisters the entry — closing the
110
+ * gap where a revoked token's in-flight WS retained data-plane
111
+ * authority until the agent itself disconnected.
112
+ */
113
+ private readonly tokenIdIndex;
114
+ /**
115
+ * Per-tokenId TTL kick timer, keyed by `tokenId`. Scheduled by
116
+ * `scheduleExpiryKick(tokenId, expiresAt)` at agent register-time
117
+ * when the auth token has a non-null `expires_at`. Fires
118
+ * `disconnectByTokenId(tokenId)` when the token's TTL elapses, and
119
+ * is cleared when (a) the timer fires, (b) `disconnectByTokenId` is
120
+ * called explicitly via revocation (no double-kick when revoke
121
+ * races TTL), or (c) the last agent under the tokenId unregisters
122
+ * naturally (avoid timer leaks on long-lived registries).
123
+ *
124
+ * Idempotent: re-scheduling the same tokenId is a no-op as long as
125
+ * a timer is still queued — a token's `expires_at` doesn't shift
126
+ * across reconnects of the same agent. Closes the sister gap
127
+ * to the revocation finding (`agent-token-revocation-stale-ws`,
128
+ * fixed in `993bc3d9d`) where natural TTL expiration had no
129
+ * propagation path to in-flight WS connections.
130
+ */
131
+ private readonly tokenExpiryTimers;
132
+ /**
133
+ * Register an agent. If the agentId already exists, updates the existing
134
+ * entry (agent reconnection scenario).
135
+ */
136
+ register(agentId: string, ws: WsLike, labels: string[], platform?: string, arch?: string, version?: string, maxConcurrency?: number, metadata?: AgentMetadata): void;
137
+ /**
138
+ * Unregister an agent by ID. Removes from all indexes.
139
+ * @returns The removed AgentEntry, or undefined if not found.
140
+ */
141
+ unregister(agentId: string): AgentEntry | undefined;
142
+ /**
143
+ * Unregister an agent by its WebSocket reference (for disconnect handling).
144
+ * @returns The removed AgentEntry, or undefined if not found.
145
+ */
146
+ unregisterByWs(ws: WsLike): AgentEntry | undefined;
147
+ /**
148
+ * Close every WS authenticated under `tokenId`, send a final
149
+ * `auth.failure` message, then unregister the entry. Returns the
150
+ * count of kicked agents.
151
+ *
152
+ * Closes the gap on the agent->orchestrator leg: when an admin
153
+ * revokes a token via `DELETE /api/v1/agent-tokens/:id`, the route
154
+ * calls this synchronously after `tokenStore.revoke(id)` so the
155
+ * in-flight WS loses data-plane authority before the handler
156
+ * returns.
157
+ *
158
+ * The WS close code is `WS_CLOSE_AGENT_AUTH_FAILED` (4010); the
159
+ * agent's reconnect loop treats both the `auth.failure` message and
160
+ * this close code as permanent and stops retrying.
161
+ */
162
+ disconnectByTokenId(tokenId: string): number;
163
+ /**
164
+ * Schedule a one-shot TTL kick for `tokenId` at `expiresAt`. When
165
+ * the timer fires (or if `expiresAt` is already past), every
166
+ * in-flight WS authenticated under the token is closed via
167
+ * `disconnectByTokenId`.
168
+ *
169
+ * Idempotent per `tokenId`: if a timer is already scheduled for
170
+ * this token, the call is a no-op. A token's `expires_at` doesn't
171
+ * change across reconnects, so re-scheduling would just re-arm the
172
+ * same trigger.
173
+ *
174
+ * Caller is the agent WS handler at register-time, when the token's
175
+ * `agent_tokens.expires_at` column is non-null. Static tokens have
176
+ * `expires_at = null` and are skipped at the call site (they have
177
+ * no TTL by design). Closes the sister gap to the revocation
178
+ * finding (`agent-token-revocation-stale-ws`, fixed in `993bc3d9d`)
179
+ * where natural TTL expiration had no propagation path to
180
+ * in-flight WS connections.
181
+ */
182
+ scheduleExpiryKick(tokenId: string, expiresAt: Date): void;
183
+ /**
184
+ * Find available agents that match ALL required labels.
185
+ * An agent is available when it has capacity (activeJobs < maxConcurrency).
186
+ *
187
+ * In addition to the subset + exclusion filters, every label declared in
188
+ * the agent's `mandatoryLabels` must appear in `requiredLabels`. This is
189
+ * the agent-side mirror of the scaler-side mandatory-labels gate
190
+ * (`findBackendForLabels`). Without it, a queued job whose `runsOn` is a
191
+ * subset of a gated agent's labels but does not list the gate label
192
+ * would be drained onto that agent the next time `onAgentAvailable`
193
+ * fires — sidestepping the opt-in semantics the gate is meant to enforce.
194
+ *
195
+ * @param requiredLabels - All labels the agent must have (intersection semantics).
196
+ * @returns Array of matching available AgentEntry objects.
197
+ */
198
+ findAvailable(requiredLabels: string[], excludeLabels?: string[]): AgentEntry[];
199
+ /**
200
+ * Check if ANY registered agent matches the required labels, regardless of capacity.
201
+ * Used to decide whether to queue (agent exists but busy) vs reject (no agent at all).
202
+ *
203
+ * Applies the same `mandatoryLabels` gate as `findAvailable` — a gated
204
+ * agent only counts as "matching" when every label in its
205
+ * `mandatoryLabels` is present in `requiredLabels`. Without this, the
206
+ * dispatcher's `queued-no-backend` decision in `dispatch()` would treat
207
+ * an off-gate gated agent as "matching but busy" and skip the peer
208
+ * reroute path even though the local agent can never accept the job.
209
+ */
210
+ hasMatchingAgent(requiredLabels: string[], excludeLabels?: string[]): boolean;
211
+ /**
212
+ * Internal helper: intersect the per-label candidate sets to find agentIds
213
+ * that satisfy `requiredLabels`. Returns `null` when any required label
214
+ * matches zero agents (so callers can short-circuit). Returns an empty
215
+ * Set on `requiredLabels.length === 0` since the caller decides the
216
+ * walk strategy in that case.
217
+ */
218
+ private intersectLabelCandidates;
219
+ /**
220
+ * Increment activeJobs for an agent.
221
+ * @returns false if agent not found.
222
+ */
223
+ incrementActiveJobs(agentId: string): boolean;
224
+ /**
225
+ * Decrement activeJobs for an agent (min 0).
226
+ * @returns false if agent not found.
227
+ */
228
+ decrementActiveJobs(agentId: string): boolean;
229
+ /**
230
+ * Update the last heartbeat timestamp for an agent.
231
+ */
232
+ updateHeartbeat(agentId: string): boolean;
233
+ /**
234
+ * Get a single agent entry by ID.
235
+ */
236
+ get(agentId: string): AgentEntry | undefined;
237
+ /**
238
+ * Get an agent entry by its WebSocket reference.
239
+ */
240
+ getByWs(ws: WsLike): AgentEntry | undefined;
241
+ /**
242
+ * Total number of registered agents.
243
+ */
244
+ getActiveCount(): number;
245
+ /**
246
+ * Iterator over all agent entries (for heartbeat checks, etc).
247
+ */
248
+ getAllEntries(): IterableIterator<AgentEntry>;
249
+ /**
250
+ * Remove an agent from the WS reverse map and label index.
251
+ * Does NOT remove from the primary agents map.
252
+ */
253
+ private removeFromIndexes;
254
+ }
255
+ //# sourceMappingURL=registry.d.ts.map