@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
@@ -28,6 +28,8 @@ export interface MockDbOptions {
28
28
  insertReturning?: unknown;
29
29
  /** Row returned by update chains ending in .returningAll().executeTakeFirstOrThrow() or executeTakeFirst(). Default: undefined */
30
30
  updatedRow?: unknown;
31
+ /** Rows returned by update chains ending in .returningAll().execute(). Default: [] */
32
+ updatedRows?: unknown[];
31
33
  /** Row returned by update chains ending in .returning(...).executeTakeFirst(). Default: undefined */
32
34
  updateReturning?: unknown;
33
35
  /** Result for update .execute() calls. Default: { numUpdatedRows: 0n } */
@@ -1,7 +1,14 @@
1
1
  import type { AgentRegistry } from './registry.js';
2
2
  import { type JobQueue, type QueuedJob, type QueuedJobInput } from '../queue/job-queue.js';
3
- import type { ScaleResult } from '../scaler/types.js';
3
+ import type { ScaleResult, ScalerRedispatchTrigger } from '../scaler/types.js';
4
4
  import type { ResourceRequest } from '@kici-dev/engine';
5
+ /**
6
+ * Default per-pass cap on how many pending jobs a capacity-freed re-drive
7
+ * re-offers to the scaler. Bounds the burst so a single free event cannot storm
8
+ * the scaler; the per-backend spawn semaphore bounds actual provisioning, and a
9
+ * job that gets `at-capacity` again simply stays pending for the next tick.
10
+ */
11
+ export declare const DEFAULT_REDRIVE_BATCH = 10;
5
12
  /**
6
13
  * Metrics interface for dispatch operations.
7
14
  * Allows the dispatcher to update Prometheus counters without
@@ -12,6 +19,8 @@ export interface DispatchMetrics {
12
19
  incJobsDispatched(status: 'dispatched' | 'queued' | 'rejected'): void;
13
20
  /** Set the queue depth gauge. */
14
21
  setQueueDepth(depth: number): void;
22
+ /** Record `count` pending jobs re-driven through the scaler by `trigger`. */
23
+ incScalerRedispatch(trigger: ScalerRedispatchTrigger, count: number): void;
15
24
  }
16
25
  /**
17
26
  * Narrow slice of `HostRosterStore` the dispatcher needs for the host-restart
@@ -27,6 +36,12 @@ export interface HostRosterRebootStore {
27
36
  }
28
37
  /**
29
38
  * Result of a dispatch attempt.
39
+ *
40
+ * `duplicate` = the dispatch_queue row for a preassigned (rerouted) jobId
41
+ * already existed, so nothing was dispatched here (the claimed agent slot is
42
+ * released and onDispatch is NOT called). The reroute caller should treat the
43
+ * job as already handled. Only reachable on a reroute re-dispatch — first-
44
+ * dispatch paths use a fresh UUID that can never collide.
30
45
  */
31
46
  type DispatchResult = {
32
47
  status: 'dispatched';
@@ -38,6 +53,9 @@ type DispatchResult = {
38
53
  } | {
39
54
  status: 'queued-no-backend';
40
55
  jobId: string;
56
+ } | {
57
+ status: 'duplicate';
58
+ jobId: string;
41
59
  } | {
42
60
  status: 'rejected';
43
61
  reason: string;
@@ -60,6 +78,13 @@ export declare class Dispatcher {
60
78
  private readonly metrics;
61
79
  private readonly onDispatch;
62
80
  private readonly onNoMatchingAgent?;
81
+ /**
82
+ * Single-flight guard for `retryPendingScaleRequests`. The capacity-freed
83
+ * hook and the leader-gated sweep can both fire concurrently; this prevents
84
+ * two re-drives from double-offering the same pending jobs to the scaler in
85
+ * the same tick.
86
+ */
87
+ private redriveInFlight;
63
88
  /**
64
89
  * Tracks which jobs are dispatched to which agents.
65
90
  * Used for marking jobs as failed on agent disconnect.
@@ -134,6 +159,9 @@ export declare class Dispatcher {
134
159
  private get gracePeriodMs();
135
160
  /** Host roster store for the reboot-pending gate; undefined ⇒ flow inert. */
136
161
  private readonly rosterStore?;
162
+ /** Coordinator drain predicate; when true, new jobs queue Pending instead of
163
+ * dispatching. Defaults to never-draining. */
164
+ private readonly isDraining;
137
165
  constructor(deps: {
138
166
  registry: AgentRegistry;
139
167
  queue: JobQueue;
@@ -142,7 +170,7 @@ export declare class Dispatcher {
142
170
  /** Optional hook called when no agent matches the job's labels.
143
171
  * When set, receives the per-job `resources` so the scaler can apply
144
172
  * per-scaler / per-orchestrator / per-machine caps before spawning. */
145
- onNoMatchingAgent?: (labels: string[], jobId: string, runId: string, excludeLabels: string[], resources?: ResourceRequest) => Promise<ScaleResult>;
173
+ onNoMatchingAgent?: (labels: string[], jobId: string, runId: string, excludeLabels: string[], resources?: ResourceRequest, orgId?: string) => Promise<ScaleResult>;
146
174
  /** Max reconnection delay from agent config (default 60s). Used to derive grace period. */
147
175
  maxReconnectDelayMs?: number;
148
176
  /** Callback fired when a job is permanently failed before/outside agent execution. */
@@ -161,6 +189,10 @@ export declare class Dispatcher {
161
189
  * reboot-pending behavior is inert (every host reads not-pending).
162
190
  */
163
191
  rosterStore?: HostRosterRebootStore;
192
+ /** Coordinator drain predicate. When true, dispatch() enqueues new jobs as
193
+ * Pending and onAgentAvailable() claims nothing — jobs already on agents
194
+ * finish. Defaults to never-draining. */
195
+ isDraining?: () => boolean;
164
196
  });
165
197
  /**
166
198
  * Dispatch a job to a matching agent, or queue it if none available.
@@ -172,6 +204,24 @@ export declare class Dispatcher {
172
204
  * 4. If queue full: return 'rejected'.
173
205
  */
174
206
  dispatch(job: QueuedJobInput): Promise<DispatchResult>;
207
+ /**
208
+ * Re-drive the scaler for jobs still pending after an `at-capacity` verdict.
209
+ *
210
+ * Called by the capacity-freed hook (`ScalerManager.onCapacityFreed`) and the
211
+ * leader-gated `PendingScaleSweeper`. Lists the oldest pending jobs (FIFO
212
+ * fairness — the longest-waiting burst victim gets the freed slot first) and
213
+ * re-runs the SAME `onNoMatchingAgent` → `requestScale` path used at dispatch
214
+ * time, so the re-drive inherits the per-backend spawn semaphore and cap
215
+ * accounting. A job that returns `at-capacity` again just stays pending for
216
+ * the next free/sweep tick — no retry state, no backoff bookkeeping.
217
+ *
218
+ * Single-flight: a second call while one is in flight returns 0, so an
219
+ * overlapping hook+sweep cannot double-offer the same jobs. Bounded by
220
+ * `maxJobs` so one free event cannot storm the scaler.
221
+ *
222
+ * @returns the number of jobs that entered `spawning`.
223
+ */
224
+ retryPendingScaleRequests(maxJobs?: number, trigger?: ScalerRedispatchTrigger): Promise<number>;
175
225
  /**
176
226
  * Dispatch a host-fanout pinned child. The job targets exactly
177
227
  * `job.pinnedAgentId`: if that agent is locally connected, satisfies the
@@ -31,8 +31,7 @@ export declare class HostRosterReaper {
31
31
  private readonly scanIntervalMs;
32
32
  private readonly setUnreachableGauge;
33
33
  private readonly rebootSweep;
34
- private timer;
35
- private isLeader;
34
+ private readonly scheduler;
36
35
  constructor(opts: HostRosterReaperOptions);
37
36
  onBecomeLeader(): void;
38
37
  onLoseLeadership(): void;
@@ -3,6 +3,22 @@ import { type HostInventoryEntry, type InventorySelector, type LabelMatcher } fr
3
3
  import type { Database, HostRosterRow } from '../db/types.js';
4
4
  /** Typed host-vars bag carried by roster rows (`string | number | boolean`). */
5
5
  export type HostProperties = Record<string, string | number | boolean>;
6
+ /**
7
+ * Reserved `host_properties` key holding the self-contained agent-payload version
8
+ * the orchestrator last staged onto a host. Read by the fleet-convergence gate;
9
+ * the `kici:` namespace is orchestrator-reserved so an agent never reports it.
10
+ */
11
+ export declare const STAGED_AGENT_VERSION_KEY = "kici:staged-agent-version";
12
+ /**
13
+ * Drop every orchestrator-reserved `kici:`-namespaced key from an
14
+ * agent-reported host-property bag. Agent-reported properties win the roster
15
+ * shallow-merge, so without this an agent could FORGE reserved keys the
16
+ * orchestrator trusts — the staged-version convergence gate and the
17
+ * root-executed restart commands both read `kici:` keys. Only orchestrator
18
+ * writes (`recordStagedVersion`) and operator declares (`declareStatic`) set
19
+ * this namespace; a registering agent never may.
20
+ */
21
+ export declare function stripReservedProperties(props: HostProperties): HostProperties;
6
22
  /**
7
23
  * Pre-agent reach metadata for a declared host — how to SSH to it for bootstrap
8
24
  * bring-up before it has a KiCI agent. All fields nullable: a host with no reach
@@ -15,6 +31,12 @@ export interface HostReach {
15
31
  sshUser: string | null;
16
32
  sshPort: number | null;
17
33
  sshKeySecret: string | null;
34
+ /**
35
+ * When true, the box can reach the orchestrator's object storage — bring-up
36
+ * picks the `s3-direct` delivery mode (box pulls the payload via a presigned
37
+ * URL). NULL / false ⇒ the conservative `ssh-push` fallback.
38
+ */
39
+ s3Reachable: boolean | null;
18
40
  }
19
41
  /**
20
42
  * Derived (read-time) status of a roster host. Never a stored mutable column:
@@ -131,6 +153,7 @@ export declare class HostRosterStore {
131
153
  sshUser?: string;
132
154
  sshPort?: number;
133
155
  sshKeySecret?: string;
156
+ s3Reachable?: boolean;
134
157
  }): Promise<{
135
158
  created: boolean;
136
159
  }>;
@@ -140,6 +163,17 @@ export declare class HostRosterStore {
140
163
  */
141
164
  getReach(agentId: string): Promise<HostReach | null>;
142
165
  get(agentId: string): Promise<HostRosterRow | null>;
166
+ /**
167
+ * Record the self-contained agent-payload version the orchestrator staged onto
168
+ * a host (bring-up or fleet re-stage). Stored in `host_properties` under a
169
+ * reserved key so the convergence gate can compare it against the target
170
+ * INDEPENDENTLY of the agent's own self-reported bundle version (two payloads
171
+ * can carry the same self-report but different staged keys). Shallow-merged, so
172
+ * it survives agent re-register (the agent never reports this reserved key).
173
+ */
174
+ recordStagedVersion(agentId: string, version: string): Promise<void>;
175
+ /** Read a host's recorded staged agent-payload version, or null when never staged. */
176
+ getStagedVersion(agentId: string): Promise<string | null>;
143
177
  listAll(): Promise<HostRosterRow[]>;
144
178
  /**
145
179
  * Resolve every roster host matching a `runsOnAll` predicate (OR-of-AND
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The single refusal wording sent to an agent whose job-scoped frame was not
3
+ * accepted on ownership grounds.
4
+ *
5
+ * Deliberately identical whether the database decided "not owned" or could not
6
+ * decide at all. A caller that could tell the two apart would hold an oracle for
7
+ * job existence, upload-commit state, and orchestrator database health — so the
8
+ * two cases are indistinguishable on the wire, and the distinction lives only in
9
+ * the orchestrator's own logs.
10
+ */
11
+ export declare const OWNERSHIP_REFUSED = "this job is not owned by this agent";
12
+ //# sourceMappingURL=ownership-refusal.d.ts.map
@@ -10,21 +10,40 @@
10
10
  * - Violation counting with sliding window (default: 5 violations in 60s)
11
11
  * - Escalation: disconnect agent after threshold violations
12
12
  */
13
+ /**
14
+ * Verdict of the DB-backed ownership lookup.
15
+ *
16
+ * `unknown` is the load-bearing member: it separates "the database says this
17
+ * agent does not own the job" (evidence of a misrouted or spoofed frame) from
18
+ * "the lookup could not be answered" (a query failure or a timeout). Only the
19
+ * former is a violation — counting an unanswerable check as evidence would let
20
+ * one transient database outage disconnect every connected agent at once.
21
+ */
22
+ export type OwnershipDbResult = 'owned' | 'not-owned' | 'unknown';
23
+ /** Deadline for a single DB-backed ownership lookup before it resolves `unknown`. */
24
+ export declare const DEFAULT_OWNERSHIP_DB_CHECK_TIMEOUT_MS = 5000;
13
25
  interface OwnershipTrackerOpts {
14
26
  /** Check if a job is owned by the given agent (active or in grace window). */
15
27
  isJobOwnedByAgent: (agentId: string, jobId: string) => boolean;
16
28
  /**
17
- * Optional DB-backed fallback. Returns true when the orchestrator
18
- * DB shows the (agent, job) pair as previously owned by this coord
19
- * OR a sibling coord — i.e. either currently `dispatched`/`recovering`
20
- * with the same `agent_id` / `recovery_agent_id`, or recently
21
- * `completed`/`failed`. When a Raft leader switch wipes the
22
- * in-memory `agentJobs` Map on the replacement coord, this fallback
23
- * accepts late `log.chunk` / `step.status` chunks from agents that
24
- * are still draining instead of rejecting them as ownership
25
- * violations.
29
+ * Optional DB-backed fallback. Returns `owned` when the orchestrator DB shows
30
+ * the (agent, job) pair as held by this coord OR a sibling coord — i.e.
31
+ * currently `dispatched`/`recovering` with the same `agent_id` /
32
+ * `recovery_agent_id`, or already terminal. `not-owned` is a decided refusal;
33
+ * `unknown` means the lookup itself could not be answered.
34
+ *
35
+ * When a Raft leader switch wipes the in-memory `agentJobs` Map on the
36
+ * replacement coord, this fallback accepts late frames from agents that are
37
+ * still draining instead of rejecting them as ownership violations.
26
38
  */
27
- isJobOwnedByAgentInDb?: (agentId: string, jobId: string) => Promise<boolean>;
39
+ isJobOwnedByAgentInDb?: (agentId: string, jobId: string) => Promise<OwnershipDbResult>;
40
+ /**
41
+ * Per-lookup deadline in ms, read fresh on every call so an operator can
42
+ * retune it fleet-wide without a restart. The read is itself bounded by
43
+ * {@link DEFAULT_OWNERSHIP_DB_CHECK_TIMEOUT_MS}, which is also the fallback
44
+ * when it stalls, throws, or returns a delay `setTimeout` cannot honour.
45
+ */
46
+ getTimeoutMs?: () => Promise<number>;
28
47
  /** Callback to disconnect an agent after escalation. */
29
48
  onDisconnect: (agentId: string, reason: string) => void;
30
49
  /** Number of violations before escalation (default: 5). */
@@ -35,6 +54,7 @@ interface OwnershipTrackerOpts {
35
54
  export declare class OwnershipTracker {
36
55
  private readonly isJobOwnedByAgent;
37
56
  private readonly isJobOwnedByAgentInDb?;
57
+ private readonly getTimeoutMs?;
38
58
  private readonly onDisconnect;
39
59
  private readonly violationThreshold;
40
60
  private readonly violationWindowMs;
@@ -63,15 +83,43 @@ export declare class OwnershipTracker {
63
83
  checkOwnership(agentId: string, jobId: string, messageType: string): boolean;
64
84
  /**
65
85
  * Async fallback used by message handlers that want HA-safe
66
- * acceptance of post-failover chunks. Returns true if the DB shows
86
+ * acceptance of post-failover frames. Returns true if the DB shows
67
87
  * the (agent, job) pair as currently or recently owned by any coord
68
- * in the cluster. On true, caches the result so subsequent same-pair
69
- * chunks return true synchronously via `checkOwnership`. On false,
70
- * records a violation exactly once (no recursive recordViolation
71
- * from the synchronous call site — `checkOwnership` skipped it
72
- * when the DB fallback was configured).
88
+ * in the cluster. On `owned`, caches the result so subsequent
89
+ * same-pair frames return true synchronously via `checkOwnership`.
90
+ * On `not-owned`, records a violation exactly once (no recursive
91
+ * recordViolation from the synchronous call site — `checkOwnership`
92
+ * skipped it when the DB fallback was configured). On `unknown` the
93
+ * frame is refused without a violation: an unanswerable check is not
94
+ * evidence of misbehaviour, and treating it as such would let one
95
+ * database outage disconnect the whole fleet.
73
96
  */
74
97
  validateAsync(agentId: string, jobId: string, messageType: string): Promise<boolean>;
98
+ /**
99
+ * Run the DB-backed lookup under a deadline. A query that throws or outruns
100
+ * the deadline resolves `unknown` — never `not-owned` — so a sick database
101
+ * refuses frames without accusing the agent of anything.
102
+ */
103
+ private resolveFromDb;
104
+ /**
105
+ * Resolve the deadline for one lookup, itself bounded by
106
+ * {@link DEFAULT_OWNERSHIP_DB_CHECK_TIMEOUT_MS}.
107
+ *
108
+ * The knob is stored in the same database the deadline exists to survive, so
109
+ * reading it unbounded would stall the very frame the deadline is there to
110
+ * refuse — the agent would wait out its own acknowledgment deadline instead
111
+ * of getting an answer. A read that stalls, throws, or yields a value
112
+ * `setTimeout` cannot honour (non-finite, sub-millisecond, or past
113
+ * {@link MAX_TIMER_DELAY_MS}) falls back to the compile-time default.
114
+ */
115
+ private resolveTimeoutMs;
116
+ /**
117
+ * Cache a DB-proven (agent, job) pair so the next frame on the same pair
118
+ * short-circuits in `checkOwnership`. The per-agent set is capped (generously
119
+ * — a typical agent runs a handful of jobs) so a misbehaving agent cannot
120
+ * grow it without bound.
121
+ */
122
+ private rememberDbAccepted;
75
123
  /**
76
124
  * Record a violation for an agent. If threshold is exceeded within the
77
125
  * violation window, triggers disconnect escalation.
@@ -1,5 +1,18 @@
1
1
  import { type Kysely } from 'kysely';
2
2
  import type { Database, AgentTokenRow } from '../db/types.js';
3
+ /**
4
+ * `created_by` marker prefix for single-use bootstrap (init-runner) tokens.
5
+ * A bootstrap token stores `created_by: '<this prefix><targetAgentId>'` so the
6
+ * register-time identity binding (agent-handler Gate 2) and the single-use
7
+ * consume check can both recognize it and resolve the bound agent id.
8
+ */
9
+ export declare const BOOTSTRAP_CREATED_BY_PREFIX = "bootstrap:";
10
+ /**
11
+ * Resolve the agent id an ephemeral token binds its holder to. Scaler tokens
12
+ * store the id verbatim in `created_by`; bootstrap tokens store it behind
13
+ * `BOOTSTRAP_CREATED_BY_PREFIX`. Returns the bare target agent id in both cases.
14
+ */
15
+ export declare function boundAgentIdFromCreatedBy(createdBy: string): string;
3
16
  /**
4
17
  * Safe token row shape returned from list/validate (excludes token_hash).
5
18
  */
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Availability gate for version-keyed agent packages.
3
+ *
4
+ * The fleet auto-upgrade convergence NEVER rolls a host to a version whose
5
+ * self-contained payload objects don't exist in the cache bucket — that would
6
+ * stage stale/absent bytes (or leave the fleet at a version skew). This helper
7
+ * `head`s each platform's payload object and reports which are missing, so the
8
+ * caller can HOLD (the convergence gate) or skip re-producing (the upgrade
9
+ * hook). It never throws — the caller decides hold-vs-alarm.
10
+ */
11
+ import type { AgentPlatform } from '@kici-dev/shared';
12
+ import { type AgentPackageDownloadStorage } from './download.js';
13
+ /** Verdict of an availability check across a platform set for one version. */
14
+ export interface PayloadAvailability {
15
+ /** True only when EVERY requested platform's payload object exists. */
16
+ available: boolean;
17
+ /** The platforms whose version-keyed payload object is absent. */
18
+ missing: AgentPlatform[];
19
+ }
20
+ /**
21
+ * Check that a version's agent payloads exist for every requested platform.
22
+ * Fail-closed by construction: an absent object lands in `missing`, so a caller
23
+ * that gates on `available` can never converge onto a version whose bytes are
24
+ * not present.
25
+ */
26
+ export declare function assertPayloadsAvailable(storage: AgentPackageDownloadStorage, version: string, platforms: AgentPlatform[]): Promise<PayloadAvailability>;
27
+ //# sourceMappingURL=availability.d.ts.map
@@ -0,0 +1,16 @@
1
+ import type { AgentPlatform } from '@kici-dev/shared';
2
+ export interface BuildAgentPackageOptions {
3
+ platform: AgentPlatform;
4
+ version: string;
5
+ nodeVersion: string;
6
+ outDir: string;
7
+ nodeMirror?: string;
8
+ npmRegistry?: string;
9
+ }
10
+ export interface AgentPackageResult {
11
+ tarballPath: string;
12
+ sha256: string;
13
+ }
14
+ /** Package the installed @kici-dev/agent + a vendored Node + npm into a self-contained tarball. */
15
+ export declare function buildSelfContainedAgentPackage(opts: BuildAgentPackageOptions): Promise<AgentPackageResult>;
16
+ //# sourceMappingURL=build-package.d.ts.map
@@ -0,0 +1,30 @@
1
+ import type { AgentPlatform } from '@kici-dev/shared';
2
+ /**
3
+ * Read side of the cache-bucket agent-package store: mint a box-routable
4
+ * presigned GET URL and read the payload's sha256 sidecar. Satisfied by the
5
+ * orchestrator S3 cache storage client (`getUrl` presigns against the external,
6
+ * container-routable endpoint; `get` reads the `.sha256` object).
7
+ */
8
+ export interface AgentPackageDownloadStorage {
9
+ getUrl(key: string): Promise<string | null>;
10
+ get(key: string): Promise<Buffer | null>;
11
+ has(key: string): Promise<boolean>;
12
+ }
13
+ /** Cache-bucket key for a payload's sha256 sidecar (mirrors the upload layout). */
14
+ export declare function agentPackageHashKey(version: string, platform: AgentPlatform): string;
15
+ /** Parse a `sha256sum`-style `<hex> <name>` sidecar into the leading hex token. */
16
+ export declare function parseSha256Sidecar(contents: string): string | null;
17
+ /**
18
+ * Mint a presigned GET URL for a version-keyed agent payload and read its
19
+ * sha256 sidecar. Returns null when the payload object is absent (an
20
+ * unresolvable version) so the caller fails fast with a clear error rather than
21
+ * staging stale bytes. The URL is box-routable (external endpoint); no standing
22
+ * S3 credential ever leaves the orchestrator.
23
+ */
24
+ export declare function presignAgentPackageDownload(storage: AgentPackageDownloadStorage, version: string, platform: AgentPlatform): Promise<{
25
+ url: string;
26
+ sha256: string | null;
27
+ } | null>;
28
+ /** True when a version-keyed payload object exists (backs the availability gate). */
29
+ export declare function agentPackageExists(storage: AgentPackageDownloadStorage, version: string, platform: AgentPlatform): Promise<boolean>;
30
+ //# sourceMappingURL=download.d.ts.map
@@ -0,0 +1,9 @@
1
+ export * from './node-binary.js';
2
+ export * from './install-closure.js';
3
+ export * from './build-package.js';
4
+ export * from './upload.js';
5
+ export * from './download.js';
6
+ export * from './store.js';
7
+ export * from './availability.js';
8
+ export * from './refresh.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,30 @@
1
+ import { type AgentPlatform } from '@kici-dev/shared';
2
+ export interface InstallClosureOptions {
3
+ version: string;
4
+ platform: AgentPlatform;
5
+ /** npm --prefix target; a package.json is seeded so npm installs into <prefix>/node_modules. */
6
+ prefixDir: string;
7
+ npmRegistry?: string;
8
+ }
9
+ /**
10
+ * The `@kici-dev/agent@<spec>` argument for the install.
11
+ *
12
+ * In production the agent is published to npm at the exact single-version, so we
13
+ * pin it verbatim (`@kici-dev/agent@0.2.0`) — the payload is provably the version
14
+ * the orchestrator runs. In development (`KICI_DEV=true`) the local Verdaccio
15
+ * registry only carries prerelease builds (`<version>-<buildCounter>`), so we
16
+ * match the current base version's prereleases instead — the same
17
+ * prerelease-compatible resolution the rest of the dev tooling uses.
18
+ */
19
+ export declare function agentInstallSpec(version: string): string;
20
+ /**
21
+ * `npm install @kici-dev/agent@<version>` for the TARGET platform into prefixDir.
22
+ *
23
+ * `--cpu`/`--os` make npm resolve every transitive optional native binding (incl.
24
+ * `@oxc-transform/binding-<platform>`) for the target platform, not the host —
25
+ * the same mechanism `scripts/package.mjs` relies on for oxc. `--omit=dev` keeps
26
+ * the closure to the runtime tree. When the published `@kici-dev/agent` ships an
27
+ * `npm-shrinkwrap.json`, npm resolves the exact released + tested tree.
28
+ */
29
+ export declare function installAgentClosure(opts: InstallClosureOptions): Promise<void>;
30
+ //# sourceMappingURL=install-closure.d.ts.map
@@ -0,0 +1,26 @@
1
+ import { type AgentPlatform } from '@kici-dev/shared';
2
+ export interface DownloadNodeOptions {
3
+ version: string;
4
+ platform: AgentPlatform;
5
+ /** Absolute path the verified `node` executable is written to. */
6
+ destBinPath: string;
7
+ /** Overrides https://nodejs.org/dist (air-gap mirror). */
8
+ nodeMirror?: string;
9
+ }
10
+ /**
11
+ * Download + SHASUMS256-verify the Node runtime for a glibc-Linux platform and
12
+ * vendor `node` + `npm` into the payload.
13
+ *
14
+ * Fetches the release's SHASUMS256.txt, finds the entry for the target
15
+ * platform's `.tar.gz`, downloads the archive, verifies its sha256 against that
16
+ * entry, and extracts the runtime into `<prefix>/` (where `<prefix>` is the
17
+ * grandparent of `destBinPath`): the `node` binary at `<prefix>/bin/node`, the
18
+ * `bin/npm` + `bin/npx` launcher symlinks, and the bundled npm package under
19
+ * `<prefix>/lib/node_modules/npm`. npm is required so the booted agent can
20
+ * install a workflow's `.kici/` dependencies on a box with no system Node —
21
+ * `resolveNpm()` finds it at `<nodeDir>/../lib/node_modules/npm/bin/npm-cli.js`.
22
+ * The vendored Node is what the produced payload boots on — no system Node is
23
+ * ever used.
24
+ */
25
+ export declare function downloadNodeBinary(opts: DownloadNodeOptions): Promise<void>;
26
+ //# sourceMappingURL=node-binary.d.ts.map
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Auto-refresh of version-keyed agent payloads on `orchestrator upgrade`.
3
+ *
4
+ * The automation-completeness principle: auto-deploy ⟹ auto-upgrade ⟹
5
+ * auto-package. After the orchestrator is upgraded to version V, this hook
6
+ * produces + uploads `agent-packages/V/kici-agent-<platform>.tar.gz(.sha256)`
7
+ * for the platforms the fleet already runs, so the convergence gate finds the
8
+ * bytes it needs with no separate operator step. Idempotent: a platform whose
9
+ * payload already exists for V is skipped, so a re-run is a no-op.
10
+ */
11
+ import { AgentPlatform } from '@kici-dev/shared';
12
+ import { type AgentPackageDownloadStorage } from './download.js';
13
+ /** Storage surface the refresh needs: existence check, listing, put. */
14
+ export interface RefreshStorage extends AgentPackageDownloadStorage {
15
+ put(key: string, data: Buffer | string): Promise<void>;
16
+ list(subPrefix: string): Promise<string[]>;
17
+ }
18
+ /** Result of one produced payload, as `kici-admin agent package` yields it. */
19
+ export interface BuiltPayload {
20
+ tarballPath: string;
21
+ sha256: string;
22
+ }
23
+ export interface RefreshDeps {
24
+ /** Build one platform's self-contained payload for `version` (the packaging lib). */
25
+ build: (platform: AgentPlatform, version: string) => Promise<BuiltPayload>;
26
+ /** Optional log sink (defaults to no-op); the CLI wires console.log. */
27
+ log?: (msg: string) => void;
28
+ }
29
+ export interface RefreshResult {
30
+ produced: AgentPlatform[];
31
+ skipped: AgentPlatform[];
32
+ }
33
+ /**
34
+ * The platforms the fleet already has payloads for — the union across every
35
+ * version present in the store EXCEPT `excludeVersion` (the just-upgraded
36
+ * target, whose payloads we are about to (re)produce). Preserves the fleet's
37
+ * arch coverage across an upgrade. Empty ⇒ the caller falls back to the
38
+ * bootstrap default set.
39
+ */
40
+ export declare function discoverFleetPlatforms(storage: RefreshStorage, excludeVersion: string): Promise<AgentPlatform[]>;
41
+ /**
42
+ * Produce + upload the target version's payloads for the fleet's platform set,
43
+ * skipping any already present (idempotent). Explicit `platforms` override the
44
+ * discovery; otherwise the fleet's existing arch coverage is preserved, falling
45
+ * back to the bootstrap default (`AgentPlatform.options`) on a fresh store.
46
+ */
47
+ export declare function refreshAgentPackages(storage: RefreshStorage, version: string, opts: {
48
+ platforms?: AgentPlatform[];
49
+ }, deps: RefreshDeps): Promise<RefreshResult>;
50
+ //# sourceMappingURL=refresh.d.ts.map
@@ -0,0 +1,15 @@
1
+ import type { CacheStorage } from '../storage/types.js';
2
+ import type { AppConfig } from '../config.js';
3
+ import type { AgentPackageDownloadStorage } from './download.js';
4
+ /**
5
+ * Resolve the agent-package store the bring-up presign handler reads from.
6
+ *
7
+ * Defaults to the orchestrator's OWN cache bucket (`cacheStorage`) — never a
8
+ * vendor CDN. An `s3://bucket[/prefix]` override (`KICI_AGENT_BINARY_SOURCE`)
9
+ * points the presign at another bucket on the SAME S3 endpoint (the customer
10
+ * supply-chain mirror); the config schema already rejects an http(s) source so
11
+ * no external HTTP default can slip in. Returns undefined when no cache storage
12
+ * is configured and no override is set (the presign RPC then refuses loudly).
13
+ */
14
+ export declare function resolveAgentPackageStore(config: AppConfig, cacheStorage: CacheStorage | undefined): AgentPackageDownloadStorage | undefined;
15
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1,24 @@
1
+ import { AgentPlatform } from '@kici-dev/shared';
2
+ /** Minimal storage surface — satisfied by the orchestrator S3 cache storage client. */
3
+ export interface AgentPackageStorage {
4
+ put(key: string, data: Buffer | string): Promise<void>;
5
+ }
6
+ /** The cache-bucket sub-prefix under which all version-keyed payloads live. */
7
+ export declare const AGENT_PACKAGES_PREFIX = "agent-packages/";
8
+ /** Cache-bucket key for a version-keyed agent payload. */
9
+ export declare function agentPackageKey(version: string, platform: AgentPlatform): string;
10
+ /**
11
+ * Parse an `agent-packages/<version>/kici-agent-<platform>.tar.gz` key back into
12
+ * its version + platform, or null when the key is not a payload tarball (e.g. a
13
+ * `.sha256` sidecar or an unrelated key). Used to discover the fleet's platform
14
+ * set from the store on upgrade.
15
+ */
16
+ export declare function parseAgentPackageKey(key: string): {
17
+ version: string;
18
+ platform: AgentPlatform;
19
+ } | null;
20
+ /** Upload a produced payload + its sha256 sidecar to the cache bucket. */
21
+ export declare function uploadAgentPackage(storage: AgentPackageStorage, version: string, platform: AgentPlatform, tarballPath: string, sha256: string): Promise<{
22
+ key: string;
23
+ }>;
24
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The orchestrator's last-resort HTTP error handler.
3
+ *
4
+ * Without one, Hono answers an unhandled throw with a bare, unstructured 500:
5
+ * no JSON body, no route context, and nothing written to our own logs. Every
6
+ * admin router already catches inside its handlers (routes/admin-errors.ts),
7
+ * and the auth path catches inside its middleware (routes/admin-auth.ts) -- this
8
+ * covers whatever neither does.
9
+ *
10
+ * It is a backstop, not a substitute for a specific boundary: a targeted catch
11
+ * can return the right status for its failure (503 when authentication cannot
12
+ * be completed), while a generic net can only say "something broke".
13
+ */
14
+ import type { ErrorHandler } from 'hono';
15
+ export interface OnErrorOptions {
16
+ /** Which app this handler guards. The orchestrator has exactly two Hono roots. */
17
+ role: 'coordinator' | 'worker';
18
+ logger?: {
19
+ error(msg: string, meta?: Record<string, unknown>): void;
20
+ };
21
+ }
22
+ /**
23
+ * Build the `app.onError` handler for one Hono composition root.
24
+ *
25
+ * @param opts - The app role recorded on every log line, and an optional logger.
26
+ * @returns A Hono error handler returning a structured 500.
27
+ */
28
+ export declare function createOnErrorHandler(opts: OnErrorOptions): ErrorHandler;
29
+ //# sourceMappingURL=app-on-error.d.ts.map