@kici-dev/orchestrator 0.5.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 +23 -0
- package/dist/agent/dispatcher.d.ts +81 -13
- package/dist/agent/host-roster.d.ts +37 -5
- package/dist/agent/registry.d.ts +2 -0
- package/dist/app.d.ts +33 -6
- 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 +7 -0
- package/dist/cli/api-client.d.ts +18 -0
- package/dist/cli/commands/cluster-settings.d.ts +11 -0
- package/dist/cli/commands/diagnose.d.ts +6 -0
- package/dist/cli/commands/held-run.d.ts +58 -0
- package/dist/cli/commands/trust-policy.d.ts +117 -12
- package/dist/cli/kici-admin.d.ts +10 -0
- package/dist/cli.js +2272 -1025
- package/dist/cluster/cluster-identity.d.ts +3 -3
- package/dist/cluster/cluster-settings-reader.d.ts +7 -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 +21 -21
- 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/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 +368 -10
- 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 +2 -2
- package/dist/metrics/prometheus.d.ts +111 -3
- package/dist/oidc/oidc-mint-registration.d.ts +7 -3
- package/dist/orchestrator-core.d.ts +79 -23
- package/dist/pipeline/direct-ingress-deps.d.ts +100 -0
- package/dist/pipeline/dispatch-matched-workflow.d.ts +302 -31
- package/dist/pipeline/global-eval-round.d.ts +14 -0
- package/dist/pipeline/internal-event-pipeline.d.ts +140 -0
- package/dist/pipeline/invoke-gate.d.ts +164 -0
- package/dist/pipeline/needs-scheduler.d.ts +13 -0
- package/dist/pipeline/process-webhook.d.ts +119 -31
- package/dist/pipeline/processor.d.ts +226 -21
- 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 +9 -0
- package/dist/pipeline/security-hold-check.d.ts +217 -0
- package/dist/pipeline/undispatched-hold-checks.d.ts +23 -0
- package/dist/policy/dashboard-write-policy-listener.d.ts +62 -0
- package/dist/policy/dashboard-write-policy.d.ts +14 -0
- package/dist/provider-registry.d.ts +10 -2
- package/dist/providers/github/check-status-poster.d.ts +11 -0
- package/dist/providers/github/index.d.ts +0 -2
- package/dist/providers/github/normalizer.d.ts +3 -2
- package/dist/providers/local/normalizer.d.ts +3 -5
- package/dist/providers/universal-git/index.d.ts +11 -2
- package/dist/queue/job-queue.d.ts +43 -1
- package/dist/registration/extractor.d.ts +3 -3
- package/dist/registration/registration-index.d.ts +7 -0
- package/dist/registration/registration-store.d.ts +22 -0
- package/dist/reporting/check-run-reporter.d.ts +94 -1
- package/dist/reporting/check-run-summary.d.ts +25 -1
- package/dist/reporting/execution-tracker.d.ts +207 -2
- 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-trust-policy.d.ts +34 -6
- package/dist/routes/admin.d.ts +9 -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 +899 -72
- 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/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 +17671 -7350
- 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 +24238 -13822
- package/dist/worker/in-memory-job-queue.d.ts +1 -1
- package/dist/ws/agent-handler.d.ts +28 -4
- package/dist/ws/dashboard-context-handler.d.ts +28 -4
- package/dist/ws/dashboard-global-workflows-handler.d.ts +6 -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 +54 -9
- package/installer-image-digests.json +3 -3
- package/package.json +24 -19
- package/sbom.spdx.json +864 -822
- package/dist/approvals/team-membership-lookup.d.ts +0 -13
- package/dist/providers/github/contributor-resolver.d.ts +0 -30
- package/dist/security/contributor-cache.d.ts +0 -83
|
@@ -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,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
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add `org_trust_policy.approval_expiry_seconds` (nullable INTEGER).
|
|
4
|
+
*
|
|
5
|
+
* The authoritative security-hold window, at the granularity the existing
|
|
6
|
+
* `approval_expiry_hours` cannot express. Nullable rather than NOT NULL with a
|
|
7
|
+
* default, and deliberately NOT backfilled: NULL means "no seconds value was
|
|
8
|
+
* ever written", and every reader falls back to `approval_expiry_hours * 3600`
|
|
9
|
+
* for such a row. A backfill would have to guess, and a NOT NULL default would
|
|
10
|
+
* make a row written by an older build — which does not know the column —
|
|
11
|
+
* silently claim the default window instead of the hours the operator set.
|
|
12
|
+
*
|
|
13
|
+
* The same shape `contexts.hold_expiry_seconds` already uses for the same
|
|
14
|
+
* reason: "null = unset, the default window applies".
|
|
15
|
+
*
|
|
16
|
+
* `approval_expiry_hours` is kept. It is not dead — it is still the only window
|
|
17
|
+
* an older peer can read, and it is still what a partial write supplies — so
|
|
18
|
+
* dropping it would be a destructive schema change against a protected surface
|
|
19
|
+
* and would break a rollback outright (the column is NOT NULL with no default).
|
|
20
|
+
*
|
|
21
|
+
* Idempotent: guarded on column existence; a re-run on a DB that already has
|
|
22
|
+
* the column is a no-op.
|
|
23
|
+
*/
|
|
24
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
25
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
26
|
+
//# sourceMappingURL=127_org_trust_policy_approval_expiry_seconds.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add `execution_runs.is_global_eval_round boolean NOT NULL DEFAULT false` —
|
|
4
|
+
* the structural marker for a run row that records a global evaluation round
|
|
5
|
+
* rather than a workflow.
|
|
6
|
+
*
|
|
7
|
+
* The re-run path must recognise such a run: re-running it re-executes the
|
|
8
|
+
* evaluation, not a workflow. The only discriminator available to it otherwise
|
|
9
|
+
* is the round job's `__globaleval__` name prefix, which a customer workflow
|
|
10
|
+
* may carry — a name a customer chooses cannot decide which code path a re-run
|
|
11
|
+
* takes. A column stamped where the round failure is recorded is
|
|
12
|
+
* collision-proof.
|
|
13
|
+
*
|
|
14
|
+
* `NOT NULL DEFAULT false` because the question has exactly two answers: every
|
|
15
|
+
* pre-existing row is an ordinary run, and there is no third "unknown" reading
|
|
16
|
+
* a null would carry.
|
|
17
|
+
*
|
|
18
|
+
* Idempotent: the add is guarded on existence and the drop uses IF EXISTS, so a
|
|
19
|
+
* re-run is a no-op.
|
|
20
|
+
*/
|
|
21
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
22
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
23
|
+
//# sourceMappingURL=128_execution_runs_global_eval_round.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add `execution_runs.dispatch_routing_key TEXT NULL` — the source whose
|
|
4
|
+
* credentials a run's `provider_context` actually holds.
|
|
5
|
+
*
|
|
6
|
+
* `routing_key` records the source the event ARRIVED on. For a cross-provider
|
|
7
|
+
* global workflow those are two different sources: the lock file resolves
|
|
8
|
+
* through another source's bundle, and `provider_context` is written from that
|
|
9
|
+
* source's credentials. Anything that pairs the inbound routing key with the
|
|
10
|
+
* stored context therefore hands one source's credentials to another source's
|
|
11
|
+
* API client — the re-run of a failed evaluation round did exactly that, and
|
|
12
|
+
* the resulting fetch either fails or reads the wrong tree.
|
|
13
|
+
*
|
|
14
|
+
* Nullable, with no default: NULL means "the same source the event arrived on",
|
|
15
|
+
* which is true of every run except a cross-provider dispatch and of every row
|
|
16
|
+
* written before this column existed. A default would have to name a routing
|
|
17
|
+
* key, and there is no cluster-wide one to name.
|
|
18
|
+
*
|
|
19
|
+
* Idempotent: the add is guarded on existence and the drop uses IF EXISTS, so a
|
|
20
|
+
* re-run 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=129_execution_runs_dispatch_routing_key.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Durable per-provision outcome, keyed by agent id.
|
|
4
|
+
*
|
|
5
|
+
* `scaler_spawning_agents` is deleted the moment a provision is torn down, so
|
|
6
|
+
* its absence cannot tell "this provision was never adopted" from "this
|
|
7
|
+
* provision was adopted and has since been torn down". The stale-spawn prune
|
|
8
|
+
* has to separate exactly those two, because the first is a real external
|
|
9
|
+
* provisioning failure every coordinator must back off on, and the second is a
|
|
10
|
+
* healthy provision that must not be reported at all.
|
|
11
|
+
*
|
|
12
|
+
* This table carries the positive signal the spawn row cannot: the adoption is
|
|
13
|
+
* written in the same transaction that stamps `adopted_by`, and it outlives the
|
|
14
|
+
* spawn row's delete. Deliberately a separate table rather than a column on
|
|
15
|
+
* `scaler_spawning_agents`: that row's delete is what the per-coordinator
|
|
16
|
+
* provisioning backoff depends on, so it is left exactly as it is.
|
|
17
|
+
*
|
|
18
|
+
* `adopted_*` and `condemned_*` are independent. A provision that was adopted
|
|
19
|
+
* and later condemned by the reaper carries BOTH, and the condemn write never
|
|
20
|
+
* touches the adoption columns — losing the adoption fact would restore the
|
|
21
|
+
* misattribution this table exists to remove.
|
|
22
|
+
*
|
|
23
|
+
* Rows are purged by the leader-gated reaper once the spawn row is gone and the
|
|
24
|
+
* retention floor has passed; see `ScalerStateStore.purgeProvisionOutcomes`.
|
|
25
|
+
*
|
|
26
|
+
* Idempotent: both statements are guarded by IF NOT EXISTS, so a re-run is a
|
|
27
|
+
* no-op — including a re-run over a database that has the table but not the
|
|
28
|
+
* index, which an existence probe over the table alone would skip.
|
|
29
|
+
*/
|
|
30
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
31
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
32
|
+
//# sourceMappingURL=130_scaler_provision_outcomes.d.ts.map
|