@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.
- package/dist/__test-helpers__/fake-scaler-state-store.d.ts +24 -0
- package/dist/__test-helpers__/mock-db-query.d.ts +130 -0
- package/dist/__test-helpers__/mock-db.d.ts +27 -0
- package/dist/agent/agent-version.d.ts +34 -0
- package/dist/agent/dispatcher.d.ts +151 -13
- package/dist/agent/host-roster.d.ts +37 -5
- package/dist/agent/registry.d.ts +2 -0
- package/dist/app.d.ts +56 -7
- package/dist/approvals/apply-decision.d.ts +67 -19
- package/dist/approvals/held-run-release-wiring.d.ts +45 -0
- package/dist/approvals/independent-wiring.d.ts +55 -0
- package/dist/approvals/resume-router.d.ts +9 -0
- package/dist/approvals/triggerer-subject.d.ts +37 -0
- package/dist/cache/dep-cache.d.ts +54 -10
- package/dist/cache/global-eval-round-cache.d.ts +95 -0
- package/dist/cache/index.d.ts +3 -0
- package/dist/cache/pending-global-evals.d.ts +42 -0
- package/dist/cache/pending-inits.d.ts +10 -0
- package/dist/cli/api-client.d.ts +18 -0
- package/dist/cli/commands/cluster-settings.d.ts +52 -3
- package/dist/cli/commands/diagnose.d.ts +6 -0
- package/dist/cli/commands/held-run.d.ts +58 -0
- package/dist/cli/commands/runs.d.ts +1 -0
- package/dist/cli/commands/trust-policy.d.ts +117 -12
- package/dist/cli/kici-admin.d.ts +10 -0
- package/dist/cli.js +2770 -938
- package/dist/cluster/cluster-identity.d.ts +3 -3
- package/dist/cluster/cluster-settings-reader.d.ts +59 -1
- package/dist/cluster/coordinator.d.ts +44 -0
- package/dist/cluster/index.d.ts +4 -0
- package/dist/cluster/peer-handler.d.ts +19 -0
- package/dist/cluster/peer-registry.d.ts +17 -0
- package/dist/cluster/plan-headroom-store.d.ts +26 -0
- package/dist/cluster/worker-eviction.d.ts +69 -0
- package/dist/cold-store/load-event-log-range.d.ts +10 -3
- package/dist/cold-store/load-secret-audit-log-range.d.ts +4 -3
- package/dist/cold-store/tables/secret-audit-log.d.ts +4 -3
- package/dist/config.d.ts +48 -21
- package/dist/content-requirements-cache.d.ts +55 -0
- package/dist/contexts/held-runs.d.ts +123 -16
- package/dist/contexts/protection/aggregate.d.ts +3 -2
- package/dist/contexts/protection/branch-gate.d.ts +15 -0
- package/dist/contexts/protection/concurrency-gate.d.ts +8 -2
- package/dist/contexts/protection/pipeline.d.ts +18 -0
- package/dist/contexts/release-queued-holds.d.ts +35 -0
- package/dist/dashboard/attestation-filters.d.ts +8 -0
- package/dist/dashboard/handler.d.ts +6 -24
- package/dist/db/migrations/109_cluster_settings_cache_knobs.d.ts +4 -0
- package/dist/db/migrations/110_cluster_settings_global_eval_knobs.d.ts +4 -0
- package/dist/db/migrations/111_cluster_settings_global_eval_wait.d.ts +4 -0
- package/dist/db/migrations/112_execution_runs_workflow_repo.d.ts +4 -0
- package/dist/db/migrations/113_execution_runs_workflow_repo_index.d.ts +30 -0
- package/dist/db/migrations/114_ingest_queue_claim.d.ts +4 -0
- package/dist/db/migrations/115_global_workflows_cluster_switch.d.ts +9 -0
- package/dist/db/migrations/116_org_plan_headroom.d.ts +4 -0
- package/dist/db/migrations/117_invoke_gate_proxy_jobs.d.ts +4 -0
- package/dist/db/migrations/118_invoke_gate_scheduling.d.ts +4 -0
- package/dist/db/migrations/119_scaler_ha_ownership.d.ts +4 -0
- package/dist/db/migrations/120_cluster_settings_scaler_reaper.d.ts +4 -0
- package/dist/db/migrations/121_org_settings_allow_untrusted_dockerfile_builds.d.ts +19 -0
- package/dist/db/migrations/122_host_roster_scaler_managed.d.ts +25 -0
- package/dist/db/migrations/123_workflow_registrations_default_branch.d.ts +24 -0
- package/dist/db/migrations/124_cluster_settings_provision_backoff.d.ts +4 -0
- package/dist/db/migrations/125_org_trust_directory.d.ts +30 -0
- package/dist/db/migrations/126_held_runs_posted_pending_check.d.ts +28 -0
- package/dist/db/migrations/127_org_trust_policy_approval_expiry_seconds.d.ts +26 -0
- package/dist/db/migrations/128_execution_runs_global_eval_round.d.ts +23 -0
- package/dist/db/migrations/129_execution_runs_dispatch_routing_key.d.ts +24 -0
- package/dist/db/migrations/130_scaler_provision_outcomes.d.ts +32 -0
- package/dist/db/types.d.ts +428 -12
- package/dist/entry-helpers.d.ts +28 -0
- package/dist/events/event-emitter.d.ts +22 -0
- package/dist/events/event-router.d.ts +87 -1
- package/dist/events/types.d.ts +2 -23
- package/dist/git/credential-broker.d.ts +94 -0
- package/dist/git/inherited-secret.d.ts +24 -0
- package/dist/git/installation-token.d.ts +38 -0
- package/dist/git/job-context.d.ts +13 -0
- package/dist/index.js +324 -84
- package/dist/metrics/agent-metrics-aggregator.d.ts +4 -4
- package/dist/metrics/prometheus.d.ts +170 -3
- package/dist/oidc/oidc-mint-registration.d.ts +7 -3
- package/dist/orchestrator-core.d.ts +91 -24
- package/dist/pipeline/content-filter.d.ts +71 -0
- package/dist/pipeline/direct-ingress-deps.d.ts +100 -0
- package/dist/pipeline/dispatch-matched-workflow.d.ts +521 -11
- package/dist/pipeline/global-eval-round.d.ts +307 -0
- package/dist/pipeline/internal-event-pipeline.d.ts +140 -0
- package/dist/pipeline/invoke-gate.d.ts +164 -0
- package/dist/pipeline/job-contexts.d.ts +16 -17
- package/dist/pipeline/needs-scheduler.d.ts +13 -0
- package/dist/pipeline/process-webhook.d.ts +126 -31
- package/dist/pipeline/processor.d.ts +282 -23
- package/dist/pipeline/rerun.d.ts +21 -0
- package/dist/pipeline/resume-workflow.d.ts +40 -7
- package/dist/pipeline/route-or-dispatch-jobs.d.ts +15 -0
- package/dist/pipeline/security-hold-check.d.ts +217 -0
- package/dist/pipeline/test-pipeline.d.ts +12 -0
- package/dist/pipeline/undispatched-hold-checks.d.ts +23 -0
- package/dist/pipeline/webhook-payload-store.d.ts +20 -0
- package/dist/policy/dashboard-write-policy-listener.d.ts +62 -0
- package/dist/policy/dashboard-write-policy.d.ts +14 -0
- package/dist/provenance/backfill-run.d.ts +10 -1
- package/dist/provider-registry.d.ts +47 -4
- package/dist/providers/github/check-status-poster.d.ts +33 -3
- package/dist/providers/github/commit-message.d.ts +20 -0
- package/dist/providers/github/file-contents.d.ts +40 -0
- package/dist/providers/github/index.d.ts +2 -2
- package/dist/providers/github/normalizer.d.ts +3 -2
- package/dist/providers/local/normalizer.d.ts +3 -5
- package/dist/providers/universal-git/config.d.ts +2 -0
- package/dist/providers/universal-git/index.d.ts +11 -2
- package/dist/providers/universal-git/normalizer.d.ts +10 -0
- package/dist/queue/cleanup.d.ts +7 -1
- package/dist/queue/job-queue.d.ts +112 -7
- package/dist/queue/terminalize-unroutable.d.ts +13 -0
- package/dist/registration/extractor.d.ts +3 -3
- package/dist/registration/registration-index.d.ts +7 -0
- package/dist/registration/registration-run-match.d.ts +47 -0
- package/dist/registration/registration-store.d.ts +22 -0
- package/dist/reporting/check-run-reporter.d.ts +146 -2
- package/dist/reporting/check-run-summary.d.ts +25 -1
- package/dist/reporting/execution-tracker.d.ts +324 -9
- package/dist/reporting/log-chunk-sink.d.ts +8 -5
- package/dist/reporting/run-aggregator.d.ts +4 -14
- package/dist/reporting/step-display-order.d.ts +43 -0
- package/dist/routes/admin-held-runs.d.ts +142 -0
- package/dist/routes/admin-org-settings.d.ts +5 -0
- package/dist/routes/admin-trust-policy.d.ts +34 -6
- package/dist/routes/admin.d.ts +15 -0
- package/dist/scaler/backend-factory.d.ts +55 -0
- package/dist/scaler/bare-metal-backend.d.ts +43 -5
- package/dist/scaler/claim-store.d.ts +119 -0
- package/dist/scaler/config.d.ts +4 -0
- package/dist/scaler/container-backend.d.ts +18 -4
- package/dist/scaler/container-routing.d.ts +23 -0
- package/dist/scaler/container-spawn.d.ts +28 -0
- package/dist/scaler/event-backend.d.ts +124 -0
- package/dist/scaler/event-provision-reaper.d.ts +350 -0
- package/dist/scaler/failure-tracker.d.ts +1 -1
- package/dist/scaler/firecracker-backend.d.ts +33 -6
- package/dist/scaler/index.d.ts +11 -1
- package/dist/scaler/label-matcher.d.ts +4 -3
- package/dist/scaler/manager.d.ts +905 -76
- package/dist/scaler/resolve-container-auth.d.ts +45 -0
- package/dist/scaler/scaler-events.d.ts +11 -0
- package/dist/scaler/scaler-state-store.d.ts +294 -10
- package/dist/scaler/types.d.ts +131 -13
- package/dist/scaler/warm-pool.d.ts +132 -29
- package/dist/security/comment-handler.d.ts +50 -11
- package/dist/security/global-workflow-policy.d.ts +52 -12
- package/dist/security/identity-link.d.ts +60 -0
- package/dist/security/lock-source.d.ts +11 -13
- package/dist/security/reduced-privilege-note.d.ts +59 -0
- package/dist/security/trust-directory-store.d.ts +233 -0
- package/dist/security/trust-policy-gate.d.ts +94 -59
- package/dist/security/trust-policy-store.d.ts +3 -0
- package/dist/security/trust-resolver.d.ts +14 -98
- package/dist/server.d.ts +11 -1
- package/dist/server.js +56329 -42234
- package/dist/stale-detector/gate-deadline-detector.d.ts +52 -0
- package/dist/stale-detector/stale-run-detector.d.ts +61 -3
- package/dist/standalone.js +37619 -23570
- package/dist/webhook/ingest-accept.d.ts +70 -0
- package/dist/webhook/ingest-overflow-buffer.d.ts +35 -4
- package/dist/webhook/ingest-overflow-replayer.d.ts +50 -6
- package/dist/worker/in-memory-job-queue.d.ts +1 -1
- package/dist/ws/agent-handler.d.ts +31 -4
- package/dist/ws/dashboard-context-handler.d.ts +28 -4
- package/dist/ws/dashboard-global-workflows-handler.d.ts +36 -9
- package/dist/ws/execution-status-frame.d.ts +32 -0
- package/dist/ws/failure-messages.d.ts +2 -0
- package/dist/ws/git-credential-relay.d.ts +39 -0
- package/dist/ws/oidc-token-relay.d.ts +6 -11
- package/dist/ws/platform-client.d.ts +68 -9
- package/dist/ws/test-relay-handlers.d.ts +35 -10
- package/installer-image-digests.json +3 -3
- package/package.json +24 -19
- package/sbom.spdx.json +868 -821
- package/dist/approvals/team-membership-lookup.d.ts +0 -13
- package/dist/pipeline/inline-eval.d.ts +0 -44
- package/dist/providers/github/contributor-resolver.d.ts +0 -30
- package/dist/security/contributor-cache.d.ts +0 -83
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Manages the lifecycle: pending -> approved/rejected/expired.
|
|
5
5
|
*/
|
|
6
|
-
import { Kysely } from 'kysely';
|
|
6
|
+
import { Kysely, type Transaction } from 'kysely';
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
import { type ApprovalRequirement, type ApproverClause, type StepApprovalPayload, ApprovalDecision, HoldScope, TriggerSource } from '@kici-dev/engine';
|
|
9
9
|
import type { Database, HeldRun, HeldRunApproval } from '../db/types.js';
|
|
10
|
+
/** A Kysely root handle or an in-flight transaction — query builders accept either. */
|
|
11
|
+
type Executor = Kysely<Database> | Transaction<Database>;
|
|
10
12
|
/** Status values for held runs (held_runs table). */
|
|
11
13
|
export declare enum HeldRunStatus {
|
|
12
14
|
Pending = "pending",
|
|
@@ -17,7 +19,25 @@ export declare enum HeldRunStatus {
|
|
|
17
19
|
}
|
|
18
20
|
/**
|
|
19
21
|
* Reason a run was held in the security queue. Persisted verbatim in
|
|
20
|
-
* `held_runs.reason` and
|
|
22
|
+
* `held_runs.reason` and whose vocabulary `buildSecurityHoldSummary` switches
|
|
23
|
+
* on.
|
|
24
|
+
*
|
|
25
|
+
* Each value names why a run sits in the queue. The enum stays whole because
|
|
26
|
+
* compiling code still names all four: `buildSecurityHoldSummary` renders one
|
|
27
|
+
* branch per value. Dropping a member breaks that, and breaks the parity test
|
|
28
|
+
* that pins `SECURITY_HOLD_JOB_IDS`' three policy-reason keys to this enum's
|
|
29
|
+
* options — the engine constant cannot import the enum, so that coupling lives
|
|
30
|
+
* only in the orchestrator's test. Nothing validates `held_runs.reason` against
|
|
31
|
+
* this enum, so a stored value is not rejected anywhere.
|
|
32
|
+
*
|
|
33
|
+
* - `fork_pr` — the org trust policy's fork switch held the run.
|
|
34
|
+
* - `context_trust` — a context's minimum-trust gate held the run.
|
|
35
|
+
* - `workflow_modification` — deprecated; no longer raised. Modifications to
|
|
36
|
+
* `.kici/` are surfaced on their own informational check and no longer feed
|
|
37
|
+
* a policy arm. Removed at v1.0.0.
|
|
38
|
+
* - `unknown_contributor` — deprecated; no longer raised. The policy turns on
|
|
39
|
+
* whether the pull request came from a fork, not on who opened it. Removed
|
|
40
|
+
* at v1.0.0.
|
|
21
41
|
*/
|
|
22
42
|
export declare const SecurityHoldReason: z.ZodEnum<{
|
|
23
43
|
context_trust: "context_trust";
|
|
@@ -37,6 +57,20 @@ export interface CreateHeldRunData {
|
|
|
37
57
|
expiresAt: Date;
|
|
38
58
|
/** Queue type: 'context' (default) or 'security'. */
|
|
39
59
|
queueType?: 'context' | 'security';
|
|
60
|
+
/**
|
|
61
|
+
* Granularity of the held element. Omit to leave the column at its `'job'`
|
|
62
|
+
* default. The org trust policy's PR-wide hold passes `'workflow'`: it fires
|
|
63
|
+
* before any job is materialized and resumes by rebuilding the whole workflow
|
|
64
|
+
* dispatch, so `routeRelease` must send it to the workflow resume path.
|
|
65
|
+
*/
|
|
66
|
+
scope?: HoldScope;
|
|
67
|
+
/**
|
|
68
|
+
* What triggered the hold. Omit to leave the column at its `'context'`
|
|
69
|
+
* default. Written explicitly by the trust-policy hold so its release signal
|
|
70
|
+
* carries the pair `routeRelease` discriminates on rather than relying on a
|
|
71
|
+
* column default to supply half of it.
|
|
72
|
+
*/
|
|
73
|
+
triggerSource?: TriggerSource;
|
|
40
74
|
}
|
|
41
75
|
/**
|
|
42
76
|
* Data required to create a generalized approval hold. Unlike the legacy
|
|
@@ -109,14 +143,57 @@ export interface ListHeldRunsOptions {
|
|
|
109
143
|
export declare class HeldRunStore {
|
|
110
144
|
private readonly db;
|
|
111
145
|
constructor(db: Kysely<Database>);
|
|
112
|
-
/**
|
|
113
|
-
|
|
146
|
+
/**
|
|
147
|
+
* Create a new held run with pending status.
|
|
148
|
+
*
|
|
149
|
+
* `exec` is the executor the INSERT runs through, defaulting to the store's
|
|
150
|
+
* own connection. A caller that writes something the row cannot exist without
|
|
151
|
+
* — the job's pending dispatch context, without which the hold can never be
|
|
152
|
+
* resumed — passes its enclosing transaction, so the two land or roll back
|
|
153
|
+
* together. Handed in rather than taken from an ambient scope: Kysely has no
|
|
154
|
+
* such scope, so a `this.db` insert inside a `db.transaction()` callback runs
|
|
155
|
+
* on a different connection and commits on its own.
|
|
156
|
+
*/
|
|
157
|
+
create(orgId: string, data: CreateHeldRunData, exec?: Executor): Promise<HeldRun>;
|
|
114
158
|
/**
|
|
115
159
|
* Create a generalized approval hold (workflow/job/step scope, explicit or
|
|
116
160
|
* context trigger) carrying a normalized `ApprovalRequirement`. Returns
|
|
117
161
|
* the created row.
|
|
162
|
+
*
|
|
163
|
+
* `exec` carries the same meaning it does on {@link create}.
|
|
164
|
+
*/
|
|
165
|
+
createHold(orgId: string, data: CreateHoldData, exec?: Executor): Promise<HeldRun>;
|
|
166
|
+
/**
|
|
167
|
+
* Record that the pending `KiCI Security` check reached the provider, for
|
|
168
|
+
* every hold that gates it, so the settle that ends one knows it has a check
|
|
169
|
+
* to terminalize.
|
|
170
|
+
*
|
|
171
|
+
* Written AFTER the post returns, never before. The two orders fail
|
|
172
|
+
* differently and the failures are not equivalent: recording first and dying
|
|
173
|
+
* before the post leaves a row claiming a check the commit does not have, and
|
|
174
|
+
* the settle then CREATES one — a completed `KiCI Security` run appearing on a
|
|
175
|
+
* commit nothing ever held. Recording second leaves the opposite residue, a
|
|
176
|
+
* real pending check the settle declines to close, which is the same stuck
|
|
177
|
+
* check the fire-and-forget post could already produce. A fabricated failing
|
|
178
|
+
* check on a pull request is worse than a stuck one, so the write goes last.
|
|
179
|
+
*
|
|
180
|
+
* **One statement for all of them, not one per hold.** A commit's check run is
|
|
181
|
+
* shared by every hold on it, and the settle asks the contention query which
|
|
182
|
+
* of them still owns it. Marking them in a loop admits a PARTIAL mark: mark
|
|
183
|
+
* the reviewer hold, fail on the security hold, and the security row keeps
|
|
184
|
+
* `posted_pending_check: false` — so it is not counted as a contender, and
|
|
185
|
+
* approving the reviewer hold terminalizes the shared check `success` while
|
|
186
|
+
* the trust hold still gates the job. That is a fabricated PASSING check,
|
|
187
|
+
* which is the worse direction, reached without any process dying: a
|
|
188
|
+
* deadlock, a statement timeout or a lost connection between the two UPDATEs
|
|
189
|
+
* is enough. A single `WHERE id IN (…)` either marks every hold or none.
|
|
190
|
+
*
|
|
191
|
+
* The residual window is therefore one statement issued immediately after the
|
|
192
|
+
* provider call returns — narrow, and not only reachable by a process death,
|
|
193
|
+
* which is why the caller logs its failure rather than treating it as
|
|
194
|
+
* impossible.
|
|
118
195
|
*/
|
|
119
|
-
|
|
196
|
+
markPendingCheckPosted(orgId: string, heldRunIds: readonly string[]): Promise<void>;
|
|
120
197
|
/** INSERT one decision row using the given executor (root or transaction). */
|
|
121
198
|
private insertDecisionRow;
|
|
122
199
|
/** Flip a pending hold to 'approved' using the given executor. Undefined if not pending. */
|
|
@@ -190,20 +267,49 @@ export declare class HeldRunStore {
|
|
|
190
267
|
*/
|
|
191
268
|
listOverdue(): Promise<HeldRun[]>;
|
|
192
269
|
/**
|
|
193
|
-
* Release overdue
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
* `
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
270
|
+
* Release overdue timer holds at ANY scope. A wait action pauses its element
|
|
271
|
+
* as a held run; on timer expiry it must RESUME (not fail like a reviewer-hold
|
|
272
|
+
* expiry). Flips each overdue pending timer row to `released` and returns a
|
|
273
|
+
* `ReleaseSignal` per row, carrying the row's own scope so the caller can
|
|
274
|
+
* route it — `routeRelease` sends a workflow-scoped one to the install-gate
|
|
275
|
+
* rebuild and a job-scoped one to the job re-dispatch path.
|
|
276
|
+
*
|
|
277
|
+
* Runs BEFORE `expireOverdue()` so these rows leave the pending pool before
|
|
278
|
+
* the expire-and-fail sweep sees them. That ordering is load-bearing, not
|
|
279
|
+
* incidental: `expireOverdue` is not scope-filtered, so a released-but-not-yet-
|
|
280
|
+
* resumed row would otherwise be expired out from under its resume.
|
|
200
281
|
*
|
|
201
|
-
* The filter matches every persisted spelling of the timer hold type, so a
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
282
|
+
* The filter matches every persisted spelling of the timer hold type, so a row
|
|
283
|
+
* an un-upgraded orchestrator wrote as `wait_timer` still resumes rather than
|
|
284
|
+
* falling through to the expire-and-fail sweep. It deliberately does NOT
|
|
285
|
+
* filter on `hold_scope`: a job-scoped timer hold used to be excluded here,
|
|
286
|
+
* which left it with no release path at all — created, never released,
|
|
287
|
+
* eventually expired, its job never dispatched.
|
|
205
288
|
*/
|
|
206
289
|
releaseDueWaitHolds(): Promise<ReleaseSignal[]>;
|
|
290
|
+
/**
|
|
291
|
+
* Every pending queued (concurrency) hold, with the org and concurrency group
|
|
292
|
+
* it belongs to — the input to the periodic release sweep, which needs to know
|
|
293
|
+
* WHICH groups have someone waiting before it looks up any limits.
|
|
294
|
+
*
|
|
295
|
+
* Returns the pair rather than full rows: the sweep only groups by it, and
|
|
296
|
+
* `listQueuedHoldsForContext` fetches the rows it actually releases.
|
|
297
|
+
*/
|
|
298
|
+
listAllQueuedHolds(): Promise<Array<{
|
|
299
|
+
orgId: string | null;
|
|
300
|
+
concurrencyGroup: string | null;
|
|
301
|
+
}>>;
|
|
302
|
+
/**
|
|
303
|
+
* List the pending queued (concurrency) holds for one context's concurrency
|
|
304
|
+
* group, oldest first.
|
|
305
|
+
*
|
|
306
|
+
* Joined to `execution_runs` and filtered by `customer_id` as well as
|
|
307
|
+
* `context`: a context NAME is not unique across tenants, so without the org
|
|
308
|
+
* predicate one org's completing job could release another org's queued hold.
|
|
309
|
+
* Oldest-first is the release order — a queue that released newest-first would
|
|
310
|
+
* starve whoever waited longest.
|
|
311
|
+
*/
|
|
312
|
+
listQueuedHoldsForContext(orgId: string, concurrencyGroup: string): Promise<HeldRun[]>;
|
|
207
313
|
/**
|
|
208
314
|
* Expire overdue pending runs. Called by the stale detector.
|
|
209
315
|
* Sets status to 'expired' and resolved_at to now() for all
|
|
@@ -224,4 +330,5 @@ export declare function createHeldRunStoreFromUrl(databaseUrl: string, opts?: {
|
|
|
224
330
|
store: HeldRunStore;
|
|
225
331
|
dispose: () => Promise<void>;
|
|
226
332
|
};
|
|
333
|
+
export {};
|
|
227
334
|
//# sourceMappingURL=held-runs.d.ts.map
|
|
@@ -26,8 +26,9 @@ export declare function evaluateMultiContextGates(envs: ReadonlyArray<{
|
|
|
26
26
|
}>, ctx: JobDispatchContext): ContextGateRejection[];
|
|
27
27
|
/**
|
|
28
28
|
* Aggregate hold/wait/queue parameters across all bound contexts, most
|
|
29
|
-
* restrictive wins: trust =
|
|
30
|
-
*
|
|
29
|
+
* restrictive wins: trust = strictest declared floor (see `TRUST_RANK` — a
|
|
30
|
+
* wording choice, not a verdict), reviewers = sorted dedup union, wait timer =
|
|
31
|
+
* max, hold expiry = min, concurrency limit = min (tightest). The concurrency
|
|
31
32
|
* strategy follows the primary (first) context.
|
|
32
33
|
*/
|
|
33
34
|
export declare function aggregateProtectionParams(envs: ReadonlyArray<Context>): EffectiveProtection;
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import type { Context, ProtectionGateResult } from '@kici-dev/engine';
|
|
2
2
|
import type { JobDispatchContext } from './pipeline.js';
|
|
3
|
+
/**
|
|
4
|
+
* The reason phrase for a branch-restricted context bound by an
|
|
5
|
+
* internally-triggered run that carries NO branch. Shared with the multi-context
|
|
6
|
+
* aggregator so the two reject paths cannot describe the same cause
|
|
7
|
+
* differently, and context-free because each caller names the context itself.
|
|
8
|
+
*
|
|
9
|
+
* An internally-triggered run usually does have a branch: a scheduled run
|
|
10
|
+
* presents its registration's default branch, and every other internal trigger
|
|
11
|
+
* inherits the branch of the run that emitted its event. Those runs are matched
|
|
12
|
+
* against the restriction patterns like any other. This phrase covers only the
|
|
13
|
+
* runs where neither source produced one — a registration whose default branch
|
|
14
|
+
* has never been captured, or an emitting run that is gone — so it names the
|
|
15
|
+
* remedy for that case rather than telling an operator to drop the restriction.
|
|
16
|
+
*/
|
|
17
|
+
export declare const INTERNAL_TRIGGER_NO_BRANCH_DETAIL: string;
|
|
3
18
|
/** Evaluate branch restrictions, trigger type filters, and repo patterns. */
|
|
4
19
|
export declare function evaluateBranchGate(env: Context, ctx: JobDispatchContext): ProtectionGateResult;
|
|
5
20
|
//# sourceMappingURL=branch-gate.d.ts.map
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type { Context, ProtectionGateResult } from '@kici-dev/engine';
|
|
2
|
-
/**
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Evaluate concurrency limits for the context.
|
|
4
|
+
*
|
|
5
|
+
* Takes only the two fields it reads rather than a whole `Context`, so the
|
|
6
|
+
* ready-dispatch re-gate can call it with the limit and strategy it resolved
|
|
7
|
+
* from a run's bound context row. Every full `Context` still satisfies it.
|
|
8
|
+
*/
|
|
9
|
+
export declare function evaluateConcurrencyGate(env: Pick<Context, 'concurrencyLimit' | 'concurrencyStrategy'>, currentRunningCount: number, _concurrencyGroup: string): ProtectionGateResult;
|
|
4
10
|
//# sourceMappingURL=concurrency-gate.d.ts.map
|
|
@@ -12,6 +12,24 @@ export interface JobDispatchContext {
|
|
|
12
12
|
repository: string;
|
|
13
13
|
runId: string;
|
|
14
14
|
jobId: string;
|
|
15
|
+
/**
|
|
16
|
+
* True when the run was triggered by the orchestrator itself (a schedule
|
|
17
|
+
* fire, a workflow/job completion, a failure batch, a `kiciEvent()`, an
|
|
18
|
+
* invoke-gate summon) rather than by a provider webhook.
|
|
19
|
+
*
|
|
20
|
+
* Such a run usually DOES carry a branch, and `branch` is then matched
|
|
21
|
+
* against the restriction patterns like any other run's: a schedule fire
|
|
22
|
+
* presents its registration's default branch, and every other internal
|
|
23
|
+
* trigger inherits the branch of the run that emitted its event.
|
|
24
|
+
*
|
|
25
|
+
* The flag matters only when `branch` is EMPTY — a failure batch or a scaler
|
|
26
|
+
* event (many runs behind it, or none), a registration whose default branch
|
|
27
|
+
* has never been captured, an emitting run that is gone. The branch gate then
|
|
28
|
+
* rejects naming that cause, instead of quoting the empty value as a branch
|
|
29
|
+
* name an operator could add to the restriction list. It never weakens the
|
|
30
|
+
* gate: a run with no branch cannot satisfy a restriction, `*` included.
|
|
31
|
+
*/
|
|
32
|
+
internallyTriggered?: boolean;
|
|
15
33
|
}
|
|
16
34
|
/** Evaluate all protection rules for a context. */
|
|
17
35
|
export declare function evaluateProtectionRules(env: Context, ctx: JobDispatchContext, currentRunningCount: number, concurrencyGroup: string, trustTier?: TrustTier): Promise<ProtectionGateResult>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Kysely } from 'kysely';
|
|
2
|
+
import type { Database } from '../db/types.js';
|
|
3
|
+
import type { HeldRunStore, ReleaseSignal } from './held-runs.js';
|
|
4
|
+
export interface ReleaseQueuedHoldsArgs {
|
|
5
|
+
db: Kysely<Database>;
|
|
6
|
+
heldRunStore: Pick<HeldRunStore, 'listQueuedHoldsForContext' | 'release'>;
|
|
7
|
+
orgId: string;
|
|
8
|
+
/** The context's concurrency group — `execution_runs.context`. */
|
|
9
|
+
concurrencyGroup: string;
|
|
10
|
+
/** The context's configured limit; `null`/`undefined` means unlimited. */
|
|
11
|
+
concurrencyLimit: number | null | undefined;
|
|
12
|
+
/** Resume a released hold by re-dispatching its job. */
|
|
13
|
+
onJobRelease: (signal: ReleaseSignal) => Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Count the jobs OCCUPYING a slot in a concurrency group, scoped to one org.
|
|
17
|
+
*
|
|
18
|
+
* A job occupies its slot from the moment it is dispatched until it reaches a
|
|
19
|
+
* terminal status — not merely while its status is `running`. Counting only
|
|
20
|
+
* `running` missed every job that had been dispatched but had not yet reported
|
|
21
|
+
* back, so the sweep read a full group as empty and released queued holds while
|
|
22
|
+
* their slots were still taken. That is a real over-admission, not a cosmetic
|
|
23
|
+
* one: the release path re-checks the limit precisely so the bound holds
|
|
24
|
+
* whenever the sweep happens to run, and an undercount defeats that re-check.
|
|
25
|
+
*
|
|
26
|
+
* The `customer_id` predicate is not optional: a context name shared across
|
|
27
|
+
* tenants would otherwise leak concurrency between them.
|
|
28
|
+
*/
|
|
29
|
+
export declare function countOccupyingJobs(db: Kysely<Database>, orgId: string, concurrencyGroup: string): Promise<number>;
|
|
30
|
+
/**
|
|
31
|
+
* Release up to `limit - running` queued holds for a group, oldest first.
|
|
32
|
+
* Returns how many actually resumed.
|
|
33
|
+
*/
|
|
34
|
+
export declare function releaseQueuedHolds(args: ReleaseQueuedHoldsArgs): Promise<number>;
|
|
35
|
+
//# sourceMappingURL=release-queued-holds.d.ts.map
|
|
@@ -50,7 +50,9 @@ export declare function baseAttestationsQuery(db: Kysely<Database>): import("kys
|
|
|
50
50
|
join_tokens: import("../db/types.js").JoinTokenTable;
|
|
51
51
|
kici_events: import("../db/types.js").KiciEventTable;
|
|
52
52
|
orchestrator_signing_keys: import("../db/types.js").OrchestratorSigningKeysTable;
|
|
53
|
+
org_plan_headroom: import("../db/types.js").OrgPlanHeadroomTable;
|
|
53
54
|
org_settings: import("../db/types.js").OrgSettingsTable;
|
|
55
|
+
org_trust_directory: import("../db/types.js").OrgTrustDirectoryTable;
|
|
54
56
|
org_trust_policy: import("../db/types.js").OrgTrustPolicyTable;
|
|
55
57
|
pending_attestations: import("../db/types.js").PendingAttestationsTable;
|
|
56
58
|
pending_job_contexts: import("../db/types.js").PendingJobContextsTable;
|
|
@@ -62,6 +64,8 @@ export declare function baseAttestationsQuery(db: Kysely<Database>): import("kys
|
|
|
62
64
|
run_ephemeral_keys: import("../db/types.js").RunEphemeralKeysTable;
|
|
63
65
|
run_secret_outputs: import("../db/types.js").RunSecretOutputsTable;
|
|
64
66
|
scaler_agent_jobs: import("../db/types.js").ScalerAgentJobsTable;
|
|
67
|
+
scaler_pending_claims: import("../db/types.js").ScalerPendingClaimsTable;
|
|
68
|
+
scaler_provision_outcomes: import("../db/types.js").ScalerProvisionOutcomesTable;
|
|
65
69
|
scaler_reservations: import("../db/types.js").ScalerReservationsTable;
|
|
66
70
|
scaler_spawning_agents: import("../db/types.js").ScalerSpawningAgentsTable;
|
|
67
71
|
scoped_secrets: import("../db/types.js").ScopedSecretsTable;
|
|
@@ -121,7 +125,9 @@ export declare function basePendingAttestationsQuery(db: Kysely<Database>): impo
|
|
|
121
125
|
join_tokens: import("../db/types.js").JoinTokenTable;
|
|
122
126
|
kici_events: import("../db/types.js").KiciEventTable;
|
|
123
127
|
orchestrator_signing_keys: import("../db/types.js").OrchestratorSigningKeysTable;
|
|
128
|
+
org_plan_headroom: import("../db/types.js").OrgPlanHeadroomTable;
|
|
124
129
|
org_settings: import("../db/types.js").OrgSettingsTable;
|
|
130
|
+
org_trust_directory: import("../db/types.js").OrgTrustDirectoryTable;
|
|
125
131
|
org_trust_policy: import("../db/types.js").OrgTrustPolicyTable;
|
|
126
132
|
pending_attestations: import("../db/types.js").PendingAttestationsTable;
|
|
127
133
|
pending_job_contexts: import("../db/types.js").PendingJobContextsTable;
|
|
@@ -133,6 +139,8 @@ export declare function basePendingAttestationsQuery(db: Kysely<Database>): impo
|
|
|
133
139
|
run_ephemeral_keys: import("../db/types.js").RunEphemeralKeysTable;
|
|
134
140
|
run_secret_outputs: import("../db/types.js").RunSecretOutputsTable;
|
|
135
141
|
scaler_agent_jobs: import("../db/types.js").ScalerAgentJobsTable;
|
|
142
|
+
scaler_pending_claims: import("../db/types.js").ScalerPendingClaimsTable;
|
|
143
|
+
scaler_provision_outcomes: import("../db/types.js").ScalerProvisionOutcomesTable;
|
|
136
144
|
scaler_reservations: import("../db/types.js").ScalerReservationsTable;
|
|
137
145
|
scaler_spawning_agents: import("../db/types.js").ScalerSpawningAgentsTable;
|
|
138
146
|
scoped_secrets: import("../db/types.js").ScopedSecretsTable;
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dashboard handler for the orchestrator.
|
|
3
|
-
*
|
|
4
|
-
* Responds to dashboard.* and run.* WS messages from Platform by querying the local
|
|
5
|
-
* execution_jobs and execution_steps tables and reading logs from LogStorage.
|
|
6
|
-
*
|
|
7
|
-
* Supported messages:
|
|
8
|
-
* - dashboard.run.detail: returns jobs with nested steps for a run
|
|
9
|
-
* - dashboard.step.logs: returns log lines for a specific step
|
|
10
|
-
* - dashboard.payload: returns the original webhook payload for a run
|
|
11
|
-
* - run.rerun.request: re-runs a completed workflow run
|
|
12
|
-
* - run.cancel.request: cancels a running workflow run
|
|
13
|
-
*/
|
|
14
1
|
import { type Kysely } from 'kysely';
|
|
15
2
|
import { type ColdStore } from '@kici-dev/shared';
|
|
16
3
|
import type { DashboardRunDetailRequest, DashboardRunsListRequest, DashboardRunsListResponse, DashboardRunsFiltersRequest, DashboardRunsFiltersResponse, DashboardSourcesListRequest, DashboardSourcesListResponse, DashboardStepLogsRequest, DashboardAttestationsListRequest, DashboardAttestationsListAllRequest, DashboardAttestationGetRequest, DashboardAttestationRetryRequest, DashboardPayloadRequest, DashboardOrchLogsRequest, DashboardEventLogListRequest, DashboardEventLogActivityRequest, DashboardEventLogDetailRequest, DashboardEventLogPayloadStreamRequest, DashboardAccessLogListRequest, DashboardEventDlqListRequest, DashboardEventDlqCountRequest, DashboardEventDlqRetryRequest, DashboardEventDlqDiscardRequest, RunRerunRequest, RunCancelRequest, ManualScheduleRequest, DashboardRunStructuredRequest, DashboardArtifactsListRequest } from '@kici-dev/engine';
|
|
@@ -125,16 +112,12 @@ interface DashboardHandlerDeps {
|
|
|
125
112
|
*/
|
|
126
113
|
eventStore?: EventStore | null;
|
|
127
114
|
/**
|
|
128
|
-
* **Test-only
|
|
129
|
-
*
|
|
115
|
+
* **Test-only fault injection**, supplied only by the build-time test double:
|
|
116
|
+
* `handleRerunRequest` awaits this hook before invoking `onRerun`, so an HA
|
|
117
|
+
* E2E can force a slow first coordinator and trigger a relay failover.
|
|
118
|
+
* Undefined (the shipped default) means no delay.
|
|
130
119
|
*/
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* **Test-only.** When set (and `testMode` is true), `handleRerunRequest`
|
|
134
|
-
* sleeps this many ms before invoking `onRerun`, so an HA E2E can force a
|
|
135
|
-
* slow first coordinator and trigger a relay failover. Ignored in production.
|
|
136
|
-
*/
|
|
137
|
-
testRerunDelayMs?: number;
|
|
120
|
+
beforeRerun?: () => Promise<void>;
|
|
138
121
|
}
|
|
139
122
|
export declare class DashboardHandler {
|
|
140
123
|
private readonly db;
|
|
@@ -153,8 +136,7 @@ export declare class DashboardHandler {
|
|
|
153
136
|
private readonly eventStore;
|
|
154
137
|
private readonly retryAttestations;
|
|
155
138
|
private readonly provenanceSigningIssuer;
|
|
156
|
-
private readonly
|
|
157
|
-
private readonly testRerunDelayMs;
|
|
139
|
+
private readonly beforeRerun;
|
|
158
140
|
constructor(deps: DashboardHandlerDeps);
|
|
159
141
|
/**
|
|
160
142
|
* Update the bound orgId + routingKey. Called from server.ts after resolving
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add the partial index `idx_execution_runs_workflow_repo` on
|
|
4
|
+
* `execution_runs (workflow_repo_identifier) WHERE workflow_repo_identifier IS NOT NULL`.
|
|
5
|
+
*
|
|
6
|
+
* Matching a workflow registration to its runs keys on the repository that
|
|
7
|
+
* DEFINES the workflow — `workflow_repo_identifier ?? repo_identifier` — which
|
|
8
|
+
* the orchestrator expresses as
|
|
9
|
+
* `workflow_repo_identifier IN (…) OR (workflow_repo_identifier IS NULL AND repo_identifier IN (…))`
|
|
10
|
+
* (`registration/registration-run-match.ts`). The second arm rides
|
|
11
|
+
* `idx_execution_runs_repo` from migration 001; the first arm had no index at
|
|
12
|
+
* all, because migration 112 added the column without one. A planner cannot
|
|
13
|
+
* use an index for only half a disjunction, so the whole predicate degraded to
|
|
14
|
+
* a sequential scan over a table that grows with every run — on
|
|
15
|
+
* `dashboard.registrations.list`, which runs its grouped MAX on every list
|
|
16
|
+
* request.
|
|
17
|
+
*
|
|
18
|
+
* With both arms indexed the planner can BitmapOr them.
|
|
19
|
+
*
|
|
20
|
+
* Partial by design, and the partiality is what makes it cheap: the column is
|
|
21
|
+
* non-null only for a cross-repository organization-wide run, a small minority
|
|
22
|
+
* of rows, so the index stays a fraction of the table's size and skips every
|
|
23
|
+
* per-repository run. It also matches the predicate exactly — the first arm
|
|
24
|
+
* can never match a NULL row, since `NULL IN (…)` is never true.
|
|
25
|
+
*
|
|
26
|
+
* Idempotent: `IF NOT EXISTS` makes a re-run a no-op.
|
|
27
|
+
*/
|
|
28
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
29
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
30
|
+
//# sourceMappingURL=113_execution_runs_workflow_repo_index.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
3
|
+
/**
|
|
4
|
+
* Restores the org column with its original NOT NULL DEFAULT false. A rollback
|
|
5
|
+
* cannot recover the per-org values the up-migration dropped — they are gone —
|
|
6
|
+
* so every org comes back at the opt-in default.
|
|
7
|
+
*/
|
|
8
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=115_global_workflows_cluster_switch.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add `org_settings.allow_untrusted_dockerfile_builds boolean NOT NULL DEFAULT false`.
|
|
4
|
+
*
|
|
5
|
+
* A job may build its container image from a Dockerfile in the repository. That
|
|
6
|
+
* build runs arbitrary `RUN` commands on the agent host's daemon, OUTSIDE the
|
|
7
|
+
* hardened posture the job's own steps get (`CapDrop: ALL`, no-new-privileges,
|
|
8
|
+
* pids/memory/CPU caps) — a build cannot be capability-restricted the way a
|
|
9
|
+
* container run can.
|
|
10
|
+
*
|
|
11
|
+
* So the default is deny for an untrusted ref (a fork PR, an unresolved
|
|
12
|
+
* contributor — the same classification the cache write scope uses). An operator
|
|
13
|
+
* who wants fork PRs building their own images turns it on per org, deliberately.
|
|
14
|
+
*
|
|
15
|
+
* Idempotent: a re-run on a DB that already has the column is a no-op.
|
|
16
|
+
*/
|
|
17
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
18
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=121_org_settings_allow_untrusted_dockerfile_builds.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add `host_roster.scaler_managed boolean NOT NULL DEFAULT false`.
|
|
4
|
+
*
|
|
5
|
+
* `runsOnAll` fans a job out across the declared fleet. Every registering agent
|
|
6
|
+
* upserts a roster row, auto-scaler-spawned ones included, so a pre-spawned
|
|
7
|
+
* warm agent was a valid fan-out target — and a child pinned to it runs at the
|
|
8
|
+
* pool's fixed shape rather than its own. This column records the one fact that
|
|
9
|
+
* separates the two populations: whether a scaler backend spawned the agent.
|
|
10
|
+
*
|
|
11
|
+
* It is written from the scaler manager's registration lookup (a spawn record
|
|
12
|
+
* exists for the agent id), NOT from `lifecycle_class`. `lifecycle_class`
|
|
13
|
+
* snapshots the auth TOKEN's type and is `ephemeral` for every agent when the
|
|
14
|
+
* auth mode is `none`, so it cannot distinguish a fleet host from a scaler
|
|
15
|
+
* agent in that mode.
|
|
16
|
+
*
|
|
17
|
+
* DEFAULT false is load-bearing: a row written before this migration must read
|
|
18
|
+
* as not-scaler-managed so an existing fleet host stays a fan-out target
|
|
19
|
+
* immediately, without waiting to re-register.
|
|
20
|
+
*
|
|
21
|
+
* Idempotent: a re-run on a DB that already has the column is a no-op.
|
|
22
|
+
*/
|
|
23
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
24
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
25
|
+
//# sourceMappingURL=122_host_roster_scaler_managed.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add `workflow_registrations.default_branch text` (nullable).
|
|
4
|
+
*
|
|
5
|
+
* A `__schedule_fire` run executes the default branch's lock file, so the
|
|
6
|
+
* default branch IS that run's branch — which is what a branch-restricted
|
|
7
|
+
* context needs in order to accept it. The value is already computed at
|
|
8
|
+
* registration time from the webhook payload (the default-branch-push check),
|
|
9
|
+
* it was simply never persisted, so a scheduled run had no branch to present.
|
|
10
|
+
*
|
|
11
|
+
* NULLABLE with no default, deliberately. The default branch is knowable only
|
|
12
|
+
* from a webhook payload, so there is nothing to backfill a pre-existing row
|
|
13
|
+
* with: a registration written before this migration reads NULL until its
|
|
14
|
+
* repo's next default-branch push re-registers it. The dispatch path reads NULL
|
|
15
|
+
* as "no branch" and the context branch gate then rejects with its honest
|
|
16
|
+
* named-cause verdict — a DEFAULT would instead invent a branch the
|
|
17
|
+
* registration never proved, which is exactly the confusion this whole column
|
|
18
|
+
* exists to end.
|
|
19
|
+
*
|
|
20
|
+
* Idempotent: a re-run on a DB that already has the column is a no-op.
|
|
21
|
+
*/
|
|
22
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
23
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
24
|
+
//# sourceMappingURL=123_workflow_registrations_default_branch.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Create `org_trust_directory` — the orchestrator's cache of the Platform-owned
|
|
4
|
+
* approval directory pushed alongside the policy on `trust_policy.update`:
|
|
5
|
+
* identity links, per-member CI trust levels, and team memberships.
|
|
6
|
+
*
|
|
7
|
+
* A sibling of `org_trust_policy` rather than more columns on it: the policy is
|
|
8
|
+
* four scalar switches, while these three are structured documents the Platform
|
|
9
|
+
* replaces wholesale on every push — `identity_links` and `team_memberships`
|
|
10
|
+
* are arrays, `member_ci_trust` is a user-id-keyed map — so they are stored as
|
|
11
|
+
* JSONB.
|
|
12
|
+
*
|
|
13
|
+
* Persisting rather than holding them only in memory is what lets
|
|
14
|
+
* `/kici approve` authorize a commenter after a restart. Without a cached
|
|
15
|
+
* directory the orchestrator cannot map a comment author onto a KiCI user at
|
|
16
|
+
* all until the Platform's next push lands, so every approval is refused in the
|
|
17
|
+
* meantime.
|
|
18
|
+
*
|
|
19
|
+
* Wherever a Platform is attached it is the only writer of this row. An
|
|
20
|
+
* independent orchestrator has no Platform, so there the operator writes it
|
|
21
|
+
* through `kici-admin trust-policy directory-set`. The two are mutually
|
|
22
|
+
* exclusive — the admin route refuses the local write on any Platform-attached
|
|
23
|
+
* orchestrator — so a deployment still only ever has one writer, and there is
|
|
24
|
+
* no counterpart to `org_trust_policy.source` to record which it was.
|
|
25
|
+
*
|
|
26
|
+
* Idempotent: guarded by IF NOT EXISTS, so a re-run is a no-op.
|
|
27
|
+
*/
|
|
28
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
29
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
30
|
+
//# sourceMappingURL=125_org_trust_directory.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add `held_runs.posted_pending_check boolean` — whether this hold's pending
|
|
4
|
+
* `KiCI Security` check actually reached the provider.
|
|
5
|
+
*
|
|
6
|
+
* `postCheckStatus` CREATES the named check run when it finds none, so
|
|
7
|
+
* terminalizing a check the hold never posted does not close anything: it puts
|
|
8
|
+
* a completed `KiCI Security` run on a commit that had none. Whether a hold
|
|
9
|
+
* posted one was derived from the row's SHAPE, which answers what the code
|
|
10
|
+
* INTENDED — a post that the provider refused, or that no check poster was in
|
|
11
|
+
* reach to attempt, leaves a shape that says "posted" and a commit that has
|
|
12
|
+
* nothing. The column records what happened instead of what was meant.
|
|
13
|
+
*
|
|
14
|
+
* Nullable, with no default, and the three values are distinct:
|
|
15
|
+
*
|
|
16
|
+
* - `true` — the post returned successfully. The hold owns the check.
|
|
17
|
+
* - `false` — no post was attempted, or one was attempted and failed. Nothing
|
|
18
|
+
* to terminalize; a settle would fabricate.
|
|
19
|
+
* - `null` — the row predates this column, so nothing recorded either way. The
|
|
20
|
+
* shape derivation still answers for it. A `false` DEFAULT would instead
|
|
21
|
+
* declare every hold pending at deploy time un-posted and strand the checks
|
|
22
|
+
* they really do have.
|
|
23
|
+
*
|
|
24
|
+
* Idempotent: a re-run on a DB that already has the column is a no-op.
|
|
25
|
+
*/
|
|
26
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
27
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
28
|
+
//# sourceMappingURL=126_held_runs_posted_pending_check.d.ts.map
|