@kici-dev/orchestrator 0.1.26 → 0.2.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 (310) 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 +69 -8
  19. package/dist/approvals/apply-decision.d.ts +1 -1
  20. package/dist/approvals/step-approval-bridge.d.ts +1 -1
  21. package/dist/artifacts/artifact-store.d.ts +233 -0
  22. package/dist/artifacts/failure-messages.d.ts +46 -0
  23. package/dist/audit/access-log.d.ts +18 -1
  24. package/dist/cache/dep-cache.d.ts +15 -0
  25. package/dist/cache/pending-inits.d.ts +4 -4
  26. package/dist/cache/user-cache.d.ts +37 -0
  27. package/dist/cancel/cancel-run.d.ts +10 -3
  28. package/dist/cancel/dashboard-cancel-handler.d.ts +19 -0
  29. package/dist/cli/api-client.d.ts +51 -5
  30. package/dist/cli/commands/agent-package.d.ts +34 -0
  31. package/dist/cli/commands/check-run.d.ts +26 -0
  32. package/dist/cli/commands/cluster-settings.d.ts +55 -0
  33. package/dist/cli/commands/context.d.ts +25 -0
  34. package/dist/cli/commands/dashboard-encryption-key.d.ts +3 -0
  35. package/dist/cli/commands/db-backup.d.ts +71 -0
  36. package/dist/cli/commands/debug-bundle.d.ts +1 -1
  37. package/dist/cli/commands/orchestrator-service/drain.d.ts +31 -0
  38. package/dist/cli/commands/orchestrator-service/index.d.ts +7 -4
  39. package/dist/cli/commands/orchestrator-service/install-env.d.ts +58 -0
  40. package/dist/cli/commands/secret.d.ts +45 -1
  41. package/dist/cli/commands/shared/admin-cli-access-log.d.ts +46 -0
  42. package/dist/cli/commands/shared/versioned-upgrade.d.ts +65 -2
  43. package/dist/cli/commands/signing-key.d.ts +3 -0
  44. package/dist/cli/commands/source.d.ts +12 -0
  45. package/dist/cli/commands/token.d.ts +9 -0
  46. package/dist/cli/commands/trust-policy.d.ts +48 -0
  47. package/dist/cli/commands/variable.d.ts +6 -6
  48. package/dist/cli/join.d.ts +1 -1
  49. package/dist/cli/service/index.d.ts +2 -2
  50. package/dist/cli/service/instance/manifest.d.ts +17 -0
  51. package/dist/cli/service/instance/resolve.d.ts +11 -0
  52. package/dist/cli/service/windows.d.ts +6 -0
  53. package/dist/cli/wizard/orchestrator-wizard.d.ts +39 -11
  54. package/dist/cli.js +10263 -3667
  55. package/dist/cluster/cluster-settings-reader.d.ts +78 -0
  56. package/dist/cluster/coordinator.d.ts +81 -9
  57. package/dist/cluster/join-client.d.ts +1 -1
  58. package/dist/cluster/leader-gated-scheduler.d.ts +50 -0
  59. package/dist/cluster/orphan-recovery.d.ts +14 -0
  60. package/dist/cluster/peer-client.d.ts +12 -2
  61. package/dist/cluster/peer-handler.d.ts +15 -4
  62. package/dist/cluster/peer-registry.d.ts +12 -0
  63. package/dist/cluster/verified-issuer-poller.d.ts +11 -0
  64. package/dist/cluster/verified-issuer.d.ts +63 -0
  65. package/dist/cold-store/tables/access-log.d.ts +1 -1
  66. package/dist/cold-store/tables/event-log.d.ts +1 -1
  67. package/dist/cold-store/tables/execution-jobs.d.ts +1 -1
  68. package/dist/cold-store/tables/execution-runs.d.ts +1 -1
  69. package/dist/cold-store/tables/execution-steps.d.ts +1 -1
  70. package/dist/cold-store/tables/secret-audit-log.d.ts +1 -1
  71. package/dist/config/loader.d.ts +1 -1
  72. package/dist/config/resolver.d.ts +2 -1
  73. package/dist/config/schema.d.ts +8 -6
  74. package/dist/config/types.d.ts +3 -2
  75. package/dist/config.d.ts +372 -46
  76. package/dist/contexts/binding-store.d.ts +36 -0
  77. package/dist/contexts/context-store.d.ts +100 -0
  78. package/dist/contexts/glob-specificity.d.ts +30 -0
  79. package/dist/{environments → contexts}/held-runs.d.ts +64 -32
  80. package/dist/{environments → contexts}/index.d.ts +1 -1
  81. package/dist/contexts/protection/aggregate.d.ts +43 -0
  82. package/dist/contexts/protection/branch-gate.d.ts +5 -0
  83. package/dist/contexts/protection/concurrency-gate.d.ts +4 -0
  84. package/dist/{environments → contexts}/protection/pipeline.d.ts +3 -3
  85. package/dist/contexts/protection/reviewer-gate.d.ts +4 -0
  86. package/dist/{environments → contexts}/protection/satisfiability.d.ts +22 -22
  87. package/dist/contexts/protection/trust-gate.d.ts +4 -0
  88. package/dist/contexts/protection/wait-timer-gate.d.ts +4 -0
  89. package/dist/contexts/variable-store.d.ts +39 -0
  90. package/dist/cron/cron-scheduler.d.ts +24 -4
  91. package/dist/cron/cron-store.d.ts +21 -7
  92. package/dist/dashboard/attestation-filters.d.ts +94 -74
  93. package/dist/dashboard/handler.d.ts +63 -3
  94. package/dist/db/migration-test-harness.d.ts +41 -0
  95. package/dist/db/migrations/067_environments_to_contexts.d.ts +36 -0
  96. package/dist/db/migrations/068_request_idempotency.d.ts +17 -0
  97. package/dist/db/migrations/069_reroute_tunables.d.ts +21 -0
  98. package/dist/db/migrations/070_execution_runs_failure_class.d.ts +4 -0
  99. package/dist/db/migrations/071_batch_accumulation.d.ts +26 -0
  100. package/dist/db/migrations/072_dispatch_queue_run_id_index.d.ts +15 -0
  101. package/dist/db/migrations/073_org_settings_ingest_concurrency.d.ts +13 -0
  102. package/dist/db/migrations/074_normalize_zero_concurrency_limit.d.ts +13 -0
  103. package/dist/db/migrations/075_ingest_overflow_buffer.d.ts +16 -0
  104. package/dist/db/migrations/076_artifacts.d.ts +19 -0
  105. package/dist/db/migrations/077_backup_runs.d.ts +13 -0
  106. package/dist/db/migrations/078_org_settings_backup_staleness.d.ts +12 -0
  107. package/dist/db/migrations/079_org_settings_scaler_spawn_timeout.d.ts +14 -0
  108. package/dist/db/migrations/080_cluster_settings.d.ts +17 -0
  109. package/dist/db/migrations/081_org_settings_queue_timeout.d.ts +19 -0
  110. package/dist/db/migrations/082_host_s3_reachable.d.ts +16 -0
  111. package/dist/db/migrations/083_org_settings_artifact_caps.d.ts +18 -0
  112. package/dist/db/migrations/084_orchestrator_signing_keys.d.ts +20 -0
  113. package/dist/db/migrations/085_cluster_settings_reroute_flap_grace_ms.d.ts +12 -0
  114. package/dist/db/migrations/086_cluster_settings_max_fanout_hosts.d.ts +12 -0
  115. package/dist/db/migrations/087_cluster_settings_event_router_rate_limit.d.ts +12 -0
  116. package/dist/db/migrations/088_cluster_settings_cache_max_tarball_bytes.d.ts +12 -0
  117. package/dist/db/migrations/089_cluster_settings_cache_ttl_days.d.ts +12 -0
  118. package/dist/db/migrations/090_cluster_settings_concurrency_wait_timeout_ms.d.ts +12 -0
  119. package/dist/db/migrations/091_cluster_settings_agent_token_ttl_ms.d.ts +12 -0
  120. package/dist/db/migrations/092_cluster_settings_version.d.ts +16 -0
  121. package/dist/db/migrations/093_org_settings_sandbox_allowlist.d.ts +4 -0
  122. package/dist/db/migrations/094_dashboard_encryption_keys.d.ts +21 -0
  123. package/dist/db/migrations/095_dashboard_write_policy_tristate.d.ts +20 -0
  124. package/dist/db/migrations/096_multi_schedule_cron_last_fired.d.ts +4 -0
  125. package/dist/db/migrations/097_execution_runs_pr_number.d.ts +4 -0
  126. package/dist/db/migrations/098_execution_runs_customer_id.d.ts +4 -0
  127. package/dist/db/migrations/099_cluster_settings_dashboard_verified_issuer.d.ts +21 -0
  128. package/dist/db/migrations/100_held_runs_hold_type_vocabulary.d.ts +31 -0
  129. package/dist/db/migrations/101_contexts_hold_expiry_drop_default.d.ts +31 -0
  130. package/dist/db/migrations/102_dispatch_queue_agent_id.d.ts +20 -0
  131. package/dist/db/migrations/103_cluster_settings_ownership_db_check_timeout_ms.d.ts +20 -0
  132. package/dist/db/migrations/104_check_run_terminal_sent.d.ts +22 -0
  133. package/dist/db/migrations/105_org_trust_policy.d.ts +19 -0
  134. package/dist/db/migrations/106_cluster_settings_check_run_tracking_ttl_days.d.ts +18 -0
  135. package/dist/db/migrations/107_check_run_tracking_updated_at_index.d.ts +23 -0
  136. package/dist/db/repos/dashboard-encryption-keys-repo.d.ts +48 -0
  137. package/dist/db/repos/signing-keys-repo.d.ts +34 -0
  138. package/dist/db/types.d.ts +499 -66
  139. package/dist/deployment/deployment-identity.d.ts +87 -2
  140. package/dist/diagnostics/checks/backup.d.ts +18 -0
  141. package/dist/diagnostics/checks/index.d.ts +2 -1
  142. package/dist/diagnostics/fleet-collector.d.ts +1 -1
  143. package/dist/drain/drain-controller.d.ts +52 -0
  144. package/dist/events/batch-accumulator.d.ts +63 -0
  145. package/dist/events/circuit-breaker.d.ts +9 -3
  146. package/dist/events/event-emitter.d.ts +31 -0
  147. package/dist/events/event-retry-scanner.d.ts +12 -2
  148. package/dist/events/event-router.d.ts +29 -0
  149. package/dist/firecracker/host-network.d.ts +2 -0
  150. package/dist/firecracker/net-interfaces.d.ts +14 -0
  151. package/dist/github-app-name-refresher/github-app-name-refresher.d.ts +19 -9
  152. package/dist/index.d.ts +2 -0
  153. package/dist/index.js +625 -22
  154. package/dist/lockfile-cache.d.ts +4 -0
  155. package/dist/lockfile-validate.d.ts +16 -9
  156. package/dist/metrics/prometheus.d.ts +114 -15
  157. package/dist/oidc/aws-kms-signer.d.ts +37 -0
  158. package/dist/oidc/command-signer.d.ts +23 -0
  159. package/dist/oidc/db-signer.d.ts +48 -0
  160. package/dist/oidc/id-token-claims.d.ts +76 -0
  161. package/dist/oidc/jwt.d.ts +18 -0
  162. package/dist/oidc/local-dev-signer.d.ts +31 -0
  163. package/dist/oidc/local-mint.d.ts +77 -0
  164. package/dist/oidc/oidc-mint-registration.d.ts +65 -0
  165. package/dist/oidc/orchestrator-mint.d.ts +97 -0
  166. package/dist/oidc/orchestrator-signer-factory.d.ts +33 -0
  167. package/dist/oidc/reconcile-signing-key.d.ts +21 -0
  168. package/dist/oidc/signer.d.ts +25 -0
  169. package/dist/oidc/signing-key-status.d.ts +23 -0
  170. package/dist/orchestrator-core.d.ts +42 -2
  171. package/dist/pipeline/decorating-secret-resolver.d.ts +5 -4
  172. package/dist/pipeline/dispatch-matched-workflow.d.ts +44 -3
  173. package/dist/pipeline/inline-eval.d.ts +2 -2
  174. package/dist/pipeline/install-secrets-resolver.d.ts +25 -14
  175. package/dist/pipeline/{job-environments.d.ts → job-contexts.d.ts} +23 -23
  176. package/dist/pipeline/manual-schedule.d.ts +28 -14
  177. package/dist/pipeline/pending-workflow-context.d.ts +1 -1
  178. package/dist/pipeline/process-webhook.d.ts +57 -2
  179. package/dist/pipeline/processor.d.ts +49 -13
  180. package/dist/pipeline/request-idempotency.d.ts +28 -0
  181. package/dist/pipeline/rerun.d.ts +20 -13
  182. package/dist/pipeline/resolve-sandbox-grant.d.ts +28 -0
  183. package/dist/pipeline/resume-workflow.d.ts +1 -1
  184. package/dist/pipeline/route-or-dispatch-jobs.d.ts +71 -0
  185. package/dist/pipeline/sandbox-allowlist-reader.d.ts +33 -0
  186. package/dist/pipeline/test-pipeline.d.ts +2 -2
  187. package/dist/policy/dashboard-write-policy.d.ts +9 -4
  188. package/dist/provenance/backfill-run.d.ts +1 -0
  189. package/dist/provenance/trust-root.d.ts +20 -0
  190. package/dist/provider-registry.d.ts +8 -0
  191. package/dist/providers/generic/normalizer.d.ts +1 -1
  192. package/dist/providers/github/auth.d.ts +1 -1
  193. package/dist/providers/github/changed-files.d.ts +14 -6
  194. package/dist/providers/github/check-status-poster.d.ts +19 -3
  195. package/dist/providers/github/contributor-resolver.d.ts +1 -1
  196. package/dist/providers/github/lock-file.d.ts +1 -1
  197. package/dist/providers/github/normalizer.d.ts +1 -1
  198. package/dist/providers/github/repo-url.d.ts +1 -1
  199. package/dist/providers/local/index.d.ts +1 -0
  200. package/dist/providers/local/local-source-config.d.ts +1 -0
  201. package/dist/providers/local/lock-file-fetcher.d.ts +1 -1
  202. package/dist/providers/local/normalizer.d.ts +1 -1
  203. package/dist/providers/local/repo-url-builder.d.ts +1 -1
  204. package/dist/providers/universal-git/changed-files.d.ts +8 -7
  205. package/dist/providers/universal-git/clone-token.d.ts +1 -1
  206. package/dist/providers/universal-git/config.d.ts +4 -4
  207. package/dist/providers/universal-git/index.d.ts +5 -1
  208. package/dist/providers/universal-git/lock-file.d.ts +6 -1
  209. package/dist/providers/universal-git/normalizer.d.ts +1 -1
  210. package/dist/providers/universal-git/repo-url.d.ts +1 -1
  211. package/dist/queue/cleanup.d.ts +69 -8
  212. package/dist/queue/job-queue.d.ts +94 -14
  213. package/dist/queue/scheduled-job.d.ts +2 -2
  214. package/dist/registration/registration-index.d.ts +1 -1
  215. package/dist/reporting/agent-failure-category.d.ts +4 -1
  216. package/dist/reporting/check-run-reporter.d.ts +34 -14
  217. package/dist/reporting/check-run-tracking-store.d.ts +70 -8
  218. package/dist/reporting/execution-tracker.d.ts +173 -17
  219. package/dist/reporting/fs-log-storage.d.ts +31 -2
  220. package/dist/reporting/job-check-run-completion.d.ts +50 -0
  221. package/dist/reporting/log-chunk-sink.d.ts +47 -0
  222. package/dist/reporting/log-retention.d.ts +16 -0
  223. package/dist/reporting/log-storage.d.ts +64 -4
  224. package/dist/reporting/log-writer.d.ts +22 -7
  225. package/dist/reporting/peer-log-normalize.d.ts +14 -0
  226. package/dist/reporting/run-aggregator.d.ts +36 -36
  227. package/dist/reporting/s3-log-storage.d.ts +102 -8
  228. package/dist/routes/admin-auth.d.ts +90 -0
  229. package/dist/routes/admin-cluster-settings.d.ts +31 -0
  230. package/dist/routes/admin-contexts.d.ts +47 -0
  231. package/dist/routes/admin-events.d.ts +3 -0
  232. package/dist/routes/admin-orchestrator-drain.d.ts +35 -0
  233. package/dist/routes/admin-registrations.d.ts +2 -2
  234. package/dist/routes/admin-runs.d.ts +9 -0
  235. package/dist/routes/admin-sources.d.ts +7 -0
  236. package/dist/routes/admin-trust-policy.d.ts +49 -0
  237. package/dist/routes/admin.d.ts +15 -1
  238. package/dist/routes/github-webhook.d.ts +9 -3
  239. package/dist/routes/provenance-oidc.d.ts +38 -0
  240. package/dist/routes/verify-attestation.d.ts +21 -0
  241. package/dist/scaler/bare-metal-backend.d.ts +9 -2
  242. package/dist/scaler/config.d.ts +25 -4
  243. package/dist/scaler/container-backend.d.ts +9 -1
  244. package/dist/scaler/firecracker-backend.d.ts +29 -2
  245. package/dist/scaler/index.d.ts +1 -1
  246. package/dist/scaler/manager.d.ts +166 -8
  247. package/dist/scaler/pending-scale-sweeper.d.ts +35 -0
  248. package/dist/scaler/types.d.ts +75 -6
  249. package/dist/secrets/backend-registry.d.ts +32 -1
  250. package/dist/secrets/context-secret-resolver.d.ts +30 -0
  251. package/dist/secrets/dashboard-encryption-key.d.ts +48 -0
  252. package/dist/secrets/ephemeral-keys.d.ts +16 -0
  253. package/dist/secrets/index.d.ts +1 -1
  254. package/dist/secrets/pg-secret-store.d.ts +13 -3
  255. package/dist/secrets/rbac.d.ts +5 -1
  256. package/dist/secrets/routing-key-scope.d.ts +6 -0
  257. package/dist/secrets/scope-routing.d.ts +126 -0
  258. package/dist/secrets/secret-resolver.d.ts +19 -32
  259. package/dist/secrets/token-manager.d.ts +5 -1
  260. package/dist/security/comment-handler.d.ts +1 -1
  261. package/dist/security/contributor-cache.d.ts +9 -1
  262. package/dist/security/trust-policy-gate.d.ts +117 -0
  263. package/dist/security/trust-policy-store.d.ts +78 -0
  264. package/dist/server.js +44012 -32721
  265. package/dist/sources/source-manager.d.ts +24 -0
  266. package/dist/stale-detector/stale-run-detector.d.ts +8 -1
  267. package/dist/standalone.js +44106 -33690
  268. package/dist/storage/blob-routes.d.ts +16 -0
  269. package/dist/storage/filesystem.d.ts +17 -0
  270. package/dist/storage/key-discriminator.d.ts +20 -0
  271. package/dist/storage/s3.d.ts +2 -0
  272. package/dist/storage/types.d.ts +16 -0
  273. package/dist/webhook/dedup.d.ts +9 -1
  274. package/dist/webhook/event-log.d.ts +13 -2
  275. package/dist/webhook/generic-sources-listener.d.ts +4 -0
  276. package/dist/webhook/ingest-admission.d.ts +140 -0
  277. package/dist/webhook/ingest-overflow-buffer.d.ts +27 -0
  278. package/dist/webhook/ingest-overflow-replayer.d.ts +49 -0
  279. package/dist/webhook/ingest-overflow-types.d.ts +73 -0
  280. package/dist/webhook/loop-lag-source.d.ts +40 -0
  281. package/dist/webhook/observed-relay-guard.d.ts +40 -0
  282. package/dist/webhook/org-ingest-cap-reader.d.ts +24 -0
  283. package/dist/webhook/register-source-bundle.d.ts +3 -0
  284. package/dist/webhook/relay-reinject.d.ts +43 -0
  285. package/dist/worker/in-memory-job-queue.d.ts +8 -3
  286. package/dist/worker-core.d.ts +10 -0
  287. package/dist/ws/agent-api-registry.d.ts +20 -0
  288. package/dist/ws/agent-handler.d.ts +63 -7
  289. package/dist/ws/bringup-api.d.ts +99 -0
  290. package/dist/ws/{dashboard-env-handler.d.ts → dashboard-context-handler.d.ts} +43 -25
  291. package/dist/ws/dashboard-run-state-handler.d.ts +31 -0
  292. package/dist/ws/failure-messages.d.ts +29 -0
  293. package/dist/ws/oidc-token-relay.d.ts +15 -0
  294. package/dist/ws/ownership-gate.d.ts +22 -0
  295. package/dist/ws/platform-client.d.ts +96 -1
  296. package/dist/ws/replay-chunker.d.ts +37 -0
  297. package/installer-image-digests.json +3 -3
  298. package/package.json +22 -21
  299. package/sbom.spdx.json +1245 -1793
  300. package/dist/cli/commands/environment.d.ts +0 -25
  301. package/dist/environments/binding-store.d.ts +0 -36
  302. package/dist/environments/environment-store.d.ts +0 -87
  303. package/dist/environments/protection/aggregate.d.ts +0 -43
  304. package/dist/environments/protection/branch-gate.d.ts +0 -5
  305. package/dist/environments/protection/concurrency-gate.d.ts +0 -7
  306. package/dist/environments/protection/reviewer-gate.d.ts +0 -7
  307. package/dist/environments/protection/trust-gate.d.ts +0 -7
  308. package/dist/environments/protection/wait-timer-gate.d.ts +0 -7
  309. package/dist/environments/variable-store.d.ts +0 -39
  310. package/dist/routes/admin-environments.d.ts +0 -47
@@ -11,9 +11,25 @@
11
11
  * filesystem backend is active (`deps.fsCache` truthy in app.ts).
12
12
  */
13
13
  import type { Hono } from 'hono';
14
+ /**
15
+ * URL prefix for the filesystem-backend blob transfer route. The app-level
16
+ * webhook body-size cap MUST exempt this prefix: blob PUTs carry internal
17
+ * artifacts (dependency tarballs up to `cacheMaxTarballBytes`, 500MB by
18
+ * default), which the S3 backend uploads direct-to-S3 uncapped. Binding them
19
+ * to the tenant-webhook body limit would 413 legitimate large caches on the
20
+ * filesystem backend. The PUT route below enforces its own `maxUploadBytes`
21
+ * bound instead.
22
+ */
23
+ export declare const CACHE_BLOB_PATH_PREFIX = "/api/v1/cache/blob/";
14
24
  export interface FsCacheRouteDeps {
15
25
  basePath: string;
16
26
  signingSecret: string;
27
+ /**
28
+ * Upper bound on a single blob PUT, in bytes. Aligned with the dep-cache's
29
+ * `cacheMaxTarballBytes` (500MB default) so the filesystem backend accepts
30
+ * the same artifact sizes the S3 backend does.
31
+ */
32
+ maxUploadBytes: number;
17
33
  }
18
34
  /** Mount filesystem-backend cache routes onto an existing Hono app. */
19
35
  export declare function registerBlobRoutes(app: Hono, deps: FsCacheRouteDeps): void;
@@ -51,11 +51,28 @@ export declare class FilesystemCacheStorage implements CacheStorage {
51
51
  delete(key: string): Promise<boolean>;
52
52
  touch(key: string): Promise<void>;
53
53
  getUrl(key: string, ttlMsOverride?: number): Promise<string | null>;
54
+ presignedGetTtlSeconds(): number;
54
55
  getUploadUrl(key: string): Promise<string>;
55
56
  getInternalUploadUrl(key: string): Promise<string>;
56
57
  initMeta(key: string): Promise<void>;
58
+ /**
59
+ * List cache keys under a prefix.
60
+ *
61
+ * The prefix is a **key prefix**, not necessarily a directory — `UserCache`'s
62
+ * `restoreKeys` fallback lists on `${prefix}${seg(restoreKey)}`, a partial
63
+ * object name. Two shapes, and both must work the way the S3 backend does:
64
+ *
65
+ * - trailing `/` — a directory. Walk it directly; this is the hot path.
66
+ * - no trailing `/` — a partial name. Walk the parent directory and filter by
67
+ * the prefix, since the prefix itself may name a file (or nothing at all).
68
+ *
69
+ * Reading the prefix as a directory in the second case is what made the
70
+ * `restoreKeys` fallback silently never hit here (`ENOENT` → `[]`) or throw
71
+ * (`ENOTDIR`, when a real object carried that exact name).
72
+ */
57
73
  list(subPrefix: string): Promise<string[]>;
58
74
  getMetadata(key: string): Promise<CacheMetadata | null>;
75
+ getObjectSize(key: string): Promise<number | null>;
59
76
  copy(srcKey: string, destKey: string): Promise<void>;
60
77
  /**
61
78
  * Recursively collect data files under `dir`, returning each as a cache key
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Width of the object-key discriminator, in hex characters.
3
+ *
4
+ * 32 hex chars is 128 bits, and the width is a security property rather than a
5
+ * formatting choice: on a case-insensitive namespace the discriminator is the
6
+ * only thing separating object names chosen by untrusted workflow code. A
7
+ * narrower value would let that code search case variants for a colliding pair
8
+ * and land two different payloads on one object.
9
+ */
10
+ export declare const KEY_DISCRIMINATOR_LENGTH = 32;
11
+ /**
12
+ * A collision-resistant discriminator for a user-supplied object-key segment.
13
+ *
14
+ * Hashes the **exact** name, before any sanitization. Sanitizing is many-to-one
15
+ * — `seg()` maps both `/` and `_` to `_`, so `a/b` and `a_b` collapse to one
16
+ * segment — and a case-insensitive backend folds `build` onto `Build`. Hashing
17
+ * the pre-sanitization name is what keeps each of those pairs two objects.
18
+ */
19
+ export declare function keyDiscriminator(exact: string): string;
20
+ //# sourceMappingURL=key-discriminator.d.ts.map
@@ -70,11 +70,13 @@ export declare class S3CacheStorage implements CacheStorage {
70
70
  delete(key: string): Promise<boolean>;
71
71
  touch(key: string): Promise<void>;
72
72
  getUrl(key: string, ttlMsOverride?: number): Promise<string | null>;
73
+ presignedGetTtlSeconds(): number;
73
74
  getUploadUrl(key: string): Promise<string>;
74
75
  getInternalUploadUrl(key: string): Promise<string>;
75
76
  initMeta(key: string): Promise<void>;
76
77
  list(subPrefix: string): Promise<string[]>;
77
78
  getMetadata(key: string): Promise<CacheMetadata | null>;
79
+ getObjectSize(key: string): Promise<number | null>;
78
80
  copy(srcKey: string, destKey: string): Promise<void>;
79
81
  /** Delete an S3 object. Idempotent (doesn't error if missing). */
80
82
  private deleteObject;
@@ -51,6 +51,15 @@ export interface CacheStorage {
51
51
  * `ttlMsOverride` applies a per-operation TTL (see `get`).
52
52
  */
53
53
  getUrl(key: string, ttlMsOverride?: number): Promise<string | null>;
54
+ /**
55
+ * The validity window, in seconds, of the pre-signed download URLs this
56
+ * backend mints via `getUrl` — i.e. how long after minting a `getUrl` link
57
+ * still authorizes a download before its signature expires. This is the
58
+ * signature expiry, NOT the artifact-retention TTL; consumers that render a
59
+ * `getUrl` link (e.g. the dashboard artifacts panel) use it to refresh the
60
+ * link before it stops working.
61
+ */
62
+ presignedGetTtlSeconds(): number;
54
63
  /**
55
64
  * Generate a pre-signed PUT URL for direct agent upload.
56
65
  * Uses the external endpoint (container-routable) when configured.
@@ -86,6 +95,13 @@ export interface CacheStorage {
86
95
  * eviction to order candidates by access recency.
87
96
  */
88
97
  getMetadata(key: string): Promise<CacheMetadata | null>;
98
+ /**
99
+ * Byte size of the stored object, or null when the object is missing. A pure
100
+ * stat — no metadata write and no TTL/last-accessed side effect. Used to
101
+ * verify an artifact's real size server-side instead of trusting the
102
+ * agent-declared value.
103
+ */
104
+ getObjectSize(key: string): Promise<number | null>;
89
105
  }
90
106
  import type { SharedS3Config } from '@kici-dev/shared';
91
107
  /**
@@ -1,5 +1,6 @@
1
1
  import type { Kysely } from 'kysely';
2
2
  import type { Database } from '../db/types.js';
3
+ import type { ClusterSettingsReader } from '../cluster/cluster-settings-reader.js';
3
4
  /**
4
5
  * Delivery ID deduplication cache with dual-layer storage:
5
6
  * 1. In-memory Set for hot-path performance (last 10,000 IDs)
@@ -12,7 +13,14 @@ export declare class DedupCache {
12
13
  private readonly db;
13
14
  private readonly memoryCache;
14
15
  private readonly insertionOrder;
15
- constructor(db: Kysely<Database>);
16
+ private readonly clusterSettings?;
17
+ private readonly defaultTtlMs;
18
+ constructor(db: Kysely<Database>, opts?: {
19
+ clusterSettings?: ClusterSettingsReader;
20
+ defaultTtlMs?: number;
21
+ });
22
+ /** Resolve the fleet-wide dedup TTL (ms), falling back to the config default. */
23
+ private ttlMs;
16
24
  /**
17
25
  * Check if a delivery ID has already been processed.
18
26
  * Checks in-memory cache first (fast path), then DB.
@@ -2,11 +2,18 @@ import { EventLogStatus, EventLogSource } from '@kici-dev/engine';
2
2
  import type { Kysely } from 'kysely';
3
3
  import type { Database } from '../db/types.js';
4
4
  import type { LogStorage } from '../reporting/log-storage.js';
5
+ import type { ClusterSettingsReader } from '../cluster/cluster-settings-reader.js';
5
6
  import type { WebhookInfo } from './handler.js';
6
7
  /** Configuration for the writer. */
7
8
  export interface EventLogWriterOptions {
8
- /** Soft cap in bytes for payload upload (default 5 MB). */
9
+ /**
10
+ * Cluster-wide fallback soft cap in bytes for payload upload (default 5 MB),
11
+ * used when no live `cluster_settings.event_log_max_payload_bytes` override
12
+ * is set. Read per-write through {@link ClusterSettingsReader}.
13
+ */
9
14
  maxPayloadBytes: number;
15
+ /** Optional fleet-wide settings reader; when present overrides maxPayloadBytes per write. */
16
+ clusterSettings?: ClusterSettingsReader;
10
17
  }
11
18
  /**
12
19
  * Outcome metadata recorded alongside the delivery row.
@@ -30,7 +37,11 @@ export interface EventLogOutcome {
30
37
  ref?: string | null;
31
38
  /** First run spawned by this delivery. */
32
39
  runId?: string | null;
33
- /** Failure reason when status='failed'. */
40
+ /**
41
+ * Failure reason when status='failed', or a degraded-evaluation note on a
42
+ * status='processed' row (e.g. path filters matched conservatively against
43
+ * an unavailable changed-files diff). Free-text; not tied to a single status.
44
+ */
34
45
  errorMessage?: string | null;
35
46
  }
36
47
  /**
@@ -39,6 +39,7 @@ import type { GenericSourceManager } from './generic-sources.js';
39
39
  import type { ProviderRegistry } from '../provider-registry.js';
40
40
  import type { AppConfig } from '../config.js';
41
41
  import type { SecretResolver } from '../secrets/secret-resolver.js';
42
+ import type { ClusterSettingsReader } from '../cluster/cluster-settings-reader.js';
42
43
  export interface GenericSourcesChangeListenerOptions {
43
44
  /** Raw pg pool — a dedicated PoolClient is checked out for LISTEN. */
44
45
  pool: pg.Pool;
@@ -51,6 +52,9 @@ export interface GenericSourcesChangeListenerOptions {
51
52
  /** Required for universal-git source rows; null is acceptable on
52
53
  * peers that cannot serve them. */
53
54
  secretResolver: SecretResolver | null;
55
+ /** Fleet-wide settings reader; threads the live lock-file cap into warm-path
56
+ * universal-git fetcher registration. */
57
+ clusterSettings?: ClusterSettingsReader;
54
58
  /** Active scaler backend on this peer. Threaded into the warm-path
55
59
  * registration so a local source added at runtime on a container /
56
60
  * firecracker scaler emits the same reachability warning as a cold-boot one. */
@@ -0,0 +1,140 @@
1
+ import { z } from 'zod';
2
+ import type { LoopLagSource } from './loop-lag-source.js';
3
+ /**
4
+ * Reasons a webhook-ingest admission is shed by the {@link IngestAdmissionController}.
5
+ *
6
+ * - `loop_overload` — the event-loop-lag gate is latched open (p99 delay above
7
+ * the shed threshold); admission sheds immediately, DB-free.
8
+ * - `codel_drop` — the CoDel controlled-delay queue is standing (minimum
9
+ * sojourn stayed above target for a full interval); the head is dropped.
10
+ * - `queue_full` — the bounded queue is at capacity, or the caller disallowed
11
+ * queueing (the WS relay path) and no slot was immediately available.
12
+ * - `max_sojourn` — a waiter exceeded the hard sojourn ceiling (< the Platform
13
+ * WS ack timeout) and is dropped so nothing waits past the caller's timeout.
14
+ */
15
+ export declare const IngestShedReason: z.ZodEnum<{
16
+ codel_drop: "codel_drop";
17
+ loop_overload: "loop_overload";
18
+ max_sojourn: "max_sojourn";
19
+ queue_full: "queue_full";
20
+ }>;
21
+ export type IngestShedReason = z.infer<typeof IngestShedReason>;
22
+ export type AdmitResult = {
23
+ admitted: true;
24
+ release: () => void;
25
+ } | {
26
+ admitted: false;
27
+ reason: IngestShedReason;
28
+ };
29
+ /** Per-call admission options. */
30
+ export interface AdmitOptions {
31
+ /**
32
+ * When true (HTTP direct ingress), a request that cannot be admitted
33
+ * immediately is enqueued on the CoDel queue. When false (Platform-WS relay,
34
+ * whose ack the Platform awaits synchronously with a 5 s budget), no queueing
35
+ * happens — the request is granted immediately or shed `queue_full` at once.
36
+ */
37
+ allowQueue?: boolean;
38
+ }
39
+ export interface IngestAdmissionConfig {
40
+ maxConcurrency: number;
41
+ maxQueueDepth: number;
42
+ codelTargetMs: number;
43
+ codelIntervalMs: number;
44
+ queueMaxWaitMs: number;
45
+ loopLagShedMs: number;
46
+ loopLagResumeMs: number;
47
+ loopLagSampleMs: number;
48
+ }
49
+ export interface IngestAdmissionSnapshot {
50
+ inflight: number;
51
+ queueDepth: number;
52
+ sheddingActive: boolean;
53
+ loopDelayP99Ms: number;
54
+ loopDelayMaxMs: number;
55
+ }
56
+ export interface IngestAdmissionDeps {
57
+ config: IngestAdmissionConfig;
58
+ loopLag: LoopLagSource;
59
+ /** injectable clock (default Date.now). */
60
+ now?: () => number;
61
+ /** durable-buffer seam (default no-op) — a future replay buffer plugs in here. */
62
+ onShed?: (reason: IngestShedReason, key: string) => void;
63
+ /** metric hook: shed counter increment (keeps the controller OTel-free). */
64
+ onShedMetric?: (reason: IngestShedReason) => void;
65
+ /** metric hook: admitted counter increment. */
66
+ onAdmitMetric?: () => void;
67
+ /** metric hook: state gauges refresh. */
68
+ onStateChange?: (s: IngestAdmissionSnapshot) => void;
69
+ /** start the real sweep timer (default true; unit tests pass false and drive tickQueue/sampleLoopLag). */
70
+ startTimer?: boolean;
71
+ }
72
+ /**
73
+ * Single-process admission controller for the webhook-ingest pipeline. Three
74
+ * layers evaluated in order on {@link admit}: (1) an event-loop-lag gate (the
75
+ * DB-free adaptive signal), (2) hard global + per-org caps (memory backstop +
76
+ * fairness), (3) a CoDel controlled-delay queue (burst absorption without
77
+ * bufferbloat). Shed is lossy — the caller redelivers.
78
+ */
79
+ export declare class IngestAdmissionController {
80
+ private readonly cfg;
81
+ private readonly loopLag;
82
+ private readonly now;
83
+ private readonly onShedSeam;
84
+ private readonly onShedMetric?;
85
+ private readonly onAdmitMetric?;
86
+ private readonly onStateChange?;
87
+ private globalInflight;
88
+ private readonly perKeyInflight;
89
+ private readonly queue;
90
+ private loopP99;
91
+ private loopMax;
92
+ /** Hysteresis latch for the loop-lag gate (open = shedding). */
93
+ private loopGateOpen;
94
+ /** CoDel: timestamp the head sojourn first rose above target; undefined when below. */
95
+ private codelAboveSince;
96
+ private codelDropping;
97
+ private readonly sweepTimer;
98
+ private stopped;
99
+ constructor(deps: IngestAdmissionDeps);
100
+ private keyInflight;
101
+ private incKey;
102
+ private decKey;
103
+ isShedding(): boolean;
104
+ snapshot(): IngestAdmissionSnapshot;
105
+ private emit;
106
+ /**
107
+ * Sample the loop-lag source into the snapshot and update the hysteresis
108
+ * latch. Called on the sweep interval (production) or directly (tests).
109
+ */
110
+ sampleLoopLag(): void;
111
+ private canAdmit;
112
+ private makeRelease;
113
+ private grant;
114
+ private shed;
115
+ /**
116
+ * @param key fairness key — org id (preferred) or routing key (DB-degraded fallback).
117
+ * @param orgCap per-key concurrency cap P (from the cached settings reader).
118
+ */
119
+ admit(key: string, orgCap: number, opts?: AdmitOptions): Promise<AdmitResult>;
120
+ /**
121
+ * Drive the queue: admit admissible waiters (fair skip of maxed keys), sweep
122
+ * the hard sojourn ceiling, then evaluate CoDel on the head. Called on every
123
+ * release and on the sweep interval; also test-drivable with the injected clock.
124
+ */
125
+ tickQueue(): void;
126
+ /** Release-driven fair dequeue: admit the first admissible waiter, skip maxed keys. */
127
+ private admitWaiters;
128
+ /** Hard sojourn ceiling: shed any waiter that waited past W_max. */
129
+ private sweepMaxSojourn;
130
+ /**
131
+ * CoDel head evaluation. While the head sojourn is below target, reset the
132
+ * dropping state (a transient burst drains cleanly). Once the head has stayed
133
+ * at/above target continuously for a full interval, enter the dropping state
134
+ * and shed the head each sweep until sojourn recovers below target.
135
+ */
136
+ private codelEval;
137
+ /** Stop the sweep timer and drain the queue (every waiter resolves as shed). */
138
+ stop(): void;
139
+ }
140
+ //# sourceMappingURL=ingest-admission.d.ts.map
@@ -0,0 +1,27 @@
1
+ import type { Kysely } from 'kysely';
2
+ import type { Database } from '../db/types.js';
3
+ import { type OverflowDelivery } from './ingest-overflow-types.js';
4
+ export interface IngestOverflowBufferDeps {
5
+ db: Kysely<Database>;
6
+ /** Buffered-row cap (KICI_INGEST_OVERFLOW_MAX). */
7
+ maxRows: number;
8
+ }
9
+ /**
10
+ * Capture side of the durable overflow buffer. On a shed, the ingest path calls
11
+ * {@link IngestOverflowBuffer.capture} additively (the 429 still stands). At the
12
+ * row cap, capture drops the delivery from the buffer (never unbounded rows) —
13
+ * the lossy fallback a retrying sender still covers.
14
+ */
15
+ export declare class IngestOverflowBuffer {
16
+ private readonly db;
17
+ private readonly maxRows;
18
+ constructor(deps: IngestOverflowBufferDeps);
19
+ /** Current buffered-row depth. */
20
+ currentDepth(): Promise<number>;
21
+ /**
22
+ * Persist a shed delivery. Returns true when a `buffered` row was inserted,
23
+ * false when the buffer is at cap (delivery dropped, `cap_full` metric bumped).
24
+ */
25
+ capture(d: OverflowDelivery): Promise<boolean>;
26
+ }
27
+ //# sourceMappingURL=ingest-overflow-buffer.d.ts.map
@@ -0,0 +1,49 @@
1
+ import type { Kysely } from 'kysely';
2
+ import type { Database } from '../db/types.js';
3
+ import { WebhookIngestOutcome } from '../pipeline/process-webhook.js';
4
+ import { type OverflowDelivery } from './ingest-overflow-types.js';
5
+ export type ReinjectFn = (d: OverflowDelivery) => Promise<WebhookIngestOutcome>;
6
+ export interface IngestOverflowReplayerDeps {
7
+ db: Kysely<Database>;
8
+ controller: {
9
+ isShedding(): boolean;
10
+ };
11
+ intervalMs: number;
12
+ batchSize: number;
13
+ maxAttempts: number;
14
+ }
15
+ /**
16
+ * Background drain for the durable overflow buffer. A pass runs only while the
17
+ * admission controller is NOT shedding (replaying into a still-overloaded
18
+ * orchestrator just re-sheds), claims the oldest `buffered` rows FIFO up to a
19
+ * bounded batch, and re-injects each through the admission-gated ingest path.
20
+ * A re-shed or error reverts the row to `buffered` (never lost); past the
21
+ * max-attempts ceiling it goes `failed`. Successful rows are swept.
22
+ */
23
+ export declare class IngestOverflowReplayer {
24
+ private readonly db;
25
+ private readonly controller;
26
+ private readonly intervalMs;
27
+ private readonly batchSize;
28
+ private readonly maxAttempts;
29
+ private reinjectDirect;
30
+ private reinjectRelay;
31
+ private timer;
32
+ private running;
33
+ private stopped;
34
+ constructor(deps: IngestOverflowReplayerDeps);
35
+ setReinjectDirect(fn: ReinjectFn): void;
36
+ setReinjectRelay(fn: ReinjectFn): void;
37
+ start(): void;
38
+ stop(): void;
39
+ /** One drain pass. Test-drivable. */
40
+ runPass(): Promise<void>;
41
+ /** Select the oldest buffered rows and claim each via a conditional update. */
42
+ private claimBatch;
43
+ private toDelivery;
44
+ private replayOne;
45
+ private revertOrFail;
46
+ private sweepReplayed;
47
+ private refreshDepthGauge;
48
+ }
49
+ //# sourceMappingURL=ingest-overflow-replayer.d.ts.map
@@ -0,0 +1,73 @@
1
+ import { z } from 'zod';
2
+ import type { WebhookInfo } from './handler.js';
3
+ import type { RelayStartMeta } from './relay-buffer.js';
4
+ /**
5
+ * Lifecycle of a durably-buffered shed delivery.
6
+ *
7
+ * - `buffered` — captured, awaiting replay.
8
+ * - `replaying` — claimed by a replay pass (a conditional-update lock so a
9
+ * restart / second loop cannot double-claim the same row).
10
+ * - `replayed` — successfully re-injected through normal ingest; swept.
11
+ * - `failed` — re-shed / errored past the max-attempts ceiling; kept for
12
+ * operator inspection with `last_error`.
13
+ */
14
+ export declare const OverflowStatus: z.ZodEnum<{
15
+ buffered: "buffered";
16
+ failed: "failed";
17
+ replayed: "replayed";
18
+ replaying: "replaying";
19
+ }>;
20
+ export type OverflowStatus = z.infer<typeof OverflowStatus>;
21
+ /**
22
+ * Which ingest boundary captured the delivery, and therefore how it is replayed:
23
+ *
24
+ * - `direct` — HTTP direct-ingress. The delivery was already signature-verified
25
+ * and normalized at ingest; replay re-injects the stored `WebhookInfo` through
26
+ * the admission-gated HTTP path (no re-verification).
27
+ * - `relay` — Platform-WS relay. The delivery was shed BEFORE signature
28
+ * verification; replay MUST re-verify the raw body against the stored headers.
29
+ */
30
+ export declare const OverflowSourceKind: z.ZodEnum<{
31
+ direct: "direct";
32
+ relay: "relay";
33
+ }>;
34
+ export type OverflowSourceKind = z.infer<typeof OverflowSourceKind>;
35
+ /** Reasons a delivery is permanently dropped from the overflow buffer. */
36
+ export declare const OverflowDropReason: z.ZodEnum<{
37
+ cap_full: "cap_full";
38
+ max_attempts: "max_attempts";
39
+ }>;
40
+ export type OverflowDropReason = z.infer<typeof OverflowDropReason>;
41
+ /** Verify-input envelope for a `relay`-origin delivery (mirrors RelayStartMeta). */
42
+ export interface OverflowRelayMeta {
43
+ signatureHeaderName: string | null;
44
+ signatureHeader: string | null;
45
+ clientIp: string | null;
46
+ headers: Record<string, string>;
47
+ requestId?: string;
48
+ }
49
+ /** A delivery captured for durable overflow replay. */
50
+ export interface OverflowDelivery {
51
+ deliveryId: string;
52
+ routingKey: string;
53
+ sourceKind: OverflowSourceKind;
54
+ /** Provider type (direct: from WebhookInfo; relay: resolved at replay). */
55
+ provider: string | null;
56
+ event: string;
57
+ action: string | null;
58
+ /**
59
+ * Base64 of the raw delivery bytes. For `direct` this is the JSON-serialized
60
+ * payload; for `relay` it is the verbatim wire body (base64 preserves bytes so
61
+ * a non-JSON generic payload replays intact and HMAC re-verification matches).
62
+ */
63
+ body: string;
64
+ /** Verify metadata; empty for `direct` (already verified). */
65
+ meta: OverflowRelayMeta;
66
+ }
67
+ /** Build a capture record from a verified HTTP-direct `WebhookInfo`. */
68
+ export declare function deliveryFromDirect(info: WebhookInfo): OverflowDelivery;
69
+ /** Build a capture record from a pre-verify WS relay `meta` + raw body. */
70
+ export declare function deliveryFromRelay(meta: RelayStartMeta, body: Buffer): OverflowDelivery;
71
+ /** Reconstruct a normalized `WebhookInfo` from a `direct`-origin delivery. */
72
+ export declare function overflowDeliveryToInfo(d: OverflowDelivery): WebhookInfo;
73
+ //# sourceMappingURL=ingest-overflow-types.d.ts.map
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Event-loop delay source for the ingest admission controller's adaptive gate.
3
+ *
4
+ * The controller reads p99/max loop delay on a short interval to decide whether
5
+ * to shed. Hiding the real `perf_hooks` primitive behind this interface lets the
6
+ * gate decision logic and the real sampler be tested separately: the controller
7
+ * unit tests drive a {@link FakeLoopLagSource} with caller-controlled values, and
8
+ * {@link RealLoopLagSource} has its own busy-spin detection test.
9
+ */
10
+ export interface LoopLagSource {
11
+ /** p99 event-loop delay in ms over the current window. */
12
+ p99(): number;
13
+ /** max event-loop delay in ms over the current window. */
14
+ max(): number;
15
+ /** reset the window's histogram (start a fresh measurement window). */
16
+ reset(): void;
17
+ /** stop the underlying monitor (real source only; no-op on the fake). */
18
+ stop(): void;
19
+ }
20
+ /** Real source backed by `perf_hooks.monitorEventLoopDelay`. */
21
+ export declare class RealLoopLagSource implements LoopLagSource {
22
+ private readonly h;
23
+ constructor(resolutionMs?: number);
24
+ p99(): number;
25
+ max(): number;
26
+ reset(): void;
27
+ stop(): void;
28
+ }
29
+ /** Deterministic test double returning caller-controlled p99/max values. */
30
+ export declare class FakeLoopLagSource implements LoopLagSource {
31
+ private _p99;
32
+ private _max;
33
+ setP99(v: number): void;
34
+ setMax(v: number): void;
35
+ p99(): number;
36
+ max(): number;
37
+ reset(): void;
38
+ stop(): void;
39
+ }
40
+ //# sourceMappingURL=loop-lag-source.d.ts.map
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Client-side half of the `observed`-mode "no relay, ever" guarantee.
3
+ *
4
+ * An `observed` orchestrator ingests only its OWN webhooks — providers post
5
+ * straight to its public URL and nothing transits the hosted Platform. The
6
+ * Platform never selects an observed connection as a relay target, so a relay
7
+ * reaching one is a defect somewhere upstream. These handlers make that case
8
+ * loud and inert instead of silently processing the payload.
9
+ */
10
+ import { WebhookRelayResult } from '@kici-dev/engine';
11
+ /** Thrown when a Platform relay reaches an observed-mode orchestrator. */
12
+ export declare class ObservedRelayRefusedError extends Error {
13
+ constructor(routingKey: string);
14
+ }
15
+ /** Reason string returned on both the verify and the refusal paths. */
16
+ export declare const OBSERVED_RELAY_REFUSAL_REASON = "orchestrator is in observed mode and does not accept Platform-relayed webhooks";
17
+ /** Minimal logger surface the guard needs (keeps the module test-friendly). */
18
+ type WarnLogger = {
19
+ warn: (message: string, meta?: Record<string, unknown>) => void;
20
+ };
21
+ /**
22
+ * `onVerifyInbound` for observed mode: refuse every relayed webhook at verify
23
+ * time, so the Platform gets a definitive `rejected_misconfigured` ack instead
24
+ * of a timeout.
25
+ */
26
+ export declare function observedRelayVerify(): {
27
+ result: WebhookRelayResult;
28
+ reason: string;
29
+ };
30
+ /**
31
+ * `onWebhookRelay` for observed mode: log loudly and reject so nothing is
32
+ * processed. Rejecting (rather than returning) keeps the failure visible in the
33
+ * Platform client's relay error path.
34
+ */
35
+ export declare function observedRelayReject(logger: WarnLogger, meta: {
36
+ routingKey: string;
37
+ deliveryId?: string;
38
+ }): Promise<void>;
39
+ export {};
40
+ //# sourceMappingURL=observed-relay-guard.d.ts.map
@@ -0,0 +1,24 @@
1
+ import type { Kysely } from 'kysely';
2
+ import type { Database } from '../db/types.js';
3
+ /** The resolved fairness key + per-key concurrency cap for an ingest admission. */
4
+ export interface AdmissionKey {
5
+ key: string;
6
+ orgCap: number;
7
+ }
8
+ export interface OrgIngestCapReader {
9
+ /**
10
+ * Resolve the fairness key + per-org cap for a routing key. Never throws; on a
11
+ * DB error / cold-miss-slow it degrades to `{ key: routingKey, orgCap:
12
+ * clusterDefault }` (per-routing-key fairness, DB-free) so admission never
13
+ * blocks on a sick DB.
14
+ */
15
+ resolve(routingKey: string): Promise<AdmissionKey>;
16
+ }
17
+ export declare function createOrgIngestCapReader(deps: {
18
+ db?: Kysely<Database>;
19
+ clusterDefault: number;
20
+ orgTtlMs?: number;
21
+ capTtlMs?: number;
22
+ maxEntries?: number;
23
+ }): OrgIngestCapReader;
24
+ //# sourceMappingURL=org-ingest-cap-reader.d.ts.map
@@ -33,6 +33,7 @@
33
33
  import type { AppConfig } from '../config.js';
34
34
  import type { ProviderRegistry } from '../provider-registry.js';
35
35
  import type { SecretResolver } from '../secrets/secret-resolver.js';
36
+ import type { ClusterSettingsReader } from '../cluster/cluster-settings-reader.js';
36
37
  import type { GenericWebhookSource } from '../db/types.js';
37
38
  export interface RegisterSourceBundleDeps {
38
39
  providerRegistry: ProviderRegistry;
@@ -40,6 +41,8 @@ export interface RegisterSourceBundleDeps {
40
41
  /** Required for universal-git source rows. Null is allowed; rows that
41
42
  * carry `git_config` will be skipped with a metric bump. */
42
43
  secretResolver: SecretResolver | null;
44
+ /** Fleet-wide settings reader; threads the live lock-file cap into universal-git fetchers. */
45
+ clusterSettings?: ClusterSettingsReader;
43
46
  /** Active scaler backend on this peer. When 'container' or 'firecracker', a
44
47
  * local source registration emits a one-time reachability warning (the repo
45
48
  * must exist inside the agent filesystem, not just on the orchestrator host). */
@@ -0,0 +1,43 @@
1
+ import type { AdmitResult } from './ingest-admission.js';
2
+ import type { WebhookInfo } from './handler.js';
3
+ import { WebhookIngestOutcome } from '../pipeline/process-webhook.js';
4
+ import type { OverflowDelivery } from './ingest-overflow-types.js';
5
+ import type { ReinjectFn } from './ingest-overflow-replayer.js';
6
+ /** Verify outcome shape the reinject cares about (subset of VerifyOutcome). */
7
+ export interface RelayVerifyResult {
8
+ result: string;
9
+ }
10
+ /**
11
+ * Collaborator seams for {@link buildRelayReinject}. Injected so the reinject
12
+ * orchestration + payload parsing can be unit-tested without the DB / secret
13
+ * store / provider registry. server.ts wires these to the real subsystems.
14
+ */
15
+ export interface RelayReinjectSeams {
16
+ /**
17
+ * Re-admit on the routing key (allowQueue:false — same non-queueing gate the
18
+ * live relay path uses). A re-shed maps the reinject to `shed` so the replayer
19
+ * reverts the row to `buffered`.
20
+ */
21
+ admit: (routingKey: string) => Promise<AdmitResult>;
22
+ /** Re-verify the raw body against the stored headers. */
23
+ verify: (d: OverflowDelivery, body: Buffer) => Promise<RelayVerifyResult>;
24
+ /** Resolve the provider string for a routing key (bundle → prefix fallback). */
25
+ resolveProvider: (routingKey: string) => string;
26
+ /** Process a verified, normalized delivery through the relay ingest pipeline. */
27
+ process: (info: WebhookInfo) => Promise<WebhookIngestOutcome>;
28
+ }
29
+ /**
30
+ * Parse a captured relay body into a payload object, mirroring the live relay
31
+ * path's content-type handling: JSON (or empty content-type) → parsed object;
32
+ * anything else → `{ rawBody, contentType }`. An empty body is an empty object.
33
+ */
34
+ export declare function parseRelayPayload(body: Buffer, headers: Record<string, string>): Record<string, unknown>;
35
+ /**
36
+ * Build the relay-origin overflow re-injector. Re-admits on the routing key,
37
+ * re-verifies the stored raw body (relay deliveries are captured pre-verify),
38
+ * normalizes it, and processes it through the admission-gated relay pipeline.
39
+ * A re-shed maps to `shed` (revert); a verify miss maps to `skipped` (terminal
40
+ * — the delivery is no longer routable, so it is not retried forever).
41
+ */
42
+ export declare function buildRelayReinject(seams: RelayReinjectSeams): ReinjectFn;
43
+ //# sourceMappingURL=relay-reinject.d.ts.map