@kici-dev/orchestrator 0.1.23 → 0.1.25
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/agent/token-store.d.ts +4 -0
- package/dist/app.d.ts +27 -0
- package/dist/audit/access-log.d.ts +4 -0
- package/dist/cache/pending-inits.d.ts +3 -2
- package/dist/cancel/cancel-run.d.ts +2 -0
- package/dist/cli/api-client.d.ts +10 -0
- package/dist/cli/commands/attestations-list.d.ts +49 -0
- package/dist/cli/commands/attestations-retry.d.ts +28 -0
- package/dist/cli/commands/attestations-reverify.d.ts +18 -0
- package/dist/cli/commands/attestations.d.ts +4 -0
- package/dist/cli/commands/cluster.d.ts +3 -0
- package/dist/cli/commands/shared/versioned-upgrade.d.ts +52 -0
- package/dist/cli/local-github-ingress-url.d.ts +8 -0
- package/dist/cli.js +3308 -1011
- package/dist/cluster/cluster-identity.d.ts +11 -0
- package/dist/cluster/reconcile-identity.d.ts +50 -0
- package/dist/cold-store/load-access-log-range.d.ts +4 -0
- package/dist/config.d.ts +4 -0
- package/dist/dashboard/attestation-filters.d.ts +131 -0
- package/dist/dashboard/handler.d.ts +56 -4
- package/dist/db/migrations/054_local_working_tree.d.ts +15 -0
- package/dist/db/migrations/055_agent_token_mandatory_labels.d.ts +18 -0
- package/dist/db/migrations/056_execution_jobs_environments.d.ts +17 -0
- package/dist/db/migrations/057_step_concurrency.d.ts +4 -0
- package/dist/db/migrations/058_access_log_agent_label.d.ts +4 -0
- package/dist/db/migrations/059_attestation_verdict.d.ts +4 -0
- package/dist/db/migrations/060_run_trigger_actor.d.ts +4 -0
- package/dist/db/migrations/061_execution_runs_environment_id.d.ts +4 -0
- package/dist/db/migrations/062_execution_runs_agent_label.d.ts +4 -0
- package/dist/db/migrations/063_access_log_agent_label_index.d.ts +10 -0
- package/dist/db/migrations/064_execution_jobs_skipped_environments.d.ts +17 -0
- package/dist/db/migrations/065_pending_attestations.d.ts +22 -0
- package/dist/db/migrations/066_pending_attestations_rejected.d.ts +13 -0
- package/dist/db/types.d.ts +113 -0
- package/dist/environments/protection/aggregate.d.ts +43 -0
- package/dist/environments/protection/satisfiability.d.ts +69 -0
- package/dist/events/circuit-breaker.d.ts +8 -5
- package/dist/events/event-router.d.ts +12 -4
- package/dist/events/event-store.d.ts +21 -3
- package/dist/events/trust-store.d.ts +6 -1
- package/dist/events/types.d.ts +6 -1
- package/dist/helpers/rate-limiter.d.ts +17 -2
- package/dist/index.js +11 -1
- package/dist/metrics/prometheus.d.ts +6 -0
- package/dist/orchestrator-core.d.ts +8 -0
- package/dist/pipeline/dispatch-matched-workflow.d.ts +8 -0
- package/dist/pipeline/flatten-lock-steps.d.ts +11 -0
- package/dist/pipeline/inline-eval.d.ts +2 -1
- package/dist/pipeline/job-environments.d.ts +71 -0
- package/dist/pipeline/manual-schedule.d.ts +23 -1
- package/dist/pipeline/process-webhook.d.ts +14 -1
- package/dist/pipeline/rerun.d.ts +1 -1
- package/dist/pipeline/test-pipeline.d.ts +15 -0
- package/dist/provenance/attestation-retrier.d.ts +92 -0
- package/dist/provenance/backfill-run.d.ts +41 -0
- package/dist/provenance/pending-attestations-repo.d.ts +64 -0
- package/dist/provenance/trust-root.d.ts +24 -0
- package/dist/provenance/verify-at-ingest.d.ts +31 -0
- package/dist/reporting/agent-failure-category.d.ts +27 -0
- package/dist/reporting/agent-run-result-mapper.d.ts +13 -0
- package/dist/reporting/execution-tracker.d.ts +38 -6
- package/dist/reporting/run-aggregator.d.ts +165 -0
- package/dist/reporting/step-log-reader.d.ts +39 -0
- package/dist/routes/admin-access-log.d.ts +2 -1
- package/dist/routes/admin-registrations.d.ts +8 -0
- package/dist/routes/admin-runs.d.ts +7 -0
- package/dist/routes/admin.d.ts +14 -0
- package/dist/routes/github-webhook.d.ts +37 -0
- package/dist/routes/health.d.ts +9 -0
- package/dist/routes/webhooks.d.ts +2 -4
- package/dist/secrets/index.d.ts +1 -1
- package/dist/server.js +5326 -2100
- package/dist/sources/source-store.d.ts +6 -0
- package/dist/stale-detector/workflow-deadline-detector.d.ts +25 -0
- package/dist/standalone.js +19787 -17304
- package/dist/storage/loopback-guard.d.ts +49 -0
- package/dist/webhook/dedup.d.ts +14 -0
- package/dist/ws/agent-handler.d.ts +38 -1
- package/dist/ws/oidc-token-relay.d.ts +31 -21
- package/dist/ws/orch-rpc.d.ts +9 -0
- package/dist/ws/platform-client.d.ts +53 -1
- package/dist/ws/test-relay-handlers.d.ts +2 -0
- package/installer-image-digests.json +3 -3
- package/package.json +6 -8
- package/sbom.spdx.json +62 -57
- package/dist/secrets/crypto.d.ts +0 -49
|
@@ -29,6 +29,17 @@ export interface ClusterIdentityDeps {
|
|
|
29
29
|
*/
|
|
30
30
|
skipSentinelValidation?: boolean;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Default cache-storage S3 prefix (mirrors the orchestrator config
|
|
34
|
+
* `cacheStorageS3Prefix` default). Empty means the cache blobs and the
|
|
35
|
+
* cluster-identity sentinel live at the bucket root — the bucket already scopes
|
|
36
|
+
* the cluster. Every place that resolves a sentinel prefix (the orchestrator
|
|
37
|
+
* runtime, the `kici-admin cluster reconcile-identity` CLI, and the staging
|
|
38
|
+
* deploy's self-heal step) MUST fall back to THIS value when no explicit prefix
|
|
39
|
+
* is set, otherwise they compute divergent sentinel keys and crash-loop the
|
|
40
|
+
* orchestrator boot on a spurious "Cluster identity mismatch".
|
|
41
|
+
*/
|
|
42
|
+
export declare const DEFAULT_CACHE_STORAGE_S3_PREFIX = "";
|
|
32
43
|
/**
|
|
33
44
|
* Build the S3 key for the cluster identity sentinel under an optional prefix.
|
|
34
45
|
* Strips any trailing slash from the prefix so callers can pass either form.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { IdempotentStep } from '@kici-dev/shared/idempotency';
|
|
2
|
+
export type ReconcileDirection = 'db-from-sentinel' | 'sentinel-from-db';
|
|
3
|
+
export interface ReconcileS3Config {
|
|
4
|
+
bucket: string;
|
|
5
|
+
/**
|
|
6
|
+
* Optional storage prefix (mirrors `KICI_STORAGE_PREFIX`). The sentinel lives
|
|
7
|
+
* at `<prefix>/.kici-cluster-id`; must match the prefix the orchestrator boots
|
|
8
|
+
* with. When omitted, `clusterSentinelKey` resolves the bucket root — the same
|
|
9
|
+
* as the orchestrator's `DEFAULT_CACHE_STORAGE_S3_PREFIX` (empty) default.
|
|
10
|
+
*/
|
|
11
|
+
prefix?: string;
|
|
12
|
+
region?: string;
|
|
13
|
+
endpoint?: string;
|
|
14
|
+
forcePathStyle?: boolean;
|
|
15
|
+
accessKeyId: string;
|
|
16
|
+
secretAccessKey: string;
|
|
17
|
+
}
|
|
18
|
+
export interface IdentityDrift {
|
|
19
|
+
dbClusterId: string | null;
|
|
20
|
+
sentinelClusterId: string | null;
|
|
21
|
+
direction: ReconcileDirection;
|
|
22
|
+
}
|
|
23
|
+
declare function readClusterIdFromDb(databaseUrl: string): Promise<string | null>;
|
|
24
|
+
declare function writeClusterIdToDb(databaseUrl: string, clusterId: string): Promise<void>;
|
|
25
|
+
declare function readSentinel(s3: ReconcileS3Config): Promise<string | null>;
|
|
26
|
+
declare function writeSentinel(s3: ReconcileS3Config, clusterId: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Indirection object for the DB + S3 reads/writes, so the unit test can stub
|
|
29
|
+
* the I/O without an ESM partial-mock dance. `buildReconcileStep` calls every
|
|
30
|
+
* reader/writer through this object; the test overrides its members directly.
|
|
31
|
+
*/
|
|
32
|
+
export declare const reconcileIo: {
|
|
33
|
+
readClusterIdFromDb: typeof readClusterIdFromDb;
|
|
34
|
+
writeClusterIdToDb: typeof writeClusterIdToDb;
|
|
35
|
+
readSentinel: typeof readSentinel;
|
|
36
|
+
writeSentinel: typeof writeSentinel;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Build the idempotent step that reconciles the cluster identity in the given
|
|
40
|
+
* direction. `check()` returns drift when the two sides disagree (or null when
|
|
41
|
+
* in sync); `apply()` performs the single write that brings them into
|
|
42
|
+
* agreement. Run it through `runIdempotentStep` (`@kici-dev/core/idempotency`).
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildReconcileStep(deps: {
|
|
45
|
+
databaseUrl: string;
|
|
46
|
+
s3: ReconcileS3Config;
|
|
47
|
+
direction: ReconcileDirection;
|
|
48
|
+
}): IdempotentStep<IdentityDrift>;
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=reconcile-identity.d.ts.map
|
|
@@ -52,6 +52,10 @@ export interface LoadAccessLogRangeArgs {
|
|
|
52
52
|
* `009_access_log_trigram.ts`. Min ~3 chars for the index to help.
|
|
53
53
|
*/
|
|
54
54
|
q?: string;
|
|
55
|
+
/** Exact-match filter on the agent provenance label (`agent_label` column). */
|
|
56
|
+
agentLabel?: string;
|
|
57
|
+
/** When true, return only agent-attributed rows (`agent_label IS NOT NULL`). */
|
|
58
|
+
agentOnly?: boolean;
|
|
55
59
|
};
|
|
56
60
|
limit: number;
|
|
57
61
|
cursor?: string;
|
package/dist/config.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
27
27
|
platformUrl: z.ZodOptional<z.ZodString>;
|
|
28
28
|
platformToken: z.ZodOptional<z.ZodString>;
|
|
29
29
|
dashboardUrl: z.ZodOptional<z.ZodString>;
|
|
30
|
+
provenanceIssuer: z.ZodOptional<z.ZodString>;
|
|
30
31
|
webhookPublicUrl: z.ZodOptional<z.ZodString>;
|
|
31
32
|
databaseUrl: z.ZodDefault<z.ZodString>;
|
|
32
33
|
lockfileCacheMax: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
@@ -99,6 +100,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
99
100
|
eventRouterRetryScanIntervalMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
100
101
|
testMode: z.ZodPipe<z.ZodDefault<z.ZodString>, z.ZodTransform<boolean, string>>;
|
|
101
102
|
testEventFailFirstN: z.ZodOptional<z.ZodString>;
|
|
103
|
+
testMintDeferAudience: z.ZodOptional<z.ZodString>;
|
|
102
104
|
eventLogMaxPayloadBytes: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
103
105
|
logLevel: z.ZodDefault<z.ZodEnum<{
|
|
104
106
|
error: "error";
|
|
@@ -248,6 +250,7 @@ export declare const envDef: import("@kici-dev/shared/env").DefineEnvResult<{
|
|
|
248
250
|
platformUrl?: string | undefined;
|
|
249
251
|
platformToken?: string | undefined;
|
|
250
252
|
dashboardUrl?: string | undefined;
|
|
253
|
+
provenanceIssuer?: string | undefined;
|
|
251
254
|
webhookPublicUrl?: string | undefined;
|
|
252
255
|
cacheStorageType?: "s3" | "filesystem" | undefined;
|
|
253
256
|
cacheStoragePath?: string | undefined;
|
|
@@ -272,6 +275,7 @@ export declare const envDef: import("@kici-dev/shared/env").DefineEnvResult<{
|
|
|
272
275
|
bootstrapAdminToken?: string | undefined;
|
|
273
276
|
orchestratorHostAgentId?: string | undefined;
|
|
274
277
|
testEventFailFirstN?: string | undefined;
|
|
278
|
+
testMintDeferAudience?: string | undefined;
|
|
275
279
|
otelExporterOtlpEndpoint?: string | undefined;
|
|
276
280
|
clusterName?: string | undefined;
|
|
277
281
|
}>;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
import type { AttestationListFilters } from '@kici-dev/engine';
|
|
3
|
+
import type { Database } from '../db/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* The org-wide attestations base query: joins `attestations` to `execution_jobs`
|
|
6
|
+
* (for the job name) and `execution_runs` (for repository / workflow context).
|
|
7
|
+
*
|
|
8
|
+
* `attestations.run_id` / `job_id` are TEXT (P1.5 schema) while the
|
|
9
|
+
* `execution_*` keys are `uuid`; Postgres won't compare `uuid = text` implicitly,
|
|
10
|
+
* so the join casts the uuid side to text — mirroring `resolveAttestationsForRun`.
|
|
11
|
+
* The `execution_runs` join is a LEFT join so a row with no matching run still
|
|
12
|
+
* lists (repository / workflow come back null).
|
|
13
|
+
*/
|
|
14
|
+
export declare function baseAttestationsQuery(db: Kysely<Database>): import("kysely").SelectQueryBuilder<{
|
|
15
|
+
cluster_meta: import("../db/types.js").ClusterMetaTable;
|
|
16
|
+
environments: import("../db/types.js").EnvironmentsTable;
|
|
17
|
+
host_roster: import("../db/types.js").HostRosterTable;
|
|
18
|
+
dispatch_queue: import("../db/types.js").DispatchQueueTable;
|
|
19
|
+
dedup_cache: import("../db/types.js").DedupCacheTable;
|
|
20
|
+
ip_allocations: import("../db/types.js").IpAllocationTable;
|
|
21
|
+
execution_runs: import("kysely").Nullable<import("../db/types.js").ExecutionRunTable>;
|
|
22
|
+
execution_jobs: import("../db/types.js").ExecutionJobTable;
|
|
23
|
+
execution_steps: import("../db/types.js").ExecutionStepTable;
|
|
24
|
+
raft_state: import("../db/types.js").RaftStateTable;
|
|
25
|
+
secret_audit_log: import("../db/types.js").SecretAuditLogTable;
|
|
26
|
+
scoped_secrets: import("../db/types.js").ScopedSecretsTable;
|
|
27
|
+
environment_bindings: import("../db/types.js").EnvironmentBindingsTable;
|
|
28
|
+
environment_variables: import("../db/types.js").EnvironmentVariablesTable;
|
|
29
|
+
environment_source_overrides: import("../db/types.js").EnvironmentSourceOverridesTable;
|
|
30
|
+
held_runs: import("../db/types.js").HeldRunsTable;
|
|
31
|
+
held_run_approvals: import("../db/types.js").HeldRunApprovalsTable;
|
|
32
|
+
admin_tokens: import("../db/types.js").AdminTokenTable;
|
|
33
|
+
agent_tokens: import("../db/types.js").AgentTokenTable;
|
|
34
|
+
config_versions: import("../db/types.js").ConfigVersionTable;
|
|
35
|
+
kici_events: import("../db/types.js").KiciEventTable;
|
|
36
|
+
generic_webhook_sources: import("../db/types.js").GenericWebhookSourceTable;
|
|
37
|
+
cross_repo_trust: import("../db/types.js").CrossRepoTrustTable;
|
|
38
|
+
test_uploads: import("../db/types.js").TestUploadsTable;
|
|
39
|
+
workflow_registrations: import("../db/types.js").WorkflowRegistrationsTable;
|
|
40
|
+
registry_versions: import("../db/types.js").RegistryVersionsTable;
|
|
41
|
+
cron_last_fired: import("../db/types.js").CronLastFiredTable;
|
|
42
|
+
run_ephemeral_keys: import("../db/types.js").RunEphemeralKeysTable;
|
|
43
|
+
run_secret_outputs: import("../db/types.js").RunSecretOutputsTable;
|
|
44
|
+
concurrency_groups: import("../db/types.js").ConcurrencyGroupsTable;
|
|
45
|
+
sources: import("../db/types.js").SourcesTable;
|
|
46
|
+
join_tokens: import("../db/types.js").JoinTokenTable;
|
|
47
|
+
org_settings: import("../db/types.js").OrgSettingsTable;
|
|
48
|
+
execution_job_needs: import("../db/types.js").ExecutionJobNeedsTable;
|
|
49
|
+
pending_job_contexts: import("../db/types.js").PendingJobContextsTable;
|
|
50
|
+
pending_workflow_contexts: import("../db/types.js").PendingWorkflowContextsTable;
|
|
51
|
+
event_log: import("../db/types.js").EventLogTable;
|
|
52
|
+
access_log: import("../db/types.js").AccessLogTable;
|
|
53
|
+
cold_store_chunk_counts: import("../db/types.js").ColdStoreChunkCountsTable;
|
|
54
|
+
cold_store_chunks: import("../db/types.js").ColdStoreChunksTable;
|
|
55
|
+
check_run_tracking: import("../db/types.js").CheckRunTrackingTable;
|
|
56
|
+
scaler_spawning_agents: import("../db/types.js").ScalerSpawningAgentsTable;
|
|
57
|
+
scaler_agent_jobs: import("../db/types.js").ScalerAgentJobsTable;
|
|
58
|
+
scaler_reservations: import("../db/types.js").ScalerReservationsTable;
|
|
59
|
+
attestations: import("../db/types.js").AttestationsTable;
|
|
60
|
+
pending_attestations: import("../db/types.js").PendingAttestationsTable;
|
|
61
|
+
remote_sources: import("../db/types.js").RemoteSourcesTable;
|
|
62
|
+
}, "execution_runs" | "execution_jobs" | "attestations", {}>;
|
|
63
|
+
export type AttestationsBaseQuery = ReturnType<typeof baseAttestationsQuery>;
|
|
64
|
+
/**
|
|
65
|
+
* Base query for the deferred-attestation outbox (`pending_attestations`),
|
|
66
|
+
* joined to `execution_jobs` (job name) and `execution_runs` (repo / workflow
|
|
67
|
+
* context) for the org-wide list's pending summaries.
|
|
68
|
+
*
|
|
69
|
+
* Same uuid/text mismatch as `baseAttestationsQuery`: `pending_attestations`
|
|
70
|
+
* `run_id` / `job_id` are TEXT while the `execution_*` keys are `uuid`, and
|
|
71
|
+
* Postgres won't compare `uuid = text` implicitly — so the joins cast the uuid
|
|
72
|
+
* side to text. Both joins are LEFT joins so a pending row with no matching
|
|
73
|
+
* run / job still lists (repository / workflow / job name come back null).
|
|
74
|
+
*/
|
|
75
|
+
export declare function basePendingAttestationsQuery(db: Kysely<Database>): import("kysely").SelectQueryBuilder<{
|
|
76
|
+
cluster_meta: import("../db/types.js").ClusterMetaTable;
|
|
77
|
+
environments: import("../db/types.js").EnvironmentsTable;
|
|
78
|
+
host_roster: import("../db/types.js").HostRosterTable;
|
|
79
|
+
dispatch_queue: import("../db/types.js").DispatchQueueTable;
|
|
80
|
+
dedup_cache: import("../db/types.js").DedupCacheTable;
|
|
81
|
+
ip_allocations: import("../db/types.js").IpAllocationTable;
|
|
82
|
+
execution_runs: import("kysely").Nullable<import("../db/types.js").ExecutionRunTable>;
|
|
83
|
+
execution_jobs: import("kysely").Nullable<import("../db/types.js").ExecutionJobTable>;
|
|
84
|
+
execution_steps: import("../db/types.js").ExecutionStepTable;
|
|
85
|
+
raft_state: import("../db/types.js").RaftStateTable;
|
|
86
|
+
secret_audit_log: import("../db/types.js").SecretAuditLogTable;
|
|
87
|
+
scoped_secrets: import("../db/types.js").ScopedSecretsTable;
|
|
88
|
+
environment_bindings: import("../db/types.js").EnvironmentBindingsTable;
|
|
89
|
+
environment_variables: import("../db/types.js").EnvironmentVariablesTable;
|
|
90
|
+
environment_source_overrides: import("../db/types.js").EnvironmentSourceOverridesTable;
|
|
91
|
+
held_runs: import("../db/types.js").HeldRunsTable;
|
|
92
|
+
held_run_approvals: import("../db/types.js").HeldRunApprovalsTable;
|
|
93
|
+
admin_tokens: import("../db/types.js").AdminTokenTable;
|
|
94
|
+
agent_tokens: import("../db/types.js").AgentTokenTable;
|
|
95
|
+
config_versions: import("../db/types.js").ConfigVersionTable;
|
|
96
|
+
kici_events: import("../db/types.js").KiciEventTable;
|
|
97
|
+
generic_webhook_sources: import("../db/types.js").GenericWebhookSourceTable;
|
|
98
|
+
cross_repo_trust: import("../db/types.js").CrossRepoTrustTable;
|
|
99
|
+
test_uploads: import("../db/types.js").TestUploadsTable;
|
|
100
|
+
workflow_registrations: import("../db/types.js").WorkflowRegistrationsTable;
|
|
101
|
+
registry_versions: import("../db/types.js").RegistryVersionsTable;
|
|
102
|
+
cron_last_fired: import("../db/types.js").CronLastFiredTable;
|
|
103
|
+
run_ephemeral_keys: import("../db/types.js").RunEphemeralKeysTable;
|
|
104
|
+
run_secret_outputs: import("../db/types.js").RunSecretOutputsTable;
|
|
105
|
+
concurrency_groups: import("../db/types.js").ConcurrencyGroupsTable;
|
|
106
|
+
sources: import("../db/types.js").SourcesTable;
|
|
107
|
+
join_tokens: import("../db/types.js").JoinTokenTable;
|
|
108
|
+
org_settings: import("../db/types.js").OrgSettingsTable;
|
|
109
|
+
execution_job_needs: import("../db/types.js").ExecutionJobNeedsTable;
|
|
110
|
+
pending_job_contexts: import("../db/types.js").PendingJobContextsTable;
|
|
111
|
+
pending_workflow_contexts: import("../db/types.js").PendingWorkflowContextsTable;
|
|
112
|
+
event_log: import("../db/types.js").EventLogTable;
|
|
113
|
+
access_log: import("../db/types.js").AccessLogTable;
|
|
114
|
+
cold_store_chunk_counts: import("../db/types.js").ColdStoreChunkCountsTable;
|
|
115
|
+
cold_store_chunks: import("../db/types.js").ColdStoreChunksTable;
|
|
116
|
+
check_run_tracking: import("../db/types.js").CheckRunTrackingTable;
|
|
117
|
+
scaler_spawning_agents: import("../db/types.js").ScalerSpawningAgentsTable;
|
|
118
|
+
scaler_agent_jobs: import("../db/types.js").ScalerAgentJobsTable;
|
|
119
|
+
scaler_reservations: import("../db/types.js").ScalerReservationsTable;
|
|
120
|
+
attestations: import("../db/types.js").AttestationsTable;
|
|
121
|
+
pending_attestations: import("../db/types.js").PendingAttestationsTable;
|
|
122
|
+
remote_sources: import("../db/types.js").RemoteSourcesTable;
|
|
123
|
+
}, "execution_runs" | "execution_jobs" | "pending_attestations", {}>;
|
|
124
|
+
/**
|
|
125
|
+
* Apply org-wide attestation filters to the base query. Digest is exact-match;
|
|
126
|
+
* name is an ILIKE substring; status / repository / workflow / job are equality;
|
|
127
|
+
* created_at gets `>=` / `<=` bounds for the date range. Absent filters are
|
|
128
|
+
* skipped.
|
|
129
|
+
*/
|
|
130
|
+
export declare function applyAttestationFilters(qb: AttestationsBaseQuery, filters: AttestationListFilters): AttestationsBaseQuery;
|
|
131
|
+
//# sourceMappingURL=attestation-filters.d.ts.map
|
|
@@ -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, DashboardRunsListRequest, DashboardRunsListResponse, DashboardRunsFiltersRequest, DashboardRunsFiltersResponse, DashboardSourcesListRequest, DashboardSourcesListResponse, DashboardStepLogsRequest, DashboardAttestationsListRequest, 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, DashboardAttestationsListRequest, DashboardAttestationsListAllRequest, DashboardAttestationGetRequest, DashboardAttestationRetryRequest, DashboardPayloadRequest, DashboardOrchLogsRequest, DashboardEventLogListRequest, DashboardEventLogDetailRequest, DashboardEventLogPayloadStreamRequest, DashboardAccessLogListRequest, DashboardEventDlqListRequest, DashboardEventDlqCountRequest, DashboardEventDlqRetryRequest, DashboardEventDlqDiscardRequest, RunRerunRequest, RunCancelRequest, ManualScheduleRequest, DashboardRunStructuredRequest } 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 { CacheStorage } from '../storage/types.js';
|
|
@@ -31,6 +31,17 @@ interface DashboardHandlerDeps {
|
|
|
31
31
|
* (the same one P1.5 writes bundles to).
|
|
32
32
|
*/
|
|
33
33
|
provenanceStorage?: CacheStorage | null;
|
|
34
|
+
/**
|
|
35
|
+
* Drain the deferred-attestation outbox on demand (mints in this process,
|
|
36
|
+
* which owns the Platform WS). Backs `dashboard.attestation.retry`. Optional —
|
|
37
|
+
* absent on orchestrators without the retrier wired.
|
|
38
|
+
*/
|
|
39
|
+
retryAttestations?: (opts: {
|
|
40
|
+
runId?: string;
|
|
41
|
+
}) => Promise<{
|
|
42
|
+
minted: number;
|
|
43
|
+
stillPending: number;
|
|
44
|
+
}>;
|
|
34
45
|
/** Send a response message back to Platform over the WS connection. */
|
|
35
46
|
send: (msg: unknown) => void;
|
|
36
47
|
/** This orchestrator's instance ID, included in job detail responses. */
|
|
@@ -59,7 +70,7 @@ interface DashboardHandlerDeps {
|
|
|
59
70
|
* compat with mixed deploys; absent means the orchestrator falls
|
|
60
71
|
* back to the legacy "no PG row → throw" path.
|
|
61
72
|
*/
|
|
62
|
-
onRerun: (runId: string, triggeredBy: string | null, routingKey?: string) => Promise<{
|
|
73
|
+
onRerun: (runId: string, triggeredBy: string | null, triggeredByAgentLabel: string | null, routingKey?: string) => Promise<{
|
|
63
74
|
newRunId: string;
|
|
64
75
|
}>;
|
|
65
76
|
/**
|
|
@@ -67,14 +78,14 @@ interface DashboardHandlerDeps {
|
|
|
67
78
|
* Returns { cancelledJobs } on success or throws on failure.
|
|
68
79
|
* The force flag indicates whether to force-cancel (SIGKILL, skip hooks).
|
|
69
80
|
*/
|
|
70
|
-
onCancel: (runId: string, cancelledBy: string | null, force?: boolean) => Promise<{
|
|
81
|
+
onCancel: (runId: string, cancelledBy: string | null, cancelledByAgentLabel: string | null, force?: boolean) => Promise<{
|
|
71
82
|
cancelledJobs: number;
|
|
72
83
|
}>;
|
|
73
84
|
/**
|
|
74
85
|
* Callback for handling manual schedule trigger requests.
|
|
75
86
|
* Returns { newRunId } on success or throws on failure.
|
|
76
87
|
*/
|
|
77
|
-
onManualSchedule: (registrationId: string, triggeredBy: string | null) => Promise<{
|
|
88
|
+
onManualSchedule: (registrationId: string, triggeredBy: string | null, triggeredByAgentLabel: string | null) => Promise<{
|
|
78
89
|
newRunId: string;
|
|
79
90
|
}>;
|
|
80
91
|
/**
|
|
@@ -99,6 +110,7 @@ export declare class DashboardHandler {
|
|
|
99
110
|
private readonly onManualSchedule;
|
|
100
111
|
private readonly coldStore;
|
|
101
112
|
private readonly eventStore;
|
|
113
|
+
private readonly retryAttestations;
|
|
102
114
|
constructor(deps: DashboardHandlerDeps);
|
|
103
115
|
/**
|
|
104
116
|
* Update the bound orgId + routingKey. Called from server.ts after resolving
|
|
@@ -166,6 +178,14 @@ export declare class DashboardHandler {
|
|
|
166
178
|
* builds a nested job/step tree, and sends the response.
|
|
167
179
|
*/
|
|
168
180
|
handleRunDetail(msg: DashboardRunDetailRequest): Promise<void>;
|
|
181
|
+
/**
|
|
182
|
+
* Handle a dashboard.run.structured request — the user-plane equivalent of
|
|
183
|
+
* the orchestrator-admin `/runs/:id/structured` endpoint. Reuses the Phase-1
|
|
184
|
+
* aggregator + provenance mapper so the result is byte-identical to the admin
|
|
185
|
+
* surface; emits an `access_log` `run.structured.read` row (carrying the
|
|
186
|
+
* agent label when the actor came through an agent PAT).
|
|
187
|
+
*/
|
|
188
|
+
handleRunStructured(msg: DashboardRunStructuredRequest): Promise<void>;
|
|
169
189
|
/**
|
|
170
190
|
* Resolve every routing key owned by an org by unioning both source
|
|
171
191
|
* tables. The orchestrator is single-org but multi-routing-key: one org
|
|
@@ -275,6 +295,38 @@ export declare class DashboardHandler {
|
|
|
275
295
|
* skipped (best-effort) rather than failing the whole list.
|
|
276
296
|
*/
|
|
277
297
|
handleAttestationsList(msg: DashboardAttestationsListRequest): Promise<void>;
|
|
298
|
+
/**
|
|
299
|
+
* Fetch + parse one attestation bundle from object storage. Returns the full
|
|
300
|
+
* detail item, or null when the bundle is missing or not valid JSON (logged).
|
|
301
|
+
* Shared by `handleAttestationsList` (per-run) and `handleAttestationGet`.
|
|
302
|
+
*/
|
|
303
|
+
private inlineBundle;
|
|
304
|
+
/**
|
|
305
|
+
* Org-wide attestations query: one page of metadata-only summaries (no bundle
|
|
306
|
+
* fetch) plus the total matching count. Filters/pagination/sort applied via
|
|
307
|
+
* the shared filter builder.
|
|
308
|
+
*/
|
|
309
|
+
private resolveAttestationsListAll;
|
|
310
|
+
/** Map the deferred-attestation outbox into pending list summaries (page 1). */
|
|
311
|
+
private resolvePendingAttestationSummaries;
|
|
312
|
+
/**
|
|
313
|
+
* Handle a dashboard.attestations.list.all request: org-wide, paginated,
|
|
314
|
+
* filtered list of attestation summaries (metadata only). Access-logged
|
|
315
|
+
* against the `attestation` target.
|
|
316
|
+
*/
|
|
317
|
+
handleAttestationsListAll(msg: DashboardAttestationsListAllRequest): Promise<void>;
|
|
318
|
+
/**
|
|
319
|
+
* Handle a dashboard.attestation.retry request: drain the deferred-attestation
|
|
320
|
+
* outbox (optionally scoped to one run) and reply with the mint counts. The
|
|
321
|
+
* mint happens in this orchestrator process, which owns the Platform WS.
|
|
322
|
+
*/
|
|
323
|
+
handleAttestationRetry(msg: DashboardAttestationRetryRequest): Promise<void>;
|
|
324
|
+
/**
|
|
325
|
+
* Handle a dashboard.attestation.get request: a single attestation by id with
|
|
326
|
+
* its bundle inlined for the detail page. Resolves the run-owning org for the
|
|
327
|
+
* access-log row, then logs against the `attestation` target.
|
|
328
|
+
*/
|
|
329
|
+
handleAttestationGet(msg: DashboardAttestationGetRequest): Promise<void>;
|
|
278
330
|
/**
|
|
279
331
|
* Handle a dashboard.payload request.
|
|
280
332
|
* Reads the webhook payload from log storage for the given runId.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Mark runs that executed an uploaded local working tree (`kici run remote`):
|
|
4
|
+
*
|
|
5
|
+
* - `execution_runs.local_working_tree boolean NOT NULL DEFAULT false` — true
|
|
6
|
+
* for runs that ran a developer's local working tree from the CLI (inline
|
|
7
|
+
* lock file). The dashboard renders a "Local machine" badge for these runs
|
|
8
|
+
* and avoids building an external repository link from the repo identifier.
|
|
9
|
+
*
|
|
10
|
+
* Idempotent (`ADD COLUMN IF NOT EXISTS`); additive with a default, so staging
|
|
11
|
+
* data is preserved.
|
|
12
|
+
*/
|
|
13
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
14
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=054_local_working_tree.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add a token-bound mandatory-label taint to agent tokens:
|
|
4
|
+
*
|
|
5
|
+
* - `agent_tokens.mandatory_labels text NULL` — a JSON-encoded `string[]` of
|
|
6
|
+
* Kubernetes-taint-style gate labels the token authorizes. When a static
|
|
7
|
+
* agent registers with this token, the set becomes the agent's registry-entry
|
|
8
|
+
* `mandatoryLabels`: the agent only accepts a job when every label here
|
|
9
|
+
* appears in the job's required labels. NULL = no taint (the default; the
|
|
10
|
+
* agent accepts any job its advertised labels match), so every existing token
|
|
11
|
+
* stays unconfined until re-minted.
|
|
12
|
+
*
|
|
13
|
+
* Idempotent (`ADD COLUMN IF NOT EXISTS`); additive, so staging data is
|
|
14
|
+
* preserved.
|
|
15
|
+
*/
|
|
16
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
17
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=055_agent_token_mandatory_labels.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add a per-job bound deployment-environment list to `execution_jobs`:
|
|
4
|
+
*
|
|
5
|
+
* - `execution_jobs.environments text NULL` — a JSON-encoded `string[]` of the
|
|
6
|
+
* ordered environment names a job binds (`environments: [...]`), in merge
|
|
7
|
+
* order. Written at dispatch with the statically-resolved names (impure
|
|
8
|
+
* dynamic elements as a `(dynamic)` placeholder), then overwritten with the
|
|
9
|
+
* fully-resolved list when a deferred-init agent eval resolves dynamic
|
|
10
|
+
* elements. NULL = the job binds no environment.
|
|
11
|
+
*
|
|
12
|
+
* Idempotent (`ADD COLUMN IF NOT EXISTS`); additive, so staging data is
|
|
13
|
+
* preserved.
|
|
14
|
+
*/
|
|
15
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
16
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=056_execution_jobs_environments.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Index `access_log.agent_label` (column added by migration 058) so the
|
|
4
|
+
* operator-facing agent filter (`kici-admin access-log list --agent-label`,
|
|
5
|
+
* the dashboard "agent name" filter) does an indexed exact-match lookup
|
|
6
|
+
* instead of a scan. Idempotent.
|
|
7
|
+
*/
|
|
8
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
9
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=063_access_log_agent_label_index.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add the test-run skipped-environment columns to `execution_jobs`:
|
|
4
|
+
*
|
|
5
|
+
* - `execution_jobs.skipped_environments text NULL` — a JSON-encoded `string[]`
|
|
6
|
+
* of the bound environment names dropped on a test/local run because they
|
|
7
|
+
* disallow local execution (`allowLocalExecution=false`) or are unconfigured.
|
|
8
|
+
* NULL = nothing skipped.
|
|
9
|
+
* - `execution_jobs.env_warning text NULL` — the user-visible warning naming the
|
|
10
|
+
* skipped environments, surfaced on the dashboard run view. NULL = no warning.
|
|
11
|
+
*
|
|
12
|
+
* Idempotent (`ADD COLUMN IF NOT EXISTS`); additive, so staging data is
|
|
13
|
+
* preserved.
|
|
14
|
+
*/
|
|
15
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
16
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=064_execution_jobs_skipped_environments.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add the `pending_attestations` deferred-attestation outbox and an idempotency
|
|
4
|
+
* unique index on `attestations`.
|
|
5
|
+
*
|
|
6
|
+
* When a build's provenance mint fails transiently, the agent freezes and
|
|
7
|
+
* DSSE-signs the statement at build time; the orchestrator records the frozen
|
|
8
|
+
* envelope here instead of failing the job. A Raft-leader-only retrier later
|
|
9
|
+
* mints the deferred token, attaches it, uploads the bundle, and records one
|
|
10
|
+
* `attestations` row — deleting the pending row. The unique index on
|
|
11
|
+
* `attestations (run_id, job_id, subject_digest)` makes that fulfilment
|
|
12
|
+
* idempotent across a cluster (ON CONFLICT DO NOTHING).
|
|
13
|
+
*
|
|
14
|
+
* `origin_kind` holds the non-`live` `AttestationOrigin` values
|
|
15
|
+
* (`deferred` / `offline-backfill`); the `created_at` default anchors the true
|
|
16
|
+
* build time so temporal honesty survives a later mint.
|
|
17
|
+
*
|
|
18
|
+
* Idempotent: guarded on table existence.
|
|
19
|
+
*/
|
|
20
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
21
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
22
|
+
//# sourceMappingURL=065_pending_attestations.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add `rejected_at` to `pending_attestations`: the terminal-rejection marker for
|
|
4
|
+
* a deferred attestation the Platform definitively cannot mint (run/job absent).
|
|
5
|
+
* NULL while the row is still pending a later mint; set once, the row is skipped
|
|
6
|
+
* by the retrier and drops out of the pending-attestations gauge. Re-armed via
|
|
7
|
+
* `kici-admin attestations retry --include-rejected`.
|
|
8
|
+
*
|
|
9
|
+
* Idempotent: guarded on column existence.
|
|
10
|
+
*/
|
|
11
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
12
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=066_pending_attestations_rejected.d.ts.map
|