@kici-dev/orchestrator 0.4.0 → 0.6.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 (183) hide show
  1. package/dist/__test-helpers__/fake-scaler-state-store.d.ts +24 -0
  2. package/dist/__test-helpers__/mock-db-query.d.ts +130 -0
  3. package/dist/__test-helpers__/mock-db.d.ts +27 -0
  4. package/dist/agent/agent-version.d.ts +34 -0
  5. package/dist/agent/dispatcher.d.ts +151 -13
  6. package/dist/agent/host-roster.d.ts +37 -5
  7. package/dist/agent/registry.d.ts +2 -0
  8. package/dist/app.d.ts +56 -7
  9. package/dist/approvals/apply-decision.d.ts +67 -19
  10. package/dist/approvals/held-run-release-wiring.d.ts +45 -0
  11. package/dist/approvals/independent-wiring.d.ts +55 -0
  12. package/dist/approvals/resume-router.d.ts +9 -0
  13. package/dist/approvals/triggerer-subject.d.ts +37 -0
  14. package/dist/cache/dep-cache.d.ts +54 -10
  15. package/dist/cache/global-eval-round-cache.d.ts +95 -0
  16. package/dist/cache/index.d.ts +3 -0
  17. package/dist/cache/pending-global-evals.d.ts +42 -0
  18. package/dist/cache/pending-inits.d.ts +10 -0
  19. package/dist/cli/api-client.d.ts +18 -0
  20. package/dist/cli/commands/cluster-settings.d.ts +52 -3
  21. package/dist/cli/commands/diagnose.d.ts +6 -0
  22. package/dist/cli/commands/held-run.d.ts +58 -0
  23. package/dist/cli/commands/runs.d.ts +1 -0
  24. package/dist/cli/commands/trust-policy.d.ts +117 -12
  25. package/dist/cli/kici-admin.d.ts +10 -0
  26. package/dist/cli.js +2770 -938
  27. package/dist/cluster/cluster-identity.d.ts +3 -3
  28. package/dist/cluster/cluster-settings-reader.d.ts +59 -1
  29. package/dist/cluster/coordinator.d.ts +44 -0
  30. package/dist/cluster/index.d.ts +4 -0
  31. package/dist/cluster/peer-handler.d.ts +19 -0
  32. package/dist/cluster/peer-registry.d.ts +17 -0
  33. package/dist/cluster/plan-headroom-store.d.ts +26 -0
  34. package/dist/cluster/worker-eviction.d.ts +69 -0
  35. package/dist/cold-store/load-event-log-range.d.ts +10 -3
  36. package/dist/cold-store/load-secret-audit-log-range.d.ts +4 -3
  37. package/dist/cold-store/tables/secret-audit-log.d.ts +4 -3
  38. package/dist/config.d.ts +48 -21
  39. package/dist/content-requirements-cache.d.ts +55 -0
  40. package/dist/contexts/held-runs.d.ts +123 -16
  41. package/dist/contexts/protection/aggregate.d.ts +3 -2
  42. package/dist/contexts/protection/branch-gate.d.ts +15 -0
  43. package/dist/contexts/protection/concurrency-gate.d.ts +8 -2
  44. package/dist/contexts/protection/pipeline.d.ts +18 -0
  45. package/dist/contexts/release-queued-holds.d.ts +35 -0
  46. package/dist/dashboard/attestation-filters.d.ts +8 -0
  47. package/dist/dashboard/handler.d.ts +6 -24
  48. package/dist/db/migrations/109_cluster_settings_cache_knobs.d.ts +4 -0
  49. package/dist/db/migrations/110_cluster_settings_global_eval_knobs.d.ts +4 -0
  50. package/dist/db/migrations/111_cluster_settings_global_eval_wait.d.ts +4 -0
  51. package/dist/db/migrations/112_execution_runs_workflow_repo.d.ts +4 -0
  52. package/dist/db/migrations/113_execution_runs_workflow_repo_index.d.ts +30 -0
  53. package/dist/db/migrations/114_ingest_queue_claim.d.ts +4 -0
  54. package/dist/db/migrations/115_global_workflows_cluster_switch.d.ts +9 -0
  55. package/dist/db/migrations/116_org_plan_headroom.d.ts +4 -0
  56. package/dist/db/migrations/117_invoke_gate_proxy_jobs.d.ts +4 -0
  57. package/dist/db/migrations/118_invoke_gate_scheduling.d.ts +4 -0
  58. package/dist/db/migrations/119_scaler_ha_ownership.d.ts +4 -0
  59. package/dist/db/migrations/120_cluster_settings_scaler_reaper.d.ts +4 -0
  60. package/dist/db/migrations/121_org_settings_allow_untrusted_dockerfile_builds.d.ts +19 -0
  61. package/dist/db/migrations/122_host_roster_scaler_managed.d.ts +25 -0
  62. package/dist/db/migrations/123_workflow_registrations_default_branch.d.ts +24 -0
  63. package/dist/db/migrations/124_cluster_settings_provision_backoff.d.ts +4 -0
  64. package/dist/db/migrations/125_org_trust_directory.d.ts +30 -0
  65. package/dist/db/migrations/126_held_runs_posted_pending_check.d.ts +28 -0
  66. package/dist/db/migrations/127_org_trust_policy_approval_expiry_seconds.d.ts +26 -0
  67. package/dist/db/migrations/128_execution_runs_global_eval_round.d.ts +23 -0
  68. package/dist/db/migrations/129_execution_runs_dispatch_routing_key.d.ts +24 -0
  69. package/dist/db/migrations/130_scaler_provision_outcomes.d.ts +32 -0
  70. package/dist/db/types.d.ts +428 -12
  71. package/dist/entry-helpers.d.ts +28 -0
  72. package/dist/events/event-emitter.d.ts +22 -0
  73. package/dist/events/event-router.d.ts +87 -1
  74. package/dist/events/types.d.ts +2 -23
  75. package/dist/git/credential-broker.d.ts +94 -0
  76. package/dist/git/inherited-secret.d.ts +24 -0
  77. package/dist/git/installation-token.d.ts +38 -0
  78. package/dist/git/job-context.d.ts +13 -0
  79. package/dist/index.js +324 -84
  80. package/dist/metrics/agent-metrics-aggregator.d.ts +4 -4
  81. package/dist/metrics/prometheus.d.ts +170 -3
  82. package/dist/oidc/oidc-mint-registration.d.ts +7 -3
  83. package/dist/orchestrator-core.d.ts +91 -24
  84. package/dist/pipeline/content-filter.d.ts +71 -0
  85. package/dist/pipeline/direct-ingress-deps.d.ts +100 -0
  86. package/dist/pipeline/dispatch-matched-workflow.d.ts +521 -11
  87. package/dist/pipeline/global-eval-round.d.ts +307 -0
  88. package/dist/pipeline/internal-event-pipeline.d.ts +140 -0
  89. package/dist/pipeline/invoke-gate.d.ts +164 -0
  90. package/dist/pipeline/job-contexts.d.ts +16 -17
  91. package/dist/pipeline/needs-scheduler.d.ts +13 -0
  92. package/dist/pipeline/process-webhook.d.ts +126 -31
  93. package/dist/pipeline/processor.d.ts +282 -23
  94. package/dist/pipeline/rerun.d.ts +21 -0
  95. package/dist/pipeline/resume-workflow.d.ts +40 -7
  96. package/dist/pipeline/route-or-dispatch-jobs.d.ts +15 -0
  97. package/dist/pipeline/security-hold-check.d.ts +217 -0
  98. package/dist/pipeline/test-pipeline.d.ts +12 -0
  99. package/dist/pipeline/undispatched-hold-checks.d.ts +23 -0
  100. package/dist/pipeline/webhook-payload-store.d.ts +20 -0
  101. package/dist/policy/dashboard-write-policy-listener.d.ts +62 -0
  102. package/dist/policy/dashboard-write-policy.d.ts +14 -0
  103. package/dist/provenance/backfill-run.d.ts +10 -1
  104. package/dist/provider-registry.d.ts +47 -4
  105. package/dist/providers/github/check-status-poster.d.ts +33 -3
  106. package/dist/providers/github/commit-message.d.ts +20 -0
  107. package/dist/providers/github/file-contents.d.ts +40 -0
  108. package/dist/providers/github/index.d.ts +2 -2
  109. package/dist/providers/github/normalizer.d.ts +3 -2
  110. package/dist/providers/local/normalizer.d.ts +3 -5
  111. package/dist/providers/universal-git/config.d.ts +2 -0
  112. package/dist/providers/universal-git/index.d.ts +11 -2
  113. package/dist/providers/universal-git/normalizer.d.ts +10 -0
  114. package/dist/queue/cleanup.d.ts +7 -1
  115. package/dist/queue/job-queue.d.ts +112 -7
  116. package/dist/queue/terminalize-unroutable.d.ts +13 -0
  117. package/dist/registration/extractor.d.ts +3 -3
  118. package/dist/registration/registration-index.d.ts +7 -0
  119. package/dist/registration/registration-run-match.d.ts +47 -0
  120. package/dist/registration/registration-store.d.ts +22 -0
  121. package/dist/reporting/check-run-reporter.d.ts +146 -2
  122. package/dist/reporting/check-run-summary.d.ts +25 -1
  123. package/dist/reporting/execution-tracker.d.ts +324 -9
  124. package/dist/reporting/log-chunk-sink.d.ts +8 -5
  125. package/dist/reporting/run-aggregator.d.ts +4 -14
  126. package/dist/reporting/step-display-order.d.ts +43 -0
  127. package/dist/routes/admin-held-runs.d.ts +142 -0
  128. package/dist/routes/admin-org-settings.d.ts +5 -0
  129. package/dist/routes/admin-trust-policy.d.ts +34 -6
  130. package/dist/routes/admin.d.ts +15 -0
  131. package/dist/scaler/backend-factory.d.ts +55 -0
  132. package/dist/scaler/bare-metal-backend.d.ts +43 -5
  133. package/dist/scaler/claim-store.d.ts +119 -0
  134. package/dist/scaler/config.d.ts +4 -0
  135. package/dist/scaler/container-backend.d.ts +18 -4
  136. package/dist/scaler/container-routing.d.ts +23 -0
  137. package/dist/scaler/container-spawn.d.ts +28 -0
  138. package/dist/scaler/event-backend.d.ts +124 -0
  139. package/dist/scaler/event-provision-reaper.d.ts +350 -0
  140. package/dist/scaler/failure-tracker.d.ts +1 -1
  141. package/dist/scaler/firecracker-backend.d.ts +33 -6
  142. package/dist/scaler/index.d.ts +11 -1
  143. package/dist/scaler/label-matcher.d.ts +4 -3
  144. package/dist/scaler/manager.d.ts +905 -76
  145. package/dist/scaler/resolve-container-auth.d.ts +45 -0
  146. package/dist/scaler/scaler-events.d.ts +11 -0
  147. package/dist/scaler/scaler-state-store.d.ts +294 -10
  148. package/dist/scaler/types.d.ts +131 -13
  149. package/dist/scaler/warm-pool.d.ts +132 -29
  150. package/dist/security/comment-handler.d.ts +50 -11
  151. package/dist/security/global-workflow-policy.d.ts +52 -12
  152. package/dist/security/identity-link.d.ts +60 -0
  153. package/dist/security/lock-source.d.ts +11 -13
  154. package/dist/security/reduced-privilege-note.d.ts +59 -0
  155. package/dist/security/trust-directory-store.d.ts +233 -0
  156. package/dist/security/trust-policy-gate.d.ts +94 -59
  157. package/dist/security/trust-policy-store.d.ts +3 -0
  158. package/dist/security/trust-resolver.d.ts +14 -98
  159. package/dist/server.d.ts +11 -1
  160. package/dist/server.js +56329 -42234
  161. package/dist/stale-detector/gate-deadline-detector.d.ts +52 -0
  162. package/dist/stale-detector/stale-run-detector.d.ts +61 -3
  163. package/dist/standalone.js +37619 -23570
  164. package/dist/webhook/ingest-accept.d.ts +70 -0
  165. package/dist/webhook/ingest-overflow-buffer.d.ts +35 -4
  166. package/dist/webhook/ingest-overflow-replayer.d.ts +50 -6
  167. package/dist/worker/in-memory-job-queue.d.ts +1 -1
  168. package/dist/ws/agent-handler.d.ts +31 -4
  169. package/dist/ws/dashboard-context-handler.d.ts +28 -4
  170. package/dist/ws/dashboard-global-workflows-handler.d.ts +36 -9
  171. package/dist/ws/execution-status-frame.d.ts +32 -0
  172. package/dist/ws/failure-messages.d.ts +2 -0
  173. package/dist/ws/git-credential-relay.d.ts +39 -0
  174. package/dist/ws/oidc-token-relay.d.ts +6 -11
  175. package/dist/ws/platform-client.d.ts +68 -9
  176. package/dist/ws/test-relay-handlers.d.ts +35 -10
  177. package/installer-image-digests.json +3 -3
  178. package/package.json +24 -19
  179. package/sbom.spdx.json +868 -821
  180. package/dist/approvals/team-membership-lookup.d.ts +0 -13
  181. package/dist/pipeline/inline-eval.d.ts +0 -44
  182. package/dist/providers/github/contributor-resolver.d.ts +0 -30
  183. package/dist/security/contributor-cache.d.ts +0 -83
@@ -9,8 +9,8 @@
9
9
  * make Mimir cardinality grow with the number of agents that have ever
10
10
  * existed (every ephemeral firecracker microVM minted a fresh ID), which
11
11
  * is unbounded. The caller-side dashboard filters by `scaler` instead,
12
- * which has a fixed enum of values (`stateful` / `container` /
13
- * `firecracker` / `bare-metal`).
12
+ * which has a fixed enum of values (`stateful`, plus every
13
+ * `ScalerBackendType`).
14
14
  *
15
15
  * Aggregation rules per metric kind:
16
16
  * - counter / upDownCounter / gauge → SUM across agents in the pool
@@ -47,10 +47,10 @@ export declare class AgentMetricsAggregator {
47
47
  private store;
48
48
  private defaultRetentionMs;
49
49
  /**
50
- * Optional lookup: agentId → scaler backend name (e.g. `container`,
50
+ * Optional lookup: agentId → scaler backend type (e.g. `container`,
51
51
  * `firecracker`, `bare-metal`). Returning null marks the agent as
52
52
  * static / stateful — we then stamp the `scaler` label as `'stateful'`.
53
- * Wired from ScalerManager.getBackendName in production. Tests can
53
+ * Wired from ScalerManager.getBackendType in production. Tests can
54
54
  * leave it undefined; in that case the `scaler` label is omitted.
55
55
  */
56
56
  private readonly getScalerForAgent?;
@@ -34,14 +34,97 @@ interface ScalerUsageRow {
34
34
  * the on-disk ledger snapshot. Per-scaler rows omit `machinePool`.
35
35
  */
36
36
  export declare function setScalerUsageBreakdown(rows: ScalerUsageRow[]): void;
37
+ interface WarmPoolGaugeRow {
38
+ /** Operator-chosen scaler name that owns the pool. */
39
+ scaler: string;
40
+ /** Normalized label set the pool keeps agents ready for. */
41
+ labelSet: string;
42
+ target: number;
43
+ ready: number;
44
+ inFlight: number;
45
+ }
46
+ /**
47
+ * Replace the current warm-pool fill state.
48
+ *
49
+ * Called by ScalerManager after each warm-pool tick and after a config reload,
50
+ * so the gauges follow the pool rather than the scrape.
51
+ */
52
+ export declare function setWarmPoolGauges(rows: WarmPoolGaugeRow[]): void;
53
+ /**
54
+ * Total warm-pool spawns started.
55
+ * Labels:
56
+ * - scaler: operator-chosen scaler name that owns the pool.
57
+ */
58
+ export declare const scalerWarmPoolSpawnsTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
59
+ /** Record a warm-pool spawn starting. */
60
+ export declare function incWarmPoolSpawns(scaler: string): void;
61
+ /**
62
+ * Total warm-pool agents destroyed as surplus to the pool's target — either
63
+ * past `idleTimeoutSeconds`, or immediately when a config reload lowers the
64
+ * target. Both paths run through the same destroy callback, so the counter
65
+ * covers both.
66
+ * Labels:
67
+ * - scaler: operator-chosen scaler name that owns the pool.
68
+ */
69
+ export declare const scalerWarmPoolReapedTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
70
+ /** Record a warm-pool agent being destroyed. */
71
+ export declare function incWarmPoolReaped(scaler: string): void;
37
72
  /** Increment the spawn-refusal counter (called by ScalerManager when a request fails the cap check). */
38
73
  export declare function incScalerSpawnRefusals(): void;
74
+ /**
75
+ * Why an event scaler's cluster-wide cap check failed.
76
+ *
77
+ * `reason` label for `kici_orch_scaler_cap_lock_failures_total`. The two are a
78
+ * different fault with a different operator response, so they must not share a
79
+ * series any more than either may share one with a plain capacity refusal.
80
+ * - `contended` — the advisory lock was still held when the wait budget
81
+ * expired. The database is healthy; several coordinators are scaling one hot
82
+ * scaler at once. Raise the scaler's cap, or the wait budget.
83
+ * - `unreachable` — the cap could not be evaluated at all (connection lost,
84
+ * statement timeout, schema error). Event autoscaling is stalled on the
85
+ * database and no cap arithmetic is happening anywhere.
86
+ */
87
+ export declare const ScalerCapLockFailureReason: {
88
+ readonly Contended: 'contended';
89
+ readonly Unreachable: 'unreachable';
90
+ };
91
+ export type ScalerCapLockFailureReason = (typeof ScalerCapLockFailureReason)[keyof typeof ScalerCapLockFailureReason];
92
+ /**
93
+ * Total event-scaler cluster-wide cap checks that failed, so their spawn was
94
+ * refused without the cap ever being evaluated.
95
+ *
96
+ * Deliberately NOT folded into `kici_orch_scaler_spawn_refusals_total`: that
97
+ * series means "the cluster is full", and the operator response is to add
98
+ * capacity or raise a cap. This one means the cap could not be evaluated, so
99
+ * event spawns fail closed for a reason that has nothing to do with capacity.
100
+ * Labels:
101
+ * - reason: contended (the lock wait budget expired) | unreachable (the cap could not be evaluated at all)
102
+ */
103
+ export declare const scalerCapLockFailuresTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
39
104
  /**
40
105
  * Record `count` pending jobs re-driven through the scaler by `trigger`
41
106
  * (`hook` = capacity-freed callback, `sweep` = leader-gated backstop).
42
107
  * Called by the dispatcher's metrics facade.
43
108
  */
44
109
  export declare function incScalerRedispatch(trigger: ScalerRedispatchTrigger, count: number): void;
110
+ /** Record a scale-up event emitted for `scaler`. */
111
+ export declare function incScalerScaleUpEmitted(scaler: string): void;
112
+ /** Record a scale-down event emitted for `scaler` with the teardown `reason`. */
113
+ export declare function incScalerScaleDownEmitted(scaler: string, reason: string): void;
114
+ /** Record an event-scaler provision that timed out before its agent registered. */
115
+ export declare function incScalerExternalProvisionTimeout(scaler: string): void;
116
+ /** Record an adoption lookup that could not reach its spawn record. */
117
+ export declare function incScalerAdoptionLookupFailure(): void;
118
+ /** Set the current count of in-flight (provisioning + active) external agents for `scaler`. */
119
+ export declare function setScalerExternalProvisioningActive(scaler: string, count: number): void;
120
+ /**
121
+ * Set how many event-scaler provisions the leader has been unable to see an
122
+ * agent for, for at least the flap grace. Zero on every non-leader, and on a
123
+ * leader whose sweep is blocked.
124
+ */
125
+ export declare function setScalerReapUnseenProvisions(count: number): void;
126
+ /** Set whether this coordinator's provision reaper is standing down (1) or sweeping (0). */
127
+ export declare function setScalerReapBlocked(blocked: boolean): void;
45
128
  /**
46
129
  * Merge current per-label counts with explicit `0`s for previously-seen labels
47
130
  * whose queue has drained. Mutates `everSeen` to include the current labels.
@@ -93,6 +176,13 @@ export declare const ingestShedTotal: import("@opentelemetry/api").Counter<impor
93
176
  export declare const stateReplayBreakerTripsTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
94
177
  /** Total webhook-ingest admissions granted. */
95
178
  export declare const ingestAdmittedTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
179
+ /**
180
+ * Webhook pipelines that threw. Labels:
181
+ * - phase: post_ack — the delivery was already acknowledged, so the failure
182
+ * could not be reported in the response and is only visible here, in the
183
+ * event log, and in the queue row.
184
+ */
185
+ export declare const webhookPipelineFailuresTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
96
186
  /** Set the current buffered-row depth (called by the buffer + replayer). */
97
187
  export declare function setIngestOverflowBuffered(value: number): void;
98
188
  /** Current buffered-row depth (test helper). */
@@ -121,13 +211,27 @@ export declare const webhooksProcessedTotal: import("@opentelemetry/api").Counte
121
211
  /**
122
212
  * Org trust-policy gate decisions.
123
213
  * Labels:
124
- * - arm: which policy arm decided — workflow_modification | fork_pr | unknown_contributor | none (the PR passed)
125
- * - action: pass | hold | reject
214
+ * - arm: which policy arm decided — fork_pr | none (the verdict carried no reason)
215
+ * - action: pass | ignore | hold | reject
126
216
  *
127
217
  * Incremented once per evaluated PR event, including passes, so the ratio of
128
218
  * gated to ungated PRs is visible rather than only the gated ones.
129
219
  */
130
220
  export declare const trustPolicyDecisionsTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
221
+ /**
222
+ * Fork pull-request events dropped by the org fork policy before any run row,
223
+ * check status, or job dispatch existed.
224
+ * Labels:
225
+ * - provider: the inbound delivery's provider (github, …)
226
+ *
227
+ * @conditionallyEmitted An org that does not ignore fork PRs emits no series.
228
+ *
229
+ * Distinct from `kici_orch_trust_policy_decisions_total{action="ignore"}`,
230
+ * which counts the verdict wherever it is reached: this counts the drop the
231
+ * ingest path actually performed, so a verdict that stopped being enforced
232
+ * shows as a divergence between the two rather than as silence.
233
+ */
234
+ export declare const forkEventsIgnoredTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
131
235
  /**
132
236
  * Duration of trigger matching operations (lock file evaluation).
133
237
  * Buckets: 1ms to 5s covering fast rejects through complex evaluations.
@@ -221,7 +325,7 @@ export type ScalerSpawnFailureBound = (typeof ScalerSpawnFailureBound)[keyof typ
221
325
  /**
222
326
  * Total scaler agent spawn failures.
223
327
  * Labels:
224
- * - backend: scaler backend type (bare-metal | container | firecracker | unknown)
328
+ * - backend: scaler backend type (bare-metal | container | event | firecracker | unknown)
225
329
  * - bound: true (job-bound spawn) | false (warm-pool/unbound)
226
330
  */
227
331
  export declare const scalerSpawnFailuresTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
@@ -291,6 +395,58 @@ export declare const universalGitRegistrationErrorsTotal: import("@opentelemetry
291
395
  * 'id_mismatch' (a username-matched link has a different provider_user_id)
292
396
  */
293
397
  export declare const trustMatchRefusedNoIdTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
398
+ /**
399
+ * Candidates handed to a global eval round.
400
+ *
401
+ * Equal to `sum(kici_orch_global_eval_verdicts_total)` by construction: every
402
+ * candidate receives exactly one verdict, including on the fail-closed path
403
+ * where the round never runs. Kept as its own series because it is the natural
404
+ * top-line rate and the denominator the outcome breakdown divides — a
405
+ * divergence between the two would be a bug in the round, never a condition an
406
+ * operator should watch for.
407
+ */
408
+ export declare const globalEvalCandidatesTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
409
+ /**
410
+ * Per-candidate verdicts a global eval round produced.
411
+ *
412
+ * Labels:
413
+ * - outcome: run (the filter admitted it) | filtered (the filter excluded it) | indeterminate (the round could not decide — a failed round, a budget breach, or a verdict that never arrived)
414
+ */
415
+ export declare const globalEvalVerdictsTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
416
+ /**
417
+ * Wall-clock duration of one dispatched global eval round, from dispatch to
418
+ * settled verdicts. A cache hit records nothing — it never dispatches a round.
419
+ *
420
+ * Buckets: 1s to 10min, covering a fast round through the default 120s agent
421
+ * budget and the 240s orchestrator wait ceiling.
422
+ *
423
+ * Labels:
424
+ * - result: success (the round settled) | error (dispatch rejected, the wait ceiling fired, or the round decided nothing)
425
+ */
426
+ export declare const globalEvalRoundDurationSeconds: import("@opentelemetry/api").Histogram<import("@opentelemetry/api").Attributes>;
427
+ /**
428
+ * Jobs a round's `DynamicJobFn` generators produced, summed over the round's
429
+ * candidates. Recorded once per settled round, including zero.
430
+ *
431
+ * Buckets cover the common small fan-outs through a large matrix expansion.
432
+ */
433
+ export declare const globalEvalJobsGenerated: import("@opentelemetry/api").Histogram<import("@opentelemetry/api").Attributes>;
434
+ /**
435
+ * Global eval round cache lookups by outcome.
436
+ *
437
+ * Three outcomes, not two. An input that cannot be serialized yields no cache
438
+ * key at all, so it never reaches the cache and registers neither a hit nor a
439
+ * miss — counting only hits and misses would drop those lookups from the
440
+ * denominator and make the hit rate read higher than it is.
441
+ *
442
+ * Expect a hit rate near zero on a healthy cluster: the key covers the whole
443
+ * event, so every real push is a miss by construction. This cache is a
444
+ * redelivery guard, not a steady-state optimization.
445
+ *
446
+ * Labels:
447
+ * - result: hit | miss | unkeyable (the round input could not be serialized)
448
+ */
449
+ export declare const globalEvalCacheLookupsTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
294
450
  /**
295
451
  * Internal events delivered to all matching workflows successfully (after the
296
452
  * lease commits processed=true).
@@ -312,6 +468,17 @@ export declare const eventRetryTotal: import("@opentelemetry/api").Counter<impor
312
468
  * - reason: why the event was DLQ'd (exhausted_retries)
313
469
  */
314
470
  export declare const eventDlqTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
471
+ /**
472
+ * Startup catch-up scans that threw. Emits no labels.
473
+ *
474
+ * The scan recovers the internal-event backlog a restart left behind, and it
475
+ * runs behind a boot latch that the composition root resolves after startup
476
+ * continues — so a failure cannot fail the bootstrap and is otherwise invisible
477
+ * until the backlog quietly ages into the DLQ. This counter is what an alert
478
+ * fires on; the accompanying `Deferred catch-up scan failed` log line carries
479
+ * the reason.
480
+ */
481
+ export declare const eventCatchUpFailuresTotal: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
315
482
  /**
316
483
  * Dispatch leases that timed out before the holding node finalised them
317
484
  * (signals a node crash mid-dispatch). Emits no labels.
@@ -56,9 +56,13 @@ export interface OidcMintRegistrationInput {
56
56
  };
57
57
  db: Kysely<Database>;
58
58
  orchestratorId: string;
59
- testMode: boolean;
60
- testMintDeferAudience?: string;
61
- testMintRejectAudience?: string;
59
+ /**
60
+ * Test-only fault-injection predicate forwarded to the relay mint handler,
61
+ * supplied only by the build-time test double. Only ever defers — the
62
+ * anti-forgery choke point is preserved. Undefined (the shipped default) means
63
+ * no fault injection.
64
+ */
65
+ initialMintFault?: (audience: string) => boolean;
62
66
  }
63
67
  /** Decide which mint handler (if any) backs `OIDC_TOKEN_REQUEST_METHOD`. */
64
68
  export declare function selectOidcMintRegistration(input: OidcMintRegistrationInput): OidcMintRegistration | undefined;
@@ -19,6 +19,7 @@ import { EventLogWriter } from './webhook/event-log.js';
19
19
  import { AccessLogWriter } from './audit/access-log.js';
20
20
  import { Dispatcher } from './agent/dispatcher.js';
21
21
  import { LockFileCache } from './lockfile-cache.js';
22
+ import { ContentRequirementsCache } from './content-requirements-cache.js';
22
23
  import { DedupCache } from './webhook/dedup.js';
23
24
  import { ObserverRegistry } from './ws/observer-registry.js';
24
25
  import { IngestAdmissionController } from './webhook/ingest-admission.js';
@@ -28,21 +29,23 @@ import { IngestOverflowBuffer } from './webhook/ingest-overflow-buffer.js';
28
29
  import { IngestOverflowReplayer } from './webhook/ingest-overflow-replayer.js';
29
30
  import { AgentMetricsAggregator } from './metrics/agent-metrics-aggregator.js';
30
31
  import { SourceLocationStore } from './app.js';
31
- import { ExecutionJobStatus, type LabelMatcher, type PeerHeartbeat, type PeerLogsCollectRequest, type PeerToPeerMessage, type ResolvedSandboxGrant } from '@kici-dev/engine';
32
+ import { ExecutionJobStatus, type PeerHeartbeat, type PeerLogsCollectRequest, type PeerToPeerMessage, type InvokeResult } from '@kici-dev/engine';
32
33
  import { ScalerManager } from './scaler/index.js';
33
34
  import type { ScalerConfig } from './scaler/index.js';
34
35
  import type { CacheStorage } from './storage/index.js';
35
36
  import { type ProvenanceTrustRoot } from './provenance/trust-root.js';
36
37
  import { type ResolvedDashboardEncryptionKey } from './secrets/dashboard-encryption-key.js';
37
- import { SourceCache, BuildCoordinator, DepCache, UserCache, DispatchCacheRefTracker, PendingBuildTracker, PendingInitTracker, PendingDynamicTracker } from './cache/index.js';
38
+ import { SourceCache, BuildCoordinator, DepCache, UserCache, DispatchCacheRefTracker, PendingBuildTracker, PendingInitTracker, PendingDynamicTracker, PendingGlobalEvalTracker, GlobalEvalRoundCache } from './cache/index.js';
38
39
  import { ArtifactStore } from './artifacts/artifact-store.js';
39
40
  import { CheckRunReporter } from './reporting/check-run-reporter.js';
41
+ import type { ProcessingDeps } from './pipeline/processor.js';
42
+ import type { InvokeGateDeps, SummonArgs, SummonedRun } from './pipeline/invoke-gate.js';
40
43
  import { StepLogBuffer } from './reporting/step-log-buffer.js';
41
44
  import { type LogStorage } from './reporting/log-storage.js';
42
45
  import { ExecutionTracker, type ExecutionTrackerDeps } from './reporting/execution-tracker.js';
43
46
  import { LogWriter } from './reporting/log-writer.js';
44
47
  import { type NormalizedLogChunk } from './reporting/log-chunk-sink.js';
45
- import { PeerRegistry, PeerClient, createPeerHandler, RaftNode, OrphanRecovery, RunCoordinator } from './cluster/index.js';
48
+ import { PeerRegistry, PeerClient, createPeerHandler, RaftNode, OrphanRecovery, RunCoordinator, PlanHeadroomStore } from './cluster/index.js';
46
49
  import { SourceStore, SourceManager } from './sources/index.js';
47
50
  import { PgSecretStore, AuditLogger, SecretResolver } from './secrets/index.js';
48
51
  import type { SecretStore } from '@kici-dev/engine';
@@ -50,11 +53,13 @@ import type { AdminRouteDeps } from './routes/admin.js';
50
53
  import { AgentTokenStore } from './agent/token-store.js';
51
54
  import { OwnershipTracker } from './agent/ownership-tracker.js';
52
55
  import { EventStore } from './events/event-store.js';
53
- import { EventRouter } from './events/event-router.js';
56
+ import { EventRouter, type EventMatchContext } from './events/event-router.js';
54
57
  import { EventEmitter } from './events/event-emitter.js';
55
58
  import { TrustStore } from './events/trust-store.js';
59
+ import type { OrchestratorFaultInjection } from './testing/fault-injection.js';
56
60
  import { GenericSourceManager } from './webhook/generic-sources.js';
57
61
  import { GenericSourcesChangeListener } from './webhook/generic-sources-listener.js';
62
+ import { DashboardWritePolicyChangeListener } from './policy/dashboard-write-policy-listener.js';
58
63
  import { RegistrationStore } from './registration/registration-store.js';
59
64
  import { RegistrationIndex } from './registration/registration-index.js';
60
65
  import { CronScheduler } from './cron/cron-scheduler.js';
@@ -98,6 +103,7 @@ export interface OrchestratorSubsystems {
98
103
  pendingBuilds: PendingBuildTracker | undefined;
99
104
  pendingInits: PendingInitTracker;
100
105
  pendingDynamics: PendingDynamicTracker;
106
+ pendingGlobalEvals: PendingGlobalEvalTracker;
101
107
  checkRunReporter: CheckRunReporter;
102
108
  stepLogBuffer: StepLogBuffer;
103
109
  sourceLocationStore: SourceLocationStore;
@@ -119,8 +125,12 @@ export interface OrchestratorSubsystems {
119
125
  tokenStore: AgentTokenStore;
120
126
  ownershipTracker: OwnershipTracker;
121
127
  lockFileCache: LockFileCache;
128
+ contentRequirementsCache: ContentRequirementsCache;
129
+ globalEvalCache: GlobalEvalRoundCache;
122
130
  dedup: DedupCache;
123
131
  eventRouter: EventRouter;
132
+ /** Invoke-gate dependencies (summon callback + chain-depth bound). */
133
+ invokeGateDeps: InvokeGateDeps;
124
134
  /**
125
135
  * Event store for custom internal events (system + custom). Exposed
126
136
  * here so the dashboard handler can serve the per-org DLQ surface
@@ -129,6 +139,13 @@ export interface OrchestratorSubsystems {
129
139
  eventStore: EventStore;
130
140
  eventEmitter: EventEmitter;
131
141
  genericSourceManager: GenericSourceManager;
142
+ /**
143
+ * Re-register a generic source's provider bundle from its database row.
144
+ * The webhook pipeline calls it on an exact registry miss so the read side
145
+ * settles against server truth rather than a stand-in bundle. Shared by the
146
+ * relay path (server.ts) and the direct-ingress path (app.ts).
147
+ */
148
+ ensureProviderBundle: (routingKey: string) => Promise<boolean>;
132
149
  trustStore: TrustStore;
133
150
  registrationStore: RegistrationStore;
134
151
  registrationIndex: RegistrationIndex;
@@ -142,6 +159,10 @@ export interface OrchestratorSubsystems {
142
159
  getLocalInventory: () => Omit<PeerHeartbeat, 'type'>;
143
160
  broadcastHeartbeatToAllPeers: () => void;
144
161
  broadcastAgentTokenRevoke: (tokenId: string) => void;
162
+ /** Platform-owned worker-ceiling cache, read by the peer-handler admission gate. */
163
+ planHeadroomStore: PlanHeadroomStore;
164
+ /** Late-bind the coordinator's cluster.membership reporter (see ClusterInfra). */
165
+ setMembershipReporter: (report: () => void) => void;
145
166
  joinHandler: JoinHandler;
146
167
  configReloader: ConfigReloader;
147
168
  localConfigVersion: number;
@@ -153,6 +174,12 @@ export interface OrchestratorSubsystems {
153
174
  * Platform when a generic source is added/removed at runtime.
154
175
  */
155
176
  genericSourcesChangeListener: GenericSourcesChangeListener;
177
+ /**
178
+ * Dashboard-write policy hot-reload listener. Keeps every coordinator's
179
+ * cached policy map — and the capability snapshot it advertises to the
180
+ * control plane — in step with a `kici-admin` write served by any peer.
181
+ */
182
+ dashboardWritePolicyChangeListener: DashboardWritePolicyChangeListener;
156
183
  /** Inbound webhook delivery log writer (event_log table + object-storage payloads). */
157
184
  eventLogWriter: EventLogWriter;
158
185
  /** Access log writer (read + mutation attribution for dashboard + admin). */
@@ -193,6 +220,17 @@ export interface OrchestratorSubsystems {
193
220
  ingestOverflowBuffer: IngestOverflowBuffer;
194
221
  /** Background replayer draining the overflow buffer once capacity recovers. */
195
222
  ingestOverflowReplayer: IngestOverflowReplayer;
223
+ /**
224
+ * The live direct-ingress `ProcessingDeps` bag, assembled inside `createApp`.
225
+ *
226
+ * A mode hook that has to resume a held run needs the same bag the pipeline
227
+ * that created the hold used — otherwise the resume runs against a second,
228
+ * hand-assembled bag that can silently diverge from it. `createApp` runs
229
+ * AFTER `onSubsystemsReady`, so this throws until it has, which is why every
230
+ * caller must invoke it lazily (inside a release callback, never at wiring
231
+ * time).
232
+ */
233
+ buildProcessingDeps: () => ProcessingDeps;
196
234
  }
197
235
  /**
198
236
  * Mode-specific hooks injected by each entry point.
@@ -262,22 +300,6 @@ export interface OrchestratorHooks {
262
300
  * are skipped here — group fan-in is resolved separately by the scheduler.
263
301
  */
264
302
  export declare function upstreamBaseNamesFromNeeds(needs: unknown): string[];
265
- /**
266
- * Partition a lock job's `runsOn` / `excludeLabels` matchers into exact label
267
- * strings and regex patterns for internal-event (cron / `ctx.emit`) dispatch.
268
- * Lock jobs carry `runsOn` as `LabelMatcher[]`; the coordinator routing and the
269
- * direct dispatcher both need exact labels for the indexed/SQL fast path and
270
- * regex patterns as a separate JS post-filter — never the raw matcher objects.
271
- */
272
- export declare function internalJobRunsOnSelectors(job: {
273
- runsOn?: readonly LabelMatcher[];
274
- excludeLabels?: readonly LabelMatcher[];
275
- }): {
276
- runsOnLabels: string[];
277
- runsOnPatterns: LabelMatcher[];
278
- excludeLabels: string[];
279
- excludePatterns: LabelMatcher[];
280
- };
281
303
  /**
282
304
  * Parse an `execution_jobs.outputs` cell (string JSON or object) to a plain
283
305
  * object, or null when empty / unparseable.
@@ -308,6 +330,22 @@ export declare function buildUpstreamStatusesByBase(rows: Array<{
308
330
  job_name: string;
309
331
  status?: string | null;
310
332
  }>): Record<string, ExecutionJobStatus> | undefined;
333
+ /**
334
+ * For each declared need that names an invoke gate, gather its per-run results
335
+ * from the gate's proxy children — `{ repo, workflow, runId, status, outputs }`,
336
+ * one entry per proxy. `outputs` is the proxy's non-secret mirrored outputs (the
337
+ * same `execution_jobs.outputs` cell `mirrorSummonedRunOntoProxy` writes); a
338
+ * repo's secret outputs live in `run_secret_outputs` and are never read here.
339
+ * Keyed by gate name; a gate that summoned zero subscribers yields an empty
340
+ * array (so `.result` stays an `InvokeResult[]`), while a declared need that is
341
+ * a regular job (no gate row) yields no key.
342
+ *
343
+ * Shared by both `ctx.needs['<gate>'].result` construction paths: the
344
+ * DynamicJobFn generator (via `gatherUpstreamSnapshot`) and a standard
345
+ * `run:`/step job (via `mergeUpstreamOutputs` → the `upstreamInvokeResults`
346
+ * dispatch field).
347
+ */
348
+ export declare function gatherInvokeResults(db: Kysely<Database>, runId: string, gateNames: readonly string[]): Promise<Record<string, InvokeResult[]>>;
311
349
  /**
312
350
  * Fold a `runsOnAll` upstream's host children into the `byHost` envelope
313
351
  * `{ byHost: { '<host>': outputs }, summary: { succeededHosts, failedHosts, outputs } }`.
@@ -358,14 +396,43 @@ export declare function mergeUpstreamOutputs(db: Kysely<Database>, runId: string
358
396
  mergedSecrets: Record<string, string> | undefined;
359
397
  upstreamJobOutputs: Record<string, Record<string, unknown>> | undefined;
360
398
  upstreamJobStatuses: Record<string, ExecutionJobStatus> | undefined;
399
+ upstreamInvokeResults: Record<string, InvokeResult[]> | undefined;
361
400
  }>;
362
- export declare function buildInternalJobConfigForWorkflow(workflow: any, job: any, sandboxGrant?: ResolvedSandboxGrant, firedSchedule?: {
363
- cronExpression?: string;
364
- timezone?: string;
365
- }): Record<string, unknown>;
401
+ export declare function buildOnEventMatched(dispatcherRef: {
402
+ current: Dispatcher | null;
403
+ }, providerRegistryRef: {
404
+ current: ProviderRegistry;
405
+ }, processingDepsRef: {
406
+ current: (() => ProcessingDeps) | null;
407
+ }): (event: any, lockFile: any, matchedWorkflows: any[], context?: EventMatchContext) => Promise<void>;
408
+ /**
409
+ * Build the invoke-gate `summon` callback: match the source repo's own opt-in
410
+ * `kiciEvent({ name })` subscribers, dispatch each as a normal in-repo run, and
411
+ * return the spawned run ids so the gate can correlate a proxy job per run.
412
+ *
413
+ * This is the composition-root half of the invoke gate — it reuses the same
414
+ * in-process match + dispatch path the internal-event router uses
415
+ * (`matchKiciEventSubscribers` + `dispatchInternalEventViaPipeline`), scoped to
416
+ * the source repo. The gate executor (`runInvokeGate`) enforces the chain-depth
417
+ * bound and persists the summon↔spawn correlation.
418
+ */
419
+ export declare function buildSummonCallback(dispatcherRef: {
420
+ current: Dispatcher | null;
421
+ }, providerRegistryRef: {
422
+ current: ProviderRegistry;
423
+ }, eventRouter: EventRouter, processingDepsRef: {
424
+ current: (() => ProcessingDeps) | null;
425
+ }): (args: SummonArgs) => Promise<SummonedRun[]>;
366
426
  export declare function bootstrapOrchestrator(config: AppConfig, hooks: OrchestratorHooks, options?: {
367
427
  otelSdk?: {
368
428
  shutdown(): Promise<void>;
369
429
  };
430
+ /**
431
+ * Test-only fault-injection policy. Undefined in production (server.ts /
432
+ * standalone.ts pass nothing), so every seam sees an undefined policy and
433
+ * runs with no fault injection. A test-only entrypoint passes a policy to
434
+ * drive the seams directly.
435
+ */
436
+ faultInjection?: OrchestratorFaultInjection;
370
437
  }): Promise<void>;
371
438
  //# sourceMappingURL=orchestrator-core.d.ts.map
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Tier-1 declarative content-requirements filter (execution-purity model, Part B).
3
+ *
4
+ * After Tier-0 trigger matching selects candidate workflows, this step fetches
5
+ * the source files each candidate's `requires` names — once per distinct
6
+ * `(repo, sha, path)` via the LRU cache — evaluates the (pure DATA) requirements
7
+ * with the engine matcher, and drops any candidate that FAILS or is
8
+ * INDETERMINATE before dispatch. No author code is executed: `requires` is a
9
+ * declarative query the orchestrator interprets, which is what keeps content
10
+ * filtering inside the orchestrator under the purity model.
11
+ *
12
+ * Fail-visible: a dropped candidate (definite negative, oversize/unparseable
13
+ * content, a fetch error, or no fetcher/cache available) is logged with the
14
+ * concrete reason. An indeterminate file NEVER passes silently.
15
+ */
16
+ import type { FileContentsFetcher, LockContentRequirement } from '@kici-dev/engine';
17
+ import type { ContentRequirementsCache } from '../content-requirements-cache.js';
18
+ /** A workflow candidate carrying the `requires` of the trigger that matched the event. */
19
+ export interface ContentFilterCandidate {
20
+ readonly name: string;
21
+ readonly requires?: readonly LockContentRequirement[];
22
+ }
23
+ /** The event the requirements are evaluated against: source repo + ref to fetch files at. */
24
+ export interface ContentFilterEvent {
25
+ /** Provider repo identifier ("owner/repo"). */
26
+ readonly repo: string;
27
+ /** Git ref (commit SHA, or branch/tag) at which files are read. */
28
+ readonly sha: string;
29
+ }
30
+ export interface ContentFilterOptions {
31
+ /** Per-delivery file-contents fetcher; `undefined` when the provider has none. */
32
+ readonly fetcher: FileContentsFetcher | undefined;
33
+ /** Shared LRU cache; `undefined` when the deployment did not wire one. */
34
+ readonly cache: ContentRequirementsCache | undefined;
35
+ /** Delivery id for log correlation. */
36
+ readonly deliveryId?: string;
37
+ }
38
+ /**
39
+ * One dropped candidate.
40
+ *
41
+ * `indeterminate` separates the two reasons a drop happens, which mean opposite
42
+ * things to a workflow author: a definite content mismatch is the requirement
43
+ * doing its job, while an unreadable file, a fetch error, or a provider with no
44
+ * file-contents fetcher is the requirement never having been evaluated at all.
45
+ * Both drop the candidate — the filter is fail-visible, so an unevaluable file
46
+ * never passes — but a trace that renders the second as "excluded" tells an
47
+ * author their requirement said no when nothing ever read it.
48
+ */
49
+ export interface DroppedCandidate {
50
+ readonly name: string;
51
+ readonly reason: string;
52
+ /** True when the requirement could not be evaluated, rather than evaluating to false. */
53
+ readonly indeterminate?: boolean;
54
+ }
55
+ export interface ContentFilterResult<C extends ContentFilterCandidate> {
56
+ readonly survivors: C[];
57
+ readonly dropped: DroppedCandidate[];
58
+ }
59
+ /**
60
+ * Filter candidates by their declarative content requirements.
61
+ *
62
+ * Gathers each distinct `(repo, sha, path)` once via the cache, evaluates every
63
+ * candidate's `requires`, and returns the survivors (pass) split from the
64
+ * dropped (fail / indeterminate, each logged with its reason). A candidate with
65
+ * no `requires` always survives without any fetch (the fast path — like an empty
66
+ * `paths` filter). When a candidate has `requires` but no fetcher/cache is
67
+ * available, it is dropped as indeterminate (fail-visible), never dispatched
68
+ * unfiltered.
69
+ */
70
+ export declare function filterByContentRequirements<C extends ContentFilterCandidate>(candidates: readonly C[], event: ContentFilterEvent, opts: ContentFilterOptions): Promise<ContentFilterResult<C>>;
71
+ //# sourceMappingURL=content-filter.d.ts.map
@@ -0,0 +1,100 @@
1
+ /**
2
+ * The `ProcessingDeps` bag the DIRECT-INGRESS pipeline runs on.
3
+ *
4
+ * Two pipelines assemble this bag. `server.ts` builds the one the Platform WS
5
+ * relay hands to `processWebhook`; this module builds the one every HTTP
6
+ * ingress uses — the direct GitHub route, the generic webhook routes, and the
7
+ * internal-event dispatch adapter. On an independent orchestrator there is no
8
+ * relay, so this is the ONLY bag it ever has.
9
+ *
10
+ * It lives outside `app.ts` because it is the seam an approval defect hides in.
11
+ * A field the composition root forgets is invisible: the pipeline reads it as
12
+ * `undefined`, every guard downstream is written to degrade rather than throw,
13
+ * and the feature is silently inert. Assembling the bag in a function with a
14
+ * declared return type is what lets a test assert the wiring directly instead
15
+ * of asserting it through a 2,000-line composition root that no test
16
+ * constructs.
17
+ */
18
+ import type { ProcessingDeps } from './processor.js';
19
+ import { TrustDirectoryStore } from '../security/trust-directory-store.js';
20
+ import { TrustPolicyStore } from '../security/trust-policy-store.js';
21
+ import type { SourceLocationData } from '../reporting/check-run-summary.js';
22
+ /**
23
+ * Everything the bag reads that `AppDependencies` already carries.
24
+ *
25
+ * Declared structurally rather than as `AppDependencies` so this module does
26
+ * not import `app.ts` (which imports it) and so the fields the bag actually
27
+ * consumes are enumerated in one readable place. `AppDependencies` satisfies it
28
+ * by construction — the `createApp` call site is the compiler's check of that.
29
+ */
30
+ export interface DirectIngressDepsSource {
31
+ db: ProcessingDeps['db'] & {};
32
+ config: {
33
+ mode: NonNullable<ProcessingDeps['orchestratorMode']>;
34
+ secretKey?: string | undefined;
35
+ instanceId?: string | undefined;
36
+ rosterGraceMs?: number | undefined;
37
+ maxFanoutHosts?: number | undefined;
38
+ globalEvalRoundTimeoutMs?: number | undefined;
39
+ globalEvalCandidateTimeoutMs?: number | undefined;
40
+ globalEvalWaitTimeoutMs?: number | undefined;
41
+ };
42
+ dedup: ProcessingDeps['dedup'];
43
+ providerRegistry: ProcessingDeps['providerRegistry'];
44
+ ensureProviderBundle?: ProcessingDeps['ensureProviderBundle'];
45
+ lockFileCache: ProcessingDeps['lockFileCache'];
46
+ contentRequirementsCache?: ProcessingDeps['contentRequirementsCache'];
47
+ dispatcher: ProcessingDeps['dispatcher'];
48
+ platformClient?: ProcessingDeps['platformClient'];
49
+ sourceCache?: ProcessingDeps['sourceCache'];
50
+ buildCoordinator?: ProcessingDeps['buildCoordinator'];
51
+ depCache?: ProcessingDeps['depCache'];
52
+ pendingBuilds?: ProcessingDeps['pendingBuilds'];
53
+ pendingInits?: ProcessingDeps['pendingInits'];
54
+ pendingDynamics?: ProcessingDeps['pendingDynamics'];
55
+ pendingGlobalEvals?: ProcessingDeps['pendingGlobalEvals'];
56
+ globalEvalCache?: ProcessingDeps['globalEvalCache'];
57
+ checkRunReporter?: ProcessingDeps['checkRunReporter'];
58
+ executionTracker?: ProcessingDeps['executionTracker'];
59
+ eventRouter?: ProcessingDeps['eventRouter'];
60
+ invokeGateDeps?: ProcessingDeps['invokeGateDeps'];
61
+ registrationStore?: ProcessingDeps['registrationStore'];
62
+ registrationIndex?: ProcessingDeps['registrationIndex'];
63
+ secretResolver?: ProcessingDeps['secretResolver'];
64
+ sandboxAllowListReader?: ProcessingDeps['sandboxAllowListReader'];
65
+ logStorage?: ProcessingDeps['logStorage'];
66
+ contextStore?: ProcessingDeps['contextStore'];
67
+ variableStore?: ProcessingDeps['variableStore'];
68
+ heldRunStore?: ProcessingDeps['heldRunStore'];
69
+ coordinator?: ProcessingDeps['coordinator'];
70
+ cronScheduler?: ProcessingDeps['cronScheduler'];
71
+ globalWorkflowPolicy?: ProcessingDeps['globalWorkflowPolicy'];
72
+ eventLogWriter?: ProcessingDeps['eventLog'];
73
+ accessLogWriter?: ProcessingDeps['accessLogWriter'];
74
+ hostRosterStore?: ProcessingDeps['hostRosterStore'];
75
+ clusterSettings?: ProcessingDeps['clusterSettings'];
76
+ }
77
+ /** The per-process stores this factory owns, exposed so the caller can reuse them. */
78
+ export interface DirectIngressStores {
79
+ trustDirectoryStore: TrustDirectoryStore;
80
+ trustPolicyStore: TrustPolicyStore;
81
+ }
82
+ /**
83
+ * Build the direct-ingress `ProcessingDeps` factory.
84
+ *
85
+ * The returned function assembles a fresh bag per call, so every field reads
86
+ * the CURRENT subsystem instance — the provider registry is swapped wholesale
87
+ * on a source reload, and a bag captured once would keep dispatching through
88
+ * the replaced one.
89
+ *
90
+ * The two stores are constructed once here rather than per call: both are
91
+ * stateless over the database handle, and one of them is read on every PR
92
+ * delivery.
93
+ */
94
+ export declare function createDirectIngressProcessingDeps(deps: DirectIngressDepsSource, hooks: {
95
+ onSourceLocationsExtracted: (workflowName: string, jobName: string, locations: Array<SourceLocationData | undefined>) => void;
96
+ }): {
97
+ build: () => ProcessingDeps;
98
+ stores: DirectIngressStores;
99
+ };
100
+ //# sourceMappingURL=direct-ingress-deps.d.ts.map