@kici-dev/orchestrator 0.15.0 → 0.16.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__/scratch-db.d.ts +16 -0
- package/dist/agent/registry.d.ts +1 -8
- package/dist/app-on-error.d.ts +1 -1
- package/dist/artifacts/artifact-store.d.ts +0 -2
- package/dist/audit/access-log.d.ts +1 -1
- package/dist/cache/source-cache.d.ts +1 -1
- package/dist/cache/user-cache.d.ts +0 -28
- package/dist/cli/api-client.d.ts +27 -1
- package/dist/cli/commands/access-log.d.ts +1 -1
- package/dist/cli/commands/cold-store-impl.d.ts +7 -84
- package/dist/cli/commands/db.d.ts +1 -0
- package/dist/cli/commands/orchestrator-service/status.d.ts +2 -0
- package/dist/cli/commands/org.d.ts +12 -0
- package/dist/cli/commands/scaler.d.ts +14 -0
- package/dist/cli/commands/secret.d.ts +1 -45
- package/dist/cli/commands/service-health.d.ts +21 -13
- package/dist/cli/commands/shared/cli-action.d.ts +17 -0
- package/dist/cli/commands/shared/db.d.ts +5 -5
- package/dist/cli/commands/shared/org-id.d.ts +5 -0
- package/dist/cli/commands/shared/service-verbs.d.ts +19 -0
- package/dist/cli/commands/shared/table.d.ts +3 -0
- package/dist/cli/commands/shared/unbound-context-warning.d.ts +2 -22
- package/dist/cli/commands/trust-policy.d.ts +7 -31
- package/dist/cli/kici-admin.d.ts +1 -1
- package/dist/cli.js +9863 -8201
- package/dist/cluster/coordinator.d.ts +2 -2
- package/dist/cluster/peer-client.d.ts +27 -1
- package/dist/cluster/peer-forget.d.ts +4 -9
- package/dist/cluster/peer-handler.d.ts +11 -1
- package/dist/cluster/peer-request-waiters.d.ts +26 -0
- package/dist/cluster/scaler-orphans-peer.d.ts +4 -9
- package/dist/cluster/scaler-reload-fanout.d.ts +29 -0
- package/dist/cluster/scaler-reload-peer.d.ts +16 -0
- package/dist/cluster/worker-cluster-settings.d.ts +1 -0
- package/dist/cold-store/load-access-log-range.d.ts +3 -3
- package/dist/cold-store/tables/access-log.d.ts +4 -12
- package/dist/cold-store/tables/event-log.d.ts +8 -19
- package/dist/cold-store/tables/execution-jobs.d.ts +7 -24
- package/dist/cold-store/tables/execution-runs.d.ts +6 -20
- package/dist/cold-store/tables/execution-steps.d.ts +8 -26
- package/dist/cold-store/tables/secret-audit-log.d.ts +4 -11
- package/dist/config/env-overlay.d.ts +3 -8
- package/dist/config/reload.d.ts +9 -2
- package/dist/config/schema.d.ts +2 -2
- package/dist/config/types.d.ts +2 -2
- package/dist/config.d.ts +13 -17
- package/dist/contexts/held-runs.d.ts +3 -6
- package/dist/dashboard/cursor.d.ts +12 -0
- package/dist/dashboard/handler.d.ts +5 -12
- package/dist/db/deferred-index-build.d.ts +42 -0
- package/dist/db/deferred-indexes.d.ts +3 -37
- package/dist/db/migrations/100_held_runs_hold_type_vocabulary.d.ts +3 -5
- package/dist/db/migrations/158_normalize_legacy_values.d.ts +4 -0
- package/dist/db/repos/org-ids-repo.d.ts +87 -0
- package/dist/db/schema-snapshot.generated.d.ts +3 -0
- package/dist/db/types.d.ts +5 -22
- package/dist/fault-injection-types.d.ts +0 -6
- package/dist/git/dispatch-git-auth.d.ts +6 -12
- package/dist/helpers/json.d.ts +3 -0
- package/dist/index.js +133 -136
- package/dist/metrics/prometheus.d.ts +0 -5
- package/dist/oidc/id-token-claims.d.ts +1 -1
- package/dist/oidc/resolve-signer.d.ts +2 -4
- package/dist/orchestrator-core.d.ts +10 -3
- package/dist/pipeline/global-eval-round.d.ts +2 -26
- package/dist/pipeline/install-secrets-resolver.d.ts +0 -3
- package/dist/pipeline/manual-schedule.d.ts +1 -7
- package/dist/provenance/dispatch-context.d.ts +5 -7
- package/dist/provenance/pending-attestations-repo.d.ts +1 -1
- package/dist/provenance/trust-root.d.ts +4 -5
- package/dist/provenance/verify-deferred-capture.d.ts +3 -3
- package/dist/provider-registry.d.ts +13 -40
- package/dist/providers/universal-git/ssh-auth.d.ts +0 -5
- package/dist/reporting/check-run-reporter.d.ts +8 -21
- package/dist/reporting/check-run-summary.d.ts +2 -2
- package/dist/reporting/execution-tracker.d.ts +1 -1
- package/dist/reporting/log-chunk-sink.d.ts +1 -1
- package/dist/reporting/run-summary-fields.d.ts +25 -0
- package/dist/reporting/s3-log-storage.d.ts +2 -2
- package/dist/routes/admin-access-log.d.ts +2 -9
- package/dist/routes/admin-backends.d.ts +2 -9
- package/dist/routes/admin-cluster-name.d.ts +2 -8
- package/dist/routes/admin-cluster-settings.d.ts +2 -8
- package/dist/routes/admin-config.d.ts +0 -3
- package/dist/routes/admin-contexts.d.ts +3 -11
- package/dist/routes/admin-db.d.ts +2 -9
- package/dist/routes/admin-env.d.ts +33 -0
- package/dist/routes/admin-event-dlq.d.ts +2 -9
- package/dist/routes/admin-event-inspect.d.ts +2 -9
- package/dist/routes/admin-event-log.d.ts +2 -9
- package/dist/routes/admin-events.d.ts +3 -13
- package/dist/routes/admin-held-runs.d.ts +2 -8
- package/dist/routes/admin-list-limit.d.ts +3 -0
- package/dist/routes/admin-maintenance.d.ts +2 -9
- package/dist/routes/admin-orchestrator-drain.d.ts +2 -9
- package/dist/routes/admin-org-settings.d.ts +2 -8
- package/dist/routes/admin-orgs.d.ts +27 -0
- package/dist/routes/admin-peer-forget.d.ts +2 -9
- package/dist/routes/admin-queue-execution.d.ts +3 -10
- package/dist/routes/admin-registrations.d.ts +3 -14
- package/dist/routes/admin-runs.d.ts +3 -14
- package/dist/routes/admin-scaler-orphans.d.ts +2 -9
- package/dist/routes/admin-scaler-reload.d.ts +41 -0
- package/dist/routes/admin-scheduled-jobs.d.ts +2 -9
- package/dist/routes/admin-signing-keys.d.ts +2 -9
- package/dist/routes/admin-sources.d.ts +2 -9
- package/dist/routes/admin-trust-policy.d.ts +2 -8
- package/dist/routes/admin.d.ts +15 -13
- package/dist/scaler/config.d.ts +12 -84
- package/dist/scaler/file-reload.d.ts +48 -0
- package/dist/scaler/manager.d.ts +47 -33
- package/dist/scaler/scaler-state-store.d.ts +5 -0
- package/dist/scaler/types.d.ts +1 -4
- package/dist/secrets/job-secret-gate.d.ts +2 -5
- package/dist/secrets/secret-resolver.d.ts +2 -4
- package/dist/security/trust-policy-gate.d.ts +0 -4
- package/dist/server.d.ts +6 -17
- package/dist/server.js +6693 -8005
- package/dist/standalone.js +5826 -6555
- package/dist/worker/reroute-dispatch.d.ts +1 -0
- package/dist/worker/reroute-spawn-control.d.ts +1 -3
- package/dist/worker-core.d.ts +9 -2
- package/dist/ws/agent-handler.d.ts +3 -3
- package/dist/ws/dashboard-access.d.ts +57 -0
- package/dist/ws/dashboard-backends-handler.d.ts +1 -6
- package/dist/ws/dashboard-context-handler.d.ts +10 -15
- package/dist/ws/dashboard-fleet-write-handler.d.ts +1 -6
- package/dist/ws/dashboard-global-workflows-handler.d.ts +1 -6
- package/dist/ws/dashboard-registrations-handler.d.ts +1 -7
- package/dist/ws/platform-client.d.ts +85 -330
- package/installer-image-digests.json +3 -3
- package/package.json +4 -4
- package/sbom.spdx.json +53 -53
- package/dist/cache/legacy-prefixes.d.ts +0 -19
- package/dist/cli/commands/agent-service/logs.d.ts +0 -14
- package/dist/cli/commands/agent-service/restart.d.ts +0 -12
- package/dist/cli/commands/agent-service/start.d.ts +0 -12
- package/dist/cli/commands/agent-service/stop.d.ts +0 -12
- package/dist/cli/commands/agent-service/uninstall.d.ts +0 -13
- package/dist/cli/commands/cache.d.ts +0 -51
- package/dist/cli/commands/orchestrator-service/logs.d.ts +0 -14
- package/dist/cli/commands/orchestrator-service/restart.d.ts +0 -12
- package/dist/cli/commands/orchestrator-service/start.d.ts +0 -12
- package/dist/cli/commands/orchestrator-service/stop.d.ts +0 -12
- package/dist/cli/commands/orchestrator-service/uninstall.d.ts +0 -13
- package/dist/git/inherited-secret.d.ts +0 -29
package/dist/config/reload.d.ts
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import type { Logger } from '@kici-dev/shared';
|
|
15
15
|
import type { AppConfig, SharedConfig } from './types.js';
|
|
16
16
|
import type { SharedConfigStore } from './shared-store.js';
|
|
17
|
+
import type { ScalerFileReloadResult } from '../scaler/file-reload.js';
|
|
17
18
|
/**
|
|
18
19
|
* Source of a reload trigger.
|
|
19
20
|
*/
|
|
@@ -29,6 +30,12 @@ export interface ReloadResult {
|
|
|
29
30
|
restartRequired?: string[];
|
|
30
31
|
/** Fields that were hot-reloaded */
|
|
31
32
|
fieldsChanged?: string[];
|
|
33
|
+
/**
|
|
34
|
+
* The scaler config's own reload outcome, when this orchestrator runs one.
|
|
35
|
+
* `success` describes the orchestrator config only: a refused scaler file
|
|
36
|
+
* shows here as `rejected` while `success` stays true.
|
|
37
|
+
*/
|
|
38
|
+
scaler?: ScalerFileReloadResult;
|
|
32
39
|
}
|
|
33
40
|
/**
|
|
34
41
|
* Options for executeReload.
|
|
@@ -53,8 +60,8 @@ export interface ConfigReloaderDeps {
|
|
|
53
60
|
sharedStore: SharedConfigStore | null;
|
|
54
61
|
/** Called after successful reload when provider config changed */
|
|
55
62
|
onProviderChange?: (newConfig: AppConfig, oldConfig: AppConfig) => Promise<void>;
|
|
56
|
-
/** Called to reload scaler configuration */
|
|
57
|
-
onScalerReload?: () => Promise<void>;
|
|
63
|
+
/** Called to reload scaler configuration; its outcome is returned as `ReloadResult.scaler`. */
|
|
64
|
+
onScalerReload?: () => Promise<ScalerFileReloadResult | void>;
|
|
58
65
|
/** Called when Platform connection settings changed */
|
|
59
66
|
onPlatformReconnect?: (newConfig: AppConfig) => Promise<void>;
|
|
60
67
|
/** Atomic swap callback -- replaces the config reference */
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -109,7 +109,7 @@ export declare const sharedConfigSchema: z.ZodObject<{
|
|
|
109
109
|
coordinator: "coordinator";
|
|
110
110
|
worker: "worker";
|
|
111
111
|
}>>;
|
|
112
|
-
|
|
112
|
+
coordinatorUrls: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodString]>>;
|
|
113
113
|
peerStaleTimeoutMs: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
114
114
|
peerDiscovery: z.ZodOptional<z.ZodEnum<{
|
|
115
115
|
platform: "platform";
|
|
@@ -201,7 +201,7 @@ export declare const appConfigSchema: z.ZodObject<{
|
|
|
201
201
|
coordinator: "coordinator";
|
|
202
202
|
worker: "worker";
|
|
203
203
|
}>>;
|
|
204
|
-
|
|
204
|
+
coordinatorUrls: z.ZodDefault<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>]>>;
|
|
205
205
|
peerStaleTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
206
206
|
peerDiscovery: z.ZodDefault<z.ZodEnum<{
|
|
207
207
|
platform: "platform";
|
package/dist/config/types.d.ts
CHANGED
|
@@ -187,8 +187,8 @@ export interface AppConfig {
|
|
|
187
187
|
peerMaxReconnectDelayMs: number;
|
|
188
188
|
/** Cluster role: coordinator (full orchestrator) or worker (delegated execution). */
|
|
189
189
|
role: 'coordinator' | 'worker';
|
|
190
|
-
/**
|
|
191
|
-
|
|
190
|
+
/** URLs of every coordinator to connect to when role=worker. */
|
|
191
|
+
coordinatorUrls: string[];
|
|
192
192
|
/** Stale peer timeout in ms. */
|
|
193
193
|
peerStaleTimeoutMs: number;
|
|
194
194
|
/** Whether this coordinator dials Platform-announced peers. */
|
package/dist/config.d.ts
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Orchestrator configuration.
|
|
2
|
+
* Orchestrator startup configuration, read from `KICI_*` environment variables.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* The new config system lives in config/ and supports:
|
|
9
|
-
* - YAML config files (config/loader.ts)
|
|
10
|
-
* - Shared DB config store (config/shared-store.ts)
|
|
11
|
-
* - 4-layer resolution: env > YAML > DB > defaults (config/resolver.ts)
|
|
12
|
-
* - KICI_ env var mapping (config/env-overlay.ts)
|
|
4
|
+
* The runtime config reloader lives in config/: YAML files (config/loader.ts),
|
|
5
|
+
* the shared DB config store (config/shared-store.ts), the env overlay
|
|
6
|
+
* (config/env-overlay.ts) and the resolution chain (config/resolver.ts).
|
|
13
7
|
*
|
|
14
8
|
* Provider configuration (GitHub Apps, etc.) is managed via the `sources` table
|
|
15
9
|
* and PgSecretStore, not through config. See SourceStore and SourceManager.
|
|
@@ -122,7 +116,6 @@ declare const configSchema: z.ZodObject<{
|
|
|
122
116
|
filesystem: "filesystem";
|
|
123
117
|
s3: "s3";
|
|
124
118
|
}>>;
|
|
125
|
-
cacheStoragePath: z.ZodOptional<z.ZodString>;
|
|
126
119
|
cacheStorageS3Bucket: z.ZodOptional<z.ZodString>;
|
|
127
120
|
cacheStorageS3Prefix: z.ZodDefault<z.ZodString>;
|
|
128
121
|
cacheStorageS3Region: z.ZodOptional<z.ZodString>;
|
|
@@ -240,7 +233,6 @@ declare const configSchema: z.ZodObject<{
|
|
|
240
233
|
coordinator: "coordinator";
|
|
241
234
|
worker: "worker";
|
|
242
235
|
}>>;
|
|
243
|
-
coordinatorUrl: z.ZodOptional<z.ZodString>;
|
|
244
236
|
coordinatorUrls: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string[], string | undefined>>;
|
|
245
237
|
peerStaleTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
246
238
|
electionGracePeriodMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
@@ -340,7 +332,6 @@ export declare const packagingConfigSchema: z.ZodObject<{
|
|
|
340
332
|
filesystem: "filesystem";
|
|
341
333
|
s3: "s3";
|
|
342
334
|
}>>;
|
|
343
|
-
cacheStoragePath: z.ZodOptional<z.ZodString>;
|
|
344
335
|
cacheStorageS3Bucket: z.ZodOptional<z.ZodString>;
|
|
345
336
|
cacheStorageS3Prefix: z.ZodDefault<z.ZodString>;
|
|
346
337
|
cacheStorageS3Region: z.ZodOptional<z.ZodString>;
|
|
@@ -458,7 +449,6 @@ export declare const packagingConfigSchema: z.ZodObject<{
|
|
|
458
449
|
coordinator: "coordinator";
|
|
459
450
|
worker: "worker";
|
|
460
451
|
}>>;
|
|
461
|
-
coordinatorUrl: z.ZodOptional<z.ZodString>;
|
|
462
452
|
coordinatorUrls: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string[], string | undefined>>;
|
|
463
453
|
peerStaleTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
464
454
|
electionGracePeriodMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
@@ -479,7 +469,7 @@ export declare const packagingConfigSchema: z.ZodObject<{
|
|
|
479
469
|
export type AppConfig = z.infer<typeof configSchema> & {
|
|
480
470
|
/** Unique identifier for this orchestrator instance, generated at startup */
|
|
481
471
|
instanceId: string;
|
|
482
|
-
/** Object storage settings (populated from
|
|
472
|
+
/** Object storage settings (populated from the KICI_STORAGE_* env vars or SharedConfig) */
|
|
483
473
|
storage?: {
|
|
484
474
|
type?: 's3' | 'filesystem';
|
|
485
475
|
bucket?: string;
|
|
@@ -585,7 +575,6 @@ export declare const envDef: import("@kici-dev/shared/env").DefineEnvResult<{
|
|
|
585
575
|
scalerProvisionBackoffMaxMs: number;
|
|
586
576
|
scalerProvisionMaxConsecutiveFailures: number;
|
|
587
577
|
cacheStorageType?: "filesystem" | "s3" | undefined;
|
|
588
|
-
cacheStoragePath?: string | undefined;
|
|
589
578
|
cacheStorageS3Bucket?: string | undefined;
|
|
590
579
|
cacheStorageS3Prefix: string;
|
|
591
580
|
cacheStorageS3Region?: string | undefined;
|
|
@@ -676,7 +665,6 @@ export declare const envDef: import("@kici-dev/shared/env").DefineEnvResult<{
|
|
|
676
665
|
peerHeartbeatIntervalMs: number;
|
|
677
666
|
peerMaxReconnectDelayMs: number;
|
|
678
667
|
role: "coordinator" | "worker";
|
|
679
|
-
coordinatorUrl?: string | undefined;
|
|
680
668
|
coordinatorUrls: string[];
|
|
681
669
|
peerStaleTimeoutMs: number;
|
|
682
670
|
electionGracePeriodMs: number;
|
|
@@ -685,6 +673,14 @@ export declare const envDef: import("@kici-dev/shared/env").DefineEnvResult<{
|
|
|
685
673
|
trustedProxies: string[];
|
|
686
674
|
};
|
|
687
675
|
}>;
|
|
676
|
+
/**
|
|
677
|
+
* Load the startup orchestrator configuration from environment variables.
|
|
678
|
+
*
|
|
679
|
+
* It reads `process.env` through the names declared in `envDef`
|
|
680
|
+
* (KICI_DATABASE_URL, KICI_PORT, …) and refuses unknown `KICI_*` names. The
|
|
681
|
+
* config reloader (`config/resolver.ts`) layers the YAML file and the shared
|
|
682
|
+
* DB config store on top at runtime.
|
|
683
|
+
*/
|
|
688
684
|
export declare function loadConfig(scope?: ConfigScope): AppConfig;
|
|
689
685
|
export {};
|
|
690
686
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -279,12 +279,9 @@ export declare class HeldRunStore {
|
|
|
279
279
|
* incidental: `expireOverdue` is not scope-filtered, so a released-but-not-yet-
|
|
280
280
|
* resumed row would otherwise be expired out from under its resume.
|
|
281
281
|
*
|
|
282
|
-
* The filter
|
|
283
|
-
*
|
|
284
|
-
*
|
|
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.
|
|
282
|
+
* The filter deliberately does NOT filter on `hold_scope`: a job-scoped timer
|
|
283
|
+
* hold used to be excluded here, which left it with no release path at all —
|
|
284
|
+
* created, never released, eventually expired, its job never dispatched.
|
|
288
285
|
*/
|
|
289
286
|
releaseDueWaitHolds(): Promise<ReleaseSignal[]>;
|
|
290
287
|
/**
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opaque pagination cursors for the dashboard list handlers:
|
|
3
|
+
* base64url(JSON(fields)), every field a string.
|
|
4
|
+
*/
|
|
5
|
+
/** Encode `fields` as a cursor. Key order follows the object literal. */
|
|
6
|
+
export declare function encodeCursor(fields: Record<string, string>): string;
|
|
7
|
+
/**
|
|
8
|
+
* Decode a cursor into exactly `keys`. Returns null when the cursor is not
|
|
9
|
+
* base64url JSON or any key is missing or not a string; other keys are dropped.
|
|
10
|
+
*/
|
|
11
|
+
export declare function decodeCursor<K extends string>(raw: string, keys: readonly K[]): Record<K, string> | null;
|
|
12
|
+
//# sourceMappingURL=cursor.d.ts.map
|
|
@@ -14,7 +14,7 @@ interface DashboardHandlerDeps {
|
|
|
14
14
|
* The orchestrator's own provenance issuer (`KICI_ORCHESTRATOR_PROVENANCE_ISSUER`)
|
|
15
15
|
* when it owns signing. Surfaced on attestations-list responses so the Platform
|
|
16
16
|
* returns it as `trustedIssuer` — the dashboard / CLI verify against the
|
|
17
|
-
* orchestrator that
|
|
17
|
+
* orchestrator that signed the bundles.
|
|
18
18
|
*/
|
|
19
19
|
provenanceSigningIssuer?: string | null;
|
|
20
20
|
/**
|
|
@@ -127,6 +127,7 @@ export declare class DashboardHandler {
|
|
|
127
127
|
private readonly send;
|
|
128
128
|
private readonly orchestratorId;
|
|
129
129
|
private readonly accessLog;
|
|
130
|
+
private readonly access;
|
|
130
131
|
private orgId;
|
|
131
132
|
private routingKey;
|
|
132
133
|
private readonly onRerun;
|
|
@@ -142,7 +143,7 @@ export declare class DashboardHandler {
|
|
|
142
143
|
* Update the bound orgId + routingKey. Called from server.ts after resolving
|
|
143
144
|
* the single tenant org from the `sources` / `generic_webhook_sources` table.
|
|
144
145
|
*
|
|
145
|
-
* NOTE: this binding is the **fallback**
|
|
146
|
+
* NOTE: this binding is the **fallback** access_log scope. Run-targeted
|
|
146
147
|
* handlers resolve the run-owning org per-request via `resolveOrgForRun`;
|
|
147
148
|
* the bound pair is consulted only when the per-target lookup yields no
|
|
148
149
|
* result (e.g. cold-archived run, deleted source). On a multi-tenant
|
|
@@ -190,14 +191,6 @@ export declare class DashboardHandler {
|
|
|
190
191
|
* has the operation switched off.
|
|
191
192
|
*/
|
|
192
193
|
private enforcePolicy;
|
|
193
|
-
/**
|
|
194
|
-
* Write an access_log row for a handler invocation. The caller resolves
|
|
195
|
-
* the run-owning org via `resolveOrgForRun` (or the registration / event-
|
|
196
|
-
* log equivalents) and threads it in here so each row carries the org
|
|
197
|
-
* that owns the target — not the handler-bound (multi-tenant: non-
|
|
198
|
-
* deterministic) pair. Best-effort; the writer swallows failures.
|
|
199
|
-
*/
|
|
200
|
-
private recordAccess;
|
|
201
194
|
/**
|
|
202
195
|
* Handle a dashboard.run.detail request.
|
|
203
196
|
* Queries execution_jobs and execution_steps for the given runId,
|
|
@@ -337,14 +330,14 @@ export declare class DashboardHandler {
|
|
|
337
330
|
* Handle a dashboard.attestations.list request: list the run's provenance
|
|
338
331
|
* attestations, inlining each stored bundle from object storage so the
|
|
339
332
|
* dashboard verifies it client-side. Mirrors `handleStepLogs` (per-run org
|
|
340
|
-
* resolution + `
|
|
333
|
+
* resolution + `access.recordIn` + `send`). Rows whose bundle can't be read are
|
|
341
334
|
* skipped (best-effort) rather than failing the whole list.
|
|
342
335
|
*/
|
|
343
336
|
handleAttestationsList(msg: DashboardAttestationsListRequest): Promise<void>;
|
|
344
337
|
/**
|
|
345
338
|
* Handle a dashboard.artifacts.list request: list the run's named artifacts
|
|
346
339
|
* with a presigned GET per entry. Mirrors `handleAttestationsList` (per-run
|
|
347
|
-
* org resolution + `
|
|
340
|
+
* org resolution + `access.recordIn` + `send`). Org is resolved server-side from
|
|
348
341
|
* the run row, never the wire, so the listing cannot cross tenants.
|
|
349
342
|
*/
|
|
350
343
|
handleArtifactsList(msg: DashboardArtifactsListRequest): Promise<void>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds the deferred indexes (`deferred-indexes.ts`) after boot, each one
|
|
3
|
+
* `CONCURRENTLY` on its own connection.
|
|
4
|
+
*/
|
|
5
|
+
import type pg from 'pg';
|
|
6
|
+
import { type Logger } from '@kici-dev/shared';
|
|
7
|
+
import { type DeferredIndex } from './deferred-indexes.js';
|
|
8
|
+
/**
|
|
9
|
+
* Distinct from the migrator's `543210001`: an index build must not block, or
|
|
10
|
+
* be blocked by, a peer applying migrations.
|
|
11
|
+
*/
|
|
12
|
+
export declare const DEFERRED_INDEX_LOCK_KEY = 543210002;
|
|
13
|
+
/**
|
|
14
|
+
* Drop a leftover invalid index before rebuilding it.
|
|
15
|
+
*
|
|
16
|
+
* An interrupted `CREATE INDEX CONCURRENTLY` leaves the index in place marked
|
|
17
|
+
* invalid: it is not used by the planner, and `IF NOT EXISTS` sees it and
|
|
18
|
+
* skips. Without this, the very first failed build would make the retry a
|
|
19
|
+
* permanent no-op — the opposite of the "retries on the next boot" contract.
|
|
20
|
+
*/
|
|
21
|
+
export declare function dropIfInvalid(client: Pick<pg.Client, 'query'>, name: string, logger: Logger): Promise<void>;
|
|
22
|
+
export interface BuildDeferredIndexesResult {
|
|
23
|
+
built: string[];
|
|
24
|
+
failed: string[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build every deferred index on one dedicated connection.
|
|
28
|
+
*
|
|
29
|
+
* The connection is taken straight from `pg` rather than from the serving
|
|
30
|
+
* pool: `CREATE INDEX CONCURRENTLY` must run outside a transaction and must
|
|
31
|
+
* not inherit a statement timeout, and a concurrent build on a large table
|
|
32
|
+
* would otherwise hold a serving connection for its whole duration.
|
|
33
|
+
*
|
|
34
|
+
* The advisory lock is `pg_try_advisory_lock`, not the blocking form: when a
|
|
35
|
+
* peer is already building, this instance has nothing to wait for.
|
|
36
|
+
*/
|
|
37
|
+
export declare function buildDeferredIndexes(databaseUrl: string, opts?: {
|
|
38
|
+
logger?: Logger;
|
|
39
|
+
indexes?: ReadonlyArray<DeferredIndex>;
|
|
40
|
+
pg?: typeof import('pg');
|
|
41
|
+
}): Promise<BuildDeferredIndexesResult>;
|
|
42
|
+
//# sourceMappingURL=deferred-index-build.d.ts.map
|
|
@@ -16,15 +16,10 @@
|
|
|
16
16
|
* a failed build retries on the next boot.
|
|
17
17
|
*
|
|
18
18
|
* A repository check enforces that new indexes on those tables land here
|
|
19
|
-
* rather than in a migration.
|
|
19
|
+
* rather than in a migration. The build itself is `deferred-index-build.ts`;
|
|
20
|
+
* this module holds only the list, so a CLI can read it without loading the
|
|
21
|
+
* orchestrator's metrics.
|
|
20
22
|
*/
|
|
21
|
-
import type pg from 'pg';
|
|
22
|
-
import { type Logger } from '@kici-dev/shared';
|
|
23
|
-
/**
|
|
24
|
-
* Distinct from the migrator's `543210001`: an index build must not block, or
|
|
25
|
-
* be blocked by, a peer applying migrations.
|
|
26
|
-
*/
|
|
27
|
-
export declare const DEFERRED_INDEX_LOCK_KEY = 543210002;
|
|
28
23
|
export interface DeferredIndex {
|
|
29
24
|
/** Index name, matching the one the SQL creates. */
|
|
30
25
|
name: string;
|
|
@@ -40,33 +35,4 @@ export interface DeferredIndex {
|
|
|
40
35
|
* prefixed by an organization or routing key.
|
|
41
36
|
*/
|
|
42
37
|
export declare const DEFERRED_INDEXES: ReadonlyArray<DeferredIndex>;
|
|
43
|
-
/**
|
|
44
|
-
* Drop a leftover invalid index before rebuilding it.
|
|
45
|
-
*
|
|
46
|
-
* An interrupted `CREATE INDEX CONCURRENTLY` leaves the index in place marked
|
|
47
|
-
* invalid: it is not used by the planner, and `IF NOT EXISTS` sees it and
|
|
48
|
-
* skips. Without this, the very first failed build would make the retry a
|
|
49
|
-
* permanent no-op — the opposite of the "retries on the next boot" contract.
|
|
50
|
-
*/
|
|
51
|
-
export declare function dropIfInvalid(client: Pick<pg.Client, 'query'>, name: string, logger: Logger): Promise<void>;
|
|
52
|
-
export interface BuildDeferredIndexesResult {
|
|
53
|
-
built: string[];
|
|
54
|
-
failed: string[];
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Build every deferred index on one dedicated connection.
|
|
58
|
-
*
|
|
59
|
-
* The connection is taken straight from `pg` rather than from the serving
|
|
60
|
-
* pool: `CREATE INDEX CONCURRENTLY` must run outside a transaction and must
|
|
61
|
-
* not inherit a statement timeout, and a concurrent build on a large table
|
|
62
|
-
* would otherwise hold a serving connection for its whole duration.
|
|
63
|
-
*
|
|
64
|
-
* The advisory lock is `pg_try_advisory_lock`, not the blocking form: when a
|
|
65
|
-
* peer is already building, this instance has nothing to wait for.
|
|
66
|
-
*/
|
|
67
|
-
export declare function buildDeferredIndexes(databaseUrl: string, opts?: {
|
|
68
|
-
logger?: Logger;
|
|
69
|
-
indexes?: ReadonlyArray<DeferredIndex>;
|
|
70
|
-
pg?: typeof import('pg');
|
|
71
|
-
}): Promise<BuildDeferredIndexesResult>;
|
|
72
38
|
//# sourceMappingURL=deferred-indexes.d.ts.map
|
|
@@ -8,11 +8,9 @@ import { type Kysely } from 'kysely';
|
|
|
8
8
|
* unknown-type badge — and two semantically identical wait holds render
|
|
9
9
|
* differently depending on which gate produced them.
|
|
10
10
|
*
|
|
11
|
-
* Writers emit the gate vocabulary; this backfills the history.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* orchestrator behaves correctly whether or not this has run — the two sides
|
|
15
|
-
* deploy independently.
|
|
11
|
+
* Writers emit the gate vocabulary; this backfills the history. Migration 158
|
|
12
|
+
* re-applies the same rewrite, after which the readers match the gate
|
|
13
|
+
* vocabulary only.
|
|
16
14
|
*
|
|
17
15
|
* Idempotent: a second run matches no rows.
|
|
18
16
|
*/
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The org ids this orchestrator holds data for, and which data names each one.
|
|
3
|
+
*
|
|
4
|
+
* The org-scoped kici-admin commands (`secret`, `context`, `variable`,
|
|
5
|
+
* `remote-source`, `org-settings`, `trust-policy`, `registration`) take an org
|
|
6
|
+
* id. This module answers "which org ids exist here" from the configuration and
|
|
7
|
+
* anchor tables, for both `GET /api/v1/admin/org-ids` and
|
|
8
|
+
* `kici-admin org list --database-url`, so the two transports cannot disagree.
|
|
9
|
+
*/
|
|
10
|
+
import { type Kysely } from 'kysely';
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
import type { Database } from '../types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Where an org id was found. `platform` is the live Platform connection, which
|
|
15
|
+
* only the admin API can see; every other value names a table.
|
|
16
|
+
*/
|
|
17
|
+
export declare const OrgIdSource: z.ZodEnum<{
|
|
18
|
+
context: "context";
|
|
19
|
+
"generic-source": "generic-source";
|
|
20
|
+
"org-settings": "org-settings";
|
|
21
|
+
platform: "platform";
|
|
22
|
+
registration: "registration";
|
|
23
|
+
"remote-source": "remote-source";
|
|
24
|
+
secret: "secret";
|
|
25
|
+
source: "source";
|
|
26
|
+
"trust-policy": "trust-policy";
|
|
27
|
+
}>;
|
|
28
|
+
export type OrgIdSource = z.infer<typeof OrgIdSource>;
|
|
29
|
+
/**
|
|
30
|
+
* The orchestrator's Platform attachment: `attached` once the Platform named
|
|
31
|
+
* the org on `auth.success`, `pending` while a Platform client has not
|
|
32
|
+
* authenticated yet, `none` when no Platform client runs (independent mode).
|
|
33
|
+
*/
|
|
34
|
+
export declare const PlatformAttachment: z.ZodEnum<{
|
|
35
|
+
attached: "attached";
|
|
36
|
+
none: "none";
|
|
37
|
+
pending: "pending";
|
|
38
|
+
}>;
|
|
39
|
+
export type PlatformAttachment = z.infer<typeof PlatformAttachment>;
|
|
40
|
+
/** One org id and the data that names it. */
|
|
41
|
+
export interface HeldOrg {
|
|
42
|
+
orgId: string;
|
|
43
|
+
sources: OrgIdSource[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Body of `GET /api/v1/admin/org-ids`. The two Platform fields are absent when the
|
|
47
|
+
* listing was read from the database directly: only the running orchestrator
|
|
48
|
+
* knows its connection.
|
|
49
|
+
*/
|
|
50
|
+
export interface OrgListResponse {
|
|
51
|
+
platformAttachment?: PlatformAttachment;
|
|
52
|
+
attachedOrgId?: string | null;
|
|
53
|
+
orgs: HeldOrg[];
|
|
54
|
+
}
|
|
55
|
+
/** The admin API path of the listing. */
|
|
56
|
+
export declare const ORG_LIST_PATH = "/api/v1/admin/org-ids";
|
|
57
|
+
interface OrgIdTable {
|
|
58
|
+
table: keyof Database;
|
|
59
|
+
column: 'org_id' | 'customer_id';
|
|
60
|
+
source: Exclude<OrgIdSource, 'platform'>;
|
|
61
|
+
/** Skip soft-deleted rows (`deleted_at IS NULL`). */
|
|
62
|
+
liveOnly?: boolean;
|
|
63
|
+
}
|
|
64
|
+
/** The configuration and anchor tables an org-scoped command reads by org id. */
|
|
65
|
+
export declare const ORG_ID_TABLES: readonly OrgIdTable[];
|
|
66
|
+
/**
|
|
67
|
+
* Every other table with an `org_id` or `customer_id` column, and why the
|
|
68
|
+
* listing does not read it. A schema test fails when a migration adds an
|
|
69
|
+
* org-keyed table that is in neither this map nor {@link ORG_ID_TABLES}.
|
|
70
|
+
*/
|
|
71
|
+
export declare const ORG_ID_TABLES_NOT_LISTED: Readonly<Record<string, string>>;
|
|
72
|
+
/** Group `(org id, source)` rows per org: org ids in byte order, sources in enum order. */
|
|
73
|
+
export declare function groupOrgIdRows(rows: ReadonlyArray<{
|
|
74
|
+
org_id: string;
|
|
75
|
+
source: OrgIdSource;
|
|
76
|
+
}>): HeldOrg[];
|
|
77
|
+
/** Add the Platform-attached org to a listing, with the `platform` source. */
|
|
78
|
+
export declare function withPlatformOrg(orgs: readonly HeldOrg[], attachedOrgId: string | null): HeldOrg[];
|
|
79
|
+
/** The attachment the admin API reports, from the Platform client's org id reader. */
|
|
80
|
+
export declare function readPlatformAttachment(getPlatformOrgId: (() => string | undefined) | undefined): {
|
|
81
|
+
platformAttachment: PlatformAttachment;
|
|
82
|
+
attachedOrgId: string | null;
|
|
83
|
+
};
|
|
84
|
+
/** Every org id the listed tables hold, in one round trip. */
|
|
85
|
+
export declare function listHeldOrgIds(db: Kysely<Database>): Promise<HeldOrg[]>;
|
|
86
|
+
export {};
|
|
87
|
+
//# sourceMappingURL=org-ids-repo.d.ts.map
|
package/dist/db/types.d.ts
CHANGED
|
@@ -1212,8 +1212,7 @@ export interface HeldRunsTable {
|
|
|
1212
1212
|
/**
|
|
1213
1213
|
* Hold type — an engine `HoldType` member ('reviewer' | 'timer' |
|
|
1214
1214
|
* 'concurrency' | 'security'). Stays `string` so a row written by a
|
|
1215
|
-
* different orchestrator version is never rejected
|
|
1216
|
-
* `normalizePersistedHoldType`.
|
|
1215
|
+
* different orchestrator version is never rejected.
|
|
1217
1216
|
*/
|
|
1218
1217
|
hold_type: string;
|
|
1219
1218
|
/** Hold status: 'pending' | 'approved' | 'rejected' | 'expired' | 'released' */
|
|
@@ -1244,7 +1243,8 @@ export interface HeldRunsTable {
|
|
|
1244
1243
|
trigger_source: Generated<string>;
|
|
1245
1244
|
/**
|
|
1246
1245
|
* Normalized `ApprovalRequirement` (clauses + expiresAt + reason) the hold
|
|
1247
|
-
* must satisfy. Null for
|
|
1246
|
+
* must satisfy. Null for a hold with no requirement: security, wait and queue
|
|
1247
|
+
* holds, which `security-hold-check.ts` tells apart on this column.
|
|
1248
1248
|
*/
|
|
1249
1249
|
approval_requirement: ColumnType<ApprovalRequirement | null, ApprovalRequirement | string | null | undefined, ApprovalRequirement | string | null>;
|
|
1250
1250
|
/**
|
|
@@ -2082,25 +2082,8 @@ export interface OrgTrustPolicyTable {
|
|
|
2082
2082
|
customer_id: string;
|
|
2083
2083
|
/** How to treat a pull request opened from a fork: ignore | hold | allow */
|
|
2084
2084
|
fork_policy: string;
|
|
2085
|
-
/**
|
|
2086
|
-
|
|
2087
|
-
*
|
|
2088
|
-
* Retained and always written, because it is the only window an older peer or
|
|
2089
|
-
* CLI can read. This build derives it from `approval_expiry_seconds` on every
|
|
2090
|
-
* write (rounded up, never below 1), so the two columns cannot disagree.
|
|
2091
|
-
*/
|
|
2092
|
-
approval_expiry_hours: number;
|
|
2093
|
-
/**
|
|
2094
|
-
* How long a security hold stays approvable before it expires, in seconds —
|
|
2095
|
-
* the authoritative window, and the only granularity that can express a
|
|
2096
|
-
* sub-hour hold.
|
|
2097
|
-
*
|
|
2098
|
-
* Nullable: NULL means no seconds value was ever written (a row predating the
|
|
2099
|
-
* column, or one written by an older build), and every reader falls back to
|
|
2100
|
-
* `approval_expiry_hours * 3600`. Same convention as
|
|
2101
|
-
* `contexts.hold_expiry_seconds`.
|
|
2102
|
-
*/
|
|
2103
|
-
approval_expiry_seconds: ColumnType<number | null, number | null | undefined, number | null>;
|
|
2085
|
+
/** How long a security hold stays approvable before it expires, in seconds. */
|
|
2086
|
+
approval_expiry_seconds: number;
|
|
2104
2087
|
/** Which side last wrote this row: platform | local */
|
|
2105
2088
|
source: string;
|
|
2106
2089
|
/** When this policy was last written */
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
* TS2307s. Only the declaration lives here — its one dependency is a type from
|
|
10
10
|
* `@kici-dev/engine`, so nothing test-only is pulled along with it.
|
|
11
11
|
*/
|
|
12
|
-
import type { OrchCapabilities } from '@kici-dev/engine';
|
|
13
12
|
/**
|
|
14
13
|
* The set of synthetic faults a test-only entrypoint can inject into the
|
|
15
14
|
* orchestrator. Every field is optional: an absent field means "no fault at
|
|
@@ -44,10 +43,5 @@ export interface OrchestratorFaultInjection {
|
|
|
44
43
|
* the first coordinator slow enough that the Platform relay fails over.
|
|
45
44
|
*/
|
|
46
45
|
beforeRerun?: () => Promise<void>;
|
|
47
|
-
/**
|
|
48
|
-
* Transform the advertised capability manifest — used to reproduce an older
|
|
49
|
-
* / sourceless orchestrator that predates a given dashboard capability.
|
|
50
|
-
*/
|
|
51
|
-
capabilitiesTransform?: (c: OrchCapabilities) => OrchCapabilities;
|
|
52
46
|
}
|
|
53
47
|
//# sourceMappingURL=fault-injection-types.d.ts.map
|
|
@@ -2,21 +2,15 @@ import type { ProviderGitAuth } from '@kici-dev/engine';
|
|
|
2
2
|
import type { ProviderBundle, ProviderRegistry } from '../provider-registry.js';
|
|
3
3
|
/** Auth the dispatch message carries; every field is optional on the wire. */
|
|
4
4
|
export interface DispatchCloneAuth {
|
|
5
|
-
/** Bare source-repository token, kept for agents that read only `token`. */
|
|
6
|
-
token?: string;
|
|
7
5
|
sourceAuth?: ProviderGitAuth;
|
|
8
6
|
workflowAuth?: ProviderGitAuth;
|
|
9
7
|
}
|
|
10
8
|
/**
|
|
11
|
-
* Mint structured auth
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* basic-auth envelope.
|
|
9
|
+
* Mint structured auth for one repository through one bundle. Providers that
|
|
10
|
+
* implement `issueGitAuth()` return the auth kind directly; otherwise a clone
|
|
11
|
+
* token is wrapped in a basic-auth envelope.
|
|
15
12
|
*/
|
|
16
|
-
export declare function mintRepoGitAuth(bundle: ProviderBundle, repoIdentifier: string, providerContext: unknown): Promise<
|
|
17
|
-
token: string | null;
|
|
18
|
-
structuredAuth: ProviderGitAuth | null;
|
|
19
|
-
}>;
|
|
13
|
+
export declare function mintRepoGitAuth(bundle: ProviderBundle, repoIdentifier: string, providerContext: unknown): Promise<ProviderGitAuth | null>;
|
|
20
14
|
/** The job fields the auth resolution reads. */
|
|
21
15
|
export interface DispatchAuthJob {
|
|
22
16
|
id: string;
|
|
@@ -35,8 +29,8 @@ export declare function gitHostOf(url: string): string | undefined;
|
|
|
35
29
|
* it may.
|
|
36
30
|
*
|
|
37
31
|
* The agent falls back across the two clones: it clones the source repository
|
|
38
|
-
* with `sourceAuth ?? workflowAuth
|
|
39
|
-
* `workflowAuth ?? sourceAuth
|
|
32
|
+
* with `sourceAuth ?? workflowAuth` and the workflow repository with
|
|
33
|
+
* `workflowAuth ?? sourceAuth`. When only one repository's credential is
|
|
40
34
|
* present, the other clone sends it to that repository's host. On the same host
|
|
41
35
|
* that is a credential the host issued; on another host it hands one provider's
|
|
42
36
|
* credential to another, so the job is refused instead. A job with no source URL
|