@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
@@ -0,0 +1,100 @@
1
+ import { type Kysely } from 'kysely';
2
+ import type { ConcurrencyStrategy, Context as EngineContext } from '@kici-dev/engine';
3
+ import type { Database, Context } from '../db/types.js';
4
+ /** Thrown by `delete` when pending held runs reference the context. */
5
+ export declare class ContextDeleteBlockedError extends Error {
6
+ readonly pendingCount: number;
7
+ constructor(pendingCount: number);
8
+ }
9
+ /**
10
+ * Map a DB context row (snake_case) to the engine Context type (camelCase).
11
+ *
12
+ * Kysely returns JSONB columns as strings; this function parses them into arrays.
13
+ */
14
+ export declare function toContext(row: Context): EngineContext;
15
+ /** Fields accepted when creating a context. */
16
+ export interface ContextCreateInput {
17
+ name: string;
18
+ type?: 'fixed' | 'glob';
19
+ globPattern?: string | null;
20
+ branchRestrictions?: string[];
21
+ triggerTypeFilters?: string[];
22
+ repoPatterns?: string[];
23
+ concurrencyLimit?: number | null;
24
+ concurrencyStrategy?: ConcurrencyStrategy;
25
+ concurrencyTimeoutMs?: number;
26
+ requiredReviewers?: string[] | null;
27
+ waitTimerSeconds?: number | null;
28
+ holdExpirySeconds?: number;
29
+ minimumTrust?: 'known' | 'trusted' | null;
30
+ allowLocalExecution?: boolean;
31
+ enabled?: boolean;
32
+ createdBy?: string | null;
33
+ }
34
+ /**
35
+ * Fields accepted when updating a context.
36
+ *
37
+ * Convention for every nullable column: `undefined` means "the caller did not
38
+ * mention this field, leave the column alone"; `null` means "clear it". The two
39
+ * are distinct on the wire (`contextUpdateRequestSchema` declares these fields
40
+ * `.nullable().optional()`), so the handler forwards both verbatim and `update`
41
+ * below writes the column's cleared state for an explicit `null` — SQL NULL for
42
+ * the nullable columns, and the empty array for `branchRestrictions`, whose
43
+ * column is `jsonb NOT NULL DEFAULT '[]'`.
44
+ */
45
+ export interface ContextUpdateInput {
46
+ name?: string;
47
+ type?: 'fixed' | 'glob';
48
+ globPattern?: string | null;
49
+ branchRestrictions?: string[] | null;
50
+ triggerTypeFilters?: string[];
51
+ repoPatterns?: string[];
52
+ concurrencyLimit?: number | null;
53
+ concurrencyStrategy?: ConcurrencyStrategy | null;
54
+ concurrencyTimeoutMs?: number;
55
+ requiredReviewers?: string[] | null;
56
+ waitTimerSeconds?: number | null;
57
+ holdExpirySeconds?: number | null;
58
+ minimumTrust?: 'known' | 'trusted' | null;
59
+ allowLocalExecution?: boolean;
60
+ enabled?: boolean;
61
+ }
62
+ /**
63
+ * Data access layer for contexts.
64
+ */
65
+ export declare class ContextStore {
66
+ private readonly db;
67
+ constructor(db: Kysely<Database>);
68
+ /** List all contexts for an org, ordered by name. */
69
+ list(orgId: string): Promise<Context[]>;
70
+ /** Get a single context by org + id. Returns null if not found. */
71
+ get(orgId: string, id: string): Promise<Context | null>;
72
+ /** Get a single context by org + name. Returns null if not found. */
73
+ getByName(orgId: string, name: string): Promise<Context | null>;
74
+ /** Create a new context. Returns the created row. */
75
+ create(orgId: string, data: ContextCreateInput): Promise<Context>;
76
+ /** Update a context. Returns the updated row, or null if not found. */
77
+ update(orgId: string, id: string, updates: ContextUpdateInput): Promise<Context | null>;
78
+ /**
79
+ * Delete a context.
80
+ *
81
+ * Bindings, variables, and source overrides cascade away via their FK.
82
+ * Terminal held-run history survives with a null `context_id` (the FK
83
+ * uses ON DELETE SET NULL). Pending held runs still reference the
84
+ * context, so deletion is blocked with `ContextDeleteBlockedError`
85
+ * until they are approved or rejected.
86
+ */
87
+ delete(orgId: string, id: string): Promise<boolean>;
88
+ /**
89
+ * Match a context name against org contexts.
90
+ *
91
+ * First tries exact name match (for fixed contexts).
92
+ * If no exact match, scans glob-type contexts and uses picomatch. When the
93
+ * name matches more than one glob pattern, the most-specific pattern wins
94
+ * (most literal characters; ties break toward fewer wildcards, then name
95
+ * ascending) so the winning context — and its protection rules — is
96
+ * deterministic across dispatches. Returns the matching context or null.
97
+ */
98
+ matchContext(orgId: string, name: string): Promise<Context | null>;
99
+ }
100
+ //# sourceMappingURL=context-store.d.ts.map
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Specificity scoring for glob environment patterns.
3
+ *
4
+ * Used to resolve which glob context governs a run when an environment name
5
+ * matches more than one pattern. The most-specific pattern (most literal
6
+ * characters) wins; ties break toward fewer wildcards, then name ascending —
7
+ * a total, deterministic order.
8
+ */
9
+ export interface GlobSpecificity {
10
+ /** Count of characters that are NOT glob metacharacters. Higher = more specific. */
11
+ literals: number;
12
+ /** Count of characters that ARE glob metacharacters. Lower = more specific. */
13
+ wildcards: number;
14
+ }
15
+ export declare function globSpecificityScore(pattern: string): GlobSpecificity;
16
+ /**
17
+ * Compares two glob contexts, ranking the more specific first.
18
+ * Returns <0 when `a` is more specific than `b`, >0 when less, 0 only when
19
+ * pattern-score and name are identical.
20
+ *
21
+ * Order: literals desc, then wildcards asc, then name asc.
22
+ */
23
+ export declare function compareGlobSpecificity(a: {
24
+ pattern: string;
25
+ name: string;
26
+ }, b: {
27
+ pattern: string;
28
+ name: string;
29
+ }): number;
30
+ //# sourceMappingURL=glob-specificity.d.ts.map
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Manages the lifecycle: pending -> approved/rejected/expired.
5
5
  */
6
- import { type Kysely } from 'kysely';
6
+ import { Kysely } from 'kysely';
7
+ import { z } from 'zod';
7
8
  import { type ApprovalRequirement, type ApproverClause, type StepApprovalPayload, ApprovalDecision, HoldScope, TriggerSource } from '@kici-dev/engine';
8
9
  import type { Database, HeldRun, HeldRunApproval } from '../db/types.js';
9
10
  /** Status values for held runs (held_runs table). */
@@ -14,20 +15,32 @@ export declare enum HeldRunStatus {
14
15
  Expired = "expired",
15
16
  Released = "released"
16
17
  }
18
+ /**
19
+ * Reason a run was held in the security queue. Persisted verbatim in
20
+ * `held_runs.reason` and switched on by `buildSecurityHoldSummary`.
21
+ */
22
+ export declare const SecurityHoldReason: z.ZodEnum<{
23
+ context_trust: "context_trust";
24
+ fork_pr: "fork_pr";
25
+ unknown_contributor: "unknown_contributor";
26
+ workflow_modification: "workflow_modification";
27
+ }>;
28
+ export type SecurityHoldReason = z.infer<typeof SecurityHoldReason>;
17
29
  /** Data required to create a held run. */
18
30
  export interface CreateHeldRunData {
19
31
  runId: string;
20
32
  jobId: string;
21
- environmentId: string;
33
+ /** Bound context id, or null for context-free holds (e.g. workflow_modification). */
34
+ contextId: string | null;
22
35
  holdType: string;
23
36
  reason: string;
24
37
  expiresAt: Date;
25
- /** Queue type: 'environment' (default) or 'security'. */
26
- queueType?: 'environment' | 'security';
38
+ /** Queue type: 'context' (default) or 'security'. */
39
+ queueType?: 'context' | 'security';
27
40
  }
28
41
  /**
29
42
  * Data required to create a generalized approval hold. Unlike the legacy
30
- * environment-only `create()`, this carries the hold scope, trigger source,
43
+ * context-only `create()`, this carries the hold scope, trigger source,
31
44
  * optional step index, and the normalized approval requirement.
32
45
  */
33
46
  export interface CreateHoldData {
@@ -37,17 +50,17 @@ export interface CreateHoldData {
37
50
  scope: HoldScope;
38
51
  /** Step index within the job for step-scoped holds; omit otherwise. */
39
52
  stepIndex?: number;
40
- /** What triggered the hold (environment policy vs SDK requireApproval). */
53
+ /** What triggered the hold (context policy vs SDK requireApproval). */
41
54
  triggerSource: TriggerSource;
42
55
  /** The normalized requirement the hold must satisfy. */
43
56
  requirement: ApprovalRequirement;
44
- /** Environment id, when the hold originates from an environment policy. */
45
- environmentId?: string | null;
46
- /** Queue type: 'environment' (default) or 'security'. */
47
- queueType?: 'environment' | 'security';
57
+ /** Context id, when the hold originates from a context policy. */
58
+ contextId?: string | null;
59
+ /** Queue type: 'context' (default) or 'security'. */
60
+ queueType?: 'context' | 'security';
48
61
  /**
49
- * Held-run `hold_type` discriminator. Defaults to `'approval'` (reviewer
50
- * holds). The workflow install gate sets `'wait_timer'` / `'concurrency'` so
62
+ * Held-run `hold_type` discriminator an engine `HoldType` member. Defaults
63
+ * to `reviewer`. The workflow install gate sets `timer` / `concurrency` so
51
64
  * the automated release sweeps can find their rows.
52
65
  */
53
66
  holdType?: string;
@@ -79,7 +92,7 @@ export interface ReleaseSignal {
79
92
  stepIndex: number | null;
80
93
  /**
81
94
  * What kind of gate created the hold. `explicit` (SDK `requireApproval`) holds
82
- * a real root job and resumes by re-dispatching it; `environment` covers the
95
+ * a real root job and resumes by re-dispatching it; `context` covers the
83
96
  * workflow install-gate (wait-timer / concurrency / env approval) which resumes
84
97
  * by rebuilding the workflow dispatch context. The resume router keys off this
85
98
  * so a workflow-scoped explicit hold goes through the job re-dispatch path
@@ -100,7 +113,7 @@ export declare class HeldRunStore {
100
113
  create(orgId: string, data: CreateHeldRunData): Promise<HeldRun>;
101
114
  /**
102
115
  * Create a generalized approval hold (workflow/job/step scope, explicit or
103
- * environment trigger) carrying a normalized `ApprovalRequirement`. Returns
116
+ * context trigger) carrying a normalized `ApprovalRequirement`. Returns
104
117
  * the created row.
105
118
  */
106
119
  createHold(orgId: string, data: CreateHoldData): Promise<HeldRun>;
@@ -151,13 +164,23 @@ export declare class HeldRunStore {
151
164
  /** List held runs for an org with optional filters. */
152
165
  listAll(orgId: string, options?: ListHeldRunsOptions): Promise<HeldRun[]>;
153
166
  /** List held runs for an org filtered by queue type with optional filters. */
154
- listByQueueType(orgId: string, queueType: 'environment' | 'security', options?: ListHeldRunsOptions): Promise<HeldRun[]>;
167
+ listByQueueType(orgId: string, queueType: 'context' | 'security', options?: ListHeldRunsOptions): Promise<HeldRun[]>;
168
+ /**
169
+ * List pending `security` holds whose run belongs to a specific PR (and repo).
170
+ *
171
+ * Joins `execution_runs` on `run_id` and filters by `repo_identifier` +
172
+ * `pr_number` so `/kici approve|reject` only affects the commented PR's holds
173
+ * rather than every pending security hold in the org. A run with a NULL
174
+ * `pr_number` (non-PR run, or a legacy run predating the column) never matches
175
+ * the equality predicate, so such holds are never released here — fail-closed.
176
+ */
177
+ listPendingSecurityHoldsForPr(orgId: string, repoIdentifier: string, prNumber: number): Promise<HeldRun[]>;
155
178
  /**
156
179
  * Approve a pending held run, enforcing queue_type boundary.
157
- * Prevents environment approvals from approving security holds and vice versa.
180
+ * Prevents context approvals from approving security holds and vice versa.
158
181
  * Throws if not found, not pending, or queue_type mismatch.
159
182
  */
160
- approveByQueueType(orgId: string, heldRunId: string, approvedBy: string, queueType: 'environment' | 'security'): Promise<HeldRun>;
183
+ approveByQueueType(orgId: string, heldRunId: string, approvedBy: string, queueType: 'context' | 'security'): Promise<HeldRun>;
161
184
  /** Get a held run by run ID and job ID. Returns null if not found. */
162
185
  getByRunAndJob(orgId: string, runId: string, jobId: string): Promise<HeldRun | null>;
163
186
  /**
@@ -167,23 +190,20 @@ export declare class HeldRunStore {
167
190
  */
168
191
  listOverdue(): Promise<HeldRun[]>;
169
192
  /**
170
- * Release overdue workflow `wait_timer` holds. The install-gate wait action
171
- * pauses the workflow as a held run; on timer expiry it must RESUME (not
172
- * fail like a reviewer-hold expiry). Flips each overdue pending
173
- * `hold_type='wait_timer'`, `hold_scope='workflow'` row to `released` and
174
- * returns a `ReleaseSignal` per row so the caller can resume the workflow.
175
- * Runs BEFORE `expireOverdue()` so these rows leave the pending pool before
176
- * the expire-and-fail sweep sees them.
193
+ * Release overdue workflow timer holds. The install-gate wait action pauses
194
+ * the workflow as a held run; on timer expiry it must RESUME (not fail like
195
+ * a reviewer-hold expiry). Flips each overdue pending `hold_type` timer,
196
+ * `hold_scope='workflow'` row to `released` and returns a `ReleaseSignal`
197
+ * per row so the caller can resume the workflow. Runs BEFORE
198
+ * `expireOverdue()` so these rows leave the pending pool before the
199
+ * expire-and-fail sweep sees them.
200
+ *
201
+ * The filter matches every persisted spelling of the timer hold type, so a
202
+ * row an un-upgraded orchestrator wrote as `wait_timer` still resumes rather
203
+ * than falling through to the expire-and-fail sweep. `hold_scope` is what
204
+ * keeps job-scoped dispatch-gate timer holds out of this sweep.
177
205
  */
178
206
  releaseDueWaitHolds(): Promise<ReleaseSignal[]>;
179
- /**
180
- * Release the oldest pending workflow `concurrency` hold for a group. Called
181
- * when a concurrency slot frees on run completion. Flips the oldest matching
182
- * pending row to `released` and returns its `ReleaseSignal`, or null when no
183
- * concurrency hold is queued for the group. `group` matches the held row's
184
- * `environment_id` (workflow-level install concurrency keys on the env id).
185
- */
186
- releaseConcurrencyHold(orgId: string, group: string): Promise<ReleaseSignal | null>;
187
207
  /**
188
208
  * Expire overdue pending runs. Called by the stale detector.
189
209
  * Sets status to 'expired' and resolved_at to now() for all
@@ -192,4 +212,16 @@ export declare class HeldRunStore {
192
212
  */
193
213
  expireOverdue(): Promise<number>;
194
214
  }
215
+ /**
216
+ * Build a HeldRunStore backed by its own connection pool to the given
217
+ * orchestrator database URL. Mirrors `createPeerCredentialStoreFromUrl` /
218
+ * `createJoinTokenManagerFromUrl`; consumed by E2E tests that exercise the
219
+ * PR-scoped hold selection against the real deployed orchestrator DB.
220
+ */
221
+ export declare function createHeldRunStoreFromUrl(databaseUrl: string, opts?: {
222
+ maxConnections?: number;
223
+ }): {
224
+ store: HeldRunStore;
225
+ dispose: () => Promise<void>;
226
+ };
195
227
  //# sourceMappingURL=held-runs.d.ts.map
@@ -1,4 +1,4 @@
1
- export { EnvironmentStore, type EnvironmentCreateInput, type EnvironmentUpdateInput, } from './environment-store.js';
1
+ export { ContextStore, type ContextCreateInput, type ContextUpdateInput } from './context-store.js';
2
2
  export { BindingStore } from './binding-store.js';
3
3
  export { VariableStore } from './variable-store.js';
4
4
  export { HeldRunStore, type CreateHeldRunData, type ListHeldRunsOptions } from './held-runs.js';
@@ -0,0 +1,43 @@
1
+ import { ContextGateRejectReason, type ConcurrencyStrategy, type Context } from '@kici-dev/engine';
2
+ import type { JobDispatchContext } from './pipeline.js';
3
+ /** A single context's rejection under all-must-pass aggregation. */
4
+ export interface ContextGateRejection {
5
+ context: string;
6
+ reason: ContextGateRejectReason;
7
+ detail: string;
8
+ }
9
+ /** Effective protection parameters after most-restrictive aggregation. */
10
+ export interface EffectiveProtection {
11
+ minimumTrust?: 'known' | 'trusted';
12
+ requiredReviewers: string[];
13
+ waitTimerSeconds: number | null;
14
+ holdExpirySeconds: number;
15
+ concurrencyLimit: number | null;
16
+ concurrencyStrategy: ConcurrencyStrategy;
17
+ }
18
+ /**
19
+ * Evaluate each context's hard reject gates against the run context. A name
20
+ * with no `Context` record yields a `context_not_found` rejection. Returns all
21
+ * rejections (empty = every context passed the reject gates).
22
+ */
23
+ export declare function evaluateMultiContextGates(envs: ReadonlyArray<{
24
+ name: string;
25
+ env: Context | undefined;
26
+ }>, ctx: JobDispatchContext): ContextGateRejection[];
27
+ /**
28
+ * Aggregate hold/wait/queue parameters across all bound contexts, most
29
+ * restrictive wins: trust = max tier, reviewers = sorted dedup union, wait timer
30
+ * = max, hold expiry = min, concurrency limit = min (tightest). The concurrency
31
+ * strategy follows the primary (first) context.
32
+ */
33
+ export declare function aggregateProtectionParams(envs: ReadonlyArray<Context>): EffectiveProtection;
34
+ /**
35
+ * Build a synthetic `Context` carrying the aggregated protection parameters,
36
+ * so the existing per-rule gate functions (trust/concurrency/reviewer/wait) can
37
+ * evaluate the all-must-pass holds in one pass. Branch/trigger/repo/enabled are
38
+ * already handled by `evaluateMultiContextGates`, so they are neutralized here.
39
+ */
40
+ export declare function buildEffectiveContext(primary: Context, eff: EffectiveProtection): Context;
41
+ /** Format a human-readable rejection reason naming the env(s) and rule(s). */
42
+ export declare function formatMultiContextRejection(rejections: ReadonlyArray<ContextGateRejection>): string;
43
+ //# sourceMappingURL=aggregate.d.ts.map
@@ -0,0 +1,5 @@
1
+ import type { Context, ProtectionGateResult } from '@kici-dev/engine';
2
+ import type { JobDispatchContext } from './pipeline.js';
3
+ /** Evaluate branch restrictions, trigger type filters, and repo patterns. */
4
+ export declare function evaluateBranchGate(env: Context, ctx: JobDispatchContext): ProtectionGateResult;
5
+ //# sourceMappingURL=branch-gate.d.ts.map
@@ -0,0 +1,4 @@
1
+ import type { Context, ProtectionGateResult } from '@kici-dev/engine';
2
+ /** Evaluate concurrency limits for the context. */
3
+ export declare function evaluateConcurrencyGate(env: Context, currentRunningCount: number, _concurrencyGroup: string): ProtectionGateResult;
4
+ //# sourceMappingURL=concurrency-gate.d.ts.map
@@ -4,7 +4,7 @@
4
4
  * Gates evaluated in order: branch -> trust -> concurrency -> reviewer -> timer.
5
5
  * First non-pass result stops evaluation.
6
6
  */
7
- import type { Environment, ProtectionGateResult, TrustTier } from '@kici-dev/engine';
7
+ import type { Context, ProtectionGateResult, TrustTier } from '@kici-dev/engine';
8
8
  /** Context needed for protection gate evaluation. */
9
9
  export interface JobDispatchContext {
10
10
  branch: string;
@@ -13,6 +13,6 @@ export interface JobDispatchContext {
13
13
  runId: string;
14
14
  jobId: string;
15
15
  }
16
- /** Evaluate all protection rules for an environment. */
17
- export declare function evaluateProtectionRules(env: Environment, ctx: JobDispatchContext, currentRunningCount: number, concurrencyGroup: string, trustTier?: TrustTier): Promise<ProtectionGateResult>;
16
+ /** Evaluate all protection rules for a context. */
17
+ export declare function evaluateProtectionRules(env: Context, ctx: JobDispatchContext, currentRunningCount: number, concurrencyGroup: string, trustTier?: TrustTier): Promise<ProtectionGateResult>;
18
18
  //# sourceMappingURL=pipeline.d.ts.map
@@ -0,0 +1,4 @@
1
+ import type { Context, ProtectionGateResult } from '@kici-dev/engine';
2
+ /** Evaluate reviewer requirements for the context. */
3
+ export declare function evaluateReviewerGate(env: Context): ProtectionGateResult;
4
+ //# sourceMappingURL=reviewer-gate.d.ts.map
@@ -1,69 +1,69 @@
1
1
  /**
2
- * Registration-time satisfiability check for multi-environment job bindings.
2
+ * Registration-time satisfiability check for multi-context job bindings.
3
3
  *
4
- * When a job binds several environments (`environments: [...]`), every
5
- * environment's protection gates must pass for the job to ever dispatch
4
+ * When a job binds several contexts (`contexts: [...]`), every
5
+ * context's protection gates must pass for the job to ever dispatch
6
6
  * (all-must-pass aggregation — see `aggregate.ts`). Some of those gates are
7
- * decidable statically: if two bound environments restrict to disjoint fixed
7
+ * decidable statically: if two bound contexts restrict to disjoint fixed
8
8
  * branch sets, no run can ever satisfy both, so the binding is provably
9
9
  * unsatisfiable and should be rejected at registration rather than failing
10
10
  * silently at every future dispatch.
11
11
  *
12
12
  * This module intersects the statically-decidable set rules (branch, trigger
13
13
  * type, repository — only when every pattern is a literal, never a glob) plus
14
- * the `enabled` gate across the **resolved** bound environments, and reports the
15
- * first provably-empty intersection. Bound names that resolve to no environment
14
+ * the `enabled` gate across the **resolved** bound contexts, and reports the
15
+ * first provably-empty intersection. Bound names that resolve to no context
16
16
  * record are lenient — skipped, never rejected — matching the dispatch-time
17
17
  * behavior in `dispatch-matched-workflow.ts`. Any glob in a rule makes that rule
18
18
  * undecidable, so it is skipped here and left to the dispatch-time catch-all
19
- * (`evaluateMultiEnvGates`).
19
+ * (`evaluateMultiContextGates`).
20
20
  */
21
21
  import { z } from 'zod';
22
- import type { Environment } from '@kici-dev/engine';
22
+ import type { Context } from '@kici-dev/engine';
23
23
  /** Which decidable rule made a binding unsatisfiable. */
24
24
  export declare const UnsatisfiableRule: z.ZodEnum<{
25
+ branch: "branch";
25
26
  enabled: "enabled";
26
27
  repo: "repo";
27
- branch: "branch";
28
28
  trigger: "trigger";
29
29
  }>;
30
30
  export type UnsatisfiableRule = z.infer<typeof UnsatisfiableRule>;
31
- /** A provably-unsatisfiable multi-environment binding, naming the rule + reason. */
31
+ /** A provably-unsatisfiable multi-context binding, naming the rule + reason. */
32
32
  export interface UnsatisfiableBinding {
33
33
  jobName: string;
34
- environments: string[];
34
+ contexts: string[];
35
35
  rule: UnsatisfiableRule;
36
36
  message: string;
37
37
  }
38
38
  /**
39
- * Returns a precise problem when the bound environments can NEVER be jointly
40
- * satisfied (a disabled environment, or mutually-exclusive fixed restrictions
41
- * among the resolved environments), else `null`. Missing (unresolved) names are
42
- * skipped — a bound name with no environment record contributes no protection
39
+ * Returns a precise problem when the bound contexts can NEVER be jointly
40
+ * satisfied (a disabled context, or mutually-exclusive fixed restrictions
41
+ * among the resolved contexts), else `null`. Missing (unresolved) names are
42
+ * skipped — a bound name with no context record contributes no protection
43
43
  * rules and is lenient at dispatch, so it is not rejected here. Glob /
44
44
  * undecidable cases also return `null` and are caught at dispatch by
45
- * `evaluateMultiEnvGates`.
45
+ * `evaluateMultiContextGates`.
46
46
  *
47
- * `envs[i]` is the resolved `Environment` for `envNames[i]` (undefined when the
48
- * name has no environment record). Only the statically-known (non-dynamic) bound
47
+ * `envs[i]` is the resolved `Context` for `envNames[i]` (undefined when the
48
+ * name has no context record). Only the statically-known (non-dynamic) bound
49
49
  * names should be passed — dynamic elements are unknown at registration and the
50
50
  * all-must-pass semantics make the static subset's exclusivity still sound.
51
51
  */
52
- export declare function checkBindingSatisfiable(jobName: string, envs: ReadonlyArray<Environment | undefined>, envNames: readonly string[]): UnsatisfiableBinding | null;
52
+ export declare function checkBindingSatisfiable(jobName: string, envs: ReadonlyArray<Context | undefined>, envNames: readonly string[]): UnsatisfiableBinding | null;
53
53
  /** Minimal lock-workflow shape needed to walk its jobs for satisfiability. */
54
54
  interface SatisfiabilityLockWorkflow {
55
55
  jobs?: readonly unknown[];
56
56
  }
57
57
  /**
58
58
  * Walk every workflow's static jobs and reject the registration when a bound
59
- * environment list is provably unsatisfiable (a disabled environment, or
59
+ * context list is provably unsatisfiable (a disabled context, or
60
60
  * mutually-exclusive fixed branch/trigger/repo restrictions among the resolved
61
- * environments — missing names are lenient, never rejected). Dynamic elements
61
+ * contexts — missing names are lenient, never rejected). Dynamic elements
62
62
  * are skipped (unresolvable at registration); the all-must-pass semantics keep
63
63
  * the static subset's exclusivity sound. Throws the first
64
64
  * `UnsatisfiableBinding.message` so the registration route / direct helper
65
65
  * surfaces it to the caller.
66
66
  */
67
- export declare function assertWorkflowsSatisfiable(workflows: ReadonlyArray<SatisfiabilityLockWorkflow>, resolveEnv: (name: string) => Promise<Environment | null>): Promise<void>;
67
+ export declare function assertWorkflowsSatisfiable(workflows: ReadonlyArray<SatisfiabilityLockWorkflow>, resolveEnv: (name: string) => Promise<Context | null>): Promise<void>;
68
68
  export {};
69
69
  //# sourceMappingURL=satisfiability.d.ts.map
@@ -0,0 +1,4 @@
1
+ import type { Context, ProtectionGateResult, TrustTier } from '@kici-dev/engine';
2
+ /** Evaluate minimumTrust requirements for the context. */
3
+ export declare function evaluateTrustGate(env: Context, trustTier: TrustTier | undefined): ProtectionGateResult;
4
+ //# sourceMappingURL=trust-gate.d.ts.map
@@ -0,0 +1,4 @@
1
+ import type { Context, ProtectionGateResult } from '@kici-dev/engine';
2
+ /** Evaluate wait timer for the context. */
3
+ export declare function evaluateWaitTimerGate(env: Context): ProtectionGateResult;
4
+ //# sourceMappingURL=wait-timer-gate.d.ts.map
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Variable store -- context variable CRUD with lock enforcement.
3
+ *
4
+ * Manages org-level context variables and per-source overrides.
5
+ * Lock enforcement: locked org vars cannot be overridden by source overrides.
6
+ */
7
+ import { type Kysely } from 'kysely';
8
+ import type { Database, ContextVariable, ContextSourceOverride } from '../db/types.js';
9
+ /**
10
+ * Data access layer for context variables and source overrides.
11
+ */
12
+ export declare class VariableStore {
13
+ private readonly db;
14
+ constructor(db: Kysely<Database>);
15
+ /** List all org-level variables for a context. */
16
+ listVars(orgId: string, contextId: string): Promise<ContextVariable[]>;
17
+ /** Upsert an org-level variable. */
18
+ setVar(orgId: string, contextId: string, key: string, value: string, locked?: boolean): Promise<void>;
19
+ /** Delete an org-level variable. */
20
+ deleteVar(orgId: string, contextId: string, key: string): Promise<void>;
21
+ /** List source overrides for a specific source (routing key). */
22
+ listSourceOverrides(orgId: string, contextId: string, routingKey: string): Promise<ContextSourceOverride[]>;
23
+ /** Upsert a source override. */
24
+ setSourceOverride(orgId: string, contextId: string, routingKey: string, key: string, value: string): Promise<void>;
25
+ /** Delete a source override. */
26
+ deleteSourceOverride(orgId: string, contextId: string, routingKey: string, key: string): Promise<void>;
27
+ /**
28
+ * Get resolved variables for a context, optionally merged with source overrides.
29
+ *
30
+ * Merge rules:
31
+ * - Org-level vars form the base
32
+ * - Source overrides can add new keys and override unlocked org vars
33
+ * - Locked org vars are NOT overridden by source overrides
34
+ *
35
+ * @param routingKey - If provided, source overrides are merged in
36
+ */
37
+ getResolvedVars(orgId: string, contextId: string, routingKey?: string): Promise<Record<string, string>>;
38
+ }
39
+ //# sourceMappingURL=variable-store.d.ts.map
@@ -2,7 +2,7 @@ import type { Kysely } from 'kysely';
2
2
  import type { Database } from '../db/types.js';
3
3
  import type { RegistrationIndex } from '../registration/registration-index.js';
4
4
  import type { EventRouter } from '../events/event-router.js';
5
- import type { CronStore } from './cron-store.js';
5
+ import { type CronStore } from './cron-store.js';
6
6
  interface CronSchedulerOptions {
7
7
  db: Kysely<Database>;
8
8
  registrationIndex: RegistrationIndex;
@@ -32,9 +32,14 @@ export declare class CronScheduler {
32
32
  private readonly cronStore;
33
33
  private readonly eventRouter;
34
34
  private readonly evaluationIntervalMs;
35
- private timer;
36
- private isLeader;
35
+ private readonly scheduler;
37
36
  private lastFiredCache;
37
+ /**
38
+ * Set when the leader-election cache load fails. While true, each evaluation
39
+ * tick re-attempts the load (see reloadCacheAfterFailure) so a transient DB
40
+ * error at leader election does not leave the cache cold for the whole tenure.
41
+ */
42
+ private cacheLoadPending;
38
43
  constructor(options: CronSchedulerOptions);
39
44
  /**
40
45
  * Called when this orchestrator becomes the Raft leader.
@@ -64,15 +69,30 @@ export declare class CronScheduler {
64
69
  * fires the schedule.
65
70
  */
66
71
  evaluate(): Promise<void>;
72
+ /**
73
+ * Re-attempt the last-fired cache load after an earlier failure at leader
74
+ * election. On success, clears the pending flag; on repeated failure, leaves
75
+ * it set so the next tick tries again. Evaluation continues either way — the
76
+ * DB-side tryClaimFire guard prevents double-fires with a stale or cold cache.
77
+ */
78
+ private reloadCacheAfterFailure;
67
79
  /**
68
80
  * Recover missed schedules after becoming leader.
69
81
  * Same logic as evaluate() but logs recovery context.
70
82
  */
71
83
  private recoverMissedSchedules;
72
84
  /**
73
- * Evaluate a single registration and fire if due.
85
+ * Evaluate a single registration and fire every due schedule trigger.
86
+ *
87
+ * A workflow may declare multiple `schedule()` triggers; each is tracked and
88
+ * fired independently (keyed per (registration, schedule)), so a second or
89
+ * third schedule is never silently skipped.
74
90
  */
75
91
  private evaluateRegistration;
92
+ /**
93
+ * Evaluate one schedule trigger of a registration and fire if due.
94
+ */
95
+ private evaluateScheduleTrigger;
76
96
  }
77
97
  export {};
78
98
  //# sourceMappingURL=cron-scheduler.d.ts.map
@@ -1,10 +1,21 @@
1
1
  import type { Kysely, Transaction } from 'kysely';
2
2
  import type { Database } from '../db/types.js';
3
3
  type DbExecutor = Kysely<Database> | Transaction<Database>;
4
+ /**
5
+ * In-memory cache key uniting a registration and one of its schedules.
6
+ *
7
+ * A workflow may declare several `schedule()` triggers, each tracked
8
+ * independently in `cron_last_fired` keyed by (registration_id, schedule_key).
9
+ * The space separator is unambiguous: a registration id is a UUID and a
10
+ * schedule key is `${cronExpression}\n${timezone}` — neither contains a space
11
+ * at the boundary that could collide.
12
+ */
13
+ export declare function cronCacheKey(registrationId: string, scheduleKey: string): string;
4
14
  /**
5
15
  * DB persistence for cron last-fired tracking.
6
16
  *
7
- * Tracks the last time each cron-triggered workflow registration was fired.
17
+ * Tracks the last time each (registration, schedule) was fired — a workflow
18
+ * with multiple `schedule()` triggers has one row per distinct schedule.
8
19
  * Used by CronScheduler for fire-once-on-recovery after leader transitions.
9
20
  * Uses upsert (INSERT ON CONFLICT UPDATE) for atomic idempotent writes.
10
21
  */
@@ -12,11 +23,14 @@ export declare class CronStore {
12
23
  private readonly db;
13
24
  constructor(db: Kysely<Database>);
14
25
  /**
15
- * Atomically claim a cron fire: only succeeds if no other orchestrator has
16
- * already fired this registration at a time >= firedAt.
26
+ * Atomically claim a cron fire for one schedule of a registration: only
27
+ * succeeds if no other orchestrator has already fired this (registration,
28
+ * schedule) at a time >= firedAt.
17
29
  *
18
30
  * Uses INSERT ... ON CONFLICT with a WHERE guard so the upsert only writes
19
- * when `last_fired_at < firedAt` (or the row doesn't exist yet).
31
+ * when `last_fired_at < firedAt` (or the row doesn't exist yet). The conflict
32
+ * target is the composite key (registration_id, schedule_key) so two distinct
33
+ * schedules of the same registration claim independently.
20
34
  *
21
35
  * Accepts an optional executor (Kysely DB handle or Transaction). The cron
22
36
  * fire path passes a Transaction so the claim and the subsequent
@@ -27,10 +41,10 @@ export declare class CronStore {
27
41
  * Returns true if this call won the race (the fire should proceed).
28
42
  * Returns false if another node already recorded a fire >= firedAt.
29
43
  */
30
- tryClaimFire(registrationId: string, firedAt: Date, executor?: DbExecutor): Promise<boolean>;
44
+ tryClaimFire(registrationId: string, scheduleKey: string, firedAt: Date, executor?: DbExecutor): Promise<boolean>;
31
45
  /**
32
- * Get all last-fired records as a Map<registrationId, lastFiredAt>.
33
- * Used for bulk loading during leader recovery.
46
+ * Get all last-fired records as a Map keyed by `cronCacheKey(registrationId,
47
+ * scheduleKey)`. Used for bulk loading during leader recovery.
34
48
  */
35
49
  getAll(): Promise<Map<string, Date>>;
36
50
  }