@kici-dev/orchestrator 0.1.14 → 0.1.16
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/README.md +13 -1
- package/dist/__test-helpers__/mock-db.d.ts +2 -0
- package/dist/agent/dispatcher.d.ts +110 -6
- package/dist/agent/registry.d.ts +14 -0
- package/dist/app.d.ts +36 -0
- package/dist/approvals/apply-decision.d.ts +60 -0
- package/dist/approvals/approval-resolver.d.ts +66 -0
- package/dist/approvals/step-approval-bridge.d.ts +72 -0
- package/dist/approvals/team-membership-lookup.d.ts +13 -0
- package/dist/cache/agent-job-failed-error.d.ts +13 -0
- package/dist/cache/dispatch-cache-ref-tracker.d.ts +45 -0
- package/dist/cache/index.d.ts +2 -0
- package/dist/cache/user-cache.d.ts +116 -0
- package/dist/cancel/cancel-run.d.ts +56 -0
- package/dist/cli/api-client.d.ts +24 -0
- package/dist/cli/commands/environment.d.ts +1 -0
- package/dist/cli/commands/firecracker/index.d.ts +11 -0
- package/dist/cli/commands/firecracker/provision.d.ts +13 -0
- package/dist/cli/commands/firecracker/teardown.d.ts +3 -0
- package/dist/cli/commands/firecracker/verify.d.ts +3 -0
- package/dist/cli/commands/scaler.d.ts +18 -0
- package/dist/cli/kici-admin.d.ts +10 -1
- package/dist/cli/service/image-digests.d.ts +21 -0
- package/dist/cli.js +4148 -455
- package/dist/cluster/peer-client.d.ts +23 -1
- package/dist/cluster/peer-handler.d.ts +9 -1
- package/dist/cluster/peer-registry.d.ts +6 -0
- package/dist/config/schema.d.ts +4 -0
- package/dist/config.d.ts +13 -0
- package/dist/dashboard/handler.d.ts +92 -1
- package/dist/db/migrations/026_event_log_lockfile_corrupt.d.ts +11 -0
- package/dist/db/migrations/027_workflow_timeout.d.ts +20 -0
- package/dist/db/migrations/028_org_settings_user_cache.d.ts +4 -0
- package/dist/db/migrations/029_dispatch_queue_attempts.d.ts +16 -0
- package/dist/db/migrations/030_held_runs_env_set_null.d.ts +13 -0
- package/dist/db/migrations/031_dispatch_queue_ack_deadline.d.ts +19 -0
- package/dist/db/migrations/032_org_settings_dispatch_ack_timeout.d.ts +14 -0
- package/dist/db/migrations/033_org_settings_approval.d.ts +19 -0
- package/dist/db/migrations/034_held_runs_generalize.d.ts +24 -0
- package/dist/db/types.d.ts +89 -3
- package/dist/diagnostics/bundle-writer.d.ts +1 -17
- package/dist/diagnostics/checks/firecracker-network.d.ts +13 -0
- package/dist/diagnostics/checks/index.d.ts +2 -1
- package/dist/diagnostics/fleet-collector.d.ts +52 -0
- package/dist/diagnostics/fleet-constants.d.ts +8 -0
- package/dist/diagnostics/fleet-selection.d.ts +15 -0
- package/dist/diagnostics/fleet-topology.d.ts +47 -0
- package/dist/diagnostics/fleet-wiring.d.ts +60 -0
- package/dist/environments/environment-store.d.ts +14 -1
- package/dist/environments/held-runs.d.ts +69 -1
- package/dist/firecracker/host-network.d.ts +83 -0
- package/dist/firecracker/persist.d.ts +14 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +380 -40
- package/dist/lockfile-cache.d.ts +1 -1
- package/dist/metrics/prometheus.d.ts +8 -0
- package/dist/orchestrator-core.d.ts +13 -2
- package/dist/pipeline/dispatch-matched-workflow.d.ts +9 -0
- package/dist/pipeline/inline-eval.d.ts +17 -2
- package/dist/pipeline/process-webhook.d.ts +19 -0
- package/dist/pipeline/processor.d.ts +28 -1
- package/dist/pipeline/test-pipeline.d.ts +10 -0
- package/dist/providers/github/lock-file.d.ts +1 -1
- package/dist/providers/internal/lock-file-fetcher.d.ts +3 -2
- package/dist/queue/job-queue.d.ts +53 -1
- package/dist/reporting/execution-tracker.d.ts +3 -1
- package/dist/routes/admin-environments.d.ts +1 -0
- package/dist/routes/fleet.d.ts +20 -0
- package/dist/scaler/bare-metal-backend.d.ts +1 -0
- package/dist/scaler/config.d.ts +4 -2
- package/dist/scaler/container-backend.d.ts +3 -2
- package/dist/scaler/disk-guard.d.ts +27 -0
- package/dist/scaler/firecracker-backend.d.ts +35 -0
- package/dist/scaler/manager.d.ts +8 -0
- package/dist/scaler/nftables.d.ts +29 -3
- package/dist/scaler/reap-orphans.d.ts +27 -0
- package/dist/scaler/types.d.ts +28 -1
- package/dist/server.js +6138 -1587
- package/dist/stale-detector/stale-run-detector.d.ts +18 -0
- package/dist/stale-detector/workflow-deadline-detector.d.ts +49 -0
- package/dist/standalone.js +18499 -14925
- package/dist/storage/filesystem.d.ts +14 -4
- package/dist/storage/s3.d.ts +19 -5
- package/dist/storage/types.d.ts +32 -5
- package/dist/worker/in-memory-job-queue.d.ts +40 -7
- package/dist/ws/agent-handler.d.ts +45 -0
- package/dist/ws/dashboard-env-handler.d.ts +36 -0
- package/dist/ws/fleet-agent-collector.d.ts +23 -0
- package/dist/ws/platform-client.d.ts +10 -1
- package/installer-image-digests.json +7 -0
- package/package.json +15 -11
- package/sbom.spdx.json +62 -57
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Authentication uses ECDH key exchange followed by join token (first connect)
|
|
11
11
|
* or HMAC credential proof (reconnection).
|
|
12
12
|
*/
|
|
13
|
-
import { type PeerHeartbeat, type PeerToPeerMessage, type JobReroute, type JobProgress, type PeerJobCancel, type PeerLogChunk, type PeerCacheUploadRequest, type PeerCacheUploadResponse, type PeerConfigReload, type PeerConfigReloadResponse, type PeerLeaving, type PeerAgentTokenRevoke, type RaftVoteRequest, type RaftVoteResponse, type RaftAppendEntries } from '@kici-dev/engine';
|
|
13
|
+
import { type PeerHeartbeat, type PeerToPeerMessage, type JobReroute, type JobProgress, type PeerJobCancel, type PeerLogChunk, type PeerCacheUploadRequest, type PeerCacheUploadResponse, type PeerConfigReload, type PeerConfigReloadResponse, type PeerLogsCollectRequest, type PeerLeaving, type PeerAgentTokenRevoke, type RaftVoteRequest, type RaftVoteResponse, type RaftAppendEntries } from '@kici-dev/engine';
|
|
14
14
|
import type { PeerRegistry } from './peer-registry.js';
|
|
15
15
|
type PeerConnectionState = 'disconnected' | 'connecting' | 'handshaking' | 'authenticating' | 'connected';
|
|
16
16
|
export interface PeerClientOptions {
|
|
@@ -78,7 +78,20 @@ export interface PeerClientOptions {
|
|
|
78
78
|
* Platform-mediated discovery dedupes against the same client.
|
|
79
79
|
*/
|
|
80
80
|
onAuthenticated?: (targetInstanceId: string) => void;
|
|
81
|
+
/**
|
|
82
|
+
* Callback when a peer.logs.collect.request is received from the peer. Builds
|
|
83
|
+
* this node's subtree bundle and streams it back via the supplied `send`
|
|
84
|
+
* (peer.logs.collect.chunk frames, or a peer.logs.collect.error on failure).
|
|
85
|
+
* If undefined, incoming collect requests are ignored.
|
|
86
|
+
*/
|
|
87
|
+
onLogsCollectRequest?: PeerLogsCollectResponder;
|
|
81
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Builds a node's subtree bundle in response to a peer.logs.collect.request and
|
|
91
|
+
* streams it back through `send`. Shared by PeerClient (outgoing-dialed peers)
|
|
92
|
+
* and the peer handler (incoming-dialed peers).
|
|
93
|
+
*/
|
|
94
|
+
export type PeerLogsCollectResponder = (msg: PeerLogsCollectRequest, send: (out: PeerToPeerMessage) => boolean) => Promise<void>;
|
|
82
95
|
export declare class PeerClient {
|
|
83
96
|
private ws;
|
|
84
97
|
private _state;
|
|
@@ -91,6 +104,8 @@ export declare class PeerClient {
|
|
|
91
104
|
private readonly ackWaiters;
|
|
92
105
|
private readonly cacheWaiters;
|
|
93
106
|
private readonly configReloadWaiters;
|
|
107
|
+
/** Correlates peer.logs.collect.request with the peer's chunked subtree response. */
|
|
108
|
+
private readonly logsCollectWaiters;
|
|
94
109
|
private readonly url;
|
|
95
110
|
private readonly joinToken?;
|
|
96
111
|
private readonly credentialFile;
|
|
@@ -112,6 +127,7 @@ export declare class PeerClient {
|
|
|
112
127
|
private readonly onAgentTokenRevoke?;
|
|
113
128
|
private readonly onPeerConfigReload?;
|
|
114
129
|
private readonly onAuthenticated?;
|
|
130
|
+
private readonly onLogsCollectRequest?;
|
|
115
131
|
constructor(options: PeerClientOptions);
|
|
116
132
|
/** Current connection state. */
|
|
117
133
|
get state(): PeerConnectionState;
|
|
@@ -150,6 +166,12 @@ export declare class PeerClient {
|
|
|
150
166
|
* if the peer doesn't reply within the timeout.
|
|
151
167
|
*/
|
|
152
168
|
sendConfigReloadAndWait(msg: PeerConfigReload, timeoutMs?: number): Promise<PeerConfigReloadResponse | null>;
|
|
169
|
+
/**
|
|
170
|
+
* Send a peer.logs.collect.request to the connected peer and await its
|
|
171
|
+
* reassembled subtree-bundle ZIP. Rejects on timeout, an error frame, or
|
|
172
|
+
* peer disconnect.
|
|
173
|
+
*/
|
|
174
|
+
sendLogsCollectAndWait(msg: PeerLogsCollectRequest, timeoutMs: number): Promise<Buffer>;
|
|
153
175
|
/**
|
|
154
176
|
* Send a cache upload request to the coordinator and wait for a response
|
|
155
177
|
* with a pre-signed URL.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* proof (reconnection), registers the peer in PeerRegistry, and routes
|
|
7
7
|
* messages bidirectionally. Sends periodic heartbeats to the connecting peer.
|
|
8
8
|
*/
|
|
9
|
-
import { type PeerHeartbeat, type PeerToPeerMessage, type JobReroute, type JobProgress, type PeerScalerEvent, type PeerJobCancel, type PeerLogChunk, type PeerCacheUploadRequest, type PeerCacheUploadResponse, type PeerConfigReload, type PeerConfigReloadResponse, type PeerLeaving, type PeerAgentTokenRevoke, type RaftVoteRequest, type RaftVoteResponse, type RaftAppendEntries } from '@kici-dev/engine';
|
|
9
|
+
import { type PeerHeartbeat, type PeerToPeerMessage, type JobReroute, type JobProgress, type PeerScalerEvent, type PeerJobCancel, type PeerLogChunk, type PeerCacheUploadRequest, type PeerCacheUploadResponse, type PeerConfigReload, type PeerConfigReloadResponse, type PeerLogsCollectRequest, type PeerLeaving, type PeerAgentTokenRevoke, type RaftVoteRequest, type RaftVoteResponse, type RaftAppendEntries } from '@kici-dev/engine';
|
|
10
10
|
import type { PeerRegistry } from './peer-registry.js';
|
|
11
11
|
import type { PeerCredentialStore } from './peer-credentials.js';
|
|
12
12
|
import { type JoinTokenManager } from './join-token.js';
|
|
@@ -78,6 +78,13 @@ export interface PeerHandlerDeps {
|
|
|
78
78
|
restartRequired?: string[];
|
|
79
79
|
fieldsChanged?: string[];
|
|
80
80
|
}>;
|
|
81
|
+
/**
|
|
82
|
+
* Callback when a peer.logs.collect.request arrives from an incoming-dialed
|
|
83
|
+
* peer. Builds this node's subtree bundle and streams it back through `send`
|
|
84
|
+
* (peer.logs.collect.chunk frames, or a peer.logs.collect.error on failure).
|
|
85
|
+
* If undefined, incoming collect requests are ignored.
|
|
86
|
+
*/
|
|
87
|
+
onLogsCollectRequest?: (msg: PeerLogsCollectRequest, send: (out: PeerToPeerMessage) => boolean) => Promise<void>;
|
|
81
88
|
}
|
|
82
89
|
/**
|
|
83
90
|
* Create a handler function for incoming peer WebSocket connections.
|
|
@@ -90,6 +97,7 @@ export declare function createPeerHandler(deps: PeerHandlerDeps): {
|
|
|
90
97
|
sendToPeer: (targetInstanceId: string, msg: PeerToPeerMessage) => boolean;
|
|
91
98
|
sendAndWaitAck: (targetInstanceId: string, msg: JobReroute, timeoutMs?: number) => Promise<boolean>;
|
|
92
99
|
sendConfigReloadAndWait: (targetInstanceId: string, msg: PeerConfigReload, timeoutMs?: number) => Promise<PeerConfigReloadResponse | null>;
|
|
100
|
+
sendLogsCollectAndWait: (targetInstanceId: string, msg: PeerLogsCollectRequest, timeoutMs: number) => Promise<Buffer>;
|
|
93
101
|
getConnectionCount: () => number;
|
|
94
102
|
broadcastHeartbeat: (inventory: Omit<PeerHeartbeat, "type">) => void;
|
|
95
103
|
broadcastAgentTokenRevoke: (msg: PeerAgentTokenRevoke) => void;
|
|
@@ -21,6 +21,12 @@ export interface PeerAgentInfo {
|
|
|
21
21
|
* in the required label set.
|
|
22
22
|
*/
|
|
23
23
|
mandatoryLabels: string[];
|
|
24
|
+
/**
|
|
25
|
+
* Name of the scaler backend that spawned this agent, or null for static
|
|
26
|
+
* (stateful) agents not bound to any scaler. Surfaced in diagnostics so the
|
|
27
|
+
* dashboard can group a peer's agents under the correct scaler row.
|
|
28
|
+
*/
|
|
29
|
+
scalerName?: string | null;
|
|
24
30
|
}
|
|
25
31
|
export interface PeerInfo {
|
|
26
32
|
instanceId: string;
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -107,6 +107,8 @@ export declare const sharedConfigSchema: z.ZodObject<{
|
|
|
107
107
|
cacheTtlDays: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
108
108
|
cacheBuildTimeoutMs: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
109
109
|
cacheMaxTarballBytes: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
110
|
+
userCacheQuotaBytes: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
111
|
+
userCacheTtlMs: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
110
112
|
eventRouter: z.ZodOptional<z.ZodObject<{
|
|
111
113
|
maxChainDepth: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
112
114
|
rateLimitPerWorkflowPerMinute: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
@@ -189,6 +191,8 @@ export declare const appConfigSchema: z.ZodObject<{
|
|
|
189
191
|
cacheTtlDays: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
190
192
|
cacheBuildTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
191
193
|
cacheMaxTarballBytes: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
194
|
+
userCacheQuotaBytes: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
195
|
+
userCacheTtlMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
192
196
|
eventRouterMaxChainDepth: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
193
197
|
eventRouterRateLimitPerWorkflowPerMinute: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
194
198
|
eventRouterEventTtlSeconds: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
package/dist/config.d.ts
CHANGED
|
@@ -36,6 +36,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
36
36
|
queueBackpressureThreshold: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
37
37
|
workerConcurrency: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
38
38
|
concurrencyWaitTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
39
|
+
dispatchAckTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
39
40
|
cacheStorageType: z.ZodOptional<z.ZodEnum<{
|
|
40
41
|
s3: "s3";
|
|
41
42
|
filesystem: "filesystem";
|
|
@@ -46,6 +47,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
46
47
|
cacheStorageS3Region: z.ZodOptional<z.ZodString>;
|
|
47
48
|
cacheStorageS3Endpoint: z.ZodOptional<z.ZodString>;
|
|
48
49
|
cacheStorageS3ExternalEndpoint: z.ZodOptional<z.ZodString>;
|
|
50
|
+
cacheStorageS3UploadEndpoint: z.ZodOptional<z.ZodString>;
|
|
49
51
|
cacheStorageS3ForcePathStyle: z.ZodOptional<z.ZodPipe<z.ZodEnum<{
|
|
50
52
|
true: "true";
|
|
51
53
|
false: "false";
|
|
@@ -56,6 +58,8 @@ declare const configSchema: z.ZodObject<{
|
|
|
56
58
|
cacheTtlDays: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
57
59
|
cacheBuildTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
58
60
|
cacheMaxTarballBytes: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
61
|
+
userCacheQuotaBytes: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
62
|
+
userCacheTtlMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
59
63
|
webhookPayloadDir: z.ZodOptional<z.ZodString>;
|
|
60
64
|
dataDir: z.ZodOptional<z.ZodString>;
|
|
61
65
|
scalerConfigPath: z.ZodOptional<z.ZodString>;
|
|
@@ -149,12 +153,17 @@ export type AppConfig = z.infer<typeof configSchema> & {
|
|
|
149
153
|
region?: string;
|
|
150
154
|
endpoint?: string;
|
|
151
155
|
externalEndpoint?: string;
|
|
156
|
+
uploadEndpoint?: string;
|
|
152
157
|
forcePathStyle?: boolean;
|
|
153
158
|
logBucket?: string;
|
|
154
159
|
/** Filesystem backend: absolute base directory for cached blobs. */
|
|
155
160
|
fsBasePath?: string;
|
|
156
161
|
/** Filesystem backend: base URL the agent uses to reach this orchestrator. */
|
|
157
162
|
fsBaseUrl?: string;
|
|
163
|
+
/** Per-org byte quota for the user-facing cache (UserCache). */
|
|
164
|
+
userCacheQuotaBytes?: number;
|
|
165
|
+
/** Per-entry TTL (ms) for the user-facing cache (UserCache). */
|
|
166
|
+
userCacheTtlMs?: number;
|
|
158
167
|
};
|
|
159
168
|
};
|
|
160
169
|
/**
|
|
@@ -177,10 +186,13 @@ export declare const envDef: import("@kici-dev/shared/env").DefineEnvResult<{
|
|
|
177
186
|
queueBackpressureThreshold: number;
|
|
178
187
|
workerConcurrency: number;
|
|
179
188
|
concurrencyWaitTimeoutMs: number;
|
|
189
|
+
dispatchAckTimeoutMs: number;
|
|
180
190
|
cacheStorageS3Prefix: string;
|
|
181
191
|
cacheTtlDays: number;
|
|
182
192
|
cacheBuildTimeoutMs: number;
|
|
183
193
|
cacheMaxTarballBytes: number;
|
|
194
|
+
userCacheQuotaBytes: number;
|
|
195
|
+
userCacheTtlMs: number;
|
|
184
196
|
staleDetectorScanIntervalMs: number;
|
|
185
197
|
staleDetectorThresholdMultiplier: number;
|
|
186
198
|
jobHeartbeatIntervalMs: number;
|
|
@@ -234,6 +246,7 @@ export declare const envDef: import("@kici-dev/shared/env").DefineEnvResult<{
|
|
|
234
246
|
cacheStorageS3Region?: string | undefined;
|
|
235
247
|
cacheStorageS3Endpoint?: string | undefined;
|
|
236
248
|
cacheStorageS3ExternalEndpoint?: string | undefined;
|
|
249
|
+
cacheStorageS3UploadEndpoint?: string | undefined;
|
|
237
250
|
cacheStorageS3ForcePathStyle?: boolean | undefined;
|
|
238
251
|
cacheStorageFsPath?: string | undefined;
|
|
239
252
|
cacheStorageFsBaseUrl?: string | undefined;
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { type Kysely } from 'kysely';
|
|
15
15
|
import { type ColdStore } from '@kici-dev/shared';
|
|
16
|
-
import type { DashboardRunDetailRequest, DashboardStepLogsRequest, DashboardPayloadRequest, DashboardOrchLogsRequest, DashboardEventLogListRequest, DashboardEventLogDetailRequest, DashboardEventLogPayloadStreamRequest, DashboardAccessLogListRequest, DashboardEventDlqListRequest, DashboardEventDlqCountRequest, DashboardEventDlqRetryRequest, DashboardEventDlqDiscardRequest, RunRerunRequest, RunCancelRequest, ManualScheduleRequest } from '@kici-dev/engine';
|
|
16
|
+
import type { DashboardRunDetailRequest, DashboardRunsListRequest, DashboardRunsListResponse, DashboardRunsFiltersRequest, DashboardRunsFiltersResponse, DashboardSourcesListRequest, DashboardSourcesListResponse, DashboardStepLogsRequest, DashboardPayloadRequest, DashboardOrchLogsRequest, DashboardEventLogListRequest, DashboardEventLogDetailRequest, DashboardEventLogPayloadStreamRequest, DashboardAccessLogListRequest, DashboardEventDlqListRequest, DashboardEventDlqCountRequest, DashboardEventDlqRetryRequest, DashboardEventDlqDiscardRequest, RunRerunRequest, RunCancelRequest, ManualScheduleRequest } from '@kici-dev/engine';
|
|
17
17
|
import type { Database } from '../db/types.js';
|
|
18
18
|
import type { LogStorage } from '../reporting/log-storage.js';
|
|
19
19
|
import type { AccessLogWriter } from '../audit/access-log.js';
|
|
@@ -155,6 +155,97 @@ export declare class DashboardHandler {
|
|
|
155
155
|
* builds a nested job/step tree, and sends the response.
|
|
156
156
|
*/
|
|
157
157
|
handleRunDetail(msg: DashboardRunDetailRequest): Promise<void>;
|
|
158
|
+
/**
|
|
159
|
+
* Resolve every routing key owned by an org by unioning both source
|
|
160
|
+
* tables. The orchestrator is single-org but multi-routing-key: one org
|
|
161
|
+
* owns one GitHub-app source plus N generic sources, each with its own
|
|
162
|
+
* `routing_key`. `execution_runs` has no `org_id` column — org ownership
|
|
163
|
+
* is expressed purely through `routing_key → sources.customer_id` /
|
|
164
|
+
* `generic_webhook_sources.customer_id`, so scoping a run query to an org
|
|
165
|
+
* means scoping it to the union of that org's routing keys.
|
|
166
|
+
*
|
|
167
|
+
* Predicates mirror the org-context resolver in `server.ts` and
|
|
168
|
+
* `resolveOrgForRoutingKey` above:
|
|
169
|
+
* - `sources`: `customer_id = orgId` excluding the `__default__` sentinel.
|
|
170
|
+
* - `generic_webhook_sources`: `customer_id = orgId` and not soft-deleted
|
|
171
|
+
* (`deleted_at is null`).
|
|
172
|
+
*/
|
|
173
|
+
private resolveOrgRoutingKeys;
|
|
174
|
+
/**
|
|
175
|
+
* Resolve a per-routing-key source identity map for a set of routing keys,
|
|
176
|
+
* unioning both source tables. Uses the identical name/subtype/provider
|
|
177
|
+
* derivation as `handleSourcesList` so a run summary's `source` block
|
|
178
|
+
* matches what the sources page shows for the same routing key. Routing
|
|
179
|
+
* keys with no live source row are simply absent from the map (the caller
|
|
180
|
+
* falls back to the run's own provider).
|
|
181
|
+
*/
|
|
182
|
+
private resolveSourceIdentities;
|
|
183
|
+
/**
|
|
184
|
+
* Look up the page's jobs in one query to derive per-run `jobCount` plus the
|
|
185
|
+
* compile-job markers (`hadCompileJob` / `compileJobId`). The compile job is
|
|
186
|
+
* the synthetic `__build__*` job KiCI inserts for the compile phase — the
|
|
187
|
+
* same definition the Platform run-list route uses
|
|
188
|
+
* (`job_name LIKE '__build__%'`). Returns a per-run aggregate keyed by
|
|
189
|
+
* `run_id`; runs with no job rows are absent (the caller omits the fields).
|
|
190
|
+
*/
|
|
191
|
+
private resolveRunJobAggregates;
|
|
192
|
+
/**
|
|
193
|
+
* Handle a dashboard.runs.list request.
|
|
194
|
+
*
|
|
195
|
+
* Returns a page of run summaries from `execution_runs`, scoped to ALL
|
|
196
|
+
* routing keys owned by this orchestrator's bound org (`this.orgId`). The
|
|
197
|
+
* orchestrator is single-org but multi-routing-key, and the bound
|
|
198
|
+
* `this.routingKey` is just ONE of the org's keys (resolved
|
|
199
|
+
* non-deterministically at startup), so filtering on it alone would drop
|
|
200
|
+
* runs that arrived under a sibling routing key. We resolve the org's full
|
|
201
|
+
* routing-key set from `sources` + `generic_webhook_sources` and filter on
|
|
202
|
+
* the union. Attribution still uses the handler-bound `orgId` /
|
|
203
|
+
* `routingKey` directly — the same inline-ctx pattern as the org-scoped
|
|
204
|
+
* event-log / access-log handlers.
|
|
205
|
+
*
|
|
206
|
+
* Used by the operator console (`support-read` break-glass) and the
|
|
207
|
+
* dashboard's run-list view. The access_log row carries the wire actor
|
|
208
|
+
* (including the platform_operator reason) so the customer can audit any
|
|
209
|
+
* operator read.
|
|
210
|
+
*/
|
|
211
|
+
handleRunsList(msg: DashboardRunsListRequest): Promise<DashboardRunsListResponse>;
|
|
212
|
+
/**
|
|
213
|
+
* Handle a dashboard.runs.filters request.
|
|
214
|
+
*
|
|
215
|
+
* Returns the distinct filter-option values the customer runs page renders
|
|
216
|
+
* in its filter controls — statuses / workflows / branches / repositories /
|
|
217
|
+
* triggerTypes / sources — scoped to ALL routing keys owned by this
|
|
218
|
+
* orchestrator's bound org (same scoping as `handleRunsList`). Distinct
|
|
219
|
+
* values are derived in-memory from a single column projection over
|
|
220
|
+
* `execution_runs`; `sources` reuses `resolveSourceIdentities` so the list
|
|
221
|
+
* matches what the sources page shows for the same routing key.
|
|
222
|
+
*
|
|
223
|
+
* `triggerTypes` is populated from `execution_runs.provider` — the
|
|
224
|
+
* orchestrator has no dedicated trigger-event column, so `provider`
|
|
225
|
+
* (`github` / `generic` / `internal`) is the closest available
|
|
226
|
+
* discriminator the customer filter can offer.
|
|
227
|
+
*
|
|
228
|
+
* Attribution uses the handler-bound `orgId` / `routingKey` directly — the
|
|
229
|
+
* same inline-ctx pattern as `handleRunsList`. The access_log row carries
|
|
230
|
+
* the wire actor (including the platform_operator reason) so the customer
|
|
231
|
+
* can audit any operator read.
|
|
232
|
+
*/
|
|
233
|
+
handleRunsFilters(msg: DashboardRunsFiltersRequest): Promise<DashboardRunsFiltersResponse>;
|
|
234
|
+
/**
|
|
235
|
+
* Handle a dashboard.sources.list request.
|
|
236
|
+
*
|
|
237
|
+
* Returns the org's webhook source summaries by unioning both source
|
|
238
|
+
* tables (GitHub-app `sources` + live `generic_webhook_sources`), scoped
|
|
239
|
+
* to this orchestrator's bound org (`this.orgId`). Source counts are tiny
|
|
240
|
+
* so the page is returned unpaginated (`msg.limit` is ignored). Secret-
|
|
241
|
+
* bearing columns (`config`, `git_config`, `verification_config`) are
|
|
242
|
+
* never projected — `git_config` is read only to derive the subtype.
|
|
243
|
+
*
|
|
244
|
+
* Attribution uses the handler-bound `orgId` / `routingKey` directly —
|
|
245
|
+
* the same inline-ctx pattern as `handleRunsList`. The access_log row
|
|
246
|
+
* carries the wire actor so the customer can audit any operator read.
|
|
247
|
+
*/
|
|
248
|
+
handleSourcesList(msg: DashboardSourcesListRequest): Promise<DashboardSourcesListResponse>;
|
|
158
249
|
/**
|
|
159
250
|
* Handle a dashboard.step.logs request.
|
|
160
251
|
* Looks up the step's log_path and reads content from LogStorage.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Extend the event_log.status CHECK constraint with 'lockfile_corrupt' so the
|
|
4
|
+
* orchestrator can log a delivery whose lock file was present but unparseable.
|
|
5
|
+
* Orchestrator-only: the Platform event_log uses a separate, narrower status set.
|
|
6
|
+
*
|
|
7
|
+
* Idempotent: the DROP ... IF EXISTS / re-ADD pair re-runs cleanly.
|
|
8
|
+
*/
|
|
9
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
10
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=026_event_log_lockfile_corrupt.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add `workflow_timeout_ms integer` to `execution_runs`.
|
|
4
|
+
*
|
|
5
|
+
* Persists the workflow-level wall-clock timeout (in milliseconds) read from
|
|
6
|
+
* the lock workflow at run creation. NULL means no workflow-level cap is
|
|
7
|
+
* configured. The WorkflowDeadlineDetector reads this column to find runs
|
|
8
|
+
* whose `started_at + workflow_timeout_ms` has passed and cancels them with
|
|
9
|
+
* the distinct workflow-timeout reason.
|
|
10
|
+
*
|
|
11
|
+
* Typed INTEGER to match the existing `*_ms` columns (`duration_ms`,
|
|
12
|
+
* `concurrency_timeout_ms`), which keeps the pg read representation a plain
|
|
13
|
+
* number rather than the BIGINT-as-string shape. INTEGER caps the timeout at
|
|
14
|
+
* ~24.8 days, far beyond any sane workflow wall-clock budget.
|
|
15
|
+
*
|
|
16
|
+
* Idempotent: re-running on a DB that already has the column is a no-op.
|
|
17
|
+
*/
|
|
18
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
19
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
20
|
+
//# sourceMappingURL=027_workflow_timeout.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add `dispatch_queue.dispatch_attempts INT NOT NULL DEFAULT 0`.
|
|
4
|
+
*
|
|
5
|
+
* Counts how many times a job has been returned to `pending` for
|
|
6
|
+
* re-dispatch after a failed delivery attempt (agent sent job.reject, or
|
|
7
|
+
* a scaler-managed agent disconnected before the job started). The
|
|
8
|
+
* dispatcher fails the job permanently once the counter reaches
|
|
9
|
+
* MAX_DISPATCH_ATTEMPTS, bounding requeue loops; `expires_at` remains the
|
|
10
|
+
* time-based backstop.
|
|
11
|
+
*
|
|
12
|
+
* Idempotent: re-running on a DB that already has the column is a no-op.
|
|
13
|
+
*/
|
|
14
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
15
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=029_dispatch_queue_attempts.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* held_runs.environment_id becomes nullable with ON DELETE SET NULL so
|
|
4
|
+
* terminal held-run history survives environment deletion (a null
|
|
5
|
+
* environment_id means the environment was since deleted). Pending held
|
|
6
|
+
* runs still block deletion — enforced in EnvironmentStore.delete.
|
|
7
|
+
*
|
|
8
|
+
* Idempotent: dropping the NOT NULL and the constraint are both no-ops on a
|
|
9
|
+
* re-run, and the constraint is re-created with the SET NULL action.
|
|
10
|
+
*/
|
|
11
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
12
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=030_held_runs_env_set_null.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add `dispatch_queue.ack_deadline TIMESTAMPTZ` and
|
|
4
|
+
* `dispatch_queue.ack_agent_id TEXT` persisting the per-dispatch
|
|
5
|
+
* acknowledgment deadline for HA-safe lost-dispatch detection.
|
|
6
|
+
*
|
|
7
|
+
* The dispatcher stamps both when a job.dispatch is sent and clears them
|
|
8
|
+
* when the agent answers (job.ack / job.reject / job.status running). A
|
|
9
|
+
* `dispatched` row past its deadline is requeued — by the owning coord's
|
|
10
|
+
* in-memory timer, or by the leader-gated sweep
|
|
11
|
+
* (`Dispatcher.sweepExpiredAckDeadlines`) when the owning coord crashed.
|
|
12
|
+
* On coord boot, `Dispatcher.recoverState()` re-arms timers from the
|
|
13
|
+
* persisted deadlines.
|
|
14
|
+
*
|
|
15
|
+
* Idempotent: re-running on a DB that already has either 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=031_dispatch_queue_ack_deadline.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add `org_settings.dispatch_ack_timeout_ms BIGINT` (nullable).
|
|
4
|
+
*
|
|
5
|
+
* Per-org override of the dispatch-acknowledgment deadline. NULL falls
|
|
6
|
+
* back to the cluster-wide default (`KICI_DISPATCH_ACK_TIMEOUT_MS`,
|
|
7
|
+
* default 10s). Operators raise it on high-latency networks via
|
|
8
|
+
* `kici-admin org-settings`.
|
|
9
|
+
*
|
|
10
|
+
* Idempotent: a re-run on a DB that already has the column is a no-op.
|
|
11
|
+
*/
|
|
12
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
13
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=032_org_settings_dispatch_ack_timeout.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add the two approval-policy columns to `org_settings`:
|
|
4
|
+
*
|
|
5
|
+
* - `approval_expiry_seconds INTEGER NOT NULL DEFAULT 86400` — how long a held
|
|
6
|
+
* approval element waits before it expires (and its run/job/step is
|
|
7
|
+
* rejected). One day by default. An SDK `requireApproval` `timeout` overrides
|
|
8
|
+
* this per element; otherwise this per-org value applies.
|
|
9
|
+
* - `allow_self_approval BOOLEAN NOT NULL DEFAULT true` — whether the user who
|
|
10
|
+
* triggered a run may also approve its held elements. Operators turn it off
|
|
11
|
+
* to enforce four-eyes review.
|
|
12
|
+
*
|
|
13
|
+
* Both are cluster-configurable per org via `kici-admin org-settings approval`
|
|
14
|
+
* and the orchestrator admin route. Idempotent: a re-run on a DB that already
|
|
15
|
+
* has the columns is a no-op (each column is guarded independently).
|
|
16
|
+
*/
|
|
17
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
18
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=033_org_settings_approval.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Generalize `held_runs` from an environment-only hold into the unified
|
|
4
|
+
* "held element" model that backs per-element approvals, and add the
|
|
5
|
+
* `held_run_approvals` table that records each approver's decision.
|
|
6
|
+
*
|
|
7
|
+
* New `held_runs` columns (all idempotent, column-exists guarded):
|
|
8
|
+
* - `hold_scope text NOT NULL DEFAULT 'job'` — 'workflow' | 'job' | 'step'
|
|
9
|
+
* (engine `HoldScope`). Existing rows held a single job, so they default to
|
|
10
|
+
* 'job'.
|
|
11
|
+
* - `step_index integer` — nullable; set only for step-scoped holds.
|
|
12
|
+
* - `trigger_source text NOT NULL DEFAULT 'environment'` — 'environment' |
|
|
13
|
+
* 'explicit' (engine `TriggerSource`). Existing holds came from environment
|
|
14
|
+
* protection, so they default to 'environment'.
|
|
15
|
+
* - `approval_requirement jsonb` — the normalized `ApprovalRequirement`
|
|
16
|
+
* (clauses + expiresAt + reason) the hold must satisfy. Nullable for legacy
|
|
17
|
+
* rows that predate the approval model.
|
|
18
|
+
*
|
|
19
|
+
* New `held_run_approvals` table: one row per approver decision, FK to
|
|
20
|
+
* `held_runs.id` (uuid) with ON DELETE CASCADE.
|
|
21
|
+
*/
|
|
22
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
23
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
24
|
+
//# sourceMappingURL=034_held_runs_generalize.d.ts.map
|
package/dist/db/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ColumnType, Generated, Insertable, Selectable, Updateable } from 'kysely';
|
|
2
|
-
import type { InitFailure } from '@kici-dev/engine';
|
|
2
|
+
import type { ApprovalRequirement, ApproverClause, InitFailure } from '@kici-dev/engine';
|
|
3
3
|
/**
|
|
4
4
|
* PostgreSQL-only database types.
|
|
5
5
|
* Column names use snake_case matching the actual database column names.
|
|
@@ -19,6 +19,7 @@ export interface Database {
|
|
|
19
19
|
environment_variables: EnvironmentVariablesTable;
|
|
20
20
|
environment_source_overrides: EnvironmentSourceOverridesTable;
|
|
21
21
|
held_runs: HeldRunsTable;
|
|
22
|
+
held_run_approvals: HeldRunApprovalsTable;
|
|
22
23
|
admin_tokens: AdminTokenTable;
|
|
23
24
|
agent_tokens: AgentTokenTable;
|
|
24
25
|
config_versions: ConfigVersionTable;
|
|
@@ -158,6 +159,17 @@ export interface DispatchQueueTable {
|
|
|
158
159
|
* real provisioning cause; cleared on dispatch. NULL when none recorded.
|
|
159
160
|
*/
|
|
160
161
|
last_provisioning_error: ColumnType<string | null, string | null | undefined, string | null>;
|
|
162
|
+
/** Times this job was returned to pending for re-dispatch (job.reject / pre-start agent loss). */
|
|
163
|
+
dispatch_attempts: Generated<number>;
|
|
164
|
+
/**
|
|
165
|
+
* Deadline by which the dispatched job's agent must answer the
|
|
166
|
+
* job.dispatch (job.ack / job.reject / job.status running). Stamped when
|
|
167
|
+
* the dispatch is sent, cleared on any answer; `dispatched` rows past the
|
|
168
|
+
* deadline are requeued by the owning coord's timer or the leader sweep.
|
|
169
|
+
*/
|
|
170
|
+
ack_deadline: ColumnType<Date | null, Date | null | undefined, Date | null>;
|
|
171
|
+
/** Agent the dispatch was sent to (for ack-timeout disconnect + logging). */
|
|
172
|
+
ack_agent_id: ColumnType<string | null, string | null | undefined, string | null>;
|
|
161
173
|
}
|
|
162
174
|
/**
|
|
163
175
|
* Deduplication cache table
|
|
@@ -266,6 +278,12 @@ export interface ExecutionRunTable {
|
|
|
266
278
|
* provider context, agent spawn). NULL for normal runs.
|
|
267
279
|
*/
|
|
268
280
|
init_failure: ColumnType<InitFailure | null, unknown, unknown>;
|
|
281
|
+
/**
|
|
282
|
+
* Whole-run wall-clock timeout in ms from the workflow lock; null when
|
|
283
|
+
* unset. Read by the WorkflowDeadlineDetector. INTEGER in Postgres, matching
|
|
284
|
+
* the other `*_ms` columns, so pg returns a plain number.
|
|
285
|
+
*/
|
|
286
|
+
workflow_timeout_ms: ColumnType<number | null, number | null | undefined, number | null>;
|
|
269
287
|
/** When this record was created */
|
|
270
288
|
created_at: Generated<Date>;
|
|
271
289
|
/**
|
|
@@ -595,8 +613,8 @@ export interface HeldRunsTable {
|
|
|
595
613
|
run_id: string;
|
|
596
614
|
/** Job ID within the run */
|
|
597
615
|
job_id: string;
|
|
598
|
-
/** Environment ID (FK to environments.id) */
|
|
599
|
-
environment_id: string;
|
|
616
|
+
/** Environment ID (FK to environments.id); null once the environment is deleted */
|
|
617
|
+
environment_id: string | null;
|
|
600
618
|
/** Hold type: 'approval' | 'wait_timer' | 'concurrency' */
|
|
601
619
|
hold_type: string;
|
|
602
620
|
/** Hold status: 'pending' | 'approved' | 'rejected' | 'expired' | 'released' */
|
|
@@ -613,10 +631,49 @@ export interface HeldRunsTable {
|
|
|
613
631
|
expires_at: Date;
|
|
614
632
|
/** When this hold was resolved */
|
|
615
633
|
resolved_at: Date | null;
|
|
634
|
+
/**
|
|
635
|
+
* Hold granularity: 'workflow' | 'job' | 'step' (engine `HoldScope`).
|
|
636
|
+
* Existing environment holds are job-scoped, hence the 'job' default.
|
|
637
|
+
*/
|
|
638
|
+
hold_scope: Generated<string>;
|
|
639
|
+
/** Step index within the job for step-scoped holds; null otherwise. */
|
|
640
|
+
step_index: number | null;
|
|
641
|
+
/**
|
|
642
|
+
* What created the hold: 'environment' (mandatory env policy) | 'explicit'
|
|
643
|
+
* (SDK `requireApproval`). Engine `TriggerSource`.
|
|
644
|
+
*/
|
|
645
|
+
trigger_source: Generated<string>;
|
|
646
|
+
/**
|
|
647
|
+
* Normalized `ApprovalRequirement` (clauses + expiresAt + reason) the hold
|
|
648
|
+
* must satisfy. Null for legacy rows that predate the approval model.
|
|
649
|
+
*/
|
|
650
|
+
approval_requirement: ColumnType<ApprovalRequirement | null, ApprovalRequirement | string | null | undefined, ApprovalRequirement | string | null>;
|
|
616
651
|
}
|
|
617
652
|
export type HeldRun = Selectable<HeldRunsTable>;
|
|
618
653
|
export type NewHeldRun = Insertable<HeldRunsTable>;
|
|
619
654
|
export type HeldRunUpdate = Updateable<HeldRunsTable>;
|
|
655
|
+
/**
|
|
656
|
+
* One approver's recorded decision on a held element. Multiple rows accumulate
|
|
657
|
+
* until the hold's `ApprovalRequirement` clauses are all satisfied (approve) or
|
|
658
|
+
* any single reject lands.
|
|
659
|
+
*/
|
|
660
|
+
export interface HeldRunApprovalsTable {
|
|
661
|
+
/** UUID primary key */
|
|
662
|
+
id: Generated<string>;
|
|
663
|
+
/** FK to held_runs.id (ON DELETE CASCADE) */
|
|
664
|
+
held_run_id: string;
|
|
665
|
+
/** The approver's user id (Keycloak sub) */
|
|
666
|
+
approver_user_id: string;
|
|
667
|
+
/** 'approve' | 'reject' (engine `ApprovalDecision`) */
|
|
668
|
+
decision: string;
|
|
669
|
+
/** Which requirement clauses this decision satisfied (for attribution). */
|
|
670
|
+
clauses_satisfied: ColumnType<ApproverClause[] | null, ApproverClause[] | string | null | undefined, ApproverClause[] | string | null>;
|
|
671
|
+
/** When the decision was recorded */
|
|
672
|
+
created_at: Generated<Date>;
|
|
673
|
+
}
|
|
674
|
+
export type HeldRunApproval = Selectable<HeldRunApprovalsTable>;
|
|
675
|
+
export type NewHeldRunApproval = Insertable<HeldRunApprovalsTable>;
|
|
676
|
+
export type HeldRunApprovalUpdate = Updateable<HeldRunApprovalsTable>;
|
|
620
677
|
/**
|
|
621
678
|
* Secret audit log table
|
|
622
679
|
* Immutable log of secret access and denial events.
|
|
@@ -1157,6 +1214,35 @@ export interface OrgSettingsTable {
|
|
|
1157
1214
|
* treats missing keys as `true`.
|
|
1158
1215
|
*/
|
|
1159
1216
|
dashboard_write_policy: ColumnType<Record<string, boolean>, Record<string, boolean> | string | undefined, Record<string, boolean> | string>;
|
|
1217
|
+
/**
|
|
1218
|
+
* Per-org byte quota for the user-facing cache (UserCache). NULL = use the
|
|
1219
|
+
* cluster-wide default (`KICI_USER_CACHE_QUOTA_BYTES`, 5 GiB). Postgres
|
|
1220
|
+
* BIGINT — pg returns a string on select; accept a number on insert/update.
|
|
1221
|
+
*/
|
|
1222
|
+
user_cache_quota_bytes: ColumnType<string | null, number | null | undefined, number | null>;
|
|
1223
|
+
/**
|
|
1224
|
+
* Per-entry TTL (ms) for the user-facing cache (UserCache). NULL = use the
|
|
1225
|
+
* cluster-wide default (`KICI_USER_CACHE_TTL_MS`, 7 days). Postgres BIGINT —
|
|
1226
|
+
* pg returns a string on select; accept a number on insert/update.
|
|
1227
|
+
*/
|
|
1228
|
+
user_cache_ttl_ms: ColumnType<string | null, number | null | undefined, number | null>;
|
|
1229
|
+
/**
|
|
1230
|
+
* Per-org dispatch-acknowledgment deadline (ms); null = cluster default
|
|
1231
|
+
* (config.dispatchAckTimeoutMs / KICI_DISPATCH_ACK_TIMEOUT_MS). Postgres
|
|
1232
|
+
* BIGINT — pg returns a string on select; accept a number on insert/update.
|
|
1233
|
+
*/
|
|
1234
|
+
dispatch_ack_timeout_ms: ColumnType<string | null, number | null | undefined, number | null>;
|
|
1235
|
+
/**
|
|
1236
|
+
* Per-org expiry (seconds) for a held approval element before it is rejected
|
|
1237
|
+
* and its run/job/step fails. NOT NULL, default 86400 (one day). An SDK
|
|
1238
|
+
* `requireApproval` `timeout` overrides this per element.
|
|
1239
|
+
*/
|
|
1240
|
+
approval_expiry_seconds: ColumnType<number, number | undefined, number>;
|
|
1241
|
+
/**
|
|
1242
|
+
* Whether the user who triggered a run may also approve its held elements.
|
|
1243
|
+
* NOT NULL, default true. Operators turn it off to enforce four-eyes review.
|
|
1244
|
+
*/
|
|
1245
|
+
allow_self_approval: ColumnType<boolean, boolean | undefined, boolean>;
|
|
1160
1246
|
/** When this setting was created */
|
|
1161
1247
|
created_at: Generated<Date>;
|
|
1162
1248
|
/** When this setting was last updated */
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* This is the primary support tool -- operators run debug-bundle and share
|
|
7
7
|
* the ZIP for troubleshooting.
|
|
8
8
|
*/
|
|
9
|
-
import archiver from 'archiver';
|
|
10
9
|
import type { DiagnosticDeps } from './types.js';
|
|
10
|
+
export { redactConfig, addLogsToArchive } from '@kici-dev/shared';
|
|
11
11
|
export interface BundleOptions {
|
|
12
12
|
/** Where to write the ZIP. */
|
|
13
13
|
outputPath: string;
|
|
@@ -26,11 +26,6 @@ export interface BundleOptions {
|
|
|
26
26
|
/** URL for recent runs endpoint. */
|
|
27
27
|
recentRunsUrl?: string;
|
|
28
28
|
}
|
|
29
|
-
/**
|
|
30
|
-
* Redact config values using allowlist approach.
|
|
31
|
-
* Only known-safe fields are preserved; everything else becomes "****".
|
|
32
|
-
*/
|
|
33
|
-
export declare function redactConfig(obj: unknown, parentKey?: string): unknown;
|
|
34
29
|
/**
|
|
35
30
|
* Create a debug bundle ZIP file.
|
|
36
31
|
*
|
|
@@ -43,15 +38,4 @@ export declare function redactConfig(obj: unknown, parentKey?: string): unknown;
|
|
|
43
38
|
* - logs/summary.json: log statistics
|
|
44
39
|
*/
|
|
45
40
|
export declare function createDebugBundle(options: BundleOptions): Promise<string>;
|
|
46
|
-
/**
|
|
47
|
-
* Add log files from logDir to the archive, respecting MAX_LOG_BYTES cap
|
|
48
|
-
* and the logWindow time filter. Matches any `*.log` file in the directory,
|
|
49
|
-
* so the per-instance filename pattern produced by
|
|
50
|
-
* `buildLogFilename()` is picked up without additional configuration.
|
|
51
|
-
*
|
|
52
|
-
* Exported for reuse by the `kici-admin debug-bundle` CLI command, which
|
|
53
|
-
* runs outside the orchestrator process but still needs to include the
|
|
54
|
-
* same log files in its locally-assembled bundle.
|
|
55
|
-
*/
|
|
56
|
-
export declare function addLogsToArchive(archive: archiver.Archiver, logDir: string, logWindowHours: number): Promise<void>;
|
|
57
41
|
//# sourceMappingURL=bundle-writer.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Firecracker host-bridge diagnostic. Emits one row per configured Firecracker
|
|
3
|
+
* scaler backend: the bridge interface + its gateway addr + its nft table must
|
|
4
|
+
* all be present, else the scaler cannot spawn microVMs.
|
|
5
|
+
*/
|
|
6
|
+
import type { DiagnosticDeps, DiagnosticResult } from '../types.js';
|
|
7
|
+
import { type BridgeHealth, type FirecrackerBridgeConfig } from '../../firecracker/host-network.js';
|
|
8
|
+
interface CheckOpts {
|
|
9
|
+
verify?: (cfg: FirecrackerBridgeConfig) => Promise<BridgeHealth>;
|
|
10
|
+
}
|
|
11
|
+
export declare function checkFirecrackerNetwork(deps: DiagnosticDeps, opts?: CheckOpts): Promise<DiagnosticResult[]>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=firecracker-network.d.ts.map
|