@kici-dev/orchestrator 0.1.27 → 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 (270) hide show
  1. package/dist/__test-helpers__/mock-db.d.ts +2 -0
  2. package/dist/agent/dispatcher.d.ts +52 -2
  3. package/dist/agent/host-roster-reaper.d.ts +1 -2
  4. package/dist/agent/host-roster.d.ts +34 -0
  5. package/dist/agent/ownership-refusal.d.ts +12 -0
  6. package/dist/agent/ownership-tracker.d.ts +64 -16
  7. package/dist/agent/token-store.d.ts +13 -0
  8. package/dist/agent-packaging/availability.d.ts +27 -0
  9. package/dist/agent-packaging/build-package.d.ts +16 -0
  10. package/dist/agent-packaging/download.d.ts +30 -0
  11. package/dist/agent-packaging/index.d.ts +9 -0
  12. package/dist/agent-packaging/install-closure.d.ts +30 -0
  13. package/dist/agent-packaging/node-binary.d.ts +26 -0
  14. package/dist/agent-packaging/refresh.d.ts +50 -0
  15. package/dist/agent-packaging/store.d.ts +15 -0
  16. package/dist/agent-packaging/upload.d.ts +24 -0
  17. package/dist/app-on-error.d.ts +29 -0
  18. package/dist/app.d.ts +56 -4
  19. package/dist/artifacts/artifact-store.d.ts +233 -0
  20. package/dist/artifacts/failure-messages.d.ts +46 -0
  21. package/dist/audit/access-log.d.ts +18 -1
  22. package/dist/cache/dep-cache.d.ts +15 -0
  23. package/dist/cache/user-cache.d.ts +37 -0
  24. package/dist/cancel/cancel-run.d.ts +10 -3
  25. package/dist/cancel/dashboard-cancel-handler.d.ts +19 -0
  26. package/dist/cli/api-client.d.ts +22 -1
  27. package/dist/cli/commands/agent-package.d.ts +34 -0
  28. package/dist/cli/commands/check-run.d.ts +26 -0
  29. package/dist/cli/commands/cluster-settings.d.ts +55 -0
  30. package/dist/cli/commands/dashboard-encryption-key.d.ts +3 -0
  31. package/dist/cli/commands/db-backup.d.ts +71 -0
  32. package/dist/cli/commands/orchestrator-service/drain.d.ts +31 -0
  33. package/dist/cli/commands/orchestrator-service/index.d.ts +7 -4
  34. package/dist/cli/commands/orchestrator-service/install-env.d.ts +58 -0
  35. package/dist/cli/commands/secret.d.ts +45 -1
  36. package/dist/cli/commands/shared/admin-cli-access-log.d.ts +46 -0
  37. package/dist/cli/commands/shared/versioned-upgrade.d.ts +65 -2
  38. package/dist/cli/commands/signing-key.d.ts +3 -0
  39. package/dist/cli/commands/source.d.ts +12 -0
  40. package/dist/cli/commands/token.d.ts +9 -0
  41. package/dist/cli/commands/trust-policy.d.ts +48 -0
  42. package/dist/cli/join.d.ts +1 -1
  43. package/dist/cli/service/index.d.ts +2 -2
  44. package/dist/cli/service/instance/manifest.d.ts +17 -0
  45. package/dist/cli/service/instance/resolve.d.ts +11 -0
  46. package/dist/cli/wizard/orchestrator-wizard.d.ts +39 -11
  47. package/dist/cli.js +9818 -3408
  48. package/dist/cluster/cluster-settings-reader.d.ts +78 -0
  49. package/dist/cluster/coordinator.d.ts +81 -9
  50. package/dist/cluster/join-client.d.ts +1 -1
  51. package/dist/cluster/leader-gated-scheduler.d.ts +50 -0
  52. package/dist/cluster/orphan-recovery.d.ts +14 -0
  53. package/dist/cluster/peer-client.d.ts +12 -2
  54. package/dist/cluster/peer-handler.d.ts +15 -4
  55. package/dist/cluster/peer-registry.d.ts +12 -0
  56. package/dist/cluster/verified-issuer-poller.d.ts +11 -0
  57. package/dist/cluster/verified-issuer.d.ts +63 -0
  58. package/dist/cold-store/tables/access-log.d.ts +1 -1
  59. package/dist/cold-store/tables/event-log.d.ts +1 -1
  60. package/dist/cold-store/tables/execution-jobs.d.ts +1 -1
  61. package/dist/cold-store/tables/execution-runs.d.ts +1 -1
  62. package/dist/cold-store/tables/execution-steps.d.ts +1 -1
  63. package/dist/cold-store/tables/secret-audit-log.d.ts +1 -1
  64. package/dist/config/loader.d.ts +1 -1
  65. package/dist/config/resolver.d.ts +2 -1
  66. package/dist/config/schema.d.ts +8 -6
  67. package/dist/config/types.d.ts +3 -2
  68. package/dist/config.d.ts +363 -53
  69. package/dist/contexts/context-store.d.ts +21 -8
  70. package/dist/contexts/glob-specificity.d.ts +30 -0
  71. package/dist/contexts/held-runs.d.ts +51 -19
  72. package/dist/contexts/protection/aggregate.d.ts +2 -2
  73. package/dist/contexts/protection/concurrency-gate.d.ts +0 -3
  74. package/dist/contexts/protection/reviewer-gate.d.ts +0 -3
  75. package/dist/contexts/protection/satisfiability.d.ts +1 -1
  76. package/dist/contexts/protection/trust-gate.d.ts +0 -3
  77. package/dist/contexts/protection/wait-timer-gate.d.ts +0 -3
  78. package/dist/cron/cron-scheduler.d.ts +24 -4
  79. package/dist/cron/cron-store.d.ts +21 -7
  80. package/dist/dashboard/attestation-filters.d.ts +92 -74
  81. package/dist/dashboard/handler.d.ts +35 -1
  82. package/dist/db/migration-test-harness.d.ts +41 -0
  83. package/dist/db/migrations/069_reroute_tunables.d.ts +21 -0
  84. package/dist/db/migrations/070_execution_runs_failure_class.d.ts +4 -0
  85. package/dist/db/migrations/071_batch_accumulation.d.ts +26 -0
  86. package/dist/db/migrations/072_dispatch_queue_run_id_index.d.ts +15 -0
  87. package/dist/db/migrations/073_org_settings_ingest_concurrency.d.ts +13 -0
  88. package/dist/db/migrations/074_normalize_zero_concurrency_limit.d.ts +13 -0
  89. package/dist/db/migrations/075_ingest_overflow_buffer.d.ts +16 -0
  90. package/dist/db/migrations/076_artifacts.d.ts +19 -0
  91. package/dist/db/migrations/077_backup_runs.d.ts +13 -0
  92. package/dist/db/migrations/078_org_settings_backup_staleness.d.ts +12 -0
  93. package/dist/db/migrations/079_org_settings_scaler_spawn_timeout.d.ts +14 -0
  94. package/dist/db/migrations/080_cluster_settings.d.ts +17 -0
  95. package/dist/db/migrations/081_org_settings_queue_timeout.d.ts +19 -0
  96. package/dist/db/migrations/082_host_s3_reachable.d.ts +16 -0
  97. package/dist/db/migrations/083_org_settings_artifact_caps.d.ts +18 -0
  98. package/dist/db/migrations/084_orchestrator_signing_keys.d.ts +20 -0
  99. package/dist/db/migrations/085_cluster_settings_reroute_flap_grace_ms.d.ts +12 -0
  100. package/dist/db/migrations/086_cluster_settings_max_fanout_hosts.d.ts +12 -0
  101. package/dist/db/migrations/087_cluster_settings_event_router_rate_limit.d.ts +12 -0
  102. package/dist/db/migrations/088_cluster_settings_cache_max_tarball_bytes.d.ts +12 -0
  103. package/dist/db/migrations/089_cluster_settings_cache_ttl_days.d.ts +12 -0
  104. package/dist/db/migrations/090_cluster_settings_concurrency_wait_timeout_ms.d.ts +12 -0
  105. package/dist/db/migrations/091_cluster_settings_agent_token_ttl_ms.d.ts +12 -0
  106. package/dist/db/migrations/092_cluster_settings_version.d.ts +16 -0
  107. package/dist/db/migrations/093_org_settings_sandbox_allowlist.d.ts +4 -0
  108. package/dist/db/migrations/094_dashboard_encryption_keys.d.ts +21 -0
  109. package/dist/db/migrations/095_dashboard_write_policy_tristate.d.ts +20 -0
  110. package/dist/db/migrations/096_multi_schedule_cron_last_fired.d.ts +4 -0
  111. package/dist/db/migrations/097_execution_runs_pr_number.d.ts +4 -0
  112. package/dist/db/migrations/098_execution_runs_customer_id.d.ts +4 -0
  113. package/dist/db/migrations/099_cluster_settings_dashboard_verified_issuer.d.ts +21 -0
  114. package/dist/db/migrations/100_held_runs_hold_type_vocabulary.d.ts +31 -0
  115. package/dist/db/migrations/101_contexts_hold_expiry_drop_default.d.ts +31 -0
  116. package/dist/db/migrations/102_dispatch_queue_agent_id.d.ts +20 -0
  117. package/dist/db/migrations/103_cluster_settings_ownership_db_check_timeout_ms.d.ts +20 -0
  118. package/dist/db/migrations/104_check_run_terminal_sent.d.ts +22 -0
  119. package/dist/db/migrations/105_org_trust_policy.d.ts +19 -0
  120. package/dist/db/migrations/106_cluster_settings_check_run_tracking_ttl_days.d.ts +18 -0
  121. package/dist/db/migrations/107_check_run_tracking_updated_at_index.d.ts +23 -0
  122. package/dist/db/repos/dashboard-encryption-keys-repo.d.ts +48 -0
  123. package/dist/db/repos/signing-keys-repo.d.ts +34 -0
  124. package/dist/db/types.d.ts +421 -7
  125. package/dist/deployment/deployment-identity.d.ts +87 -2
  126. package/dist/diagnostics/checks/backup.d.ts +18 -0
  127. package/dist/diagnostics/checks/index.d.ts +2 -1
  128. package/dist/diagnostics/fleet-collector.d.ts +1 -1
  129. package/dist/drain/drain-controller.d.ts +52 -0
  130. package/dist/events/batch-accumulator.d.ts +63 -0
  131. package/dist/events/circuit-breaker.d.ts +9 -3
  132. package/dist/events/event-emitter.d.ts +31 -0
  133. package/dist/events/event-retry-scanner.d.ts +12 -2
  134. package/dist/events/event-router.d.ts +29 -0
  135. package/dist/firecracker/host-network.d.ts +2 -0
  136. package/dist/firecracker/net-interfaces.d.ts +14 -0
  137. package/dist/github-app-name-refresher/github-app-name-refresher.d.ts +18 -8
  138. package/dist/index.d.ts +2 -0
  139. package/dist/index.js +604 -16
  140. package/dist/lockfile-cache.d.ts +4 -0
  141. package/dist/lockfile-validate.d.ts +16 -9
  142. package/dist/metrics/prometheus.d.ts +112 -15
  143. package/dist/oidc/aws-kms-signer.d.ts +37 -0
  144. package/dist/oidc/command-signer.d.ts +23 -0
  145. package/dist/oidc/db-signer.d.ts +48 -0
  146. package/dist/oidc/id-token-claims.d.ts +22 -9
  147. package/dist/oidc/jwt.d.ts +5 -2
  148. package/dist/oidc/local-dev-signer.d.ts +1 -1
  149. package/dist/oidc/oidc-mint-registration.d.ts +27 -11
  150. package/dist/oidc/orchestrator-mint.d.ts +97 -0
  151. package/dist/oidc/orchestrator-signer-factory.d.ts +33 -0
  152. package/dist/oidc/reconcile-signing-key.d.ts +21 -0
  153. package/dist/oidc/signer.d.ts +25 -0
  154. package/dist/oidc/signing-key-status.d.ts +23 -0
  155. package/dist/orchestrator-core.d.ts +42 -2
  156. package/dist/pipeline/decorating-secret-resolver.d.ts +3 -2
  157. package/dist/pipeline/dispatch-matched-workflow.d.ts +41 -0
  158. package/dist/pipeline/install-secrets-resolver.d.ts +12 -1
  159. package/dist/pipeline/manual-schedule.d.ts +20 -13
  160. package/dist/pipeline/pending-workflow-context.d.ts +1 -1
  161. package/dist/pipeline/process-webhook.d.ts +57 -2
  162. package/dist/pipeline/processor.d.ts +44 -8
  163. package/dist/pipeline/rerun.d.ts +12 -13
  164. package/dist/pipeline/resolve-sandbox-grant.d.ts +28 -0
  165. package/dist/pipeline/route-or-dispatch-jobs.d.ts +71 -0
  166. package/dist/pipeline/sandbox-allowlist-reader.d.ts +33 -0
  167. package/dist/policy/dashboard-write-policy.d.ts +9 -4
  168. package/dist/provenance/backfill-run.d.ts +1 -0
  169. package/dist/provenance/trust-root.d.ts +13 -0
  170. package/dist/providers/generic/normalizer.d.ts +1 -1
  171. package/dist/providers/github/auth.d.ts +1 -1
  172. package/dist/providers/github/changed-files.d.ts +14 -6
  173. package/dist/providers/github/check-status-poster.d.ts +19 -3
  174. package/dist/providers/github/contributor-resolver.d.ts +1 -1
  175. package/dist/providers/github/lock-file.d.ts +1 -1
  176. package/dist/providers/github/normalizer.d.ts +1 -1
  177. package/dist/providers/github/repo-url.d.ts +1 -1
  178. package/dist/providers/local/lock-file-fetcher.d.ts +1 -1
  179. package/dist/providers/local/normalizer.d.ts +1 -1
  180. package/dist/providers/local/repo-url-builder.d.ts +1 -1
  181. package/dist/providers/universal-git/changed-files.d.ts +8 -7
  182. package/dist/providers/universal-git/clone-token.d.ts +1 -1
  183. package/dist/providers/universal-git/config.d.ts +4 -4
  184. package/dist/providers/universal-git/index.d.ts +5 -1
  185. package/dist/providers/universal-git/lock-file.d.ts +6 -1
  186. package/dist/providers/universal-git/normalizer.d.ts +1 -1
  187. package/dist/providers/universal-git/repo-url.d.ts +1 -1
  188. package/dist/queue/cleanup.d.ts +69 -8
  189. package/dist/queue/job-queue.d.ts +94 -14
  190. package/dist/queue/scheduled-job.d.ts +2 -2
  191. package/dist/registration/registration-index.d.ts +1 -1
  192. package/dist/reporting/agent-failure-category.d.ts +4 -1
  193. package/dist/reporting/check-run-reporter.d.ts +34 -14
  194. package/dist/reporting/check-run-tracking-store.d.ts +70 -8
  195. package/dist/reporting/execution-tracker.d.ts +156 -10
  196. package/dist/reporting/fs-log-storage.d.ts +31 -2
  197. package/dist/reporting/job-check-run-completion.d.ts +50 -0
  198. package/dist/reporting/log-chunk-sink.d.ts +47 -0
  199. package/dist/reporting/log-retention.d.ts +16 -0
  200. package/dist/reporting/log-storage.d.ts +64 -4
  201. package/dist/reporting/log-writer.d.ts +22 -7
  202. package/dist/reporting/peer-log-normalize.d.ts +14 -0
  203. package/dist/reporting/run-aggregator.d.ts +32 -32
  204. package/dist/reporting/s3-log-storage.d.ts +102 -8
  205. package/dist/routes/admin-auth.d.ts +90 -0
  206. package/dist/routes/admin-cluster-settings.d.ts +31 -0
  207. package/dist/routes/admin-events.d.ts +3 -0
  208. package/dist/routes/admin-orchestrator-drain.d.ts +35 -0
  209. package/dist/routes/admin-runs.d.ts +9 -0
  210. package/dist/routes/admin-sources.d.ts +7 -0
  211. package/dist/routes/admin-trust-policy.d.ts +49 -0
  212. package/dist/routes/admin.d.ts +15 -1
  213. package/dist/routes/github-webhook.d.ts +9 -3
  214. package/dist/routes/provenance-oidc.d.ts +38 -0
  215. package/dist/routes/verify-attestation.d.ts +21 -0
  216. package/dist/scaler/bare-metal-backend.d.ts +9 -2
  217. package/dist/scaler/config.d.ts +25 -4
  218. package/dist/scaler/container-backend.d.ts +9 -1
  219. package/dist/scaler/firecracker-backend.d.ts +29 -2
  220. package/dist/scaler/index.d.ts +1 -1
  221. package/dist/scaler/manager.d.ts +166 -8
  222. package/dist/scaler/pending-scale-sweeper.d.ts +35 -0
  223. package/dist/scaler/types.d.ts +75 -6
  224. package/dist/secrets/backend-registry.d.ts +32 -1
  225. package/dist/secrets/dashboard-encryption-key.d.ts +48 -0
  226. package/dist/secrets/ephemeral-keys.d.ts +16 -0
  227. package/dist/secrets/pg-secret-store.d.ts +10 -0
  228. package/dist/secrets/rbac.d.ts +5 -1
  229. package/dist/secrets/routing-key-scope.d.ts +6 -0
  230. package/dist/secrets/scope-routing.d.ts +126 -0
  231. package/dist/secrets/secret-resolver.d.ts +1 -14
  232. package/dist/secrets/token-manager.d.ts +5 -1
  233. package/dist/security/contributor-cache.d.ts +9 -1
  234. package/dist/security/trust-policy-gate.d.ts +117 -0
  235. package/dist/security/trust-policy-store.d.ts +78 -0
  236. package/dist/server.js +35769 -25052
  237. package/dist/sources/source-manager.d.ts +24 -0
  238. package/dist/stale-detector/stale-run-detector.d.ts +7 -0
  239. package/dist/standalone.js +34831 -25317
  240. package/dist/storage/filesystem.d.ts +17 -0
  241. package/dist/storage/key-discriminator.d.ts +20 -0
  242. package/dist/storage/s3.d.ts +2 -0
  243. package/dist/storage/types.d.ts +16 -0
  244. package/dist/webhook/dedup.d.ts +9 -1
  245. package/dist/webhook/event-log.d.ts +13 -2
  246. package/dist/webhook/generic-sources-listener.d.ts +4 -0
  247. package/dist/webhook/ingest-admission.d.ts +140 -0
  248. package/dist/webhook/ingest-overflow-buffer.d.ts +27 -0
  249. package/dist/webhook/ingest-overflow-replayer.d.ts +49 -0
  250. package/dist/webhook/ingest-overflow-types.d.ts +73 -0
  251. package/dist/webhook/loop-lag-source.d.ts +40 -0
  252. package/dist/webhook/observed-relay-guard.d.ts +40 -0
  253. package/dist/webhook/org-ingest-cap-reader.d.ts +24 -0
  254. package/dist/webhook/register-source-bundle.d.ts +3 -0
  255. package/dist/webhook/relay-reinject.d.ts +43 -0
  256. package/dist/worker/in-memory-job-queue.d.ts +8 -3
  257. package/dist/worker-core.d.ts +10 -0
  258. package/dist/ws/agent-api-registry.d.ts +20 -0
  259. package/dist/ws/agent-handler.d.ts +63 -7
  260. package/dist/ws/bringup-api.d.ts +99 -0
  261. package/dist/ws/dashboard-context-handler.d.ts +28 -10
  262. package/dist/ws/dashboard-run-state-handler.d.ts +31 -0
  263. package/dist/ws/failure-messages.d.ts +29 -0
  264. package/dist/ws/oidc-token-relay.d.ts +9 -0
  265. package/dist/ws/ownership-gate.d.ts +22 -0
  266. package/dist/ws/platform-client.d.ts +96 -1
  267. package/dist/ws/replay-chunker.d.ts +37 -0
  268. package/installer-image-digests.json +3 -3
  269. package/package.json +22 -21
  270. package/sbom.spdx.json +1240 -1788
@@ -18,7 +18,26 @@ export declare class BackendRegistry {
18
18
  private readonly db;
19
19
  private readonly masterKey;
20
20
  private readonly logger?;
21
- constructor(db: Kysely<any>, masterKey: Buffer, logger?: Logger | undefined);
21
+ private readonly oldMasterKey?;
22
+ constructor(db: Kysely<any>, masterKey: Buffer, logger?: Logger | undefined, oldMasterKey?: Buffer | undefined);
23
+ /**
24
+ * Decrypt a backend config with the current master key, falling back to the
25
+ * old key during a rotation grace window. Same dual-key pattern as
26
+ * PgSecretStore.decryptWithFallback / ephemeral-keys.decryptPrivateKey. The
27
+ * AAD stays `row.name` — ciphertext remains bound to its logical backend.
28
+ * Never called for sentinel rows (config_encrypted = '').
29
+ */
30
+ private decryptConfigWithFallback;
31
+ /** Loud, recovery-pointing error for a backend stranded by key rotation. */
32
+ private strandedError;
33
+ /**
34
+ * Re-seal a backend config that decrypted only under the old key back under
35
+ * the current master key. Runs at load time while KICI_SECRET_KEY_OLD is
36
+ * still configured, healing deployments that rotated before backend configs
37
+ * were part of the rotation sweep. The concurrent-rotation guard
38
+ * (`config_key_version` match) keeps a racing rotation from being clobbered.
39
+ */
40
+ private selfHealStrandedRow;
22
41
  /**
23
42
  * Register a new backend. Encrypts config and stores in DB.
24
43
  */
@@ -64,5 +83,17 @@ export declare class BackendRegistry {
64
83
  * Update sync status for a backend.
65
84
  */
66
85
  updateSyncStatus(name: string, scopeCount: number, error?: string): Promise<void>;
86
+ /**
87
+ * Re-encrypt every non-sentinel backend config under the current master key
88
+ * at max(config_key_version)+1. Same transactional skip-and-count shape as
89
+ * SharedConfigStore.rotateKey — an undecryptable row is counted and left in
90
+ * place (never aborts the sweep); recovery guidance lives in strandedError.
91
+ * Sentinel rows (config_encrypted = '') are excluded from the candidate set
92
+ * and never counted.
93
+ */
94
+ rotateKey(): Promise<{
95
+ reEncrypted: number;
96
+ skipped: number;
97
+ }>;
67
98
  }
68
99
  //# sourceMappingURL=backend-registry.d.ts.map
@@ -0,0 +1,48 @@
1
+ import { type JWK } from 'jose';
2
+ import type { DashboardEncryptionKeyRepo } from '../db/repos/dashboard-encryption-keys-repo.js';
3
+ export interface GeneratedDashboardEncryptionKey {
4
+ kid: string;
5
+ publicJwk: JWK;
6
+ /** AES-256-GCM-wrapped DER private key (master-key wrapped). */
7
+ encryptedPrivateKey: string;
8
+ /** DER-SPKI public key Buffer (for callers that need the raw bytes). */
9
+ publicKeyDer: Buffer;
10
+ }
11
+ /**
12
+ * Generate a fresh X25519 dashboard-encryption key: the OKP public JWK
13
+ * (`use:'enc'`, `kid` = RFC 7638 thumbprint) plus the master-key-wrapped
14
+ * private half.
15
+ */
16
+ export declare function generateDashboardEncryptionKey(secretKey: string): Promise<GeneratedDashboardEncryptionKey>;
17
+ export interface ReconcileDashboardEncryptionKeyDeps {
18
+ repo: Pick<DashboardEncryptionKeyRepo, 'getActiveRow' | 'upsertActive' | 'getByKid'>;
19
+ isLeader: () => boolean;
20
+ /** The orchestrator master key (`KICI_SECRET_KEY`), for db-custody wrapping. */
21
+ secretKey: string | undefined;
22
+ /** Called once when a NEW kid is first activated (audit log, system actor). */
23
+ audit: (info: {
24
+ kid: string;
25
+ }) => Promise<void> | void;
26
+ }
27
+ /** The resolved active dashboard-encryption key + a per-request decrypt closure. */
28
+ export interface ResolvedDashboardEncryptionKey {
29
+ activeKid: string;
30
+ publicJwk: JWK;
31
+ /**
32
+ * Unwrap the DER private key for a given `kid` — the active key OR a
33
+ * rotated-out one whose row is still on record. The lookup is
34
+ * status-agnostic, so a revoked key that has left the published JWKS still
35
+ * decrypts; null means the kid is unknown (never minted, or its row was
36
+ * deleted). Reads the wrapped private half from the DB each call, so
37
+ * rotation is picked up without a restart.
38
+ */
39
+ decryptPrivateKeyDer: (kid: string) => Promise<Buffer | null>;
40
+ }
41
+ /**
42
+ * Ensure exactly one `active` dashboard-encryption key exists and return the
43
+ * resolved key + decrypt closure, or null when not yet ready (non-leader before
44
+ * the leader has generated it). Requires `KICI_SECRET_KEY` (throws otherwise —
45
+ * the private key is master-key wrapped, same posture as db-custody signing).
46
+ */
47
+ export declare function reconcileDashboardEncryptionKey(deps: ReconcileDashboardEncryptionKeyDeps): Promise<ResolvedDashboardEncryptionKey | null>;
48
+ //# sourceMappingURL=dashboard-encryption-key.d.ts.map
@@ -46,4 +46,20 @@ export declare function decryptSecretOutput(envelope: {
46
46
  agentPublicKey: string;
47
47
  encrypted: string;
48
48
  }, runPrivateKeyDer: Buffer): string;
49
+ /**
50
+ * Decrypt a browser-sealed dashboard write.
51
+ *
52
+ * Under the `encrypted` dashboard-write posture the browser seals the value to
53
+ * the orchestrator's published X25519 encryption key using the SAME
54
+ * ECDH → HKDF → AES-256-GCM envelope the agent uses for run secret outputs,
55
+ * but with the `kici-dashboard-sealed-write` HKDF info string.
56
+ *
57
+ * @param envelope - `{ ephemeralPublicKey: base64 DER-SPKI, encrypted: base64 IV||tag||ct }`
58
+ * @param encryptionPrivateKeyDer - DER-encoded orchestrator X25519 private key
59
+ * @returns Decrypted plaintext string
60
+ */
61
+ export declare function decryptDashboardSealedWrite(envelope: {
62
+ ephemeralPublicKey: string;
63
+ encrypted: string;
64
+ }, encryptionPrivateKeyDer: Buffer): string;
49
65
  //# sourceMappingURL=ephemeral-keys.d.ts.map
@@ -19,6 +19,16 @@ export declare class SecretScopeNotFoundError extends Error {
19
19
  readonly scope: string;
20
20
  constructor(scope: string);
21
21
  }
22
+ /**
23
+ * Thrown by `renameScope` when the destination scope already holds secret rows
24
+ * or context bindings. Renaming onto it would merge two scopes rather than move
25
+ * one. The admin HTTP route maps it to a 409; the dashboard rename handler
26
+ * relays its message as the operation's error text.
27
+ */
28
+ export declare class SecretScopeExistsError extends Error {
29
+ readonly scope: string;
30
+ constructor(scope: string);
31
+ }
22
32
  /**
23
33
  * PostgreSQL secret store with AES-256-GCM encryption.
24
34
  * Uses scoped_secrets table keyed by (org_id, scope, key).
@@ -13,7 +13,11 @@ export type Role = 'owner' | 'admin' | 'auditor';
13
13
  /**
14
14
  * Permissions for the secrets management admin API.
15
15
  */
16
- export type Permission = 'context.create' | 'context.read' | 'context.update' | 'context.delete' | 'secret.read' | 'secret.write' | 'secret.delete' | 'secret.reveal' | 'audit.read' | 'token.manage' | 'key.rotate' | 'run.read' | 'run.cancel' | 'event_log.read' | 'event_log.read_payload' | 'access_log.read' | 'scheduled_job.trigger' | 'attestation.retry' | 'event_dlq.read' | 'event_dlq.manage';
16
+ export type Permission = 'context.create' | 'context.read' | 'context.update' | 'context.delete' | 'secret.read' | 'secret.write' | 'secret.delete' | 'secret.reveal' | 'audit.read' | 'token.manage' | 'key.rotate' | 'run.read' | 'run.cancel' | 'event_log.read' | 'event_log.read_payload' | 'access_log.read' | 'scheduled_job.trigger' | 'attestation.retry' | 'event_dlq.read' | 'event_dlq.manage' | 'orchestrator.drain'
17
+ /** Read the org-wide CI trust policy that gates fork / unknown / workflow-change PRs. */
18
+ | 'ci_trust.read'
19
+ /** Modify org-wide trust policies (independent mode only — Platform-attached PATCH refuses). */
20
+ | 'ci_trust.admin';
17
21
  /**
18
22
  * Error thrown when a role lacks the required permission.
19
23
  */
@@ -17,6 +17,12 @@
17
17
  * access is denied, or `null` to let the handler continue. The middleware
18
18
  * mounted in each admin route file is responsible for calling
19
19
  * `c.set('routingKey', tokenInfo.routingKey)` so these helpers can read it.
20
+ *
21
+ * NOT a scope name. `requested` must be a routing key (`<provider>:<id>`) read
22
+ * from a row or an explicit request field. Secret scope names live in a
23
+ * different namespace — a path whose `:` is reserved as the backend qualifier —
24
+ * and must never be passed here. Secret routes have no per-routing-key slice;
25
+ * they use `requireUnscopedToken` instead.
20
26
  */
21
27
  import type { Context } from 'hono';
22
28
  /**
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Backend-qualified scope routing.
3
+ *
4
+ * A secret scope travels over the wire in *qualified* form -- `<backend>:<path>`
5
+ * -- while every `SecretStore` implementation is addressed with the bare
6
+ * `<path>`. This module owns the single split between the two forms so the two
7
+ * write planes (the dashboard WebSocket handler and the HTTP admin API) can
8
+ * never drift apart on where the qualifier is stripped.
9
+ *
10
+ * The registered-backend map IS the whitelist: a head before the first `:` is a
11
+ * backend qualifier only when it names a registered backend. Anything else --
12
+ * an unregistered head, a leading `:`, no `:` at all -- stays whole and is
13
+ * routed to the default store, where the ordinary scope-name validation
14
+ * rejects it if it is malformed. That is what keeps routing keys
15
+ * (`<provider>:<id>`) out of the secret-scope namespace: `github:42` names no
16
+ * backend, so it stays whole and is rejected as a scope path.
17
+ */
18
+ /**
19
+ * The subset of `SecretStore` a scope-taking route or WS handler needs.
20
+ *
21
+ * Deliberately narrower than the full `SecretStore` from `@kici-dev/engine`:
22
+ * routing only needs the scope-addressed methods, so a caller may pass a
23
+ * partial store (the degraded store below, a unit-test fake) without
24
+ * implementing value resolution.
25
+ */
26
+ export interface ScopedSecretStore {
27
+ listScopes(orgId: string): Promise<string[]>;
28
+ listKeys(orgId: string, scope: string): Promise<string[]>;
29
+ setSecret(orgId: string, scope: string, key: string, value: string): Promise<void>;
30
+ deleteSecret(orgId: string, scope: string, key: string): Promise<void>;
31
+ createScope?(orgId: string, scope: string): Promise<void>;
32
+ renameScope?(orgId: string, oldScope: string, newScope: string): Promise<void>;
33
+ deleteScope?(orgId: string, scope: string): Promise<void>;
34
+ }
35
+ /**
36
+ * Raised when a secret write is issued against an orchestrator that has no
37
+ * secret store configured.
38
+ *
39
+ * The message is operator-facing: the dashboard write planes relay it verbatim
40
+ * as the `error` on their response, so it names the deployment condition rather
41
+ * than the internal cause.
42
+ */
43
+ export declare class SecretsUnavailableError extends Error {
44
+ constructor();
45
+ }
46
+ /**
47
+ * The store an orchestrator serves the dashboard from when it has no secret
48
+ * store configured.
49
+ *
50
+ * The read/write asymmetry is deliberate. `listScopes` / `listKeys` return
51
+ * empty because "this deployment holds no secrets" is true and complete.
52
+ * `setSecret` / `deleteSecret` reject, because a write that resolved here would
53
+ * be discarded while the dashboard reported the secret as stored -- and a
54
+ * delete that resolved would leave a credential the operator believes is
55
+ * revoked. The optional scope methods stay unimplemented: the write planes
56
+ * already refuse a scope operation a store does not support.
57
+ */
58
+ export declare function createUnavailableSecretStore(): ScopedSecretStore;
59
+ /** Backend name assumed when a wire scope carries no recognised qualifier. */
60
+ export declare const DEFAULT_BACKEND_NAME = "pg";
61
+ /** Outcome of resolving a wire-form scope against the registered backends. */
62
+ export interface ResolvedScope<S> {
63
+ /** The store the operation must be issued against. */
64
+ store: S;
65
+ /** The backend the scope resolved to (the default name when unqualified). */
66
+ backendName: string;
67
+ /** The bare scope path to pass to the store -- never carries a qualifier. */
68
+ path: string;
69
+ /** True when the wire scope carried a recognised `<backend>:` qualifier. */
70
+ qualified: boolean;
71
+ }
72
+ /**
73
+ * The one method of the secret-backend registry that store loading needs.
74
+ *
75
+ * Structural on purpose: keeping the concrete registry out of this module lets
76
+ * both write planes -- and their unit tests -- supply their own loader without
77
+ * dragging a database-backed registry into a pure routing module.
78
+ */
79
+ export interface BackendStoreRegistry<S, L> {
80
+ loadAllStores(auditLogger: L): Promise<Map<string, S>>;
81
+ }
82
+ /**
83
+ * Load the registered secret backends for one operation.
84
+ *
85
+ * Never cache the result: a backend's credentials can rotate, and a backend can
86
+ * be added or removed, between operations -- a stale store would write to the
87
+ * wrong place. A registry failure propagates rather than degrading to the
88
+ * default store, because a misrouted secret write is worse than a failed one.
89
+ *
90
+ * The default-backend entry is ALWAYS `defaultStore`, overriding whatever the
91
+ * registry returned. The registry builds its own `PgSecretStore` for the seeded
92
+ * `pg` row, and that instance carries none of the orchestrator's configuration:
93
+ * `customerSecretsEnabled` defaults to true (so it would ignore an operator's
94
+ * `pgCustomerSecrets: false`), its key version is hardcoded to 1, and it has no
95
+ * old-master-key fallback (so it cannot decrypt rows written before a
96
+ * rotation). Overriding only when the registry omitted the entry is dead code
97
+ * -- the default row is seeded at startup -- and would let `pg:<path>` and
98
+ * `<path>` behave differently, which is the very defect this routing exists to
99
+ * fix.
100
+ *
101
+ * @param registry - Backend registry, or undefined when none is configured.
102
+ * @param auditLogger - Audit logger handed to the registry's store factory.
103
+ * @param defaultStore - Configured store for the default backend.
104
+ * @param defaultBackendName - Name the default store is registered under.
105
+ */
106
+ export declare function loadRoutableStores<S, L>(registry: BackendStoreRegistry<S, L> | undefined, auditLogger: L, defaultStore: S, defaultBackendName?: string): Promise<Map<string, S>>;
107
+ /**
108
+ * Split a wire-form scope into the store that owns it and the bare path.
109
+ *
110
+ * Pure: takes the already-loaded store map rather than loading it, so both
111
+ * planes can unit-test routing without a database.
112
+ *
113
+ * @param wireScope - Scope as supplied by the caller, possibly `<backend>:<path>`.
114
+ * @param stores - Registered backends, keyed by backend name.
115
+ * @param defaultStore - Store used when the scope carries no recognised qualifier.
116
+ * @param defaultBackendName - Backend name reported for an unqualified scope.
117
+ */
118
+ export declare function resolveScope<S>(wireScope: string, stores: Map<string, S>, defaultStore: S, defaultBackendName?: string): ResolvedScope<S>;
119
+ /**
120
+ * Join a backend name and a bare path back into wire form.
121
+ *
122
+ * Used for audit records and cross-backend listings, so an operator reading the
123
+ * audit log sees the same qualified string the caller sent.
124
+ */
125
+ export declare function toWireScope(backendName: string, path: string): string;
126
+ //# sourceMappingURL=scope-routing.d.ts.map
@@ -7,7 +7,7 @@
7
7
  * 2. Gets bindings for that context
8
8
  * 3. Queries ALL registered backend stores for secrets
9
9
  * 4. Prefixes each secret's scope with the backend name (e.g., pg:aws/prod)
10
- * 5. Uses resolveSecretsForContext to match bindings against prefixed secrets
10
+ * 5. Uses resolveSecretsWithProvenance to match bindings against prefixed secrets
11
11
  * 6. Returns a flat decrypted key-value map
12
12
  *
13
13
  * unreachable backends cause job failure (not silent skip).
@@ -148,18 +148,5 @@ export declare class SecretResolver implements SecretResolverApi {
148
148
  * jobs referencing only healthy backends succeed normally.
149
149
  */
150
150
  private checkScopedFailure;
151
- /**
152
- * Find the winning secret for a given key, mirroring the engine scope
153
- * resolver's host-aware matching and `(host specificity, scope depth)`
154
- * precedence so the enriched metadata reports the same secret the flat
155
- * resolution selected.
156
- */
157
- private findWinningSecret;
158
- /**
159
- * Resolve the effective scope pattern a binding contributes for a host,
160
- * applying the host gate and per-child scope templating. Mirrors the engine
161
- * scope resolver's `bindingScopeForHost`. Returns `null` to skip the binding.
162
- */
163
- private bindingScopeForHost;
164
151
  }
165
152
  //# sourceMappingURL=secret-resolver.d.ts.map
@@ -16,15 +16,19 @@ export declare class TokenManager {
16
16
  * @param label - Human-readable label for this token.
17
17
  * @param role - Role to assign (owner, admin, auditor).
18
18
  * @param routingKey - Optional routing key scope (null = all).
19
+ * @param expiresAt - Optional absolute expiry. When omitted the token
20
+ * never expires (null); `validate()` already enforces the column.
19
21
  * @returns The plaintext token (shown once) and the row ID.
20
22
  */
21
- generateToken(label: string, role: Role, routingKey?: string | null): Promise<{
23
+ generateToken(label: string, role: Role, routingKey?: string | null, expiresAt?: Date | null): Promise<{
22
24
  token: string;
23
25
  id: string;
24
26
  }>;
25
27
  /**
26
28
  * Validate a plaintext token against stored hashes.
27
29
  *
30
+ * On success, fires a non-blocking update to last_used_at.
31
+ *
28
32
  * @param token - The plaintext token to validate.
29
33
  * @returns Token info if valid, null if invalid/expired/revoked.
30
34
  */
@@ -5,18 +5,26 @@
5
5
  * Uses a 15-minute TTL and 10,000 max entries.
6
6
  */
7
7
  import type { ContributorResolver, ContributorInfo } from '@kici-dev/engine';
8
+ import type { ClusterSettingsReader } from '../cluster/cluster-settings-reader.js';
8
9
  /**
9
10
  * Caches ContributorResolver results in an LRU cache.
10
11
  *
11
12
  * Cache key format: `{provider}:{repoFullName}:{username}`
12
- * TTL: 15 minutes (configurable for testing).
13
+ * TTL: cluster-configurable (`cluster_settings.contributor_cache_ttl_ms`,
14
+ * default 15 minutes). The TTL is resolved at each `set()` and applied
15
+ * per-entry, so a live override affects newly-cached entries without a restart.
13
16
  */
14
17
  export declare class ContributorCache {
15
18
  private readonly cache;
19
+ private readonly clusterSettings?;
20
+ private readonly defaultTtlMs;
16
21
  constructor(options?: {
17
22
  ttlMs?: number;
18
23
  maxEntries?: number;
24
+ clusterSettings?: ClusterSettingsReader;
19
25
  });
26
+ /** Resolve the fleet-wide contributor-cache TTL (ms), falling back to the config default. */
27
+ private ttlMs;
20
28
  /**
21
29
  * Build the cache key from provider, repo, and username.
22
30
  */
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Org trust-policy gate — turns the Platform-owned policy plus three per-PR
3
+ * signals into exactly one outcome.
4
+ *
5
+ * Pure: no I/O, no DB, no clock. The caller supplies the effective policy (see
6
+ * `resolveEffectivePolicy`) and the signals; enforcement lives in the dispatch
7
+ * gate.
8
+ *
9
+ * Scope: the caller only invokes this for sources whose provider bundle carries
10
+ * a `ContributorResolver` (GitHub today). Every other source is trusted by
11
+ * construction and never reaches here.
12
+ */
13
+ import { z } from 'zod';
14
+ import type { OrchestratorMode, TrustPolicy, TrustTier } from '@kici-dev/engine';
15
+ import { SecurityHoldReason } from '../contexts/held-runs.js';
16
+ import type { StoredTrustPolicy } from './trust-policy-store.js';
17
+ /**
18
+ * Which arm of the gate is actually in force for an org — the vocabulary the
19
+ * admin API reports and `kici-admin trust-policy show` renders.
20
+ *
21
+ * `policy` means `resolveEffectivePolicy` produced a policy and all three arms
22
+ * apply; `legacy` means it produced `null`, so only the legacy
23
+ * workflow-modification rule runs and there are no policy values to report.
24
+ * Named here, next to the resolver that decides between them, so the route and
25
+ * the CLI cannot drift apart on a bare string literal.
26
+ */
27
+ export declare const TrustPolicyEnforcement: z.ZodEnum<{
28
+ legacy: "legacy";
29
+ policy: "policy";
30
+ }>;
31
+ export type TrustPolicyEnforcement = z.infer<typeof TrustPolicyEnforcement>;
32
+ /** The per-PR facts the policy is evaluated against. */
33
+ export interface TrustPolicySignals {
34
+ /** Resolved contributor tier; undefined when trust resolution failed. */
35
+ tier: TrustTier | undefined;
36
+ /** The PR's head repo differs from its base repo. */
37
+ isForkPR: boolean;
38
+ /** The PR changes `.kici/` workflow definitions. */
39
+ hasWorkflowModifications: boolean;
40
+ }
41
+ /**
42
+ * The reasons the ORG TRUST POLICY itself can raise — its three arms.
43
+ *
44
+ * `context_trust` is excluded at the type level rather than merely by
45
+ * convention: that reason belongs to the per-context minimum-trust gate, which
46
+ * holds an individual job under its real name. Narrowing here is what lets
47
+ * `SECURITY_HOLD_JOB_IDS` drop its phantom `context_trust` sentinel — a value
48
+ * that existed only to satisfy a `Record<SecurityHoldReason, ...>` and was never
49
+ * written to a single row.
50
+ */
51
+ export type TrustPolicyHoldReason = Exclude<SecurityHoldReason, 'context_trust'>;
52
+ export type TrustPolicyOutcome = {
53
+ action: 'pass';
54
+ } | {
55
+ action: 'hold';
56
+ reason: TrustPolicyHoldReason;
57
+ message: string;
58
+ /**
59
+ * Hours the resulting hold stays approvable, taken from the SAME policy
60
+ * that produced this verdict. `null` in independent mode, where there is
61
+ * no upstream policy and therefore no operator-set window.
62
+ *
63
+ * Carried on the outcome rather than re-read at the hold site: a second,
64
+ * independent read bypassed `resolveEffectivePolicy`, so it was both a
65
+ * TOCTOU (the policy could change between deciding and sizing) and a
66
+ * divergence — independent mode got the 72h default where the decision
67
+ * path deliberately has no policy at all.
68
+ */
69
+ approvalExpiryHours: number | null;
70
+ } | {
71
+ action: 'reject';
72
+ reason: TrustPolicyHoldReason;
73
+ message: string;
74
+ };
75
+ /**
76
+ * The policy a Platform-attached orchestrator applies when it has no stored
77
+ * row. Every arm holds — a hold is recoverable by approval, and these are the
78
+ * documented org defaults, so an org that never changed its policy gets the
79
+ * behavior its dashboard shows.
80
+ *
81
+ * This is NOT necessarily a brief transient. The Platform sends
82
+ * `trust_policy.update` only when the org has a `trust_policies` row, and that
83
+ * row is created lazily on a dashboard read — so an org that has never opened
84
+ * Settings > CI trust receives no push at all and stays on these values
85
+ * indefinitely. The expiry is therefore the generous documented default rather
86
+ * than a short one: a short window would auto-fail legitimate runs.
87
+ */
88
+ export declare const FAIL_CLOSED_POLICY: TrustPolicy;
89
+ /**
90
+ * Pick the policy to evaluate. A stored row always wins. Without one, a
91
+ * Platform-attached orchestrator fails closed (a push is imminent); an
92
+ * independent orchestrator has no upstream authority at all, so it gets `null`
93
+ * and the evaluator applies only the legacy rule — which is what keeps this
94
+ * change from silently gating existing independent deployments on upgrade.
95
+ *
96
+ * `PLATFORM_CONNECTED_MODES` is the shared definition of "expects a Platform
97
+ * push", so a mode added there is fail-closed here without a second edit.
98
+ */
99
+ export declare function resolveEffectivePolicy(stored: StoredTrustPolicy | null, mode: OrchestratorMode): TrustPolicy | null;
100
+ /**
101
+ * Evaluate the policy.
102
+ *
103
+ * Arms are evaluated in a fixed order — workflow_modification, fork_pr,
104
+ * unknown_contributor — and then any `reject` beats any `hold`, with the first
105
+ * arm in that order supplying the reason among equals. That makes a PR tripping
106
+ * several arms produce one outcome with a stable reason rather than a verdict
107
+ * that depends on evaluation accident.
108
+ *
109
+ * An unresolved tier (`undefined`) counts as `unknown`, never as a pass: a
110
+ * trust resolution that could not be answered is not evidence of trust.
111
+ *
112
+ * A `null` policy applies only the legacy rule (workflow modifications by a
113
+ * non-trusted contributor hold), reproducing behavior from before the policy was
114
+ * enforced.
115
+ */
116
+ export declare function evaluateTrustPolicy(policy: TrustPolicy | null, signals: TrustPolicySignals): TrustPolicyOutcome;
117
+ //# sourceMappingURL=trust-policy-gate.d.ts.map
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Cache of the Platform-owned org trust policy.
3
+ *
4
+ * The Platform is the authority for a Platform-attached org and pushes the
5
+ * policy on `trust_policy.update`; this store persists it so the policy survives
6
+ * a restart instead of being unknown until the next push. In independent mode
7
+ * there is no Platform, so the operator writes the same row via
8
+ * `kici-admin trust-policy set` and `source` records which wrote it.
9
+ */
10
+ import { Kysely, type Transaction } from 'kysely';
11
+ import { z } from 'zod';
12
+ import type { TrustPolicy } from '@kici-dev/engine';
13
+ import type { Database } from '../db/types.js';
14
+ /** Who wrote the cached policy row. */
15
+ export declare const TrustPolicySource: z.ZodEnum<{
16
+ local: "local";
17
+ platform: "platform";
18
+ }>;
19
+ export type TrustPolicySource = z.infer<typeof TrustPolicySource>;
20
+ /**
21
+ * The strictest documented defaults. Used to fill gaps on a local merge; the
22
+ * fail-closed policy an unknown org resolves to lives in `trust-policy-gate.ts`.
23
+ */
24
+ export declare const DEFAULT_TRUST_POLICY: TrustPolicy;
25
+ /** A policy as stored, with its provenance. */
26
+ export interface StoredTrustPolicy extends TrustPolicy {
27
+ source: TrustPolicySource;
28
+ updatedAt: Date;
29
+ }
30
+ export declare class TrustPolicyStore {
31
+ private readonly db;
32
+ constructor(db: Kysely<Database>);
33
+ /** `executor` lets a caller read inside its own transaction. */
34
+ get(orgId: string, executor?: Kysely<Database> | Transaction<Database>): Promise<StoredTrustPolicy | null>;
35
+ /**
36
+ * Needs no lock, unlike `upsertLocal`: a push carries every field, so there
37
+ * is no read-merge to lose and concurrent pushes correctly settle on the
38
+ * last one. The two writers also never overlap — `upsertLocal` is reachable
39
+ * only in independent mode, where no Platform pushes.
40
+ */
41
+ upsertFromPlatform(orgId: string, policy: TrustPolicy): Promise<void>;
42
+ /**
43
+ * Write an operator-supplied policy. Only reachable in independent mode — the
44
+ * admin route refuses on a Platform-attached orchestrator, because the next
45
+ * push would clobber the write.
46
+ *
47
+ * The read-merge-write is serialised per org by a transaction-scoped
48
+ * advisory lock. The transaction alone would NOT give that: under READ
49
+ * COMMITTED two concurrent PATCHes both read the pre-existing row, and the
50
+ * second `ON CONFLICT DO UPDATE` then overwrites every column from its own
51
+ * stale merge — silently dropping the first operator's change (a tightened
52
+ * `unknownContributorPolicy` reverting to whatever the second caller last
53
+ * saw). The lock releases on commit or rollback, so there is no unlock to
54
+ * leak.
55
+ *
56
+ * `onWrite` receives the same transaction and the merged result, so an audit
57
+ * row written there commits or rolls back with the policy itself — a
58
+ * loosened `forkPolicy` can never land unattributed.
59
+ *
60
+ * Returns the merged policy so the caller does not need a second read (which
61
+ * would be outside the transaction and could observe a later write).
62
+ */
63
+ upsertLocal(orgId: string, patch: Partial<TrustPolicy>, onWrite?: (trx: Transaction<Database>, merged: TrustPolicy) => Promise<void>): Promise<TrustPolicy>;
64
+ private write;
65
+ }
66
+ /**
67
+ * Build a TrustPolicyStore backed by its own connection pool to the given
68
+ * orchestrator database URL. Mirrors `createHeldRunStoreFromUrl`; consumed by
69
+ * E2E tests that assert the pushed policy is persisted in the real deployed
70
+ * orchestrator DB rather than held in process memory.
71
+ */
72
+ export declare function createTrustPolicyStoreFromUrl(databaseUrl: string, opts?: {
73
+ maxConnections?: number;
74
+ }): {
75
+ store: TrustPolicyStore;
76
+ dispose: () => Promise<void>;
77
+ };
78
+ //# sourceMappingURL=trust-policy-store.d.ts.map