@kici-dev/orchestrator 0.1.27 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. package/dist/__test-helpers__/mock-db.d.ts +2 -0
  2. package/dist/agent/dispatcher.d.ts +52 -2
  3. package/dist/agent/host-roster-reaper.d.ts +1 -2
  4. package/dist/agent/host-roster.d.ts +34 -0
  5. package/dist/agent/ownership-refusal.d.ts +12 -0
  6. package/dist/agent/ownership-tracker.d.ts +64 -16
  7. package/dist/agent/token-store.d.ts +13 -0
  8. package/dist/agent-packaging/availability.d.ts +27 -0
  9. package/dist/agent-packaging/build-package.d.ts +16 -0
  10. package/dist/agent-packaging/download.d.ts +30 -0
  11. package/dist/agent-packaging/index.d.ts +9 -0
  12. package/dist/agent-packaging/install-closure.d.ts +30 -0
  13. package/dist/agent-packaging/node-binary.d.ts +26 -0
  14. package/dist/agent-packaging/refresh.d.ts +50 -0
  15. package/dist/agent-packaging/store.d.ts +15 -0
  16. package/dist/agent-packaging/upload.d.ts +24 -0
  17. package/dist/app-on-error.d.ts +29 -0
  18. package/dist/app.d.ts +56 -4
  19. package/dist/artifacts/artifact-store.d.ts +233 -0
  20. package/dist/artifacts/failure-messages.d.ts +46 -0
  21. package/dist/audit/access-log.d.ts +18 -1
  22. package/dist/cache/dep-cache.d.ts +15 -0
  23. package/dist/cache/user-cache.d.ts +37 -0
  24. package/dist/cancel/cancel-run.d.ts +10 -3
  25. package/dist/cancel/dashboard-cancel-handler.d.ts +19 -0
  26. package/dist/cli/api-client.d.ts +44 -1
  27. package/dist/cli/commands/agent-package.d.ts +34 -0
  28. package/dist/cli/commands/check-run.d.ts +26 -0
  29. package/dist/cli/commands/cluster-settings.d.ts +55 -0
  30. package/dist/cli/commands/dashboard-encryption-key.d.ts +3 -0
  31. package/dist/cli/commands/db-backup.d.ts +71 -0
  32. package/dist/cli/commands/orchestrator-service/drain.d.ts +31 -0
  33. package/dist/cli/commands/orchestrator-service/index.d.ts +7 -4
  34. package/dist/cli/commands/orchestrator-service/install-env.d.ts +58 -0
  35. package/dist/cli/commands/secret.d.ts +45 -1
  36. package/dist/cli/commands/shared/admin-cli-access-log.d.ts +46 -0
  37. package/dist/cli/commands/shared/versioned-upgrade.d.ts +65 -2
  38. package/dist/cli/commands/signing-key.d.ts +3 -0
  39. package/dist/cli/commands/source.d.ts +12 -0
  40. package/dist/cli/commands/token.d.ts +9 -0
  41. package/dist/cli/commands/trust-policy.d.ts +48 -0
  42. package/dist/cli/join.d.ts +1 -1
  43. package/dist/cli/service/index.d.ts +2 -2
  44. package/dist/cli/service/instance/manifest.d.ts +17 -0
  45. package/dist/cli/service/instance/resolve.d.ts +11 -0
  46. package/dist/cli/wizard/orchestrator-wizard.d.ts +39 -11
  47. package/dist/cli.js +9921 -3409
  48. package/dist/cluster/cluster-settings-reader.d.ts +78 -0
  49. package/dist/cluster/coordinator.d.ts +81 -9
  50. package/dist/cluster/join-client.d.ts +1 -1
  51. package/dist/cluster/leader-gated-scheduler.d.ts +50 -0
  52. package/dist/cluster/orphan-recovery.d.ts +14 -0
  53. package/dist/cluster/peer-client.d.ts +12 -2
  54. package/dist/cluster/peer-handler.d.ts +15 -4
  55. package/dist/cluster/peer-registry.d.ts +12 -0
  56. package/dist/cluster/verified-issuer-poller.d.ts +11 -0
  57. package/dist/cluster/verified-issuer.d.ts +63 -0
  58. package/dist/cold-store/tables/access-log.d.ts +1 -1
  59. package/dist/cold-store/tables/event-log.d.ts +1 -1
  60. package/dist/cold-store/tables/execution-jobs.d.ts +1 -1
  61. package/dist/cold-store/tables/execution-runs.d.ts +1 -1
  62. package/dist/cold-store/tables/execution-steps.d.ts +1 -1
  63. package/dist/cold-store/tables/secret-audit-log.d.ts +1 -1
  64. package/dist/config/loader.d.ts +1 -1
  65. package/dist/config/resolver.d.ts +2 -1
  66. package/dist/config/schema.d.ts +9 -6
  67. package/dist/config/types.d.ts +5 -2
  68. package/dist/config.d.ts +366 -53
  69. package/dist/contexts/context-store.d.ts +21 -8
  70. package/dist/contexts/glob-specificity.d.ts +30 -0
  71. package/dist/contexts/held-runs.d.ts +51 -19
  72. package/dist/contexts/protection/aggregate.d.ts +2 -2
  73. package/dist/contexts/protection/concurrency-gate.d.ts +0 -3
  74. package/dist/contexts/protection/reviewer-gate.d.ts +0 -3
  75. package/dist/contexts/protection/satisfiability.d.ts +1 -1
  76. package/dist/contexts/protection/trust-gate.d.ts +0 -3
  77. package/dist/contexts/protection/wait-timer-gate.d.ts +0 -3
  78. package/dist/cron/cron-scheduler.d.ts +24 -4
  79. package/dist/cron/cron-store.d.ts +21 -7
  80. package/dist/dashboard/attestation-filters.d.ts +92 -74
  81. package/dist/dashboard/handler.d.ts +35 -1
  82. package/dist/db/migration-test-harness.d.ts +41 -0
  83. package/dist/db/migrations/069_reroute_tunables.d.ts +21 -0
  84. package/dist/db/migrations/070_execution_runs_failure_class.d.ts +4 -0
  85. package/dist/db/migrations/071_batch_accumulation.d.ts +26 -0
  86. package/dist/db/migrations/072_dispatch_queue_run_id_index.d.ts +15 -0
  87. package/dist/db/migrations/073_org_settings_ingest_concurrency.d.ts +13 -0
  88. package/dist/db/migrations/074_normalize_zero_concurrency_limit.d.ts +13 -0
  89. package/dist/db/migrations/075_ingest_overflow_buffer.d.ts +16 -0
  90. package/dist/db/migrations/076_artifacts.d.ts +19 -0
  91. package/dist/db/migrations/077_backup_runs.d.ts +13 -0
  92. package/dist/db/migrations/078_org_settings_backup_staleness.d.ts +12 -0
  93. package/dist/db/migrations/079_org_settings_scaler_spawn_timeout.d.ts +14 -0
  94. package/dist/db/migrations/080_cluster_settings.d.ts +17 -0
  95. package/dist/db/migrations/081_org_settings_queue_timeout.d.ts +19 -0
  96. package/dist/db/migrations/082_host_s3_reachable.d.ts +16 -0
  97. package/dist/db/migrations/083_org_settings_artifact_caps.d.ts +18 -0
  98. package/dist/db/migrations/084_orchestrator_signing_keys.d.ts +20 -0
  99. package/dist/db/migrations/085_cluster_settings_reroute_flap_grace_ms.d.ts +12 -0
  100. package/dist/db/migrations/086_cluster_settings_max_fanout_hosts.d.ts +12 -0
  101. package/dist/db/migrations/087_cluster_settings_event_router_rate_limit.d.ts +12 -0
  102. package/dist/db/migrations/088_cluster_settings_cache_max_tarball_bytes.d.ts +12 -0
  103. package/dist/db/migrations/089_cluster_settings_cache_ttl_days.d.ts +12 -0
  104. package/dist/db/migrations/090_cluster_settings_concurrency_wait_timeout_ms.d.ts +12 -0
  105. package/dist/db/migrations/091_cluster_settings_agent_token_ttl_ms.d.ts +12 -0
  106. package/dist/db/migrations/092_cluster_settings_version.d.ts +16 -0
  107. package/dist/db/migrations/093_org_settings_sandbox_allowlist.d.ts +4 -0
  108. package/dist/db/migrations/094_dashboard_encryption_keys.d.ts +21 -0
  109. package/dist/db/migrations/095_dashboard_write_policy_tristate.d.ts +20 -0
  110. package/dist/db/migrations/096_multi_schedule_cron_last_fired.d.ts +4 -0
  111. package/dist/db/migrations/097_execution_runs_pr_number.d.ts +4 -0
  112. package/dist/db/migrations/098_execution_runs_customer_id.d.ts +4 -0
  113. package/dist/db/migrations/099_cluster_settings_dashboard_verified_issuer.d.ts +21 -0
  114. package/dist/db/migrations/100_held_runs_hold_type_vocabulary.d.ts +31 -0
  115. package/dist/db/migrations/101_contexts_hold_expiry_drop_default.d.ts +31 -0
  116. package/dist/db/migrations/102_dispatch_queue_agent_id.d.ts +20 -0
  117. package/dist/db/migrations/103_cluster_settings_ownership_db_check_timeout_ms.d.ts +20 -0
  118. package/dist/db/migrations/104_check_run_terminal_sent.d.ts +22 -0
  119. package/dist/db/migrations/105_org_trust_policy.d.ts +19 -0
  120. package/dist/db/migrations/106_cluster_settings_check_run_tracking_ttl_days.d.ts +18 -0
  121. package/dist/db/migrations/107_check_run_tracking_updated_at_index.d.ts +23 -0
  122. package/dist/db/migrations/108_unroutable_fast_fail.d.ts +4 -0
  123. package/dist/db/repos/dashboard-encryption-keys-repo.d.ts +48 -0
  124. package/dist/db/repos/signing-keys-repo.d.ts +34 -0
  125. package/dist/db/types.d.ts +441 -7
  126. package/dist/deployment/deployment-identity.d.ts +87 -2
  127. package/dist/diagnostics/checks/backup.d.ts +18 -0
  128. package/dist/diagnostics/checks/index.d.ts +2 -1
  129. package/dist/diagnostics/fleet-collector.d.ts +1 -1
  130. package/dist/drain/drain-controller.d.ts +52 -0
  131. package/dist/events/batch-accumulator.d.ts +63 -0
  132. package/dist/events/circuit-breaker.d.ts +9 -3
  133. package/dist/events/event-emitter.d.ts +31 -0
  134. package/dist/events/event-retry-scanner.d.ts +12 -2
  135. package/dist/events/event-router.d.ts +29 -0
  136. package/dist/firecracker/host-network.d.ts +2 -0
  137. package/dist/firecracker/net-interfaces.d.ts +14 -0
  138. package/dist/github-app-name-refresher/github-app-name-refresher.d.ts +18 -8
  139. package/dist/index.d.ts +2 -0
  140. package/dist/index.js +654 -29
  141. package/dist/lockfile-cache.d.ts +4 -0
  142. package/dist/lockfile-validate.d.ts +16 -9
  143. package/dist/metrics/prometheus.d.ts +113 -15
  144. package/dist/oidc/aws-kms-signer.d.ts +37 -0
  145. package/dist/oidc/command-signer.d.ts +23 -0
  146. package/dist/oidc/db-signer.d.ts +48 -0
  147. package/dist/oidc/id-token-claims.d.ts +22 -9
  148. package/dist/oidc/jwt.d.ts +5 -2
  149. package/dist/oidc/local-dev-signer.d.ts +1 -1
  150. package/dist/oidc/oidc-mint-registration.d.ts +27 -11
  151. package/dist/oidc/orchestrator-mint.d.ts +97 -0
  152. package/dist/oidc/orchestrator-signer-factory.d.ts +33 -0
  153. package/dist/oidc/reconcile-signing-key.d.ts +21 -0
  154. package/dist/oidc/signer.d.ts +25 -0
  155. package/dist/oidc/signing-key-status.d.ts +23 -0
  156. package/dist/orchestrator-core.d.ts +42 -2
  157. package/dist/pipeline/decorating-secret-resolver.d.ts +3 -2
  158. package/dist/pipeline/dispatch-matched-workflow.d.ts +41 -0
  159. package/dist/pipeline/install-secrets-resolver.d.ts +12 -1
  160. package/dist/pipeline/manual-schedule.d.ts +20 -13
  161. package/dist/pipeline/pending-workflow-context.d.ts +1 -1
  162. package/dist/pipeline/process-webhook.d.ts +57 -2
  163. package/dist/pipeline/processor.d.ts +44 -8
  164. package/dist/pipeline/rerun.d.ts +12 -13
  165. package/dist/pipeline/resolve-sandbox-grant.d.ts +28 -0
  166. package/dist/pipeline/route-or-dispatch-jobs.d.ts +71 -0
  167. package/dist/pipeline/sandbox-allowlist-reader.d.ts +33 -0
  168. package/dist/policy/dashboard-write-policy.d.ts +9 -4
  169. package/dist/provenance/backfill-run.d.ts +1 -0
  170. package/dist/provenance/trust-root.d.ts +13 -0
  171. package/dist/providers/generic/normalizer.d.ts +1 -1
  172. package/dist/providers/github/auth.d.ts +1 -1
  173. package/dist/providers/github/changed-files.d.ts +14 -6
  174. package/dist/providers/github/check-status-poster.d.ts +19 -3
  175. package/dist/providers/github/contributor-resolver.d.ts +1 -1
  176. package/dist/providers/github/lock-file.d.ts +1 -1
  177. package/dist/providers/github/normalizer.d.ts +1 -1
  178. package/dist/providers/github/repo-url.d.ts +1 -1
  179. package/dist/providers/local/lock-file-fetcher.d.ts +1 -1
  180. package/dist/providers/local/normalizer.d.ts +1 -1
  181. package/dist/providers/local/repo-url-builder.d.ts +1 -1
  182. package/dist/providers/universal-git/changed-files.d.ts +8 -7
  183. package/dist/providers/universal-git/clone-token.d.ts +1 -1
  184. package/dist/providers/universal-git/config.d.ts +4 -4
  185. package/dist/providers/universal-git/index.d.ts +5 -1
  186. package/dist/providers/universal-git/lock-file.d.ts +6 -1
  187. package/dist/providers/universal-git/normalizer.d.ts +1 -1
  188. package/dist/providers/universal-git/repo-url.d.ts +1 -1
  189. package/dist/queue/bootstrap.d.ts +5 -0
  190. package/dist/queue/cleanup.d.ts +72 -9
  191. package/dist/queue/job-queue.d.ts +141 -14
  192. package/dist/queue/scheduled-job.d.ts +3 -2
  193. package/dist/queue/terminalize-unroutable.d.ts +53 -0
  194. package/dist/queue/unroutable-probe.d.ts +52 -0
  195. package/dist/registration/registration-index.d.ts +1 -1
  196. package/dist/reporting/agent-failure-category.d.ts +4 -1
  197. package/dist/reporting/check-run-reporter.d.ts +34 -14
  198. package/dist/reporting/check-run-tracking-store.d.ts +70 -8
  199. package/dist/reporting/execution-tracker.d.ts +156 -10
  200. package/dist/reporting/fs-log-storage.d.ts +31 -2
  201. package/dist/reporting/job-check-run-completion.d.ts +50 -0
  202. package/dist/reporting/log-chunk-sink.d.ts +47 -0
  203. package/dist/reporting/log-retention.d.ts +16 -0
  204. package/dist/reporting/log-storage.d.ts +64 -4
  205. package/dist/reporting/log-writer.d.ts +22 -7
  206. package/dist/reporting/peer-log-normalize.d.ts +14 -0
  207. package/dist/reporting/run-aggregator.d.ts +50 -33
  208. package/dist/reporting/s3-log-storage.d.ts +102 -8
  209. package/dist/routes/admin-auth.d.ts +90 -0
  210. package/dist/routes/admin-cluster-settings.d.ts +31 -0
  211. package/dist/routes/admin-events.d.ts +3 -0
  212. package/dist/routes/admin-orchestrator-drain.d.ts +35 -0
  213. package/dist/routes/admin-runs.d.ts +9 -0
  214. package/dist/routes/admin-sources.d.ts +7 -0
  215. package/dist/routes/admin-trust-policy.d.ts +49 -0
  216. package/dist/routes/admin.d.ts +15 -1
  217. package/dist/routes/github-webhook.d.ts +9 -3
  218. package/dist/routes/provenance-oidc.d.ts +38 -0
  219. package/dist/routes/verify-attestation.d.ts +21 -0
  220. package/dist/scaler/bare-metal-backend.d.ts +9 -2
  221. package/dist/scaler/config.d.ts +25 -4
  222. package/dist/scaler/container-backend.d.ts +9 -1
  223. package/dist/scaler/firecracker-backend.d.ts +29 -2
  224. package/dist/scaler/index.d.ts +1 -1
  225. package/dist/scaler/manager.d.ts +166 -8
  226. package/dist/scaler/pending-scale-sweeper.d.ts +35 -0
  227. package/dist/scaler/types.d.ts +75 -6
  228. package/dist/secrets/backend-registry.d.ts +32 -1
  229. package/dist/secrets/dashboard-encryption-key.d.ts +48 -0
  230. package/dist/secrets/ephemeral-keys.d.ts +16 -0
  231. package/dist/secrets/pg-secret-store.d.ts +10 -0
  232. package/dist/secrets/rbac.d.ts +5 -1
  233. package/dist/secrets/routing-key-scope.d.ts +6 -0
  234. package/dist/secrets/scope-routing.d.ts +126 -0
  235. package/dist/secrets/secret-resolver.d.ts +1 -14
  236. package/dist/secrets/token-manager.d.ts +5 -1
  237. package/dist/security/contributor-cache.d.ts +9 -1
  238. package/dist/security/trust-policy-gate.d.ts +117 -0
  239. package/dist/security/trust-policy-store.d.ts +78 -0
  240. package/dist/server.js +36074 -25052
  241. package/dist/sources/source-manager.d.ts +24 -0
  242. package/dist/stale-detector/stale-run-detector.d.ts +7 -0
  243. package/dist/standalone.js +35203 -25387
  244. package/dist/storage/filesystem.d.ts +17 -0
  245. package/dist/storage/key-discriminator.d.ts +20 -0
  246. package/dist/storage/s3.d.ts +2 -0
  247. package/dist/storage/types.d.ts +16 -0
  248. package/dist/webhook/dedup.d.ts +9 -1
  249. package/dist/webhook/event-log.d.ts +13 -2
  250. package/dist/webhook/generic-sources-listener.d.ts +4 -0
  251. package/dist/webhook/ingest-admission.d.ts +140 -0
  252. package/dist/webhook/ingest-overflow-buffer.d.ts +27 -0
  253. package/dist/webhook/ingest-overflow-replayer.d.ts +49 -0
  254. package/dist/webhook/ingest-overflow-types.d.ts +73 -0
  255. package/dist/webhook/loop-lag-source.d.ts +40 -0
  256. package/dist/webhook/observed-relay-guard.d.ts +40 -0
  257. package/dist/webhook/org-ingest-cap-reader.d.ts +24 -0
  258. package/dist/webhook/register-source-bundle.d.ts +3 -0
  259. package/dist/webhook/relay-reinject.d.ts +43 -0
  260. package/dist/worker/in-memory-job-queue.d.ts +8 -3
  261. package/dist/worker-core.d.ts +10 -0
  262. package/dist/ws/agent-api-registry.d.ts +20 -0
  263. package/dist/ws/agent-handler.d.ts +63 -7
  264. package/dist/ws/bringup-api.d.ts +99 -0
  265. package/dist/ws/dashboard-context-handler.d.ts +28 -10
  266. package/dist/ws/dashboard-run-state-handler.d.ts +31 -0
  267. package/dist/ws/failure-messages.d.ts +29 -0
  268. package/dist/ws/oidc-token-relay.d.ts +9 -0
  269. package/dist/ws/ownership-gate.d.ts +22 -0
  270. package/dist/ws/platform-client.d.ts +96 -1
  271. package/dist/ws/replay-chunker.d.ts +37 -0
  272. package/installer-image-digests.json +3 -3
  273. package/package.json +22 -21
  274. package/sbom.spdx.json +1240 -1788
package/dist/app.d.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  * - Request ID and logging middleware
11
11
  * - 25MB body size limit
12
12
  *
13
- * Pattern follows packages/platform/src/app.ts: returns { app, injectWebSocket }.
13
+ * Pattern follows packages/platform/src/app.ts: returns { app, wss }.
14
14
  */
15
15
  import type { Kysely } from 'kysely';
16
16
  import type pg from 'pg';
@@ -21,6 +21,7 @@ import type { Database } from './db/types.js';
21
21
  import type { AgentRegistry } from './agent/registry.js';
22
22
  import type { Dispatcher } from './agent/dispatcher.js';
23
23
  import type { RunCoordinator } from './cluster/coordinator.js';
24
+ import type { ClusterSettingsReader } from './cluster/cluster-settings-reader.js';
24
25
  import type { PeerRegistry } from './cluster/peer-registry.js';
25
26
  import type { JobQueue } from './queue/job-queue.js';
26
27
  import type { DedupCache } from './webhook/dedup.js';
@@ -32,6 +33,7 @@ import type { SourceCache } from './cache/index.js';
32
33
  import type { BuildCoordinator } from './cache/index.js';
33
34
  import type { DepCache } from './cache/index.js';
34
35
  import type { UserCache } from './cache/index.js';
36
+ import type { ArtifactStore } from './artifacts/artifact-store.js';
35
37
  import type { DispatchCacheRefTracker } from './cache/index.js';
36
38
  import type { PendingBuildTracker } from './cache/index.js';
37
39
  import type { PendingInitTracker } from './cache/index.js';
@@ -39,7 +41,7 @@ import type { PendingDynamicTracker } from './cache/index.js';
39
41
  import type { CacheStorage } from './storage/types.js';
40
42
  import type { ProvenanceTrustRoot } from './provenance/trust-root.js';
41
43
  import type { LocalSigner } from './oidc/local-dev-signer.js';
42
- import { type CheckRunReporter } from './reporting/check-run-reporter.js';
44
+ import type { CheckRunReporter } from './reporting/check-run-reporter.js';
43
45
  import type { ExecutionTracker } from './reporting/execution-tracker.js';
44
46
  import type { LogWriter } from './reporting/log-writer.js';
45
47
  import type { LogStorage } from './reporting/log-storage.js';
@@ -62,6 +64,12 @@ import type { RegistrationStore } from './registration/registration-store.js';
62
64
  import type { RegistrationIndex } from './registration/registration-index.js';
63
65
  import type { CronScheduler } from './cron/cron-scheduler.js';
64
66
  import { type ConfigRouteDeps } from './routes/admin-config.js';
67
+ import { WebhookIngestOutcome } from './pipeline/process-webhook.js';
68
+ import type { IngestOverflowBuffer } from './webhook/ingest-overflow-buffer.js';
69
+ import { type OverflowDelivery } from './webhook/ingest-overflow-types.js';
70
+ import type { IngestAdmissionController } from './webhook/ingest-admission.js';
71
+ import type { OrgIngestCapReader } from './webhook/org-ingest-cap-reader.js';
72
+ import type { SandboxAllowListReader } from './pipeline/sandbox-allowlist-reader.js';
65
73
  import type { ConcurrencyGroupTracker } from './concurrency/group-tracker.js';
66
74
  import type { ConcurrencyQueueManager } from './concurrency/queue-manager.js';
67
75
  import type { EventRouter } from './events/event-router.js';
@@ -85,6 +93,8 @@ export interface AppDependencies {
85
93
  config: AppConfig;
86
94
  db: Kysely<Database>;
87
95
  pool: pg.Pool;
96
+ /** Fleet-wide settings reader; threads the live lock-file cap into warm-added universal-git sources. */
97
+ clusterSettings?: ClusterSettingsReader;
88
98
  registry: AgentRegistry;
89
99
  /**
90
100
  * Warmth latch surfaced on `GET /ready`. Returns `true` only once the
@@ -100,6 +110,22 @@ export interface AppDependencies {
100
110
  lockFileCache: LockFileCache;
101
111
  providerRegistry: ProviderRegistry;
102
112
  platformClient?: PlatformClient;
113
+ /**
114
+ * Webhook-ingest admission controller (shared with the WS relay path). When
115
+ * present, the HTTP ingest closure admits before running the pipeline and
116
+ * sheds (429 + Retry-After) when the controller is saturated.
117
+ */
118
+ ingestController?: IngestAdmissionController;
119
+ /** Resolves the fairness key + per-org cap for a routing key (cached, DB-degraded). */
120
+ ingestCapReader?: OrgIngestCapReader;
121
+ /** Reads the per-org container-sandbox escape-hatch allow-list at dispatch (uncached, DB-degraded). */
122
+ sandboxAllowListReader?: SandboxAllowListReader;
123
+ /**
124
+ * Durable overflow buffer (capture side). When present and
125
+ * `config.ingestOverflowEnabled`, a shed HTTP delivery is additively persisted
126
+ * for later replay; absent → capture disabled.
127
+ */
128
+ ingestOverflowBuffer?: IngestOverflowBuffer;
103
129
  /**
104
130
  * Fulfil deferred attestations on demand (mints in this process, which owns
105
131
  * the Platform WS). Backs `POST /api/v1/admin/attestations/retry`. Wired only
@@ -122,6 +148,8 @@ export interface AppDependencies {
122
148
  depCache?: DepCache;
123
149
  /** User-facing cache (ctx.cache / declarative job-step cache). Optional — requires cache storage. */
124
150
  userCache?: UserCache;
151
+ /** User-facing artifact store (ctx.artifacts). Optional — requires cache storage + DB. */
152
+ artifactStore?: ArtifactStore;
125
153
  /**
126
154
  * Server-side jobId -> user-cache-namespace store. Written at dispatch time
127
155
  * (orchestrator-core's buildOnDispatch); read by the agent-WS handler to
@@ -140,6 +168,29 @@ export interface AppDependencies {
140
168
  * is registered so `ctx.kici.oidc.token()` mints a `kici-local` dev token.
141
169
  */
142
170
  localOidcSigner?: LocalSigner;
171
+ /**
172
+ * Orchestrator-owned provenance signing (Phase 1 root of trust). Present when
173
+ * `KICI_ORCHESTRATOR_PROVENANCE_ISSUER` is configured: the orchestrator mints +
174
+ * signs identity tokens locally with its own ES256 key, and serves its own
175
+ * OIDC discovery + JWKS + native verify endpoint. `resolveOrchestratorSigner`
176
+ * lazily reconciles the active signing key (leader-election-race-safe); the
177
+ * repo backs the `.well-known` + verify routes.
178
+ */
179
+ provenanceSigning?: {
180
+ issuer: string;
181
+ resolveSigner: () => Promise<import('./oidc/signer.js').Signer | null>;
182
+ repo: import('./db/repos/signing-keys-repo.js').OrchestratorSigningKeyRepo;
183
+ };
184
+ /**
185
+ * Dashboard-encryption (X25519) key custody. Present whenever KICI_SECRET_KEY
186
+ * is configured. `repo` backs the JWKS enc-key publication; `resolve` lazily
187
+ * reconciles the active key (leader-election-race-safe) for the WS decrypt
188
+ * handler.
189
+ */
190
+ dashboardEncryption?: {
191
+ repo: import('./db/repos/dashboard-encryption-keys-repo.js').DashboardEncryptionKeyRepo;
192
+ resolve: () => Promise<import('./secrets/dashboard-encryption-key.js').ResolvedDashboardEncryptionKey | null>;
193
+ };
143
194
  /**
144
195
  * Filesystem cache backend handle. Only set when KICI_STORAGE_TYPE is
145
196
  * `filesystem`. Drives the /api/v1/cache/blob/* HTTP route that serves and
@@ -300,11 +351,12 @@ export declare class SourceLocationStore {
300
351
  * Create Hono application with all routes and middleware.
301
352
  *
302
353
  * @param deps - Application dependencies (injected for testability)
303
- * @returns Object with Hono app instance and injectWebSocket function
354
+ * @returns Object with Hono app instance and the configured WebSocket server
304
355
  */
305
356
  export declare function createApp(deps: AppDependencies): {
306
357
  app: import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, import("hono/types").BlankSchema, string, string>;
307
- injectWebSocket: (server: import("http").Server | import("http2").Http2Server | import("http2").Http2SecureServer) => void;
358
+ wss: import("ws").Server<typeof import("ws").WebSocket, typeof import("http").IncomingMessage>;
359
+ reinjectDirect: (d: OverflowDelivery) => Promise<WebhookIngestOutcome>;
308
360
  onSourceLocationsExtracted: (workflowName: string, jobName: string, locations: Array<{
309
361
  file: string;
310
362
  line: number;
@@ -0,0 +1,233 @@
1
+ import type { Kysely } from 'kysely';
2
+ import type { ArtifactRejectReason } from '@kici-dev/engine';
3
+ import type { Database } from '../db/types.js';
4
+ import type { CacheStorage } from '../storage/types.js';
5
+ /**
6
+ * The presigned PUT never landed an object, so there is nothing to record.
7
+ * Distinct from a transient storage/DB error: a caller retrying the commit
8
+ * would keep finding the object absent, so this failure is terminal and is
9
+ * reported straight back to the agent (which fails the workflow step).
10
+ */
11
+ export declare class ArtifactObjectMissingError extends Error {
12
+ readonly storageKey: string;
13
+ constructor(storageKey: string);
14
+ }
15
+ /**
16
+ * The requested artifact name violates the shared name contract. Terminal: the
17
+ * name is fixed for the life of the request, so a retry would fail identically.
18
+ */
19
+ export declare class ArtifactInvalidNameError extends Error {
20
+ constructor(detail: string);
21
+ }
22
+ /**
23
+ * Map a `completeUpload` failure onto a message safe to send to the agent — which
24
+ * runs untrusted workflow code, so the reason reaches the workflow author and its
25
+ * step logs.
26
+ *
27
+ * An invalid-name error already carries a safe message: its constructor formats
28
+ * the schema's own fixed detail, so it passes through unchanged. An object-missing
29
+ * error is a genuinely actionable terminal case and keeps its own category, but
30
+ * the storage key its message embeds does not travel. Anything else is an internal
31
+ * failure the author cannot act on, so it collapses to one literal; the raw
32
+ * exception stays in the orchestrator's own log line.
33
+ */
34
+ export declare function classifyArtifactCommitFailure(err: unknown): string;
35
+ /** Cluster-wide default per-org artifact byte quota: 20 GiB. */
36
+ export declare const DEFAULT_ARTIFACT_QUOTA_BYTES: number;
37
+ /** Cluster-wide default per-artifact TTL: 30 days. */
38
+ export declare const DEFAULT_ARTIFACT_TTL_MS: number;
39
+ /** Cluster-wide default per-artifact size cap: 1 GiB. */
40
+ export declare const DEFAULT_ARTIFACT_MAX_BYTES: number;
41
+ /** Cluster-wide default per-run artifact count cap. */
42
+ export declare const DEFAULT_ARTIFACT_MAX_PER_RUN = 50;
43
+ /**
44
+ * Storage key for a run's named artifact.
45
+ *
46
+ * Injective over names: distinct names always produce distinct keys, so a
47
+ * second upload can never silently overwrite the first while both rows keep
48
+ * their own hash.
49
+ *
50
+ * The trailing discriminator is a hash of the exact name, and it is what keeps
51
+ * the keys apart on a CASE-INSENSITIVE object namespace — the filesystem
52
+ * backend on a macOS or Windows host. There `bundle` and `Bundle` would
53
+ * otherwise be two keys resolving to one file; because their discriminators
54
+ * differ, the keys differ by more than case and stay two objects. That is why
55
+ * the discriminator is wide (see `KEY_DISCRIMINATOR_LENGTH`): under case
56
+ * folding it carries the whole separation on its own. The readable stem is kept
57
+ * so an operator browsing the bucket can still tell which artifact an object
58
+ * is.
59
+ *
60
+ * Hashing the EXACT name rather than the sanitized one is deliberate:
61
+ * sanitizing is many-to-one, so a discriminator over its output would fold
62
+ * `a/b` and `a_b` back together.
63
+ *
64
+ * Changing this format does not strand existing artifacts — the key is
65
+ * persisted in `artifacts.storage_key` and the download paths read that column
66
+ * rather than re-deriving. Only the grant and commit paths derive, and both do
67
+ * so at upload time.
68
+ */
69
+ export declare function artifactStorageKey(runId: string, name: string): string;
70
+ /**
71
+ * Per-org override of the artifact limits, read from `org_settings`. Each field
72
+ * is optional; an undefined field falls back to the cluster-wide default.
73
+ */
74
+ export interface ArtifactOrgLimits {
75
+ quotaBytes?: number;
76
+ ttlMs?: number;
77
+ maxBytes?: number;
78
+ maxPerRun?: number;
79
+ }
80
+ /** Resolves the per-org artifact limits (e.g. an `org_settings` read). */
81
+ export type ArtifactOrgLimitsReader = (customerId: string) => Promise<ArtifactOrgLimits>;
82
+ /** Outcome of a begin-upload grant request. */
83
+ export interface ArtifactBeginUploadResult {
84
+ outcome: 'granted' | 'rejected';
85
+ uploadUrl?: string;
86
+ storageKey?: string;
87
+ reason?: ArtifactRejectReason;
88
+ /**
89
+ * Free-text rejection detail carried when no enforcement `reason` applies —
90
+ * today, a name that violates the artifact-name contract.
91
+ */
92
+ error?: string;
93
+ }
94
+ /** Outcome of a download lookup. */
95
+ export interface ArtifactDownloadResult {
96
+ outcome: 'found' | 'not_found';
97
+ downloadUrl?: string;
98
+ sizeBytes?: number;
99
+ sha256?: string;
100
+ }
101
+ /** A run's artifact as surfaced to the dashboard. */
102
+ export interface ArtifactListEntry {
103
+ name: string;
104
+ jobId: string;
105
+ sizeBytes: number;
106
+ sha256: string;
107
+ createdAt: string;
108
+ /**
109
+ * Presigned GET for the backing object. Present on the run-detail listing
110
+ * (`listForRunWithUrls`); omitted when the object could not be resolved
111
+ * (expired / gone).
112
+ */
113
+ downloadUrl?: string;
114
+ }
115
+ export declare class ArtifactStore {
116
+ private readonly storage;
117
+ private readonly db;
118
+ private readonly defaultQuotaBytes;
119
+ private readonly defaultTtlMs;
120
+ private readonly maxBytes;
121
+ private readonly maxPerRun;
122
+ private readonly orgLimitsReader?;
123
+ constructor(opts: {
124
+ storage: CacheStorage;
125
+ db: Kysely<Database>;
126
+ /** Cluster-wide default quota (env default). */
127
+ quotaBytes?: number;
128
+ /** Cluster-wide default TTL (env default). */
129
+ ttlMs?: number;
130
+ /** Per-artifact size cap. */
131
+ maxBytes?: number;
132
+ /** Per-run artifact count cap. */
133
+ maxPerRun?: number;
134
+ /** Per-org override reader (org_settings). When unset, defaults apply. */
135
+ orgLimitsReader?: ArtifactOrgLimitsReader;
136
+ });
137
+ /**
138
+ * Resolve the effective quota, TTL, per-artifact size cap, and per-run count
139
+ * cap for an org. Each value is the per-org `org_settings` override when set,
140
+ * otherwise the cluster-wide default.
141
+ */
142
+ private resolveLimits;
143
+ /** ISO cutoff for TTL filtering: rows created before this are expired. */
144
+ private cutoff;
145
+ /**
146
+ * Grant or refuse a presigned PUT for a named artifact. Order: name contract →
147
+ * resolve limits → size cap → duplicate name → per-run count cap → org quota.
148
+ * The size cap and per-run count cap are the resolved per-org override when
149
+ * set, otherwise the cluster-wide default. No presigned URL is minted for a
150
+ * request that would violate any gate.
151
+ *
152
+ * The name is checked first, and here rather than only in the SDK, because the
153
+ * agent runs untrusted customer workflow code: a name that bypassed the SDK
154
+ * check would be sanitized onto another name's storage key, letting a second
155
+ * upload overwrite the first object while both rows keep their own hash. A
156
+ * contract violation is not an enforcement rejection, so it carries a
157
+ * free-text `error` and no `reason`.
158
+ */
159
+ beginUpload(args: {
160
+ customerId: string;
161
+ runId: string;
162
+ name: string;
163
+ declaredSizeBytes: number;
164
+ }): Promise<ArtifactBeginUploadResult>;
165
+ /**
166
+ * Commit a completed upload: write the object metadata sidecar, then insert
167
+ * the DB row. The `UNIQUE (run_id, name)` constraint (via onConflict-do-nothing)
168
+ * is the immutability backstop for a racing duplicate that slipped past the
169
+ * pre-mint check.
170
+ *
171
+ * Neither agent-supplied value is trusted: the storage key is re-derived from
172
+ * the server-resolved `runId` + `name`, and the recorded size is the real byte
173
+ * size of the stored object read back from the storage backend. Agents run
174
+ * untrusted customer workflow code, so an echoed key could otherwise point a
175
+ * row at another tenant's object, and a declared size could under-account the
176
+ * per-org quota (a presigned PUT does not bind content length).
177
+ *
178
+ * The name is re-validated here, not only at `beginUpload`: a commit is its
179
+ * own inbound message, so an agent can send one for a name it never got a
180
+ * grant for. Without the check, a non-conforming name would derive the
181
+ * storage key of a *different*, already-committed artifact and record a second
182
+ * row against that same object with its own hash.
183
+ *
184
+ * Throws when the commit cannot be recorded — `ArtifactInvalidNameError` for a
185
+ * name that violates the contract, `ArtifactObjectMissingError` when the
186
+ * presigned PUT never landed an object, or the underlying storage / DB error
187
+ * otherwise. The caller reports the failure back to the agent, which fails the
188
+ * workflow step rather than leaving a green run with no artifact.
189
+ */
190
+ completeUpload(args: {
191
+ customerId: string;
192
+ runId: string;
193
+ jobId: string;
194
+ name: string;
195
+ /** Agent-declared size. Advisory — the stored object is stat'd instead. */
196
+ sizeBytes: number;
197
+ sha256: string;
198
+ /** Agent-echoed key. Ignored — the key is re-derived server-side. */
199
+ storageKey: string;
200
+ }): Promise<void>;
201
+ /** Load a single artifact row (any TTL state) for a run + name. */
202
+ private loadRow;
203
+ private isExpired;
204
+ /**
205
+ * Resolve a named artifact of a run to a presigned GET + its size/sha256, or
206
+ * `not_found` when the name was never uploaded, has expired, or its backing
207
+ * object is gone.
208
+ */
209
+ download(args: {
210
+ customerId: string;
211
+ runId: string;
212
+ name: string;
213
+ }): Promise<ArtifactDownloadResult>;
214
+ /** ISO string for a row's created_at (Date or already-string). */
215
+ private createdAtIso;
216
+ /** Load a run's non-expired artifact rows, newest first, given the org TTL. */
217
+ private loadRunRows;
218
+ /**
219
+ * List a run's non-expired artifacts with a presigned GET per entry, newest
220
+ * first — the shape the dashboard run-detail panel renders. Resolves the org
221
+ * TTL once, then mints one presigned URL per row; a row whose backing object
222
+ * is gone lists its metadata with `downloadUrl` omitted rather than being
223
+ * dropped. Also reports the presigned-URL expiry (seconds) — the storage
224
+ * backend's `getUrl` signature TTL, NOT the artifact-retention `ttlMs` — so
225
+ * the dashboard can refresh a rendered `downloadUrl` before its signature
226
+ * expires.
227
+ */
228
+ listForRunWithUrls(customerId: string, runId: string): Promise<{
229
+ artifacts: ArtifactListEntry[];
230
+ downloadUrlExpiresInSeconds: number;
231
+ }>;
232
+ }
233
+ //# sourceMappingURL=artifact-store.d.ts.map
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Safe, fixed messages the orchestrator sends to the agent (and through it to
3
+ * the workflow author) when a user-artifact request is refused for something
4
+ * other than an enforcement gate or a genuine lookup miss — an internal failure,
5
+ * or a request that violates the artifact-name contract.
6
+ *
7
+ * These are presentation strings, not a wire vocabulary: the protocol carries
8
+ * them in the free-text `error` field of `artifacts.upload.response` /
9
+ * `artifacts.download.response` and in the free-text `reason` field of
10
+ * `artifacts.upload.complete.ack`, so an orchestrator is free to reword them
11
+ * without any agent-side change. They live here — rather than inline at each
12
+ * send site — so the handler and its tests share one definition.
13
+ *
14
+ * Raw exception text is never one of these. Exceptions stay in the
15
+ * orchestrator's own logs; the author sees only "this is an orchestrator or
16
+ * configuration problem", never a database endpoint or a stack frame.
17
+ */
18
+ export declare const ArtifactInternalFailure: Readonly<{
19
+ /** Upload requested but the orchestrator has no artifact store configured. */
20
+ readonly uploadNotConfigured: 'artifact uploads are not configured on this orchestrator';
21
+ /** Download requested but the orchestrator has no artifact store configured. */
22
+ readonly downloadNotConfigured: 'artifact downloads are not configured on this orchestrator';
23
+ /** The job's run could not be resolved server-side (upload and download). */
24
+ readonly unresolvableRun: 'the run for this job could not be resolved on the orchestrator';
25
+ /** `beginUpload` threw. */
26
+ readonly uploadFailed: 'the orchestrator hit an internal error while starting the upload';
27
+ /** `download` threw. */
28
+ readonly downloadFailed: 'the orchestrator hit an internal error while resolving the download';
29
+ /** `completeUpload` threw with no more specific classification. */
30
+ readonly commitFailed: 'the orchestrator hit an internal error while committing the upload';
31
+ /** The uploaded object was absent from storage at commit time. */
32
+ readonly commitObjectMissing: 'the uploaded artifact object was not found in storage — the upload may not have completed';
33
+ }>;
34
+ /**
35
+ * The artifact-name rejection prefix and message builder are defined in
36
+ * `@kici-dev/engine`, beside `ArtifactNameSchema` itself, so the orchestrator and
37
+ * the agent sandbox render one wording. Such a rejection is neither an
38
+ * enforcement gate (nothing about the org's usage refuses it) nor an internal
39
+ * failure — the sandbox validates the same contract at the call site, so a name
40
+ * only reaches this path from an agent that bypassed or predates that check.
41
+ *
42
+ * Re-exported here because this module is where the orchestrator's artifact
43
+ * failure messages live — callers keep their existing import path.
44
+ */
45
+ export { ARTIFACT_INVALID_NAME_PREFIX, artifactInvalidNameError } from '@kici-dev/engine';
46
+ //# sourceMappingURL=failure-messages.d.ts.map
@@ -1,4 +1,4 @@
1
- import type { Kysely } from 'kysely';
1
+ import type { Kysely, Transaction } from 'kysely';
2
2
  import { type ColdStore } from '@kici-dev/shared';
3
3
  import { type AccessLogAction, type AccessLogItem, type AccessLogOutcome, type AccessLogRateLimiter, type AccessLogSource, type AccessLogTargetType, type ActorPrincipal, type ActorType } from '@kici-dev/engine';
4
4
  import type { Database } from '../db/types.js';
@@ -70,6 +70,23 @@ export declare class AccessLogWriter {
70
70
  */
71
71
  setColdStore(coldStore: ColdStore | null): void;
72
72
  record(entry: AccessLogRecord): Promise<void>;
73
+ /**
74
+ * Transactional variant: writes the row through the caller's executor so it
75
+ * commits or rolls back with the mutation it audits.
76
+ *
77
+ * Unlike `record`, failures PROPAGATE. The best-effort swallow exists so a
78
+ * broken `access_log` cannot take down dashboard reads; a caller that opted
79
+ * into a transaction is asserting the opposite — the mutation must not land
80
+ * unaudited — so the error has to reach the transaction and abort it.
81
+ *
82
+ * The per-action `POLICY_BY_ACTION` gate still applies, so a `sample` /
83
+ * `rate_limit` action would be dropped here silently and the caller's
84
+ * mutation would commit unaudited after all. Callers must therefore use an
85
+ * action whose policy is `always` — which is why `trust_policy.updated` is
86
+ * one.
87
+ */
88
+ recordInTransaction(executor: Kysely<Database> | Transaction<Database>, entry: AccessLogRecord): Promise<void>;
89
+ private insert;
73
90
  /**
74
91
  * Phase D: delegates to `loadAccessLogRange` so cold-store rows are
75
92
  * merged transparently when pagination crosses the warm cutoff. The
@@ -8,13 +8,28 @@
8
8
  * Cache key format: deps/{platform}-{arch}/{lockfileHash}.tar.gz
9
9
  */
10
10
  import type { CacheStorage } from '../storage/types.js';
11
+ import type { ClusterSettingsReader } from '../cluster/cluster-settings-reader.js';
11
12
  export declare class DepCache {
12
13
  private readonly storage;
13
14
  private readonly maxTarballBytes;
15
+ private readonly cacheTtlDaysFallback;
16
+ private readonly clusterSettings?;
14
17
  constructor(options: {
15
18
  storage: CacheStorage;
16
19
  maxTarballBytes?: number;
20
+ /** Cluster default for the dependency-cache entry TTL, in days. */
21
+ cacheTtlDaysFallback?: number;
22
+ /** Reader for the fleet-wide `cache_max_tarball_bytes` / `cache_ttl_days` overrides. */
23
+ clusterSettings?: ClusterSettingsReader;
17
24
  });
25
+ /**
26
+ * Resolve the live dependency-cache entry TTL as a per-operation override
27
+ * (ms) from `cluster_settings.cache_ttl_days`, falling back to the cluster
28
+ * default. `undefined` when no reader is wired, so the storage backend uses
29
+ * its own configured TTL. Passed to read/expiry operations so an operator's
30
+ * `cache_ttl_days` change takes effect on the next lookup.
31
+ */
32
+ private resolveTtlMsOverride;
18
33
  /** Check if a dep tarball exists in cache. */
19
34
  has(lockfileHash: string, platform: string, arch: string): Promise<boolean>;
20
35
  /**
@@ -88,7 +88,44 @@ export declare class UserCache {
88
88
  private writePrefix;
89
89
  /** Namespace prefixes the ref may READ, in priority order. Isolated reads its own run scope, then shared. */
90
90
  private readPrefixes;
91
+ /**
92
+ * Object key for a committed cache entry.
93
+ *
94
+ * The trailing discriminator is a hash of the EXACT cache key, and it is what
95
+ * keeps `build` and `Build` apart on a case-insensitive namespace — the
96
+ * filesystem backend on a macOS or Windows host, where the two would
97
+ * otherwise resolve to one object and a restore could return the other key's
98
+ * tarball.
99
+ *
100
+ * It is deliberately a SUFFIX: `restoreByPrefix` matches `restoreKeys` by
101
+ * string prefix, so appending leaves those semantics untouched. The only
102
+ * parse that has to know about it is the `matchedKey` slice.
103
+ */
91
104
  private finalKey;
105
+ /**
106
+ * The pre-discriminator object key.
107
+ *
108
+ * @deprecated Read-only compatibility path for entries written before the key
109
+ * carried a discriminator. Nothing writes this format; it is removed at the
110
+ * next major, by which point every such entry has aged out of the cache TTL.
111
+ */
112
+ private legacyFinalKey;
113
+ /**
114
+ * Restore an entry still stored in the pre-discriminator key format.
115
+ *
116
+ * Two gates, and BOTH are load-bearing — dropping either re-creates the
117
+ * wrong-cache-hit this change fixes:
118
+ *
119
+ * 1. `unambiguousLegacyKey` statically rules out any key that could have
120
+ * collided with a case variant in the old format.
121
+ * 2. The listed name must match byte-exactly. A case-insensitive backend
122
+ * resolves `getUrl('build')` to an object created as `Build`, but its
123
+ * *listing* reports the real created name — so comparing against the
124
+ * listing is what detects that the object is not really ours.
125
+ *
126
+ * @deprecated Removed at the next major; see `legacyFinalKey`.
127
+ */
128
+ private restoreLegacyExact;
92
129
  /** Restore: try the exact key across read prefixes, then restoreKeys prefix scan (newest wins). */
93
130
  restore(ref: UserCacheRef & {
94
131
  key: string;
@@ -41,6 +41,11 @@ export interface CancelRunResult {
41
41
  agentsNotified: number;
42
42
  /** Number of pending/queued execution_jobs rows marked cancelled. */
43
43
  pendingCancelled: number;
44
+ /**
45
+ * True when the run was already in a terminal status, so the cancel was a
46
+ * no-op: no agent was notified and no row was written.
47
+ */
48
+ alreadyTerminal: boolean;
44
49
  }
45
50
  /**
46
51
  * Cancel a whole run, recording `reason` on its cancelled jobs and (if not
@@ -50,9 +55,11 @@ export interface CancelRunResult {
50
55
  * the run to its terminal status immediately so the run does not linger in
51
56
  * `cancelling`.
52
57
  *
53
- * Idempotent against terminal runs: callers should pre-check terminal state
54
- * (the cancel route returns 409); the underlying UPDATEs are status-guarded so
55
- * a double-call is harmless.
58
+ * A cancel targeting a run that is already terminal is a no-op: the run's
59
+ * status is read first and, when terminal, the function returns
60
+ * `alreadyTerminal: true` having written nothing. Entry points map that to
61
+ * their own convention (the operator route answers 409; the dashboard/MCP path
62
+ * returns a structured already-terminal result).
56
63
  */
57
64
  export declare function cancelRunWithReason(deps: CancelRunDeps, runId: string, reason: string, options?: CancelRunOptions): Promise<CancelRunResult>;
58
65
  //# sourceMappingURL=cancel-run.d.ts.map
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The cancel handler behind the dashboard, the `kici runs cancel` CLI, and the
3
+ * MCP `cancel_run` tool.
4
+ *
5
+ * It delegates to `cancelRunWithReason` so the customer-facing cancel follows
6
+ * the same mechanics as the operator-facing one: an already-terminal run is a
7
+ * no-op, only OPEN agent sockets are notified, queued dispatch rows are
8
+ * cancelled, pending jobs are marked cancelled, and a run with no outstanding
9
+ * agent work is driven terminal.
10
+ *
11
+ * `cancelledJobs` counts notified agents plus pending/queued job rows marked
12
+ * cancelled, matching the operator route.
13
+ */
14
+ import { type CancelRunDeps } from './cancel-run.js';
15
+ export declare function createDashboardCancelHandler(deps: CancelRunDeps): (runId: string, cancelledBy: string | null, cancelledByAgentLabel: string | null, force?: boolean) => Promise<{
16
+ cancelledJobs: number;
17
+ alreadyTerminal: boolean;
18
+ }>;
19
+ //# sourceMappingURL=dashboard-cancel-handler.d.ts.map
@@ -63,6 +63,28 @@ export interface GenericSourceResponse {
63
63
  /** Universal-git config; raw JSON string or parsed object (pg driver dependent). */
64
64
  git_config?: string | GenericSourceGitConfigPayload | null;
65
65
  }
66
+ /**
67
+ * `fetch` rejects with a bare `TypeError: fetch failed` when it cannot reach the
68
+ * host — it names neither the address dialled nor the knob that sets it. Printed
69
+ * through the CLI's `Error: ${message}` handler that becomes `Error: fetch
70
+ * failed`, which reads like a fault in the subcommand rather than a misaddressed
71
+ * client, and sends the operator debugging the wrong thing.
72
+ *
73
+ * The trap is sharpened by two details of this CLI. The base URL comes from
74
+ * `KICI_ADMIN_URL`, not the `KICI_ORCHESTRATOR_URL` an operator is likelier to
75
+ * have exported; and subcommands accepting `--database-url` fall back to direct
76
+ * DB access, so on a host with `KICI_DATABASE_URL` set they keep working while
77
+ * the HTTP-only ones fail — making it look like specific subcommands are broken.
78
+ *
79
+ * So: name the address, name the variable, and name the near-miss.
80
+ */
81
+ /**
82
+ * Best-effort one-line detail from a rejected `fetch`. Returns '' when nothing
83
+ * useful is available, so the caller can omit the parenthetical rather than
84
+ * print an empty one.
85
+ */
86
+ export declare function firstCauseMessage(err: unknown): string;
87
+ export declare function fetchAdminApi(url: string, init: RequestInit, baseUrl: string): Promise<Response>;
66
88
  export declare class AdminApiClient {
67
89
  private readonly baseUrl;
68
90
  private readonly token;
@@ -106,7 +128,14 @@ export declare class AdminApiClient {
106
128
  logWindowHours?: number;
107
129
  timeoutSeconds?: number;
108
130
  }, outPath: string): Promise<void>;
109
- listScopes(orgId: string): Promise<{
131
+ /**
132
+ * List secret scopes for an org.
133
+ *
134
+ * @param allBackends - Aggregate every registered backend and return scopes
135
+ * in qualified `<backend>:<path>` form. Default (false) returns the bare,
136
+ * pg-only listing; that default flips at v1.0.0.
137
+ */
138
+ listScopes(orgId: string, allBackends?: boolean): Promise<{
110
139
  scopes: string[];
111
140
  }>;
112
141
  listKeys(orgId: string, scope: string): Promise<{
@@ -150,6 +179,8 @@ export declare class AdminApiClient {
150
179
  reEncrypted: number;
151
180
  reEncryptedConfigs: number;
152
181
  skippedConfigs: number;
182
+ reEncryptedBackends: number;
183
+ skippedBackends: number;
153
184
  }>;
154
185
  createGenericSource(data: {
155
186
  orgId: string;
@@ -223,6 +254,8 @@ export declare class AdminApiClient {
223
254
  label: string;
224
255
  role: string;
225
256
  routingKey?: string;
257
+ /** Optional absolute expiry as an ISO datetime string. */
258
+ expiresAt?: string;
226
259
  }): Promise<{
227
260
  token: string;
228
261
  id: string;
@@ -294,6 +327,16 @@ export declare class AdminApiClient {
294
327
  version?: number;
295
328
  errors?: string[];
296
329
  }>;
330
+ /** Flip the coordinator drain flag on ('drain') or off ('resume'). */
331
+ drain(action: 'drain' | 'resume'): Promise<{
332
+ draining: boolean;
333
+ jobsRunning: number;
334
+ }>;
335
+ /** Report the coordinator's current drain state without changing it. */
336
+ drainStatus(): Promise<{
337
+ draining: boolean;
338
+ jobsRunning: number;
339
+ }>;
297
340
  createApiKey(opts: {
298
341
  label?: string;
299
342
  routingKeys?: string[];