@kici-dev/orchestrator 0.1.27 → 0.3.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__/mock-db.d.ts +2 -0
- package/dist/agent/dispatcher.d.ts +52 -2
- package/dist/agent/host-roster-reaper.d.ts +1 -2
- package/dist/agent/host-roster.d.ts +34 -0
- package/dist/agent/ownership-refusal.d.ts +12 -0
- package/dist/agent/ownership-tracker.d.ts +64 -16
- package/dist/agent/token-store.d.ts +13 -0
- package/dist/agent-packaging/availability.d.ts +27 -0
- package/dist/agent-packaging/build-package.d.ts +16 -0
- package/dist/agent-packaging/download.d.ts +30 -0
- package/dist/agent-packaging/index.d.ts +9 -0
- package/dist/agent-packaging/install-closure.d.ts +30 -0
- package/dist/agent-packaging/node-binary.d.ts +26 -0
- package/dist/agent-packaging/refresh.d.ts +50 -0
- package/dist/agent-packaging/store.d.ts +15 -0
- package/dist/agent-packaging/upload.d.ts +24 -0
- package/dist/app-on-error.d.ts +29 -0
- package/dist/app.d.ts +56 -4
- package/dist/artifacts/artifact-store.d.ts +233 -0
- package/dist/artifacts/failure-messages.d.ts +46 -0
- package/dist/audit/access-log.d.ts +18 -1
- package/dist/cache/dep-cache.d.ts +15 -0
- package/dist/cache/user-cache.d.ts +37 -0
- package/dist/cancel/cancel-run.d.ts +10 -3
- package/dist/cancel/dashboard-cancel-handler.d.ts +19 -0
- package/dist/cli/api-client.d.ts +44 -1
- package/dist/cli/commands/agent-package.d.ts +34 -0
- package/dist/cli/commands/check-run.d.ts +26 -0
- package/dist/cli/commands/cluster-settings.d.ts +55 -0
- package/dist/cli/commands/dashboard-encryption-key.d.ts +3 -0
- package/dist/cli/commands/db-backup.d.ts +71 -0
- package/dist/cli/commands/orchestrator-service/drain.d.ts +31 -0
- package/dist/cli/commands/orchestrator-service/index.d.ts +7 -4
- package/dist/cli/commands/orchestrator-service/install-env.d.ts +58 -0
- package/dist/cli/commands/secret.d.ts +45 -1
- package/dist/cli/commands/shared/admin-cli-access-log.d.ts +46 -0
- package/dist/cli/commands/shared/versioned-upgrade.d.ts +65 -2
- package/dist/cli/commands/signing-key.d.ts +3 -0
- package/dist/cli/commands/source.d.ts +12 -0
- package/dist/cli/commands/token.d.ts +9 -0
- package/dist/cli/commands/trust-policy.d.ts +48 -0
- package/dist/cli/join.d.ts +1 -1
- package/dist/cli/service/index.d.ts +2 -2
- package/dist/cli/service/instance/manifest.d.ts +17 -0
- package/dist/cli/service/instance/resolve.d.ts +11 -0
- package/dist/cli/wizard/orchestrator-wizard.d.ts +39 -11
- package/dist/cli.js +9921 -3409
- package/dist/cluster/cluster-settings-reader.d.ts +78 -0
- package/dist/cluster/coordinator.d.ts +81 -9
- package/dist/cluster/join-client.d.ts +1 -1
- package/dist/cluster/leader-gated-scheduler.d.ts +50 -0
- package/dist/cluster/orphan-recovery.d.ts +14 -0
- package/dist/cluster/peer-client.d.ts +12 -2
- package/dist/cluster/peer-handler.d.ts +15 -4
- package/dist/cluster/peer-registry.d.ts +12 -0
- package/dist/cluster/verified-issuer-poller.d.ts +11 -0
- package/dist/cluster/verified-issuer.d.ts +63 -0
- package/dist/cold-store/tables/access-log.d.ts +1 -1
- package/dist/cold-store/tables/event-log.d.ts +1 -1
- package/dist/cold-store/tables/execution-jobs.d.ts +1 -1
- package/dist/cold-store/tables/execution-runs.d.ts +1 -1
- package/dist/cold-store/tables/execution-steps.d.ts +1 -1
- package/dist/cold-store/tables/secret-audit-log.d.ts +1 -1
- package/dist/config/loader.d.ts +1 -1
- package/dist/config/resolver.d.ts +2 -1
- package/dist/config/schema.d.ts +9 -6
- package/dist/config/types.d.ts +5 -2
- package/dist/config.d.ts +366 -53
- package/dist/contexts/context-store.d.ts +21 -8
- package/dist/contexts/glob-specificity.d.ts +30 -0
- package/dist/contexts/held-runs.d.ts +51 -19
- package/dist/contexts/protection/aggregate.d.ts +2 -2
- package/dist/contexts/protection/concurrency-gate.d.ts +0 -3
- package/dist/contexts/protection/reviewer-gate.d.ts +0 -3
- package/dist/contexts/protection/satisfiability.d.ts +1 -1
- package/dist/contexts/protection/trust-gate.d.ts +0 -3
- package/dist/contexts/protection/wait-timer-gate.d.ts +0 -3
- package/dist/cron/cron-scheduler.d.ts +24 -4
- package/dist/cron/cron-store.d.ts +21 -7
- package/dist/dashboard/attestation-filters.d.ts +92 -74
- package/dist/dashboard/handler.d.ts +35 -1
- package/dist/db/migration-test-harness.d.ts +41 -0
- package/dist/db/migrations/069_reroute_tunables.d.ts +21 -0
- package/dist/db/migrations/070_execution_runs_failure_class.d.ts +4 -0
- package/dist/db/migrations/071_batch_accumulation.d.ts +26 -0
- package/dist/db/migrations/072_dispatch_queue_run_id_index.d.ts +15 -0
- package/dist/db/migrations/073_org_settings_ingest_concurrency.d.ts +13 -0
- package/dist/db/migrations/074_normalize_zero_concurrency_limit.d.ts +13 -0
- package/dist/db/migrations/075_ingest_overflow_buffer.d.ts +16 -0
- package/dist/db/migrations/076_artifacts.d.ts +19 -0
- package/dist/db/migrations/077_backup_runs.d.ts +13 -0
- package/dist/db/migrations/078_org_settings_backup_staleness.d.ts +12 -0
- package/dist/db/migrations/079_org_settings_scaler_spawn_timeout.d.ts +14 -0
- package/dist/db/migrations/080_cluster_settings.d.ts +17 -0
- package/dist/db/migrations/081_org_settings_queue_timeout.d.ts +19 -0
- package/dist/db/migrations/082_host_s3_reachable.d.ts +16 -0
- package/dist/db/migrations/083_org_settings_artifact_caps.d.ts +18 -0
- package/dist/db/migrations/084_orchestrator_signing_keys.d.ts +20 -0
- package/dist/db/migrations/085_cluster_settings_reroute_flap_grace_ms.d.ts +12 -0
- package/dist/db/migrations/086_cluster_settings_max_fanout_hosts.d.ts +12 -0
- package/dist/db/migrations/087_cluster_settings_event_router_rate_limit.d.ts +12 -0
- package/dist/db/migrations/088_cluster_settings_cache_max_tarball_bytes.d.ts +12 -0
- package/dist/db/migrations/089_cluster_settings_cache_ttl_days.d.ts +12 -0
- package/dist/db/migrations/090_cluster_settings_concurrency_wait_timeout_ms.d.ts +12 -0
- package/dist/db/migrations/091_cluster_settings_agent_token_ttl_ms.d.ts +12 -0
- package/dist/db/migrations/092_cluster_settings_version.d.ts +16 -0
- package/dist/db/migrations/093_org_settings_sandbox_allowlist.d.ts +4 -0
- package/dist/db/migrations/094_dashboard_encryption_keys.d.ts +21 -0
- package/dist/db/migrations/095_dashboard_write_policy_tristate.d.ts +20 -0
- package/dist/db/migrations/096_multi_schedule_cron_last_fired.d.ts +4 -0
- package/dist/db/migrations/097_execution_runs_pr_number.d.ts +4 -0
- package/dist/db/migrations/098_execution_runs_customer_id.d.ts +4 -0
- package/dist/db/migrations/099_cluster_settings_dashboard_verified_issuer.d.ts +21 -0
- package/dist/db/migrations/100_held_runs_hold_type_vocabulary.d.ts +31 -0
- package/dist/db/migrations/101_contexts_hold_expiry_drop_default.d.ts +31 -0
- package/dist/db/migrations/102_dispatch_queue_agent_id.d.ts +20 -0
- package/dist/db/migrations/103_cluster_settings_ownership_db_check_timeout_ms.d.ts +20 -0
- package/dist/db/migrations/104_check_run_terminal_sent.d.ts +22 -0
- package/dist/db/migrations/105_org_trust_policy.d.ts +19 -0
- package/dist/db/migrations/106_cluster_settings_check_run_tracking_ttl_days.d.ts +18 -0
- package/dist/db/migrations/107_check_run_tracking_updated_at_index.d.ts +23 -0
- package/dist/db/migrations/108_unroutable_fast_fail.d.ts +4 -0
- package/dist/db/repos/dashboard-encryption-keys-repo.d.ts +48 -0
- package/dist/db/repos/signing-keys-repo.d.ts +34 -0
- package/dist/db/types.d.ts +441 -7
- package/dist/deployment/deployment-identity.d.ts +87 -2
- package/dist/diagnostics/checks/backup.d.ts +18 -0
- package/dist/diagnostics/checks/index.d.ts +2 -1
- package/dist/diagnostics/fleet-collector.d.ts +1 -1
- package/dist/drain/drain-controller.d.ts +52 -0
- package/dist/events/batch-accumulator.d.ts +63 -0
- package/dist/events/circuit-breaker.d.ts +9 -3
- package/dist/events/event-emitter.d.ts +31 -0
- package/dist/events/event-retry-scanner.d.ts +12 -2
- package/dist/events/event-router.d.ts +29 -0
- package/dist/firecracker/host-network.d.ts +2 -0
- package/dist/firecracker/net-interfaces.d.ts +14 -0
- package/dist/github-app-name-refresher/github-app-name-refresher.d.ts +18 -8
- package/dist/index.d.ts +2 -0
- package/dist/index.js +654 -29
- package/dist/lockfile-cache.d.ts +4 -0
- package/dist/lockfile-validate.d.ts +16 -9
- package/dist/metrics/prometheus.d.ts +113 -15
- package/dist/oidc/aws-kms-signer.d.ts +37 -0
- package/dist/oidc/command-signer.d.ts +23 -0
- package/dist/oidc/db-signer.d.ts +48 -0
- package/dist/oidc/id-token-claims.d.ts +22 -9
- package/dist/oidc/jwt.d.ts +5 -2
- package/dist/oidc/local-dev-signer.d.ts +1 -1
- package/dist/oidc/oidc-mint-registration.d.ts +27 -11
- package/dist/oidc/orchestrator-mint.d.ts +97 -0
- package/dist/oidc/orchestrator-signer-factory.d.ts +33 -0
- package/dist/oidc/reconcile-signing-key.d.ts +21 -0
- package/dist/oidc/signer.d.ts +25 -0
- package/dist/oidc/signing-key-status.d.ts +23 -0
- package/dist/orchestrator-core.d.ts +42 -2
- package/dist/pipeline/decorating-secret-resolver.d.ts +3 -2
- package/dist/pipeline/dispatch-matched-workflow.d.ts +41 -0
- package/dist/pipeline/install-secrets-resolver.d.ts +12 -1
- package/dist/pipeline/manual-schedule.d.ts +20 -13
- package/dist/pipeline/pending-workflow-context.d.ts +1 -1
- package/dist/pipeline/process-webhook.d.ts +57 -2
- package/dist/pipeline/processor.d.ts +44 -8
- package/dist/pipeline/rerun.d.ts +12 -13
- package/dist/pipeline/resolve-sandbox-grant.d.ts +28 -0
- package/dist/pipeline/route-or-dispatch-jobs.d.ts +71 -0
- package/dist/pipeline/sandbox-allowlist-reader.d.ts +33 -0
- package/dist/policy/dashboard-write-policy.d.ts +9 -4
- package/dist/provenance/backfill-run.d.ts +1 -0
- package/dist/provenance/trust-root.d.ts +13 -0
- package/dist/providers/generic/normalizer.d.ts +1 -1
- package/dist/providers/github/auth.d.ts +1 -1
- package/dist/providers/github/changed-files.d.ts +14 -6
- package/dist/providers/github/check-status-poster.d.ts +19 -3
- package/dist/providers/github/contributor-resolver.d.ts +1 -1
- package/dist/providers/github/lock-file.d.ts +1 -1
- package/dist/providers/github/normalizer.d.ts +1 -1
- package/dist/providers/github/repo-url.d.ts +1 -1
- package/dist/providers/local/lock-file-fetcher.d.ts +1 -1
- package/dist/providers/local/normalizer.d.ts +1 -1
- package/dist/providers/local/repo-url-builder.d.ts +1 -1
- package/dist/providers/universal-git/changed-files.d.ts +8 -7
- package/dist/providers/universal-git/clone-token.d.ts +1 -1
- package/dist/providers/universal-git/config.d.ts +4 -4
- package/dist/providers/universal-git/index.d.ts +5 -1
- package/dist/providers/universal-git/lock-file.d.ts +6 -1
- package/dist/providers/universal-git/normalizer.d.ts +1 -1
- package/dist/providers/universal-git/repo-url.d.ts +1 -1
- package/dist/queue/bootstrap.d.ts +5 -0
- package/dist/queue/cleanup.d.ts +72 -9
- package/dist/queue/job-queue.d.ts +141 -14
- package/dist/queue/scheduled-job.d.ts +3 -2
- package/dist/queue/terminalize-unroutable.d.ts +53 -0
- package/dist/queue/unroutable-probe.d.ts +52 -0
- package/dist/registration/registration-index.d.ts +1 -1
- package/dist/reporting/agent-failure-category.d.ts +4 -1
- package/dist/reporting/check-run-reporter.d.ts +34 -14
- package/dist/reporting/check-run-tracking-store.d.ts +70 -8
- package/dist/reporting/execution-tracker.d.ts +156 -10
- package/dist/reporting/fs-log-storage.d.ts +31 -2
- package/dist/reporting/job-check-run-completion.d.ts +50 -0
- package/dist/reporting/log-chunk-sink.d.ts +47 -0
- package/dist/reporting/log-retention.d.ts +16 -0
- package/dist/reporting/log-storage.d.ts +64 -4
- package/dist/reporting/log-writer.d.ts +22 -7
- package/dist/reporting/peer-log-normalize.d.ts +14 -0
- package/dist/reporting/run-aggregator.d.ts +50 -33
- package/dist/reporting/s3-log-storage.d.ts +102 -8
- package/dist/routes/admin-auth.d.ts +90 -0
- package/dist/routes/admin-cluster-settings.d.ts +31 -0
- package/dist/routes/admin-events.d.ts +3 -0
- package/dist/routes/admin-orchestrator-drain.d.ts +35 -0
- package/dist/routes/admin-runs.d.ts +9 -0
- package/dist/routes/admin-sources.d.ts +7 -0
- package/dist/routes/admin-trust-policy.d.ts +49 -0
- package/dist/routes/admin.d.ts +15 -1
- package/dist/routes/github-webhook.d.ts +9 -3
- package/dist/routes/provenance-oidc.d.ts +38 -0
- package/dist/routes/verify-attestation.d.ts +21 -0
- package/dist/scaler/bare-metal-backend.d.ts +9 -2
- package/dist/scaler/config.d.ts +25 -4
- package/dist/scaler/container-backend.d.ts +9 -1
- package/dist/scaler/firecracker-backend.d.ts +29 -2
- package/dist/scaler/index.d.ts +1 -1
- package/dist/scaler/manager.d.ts +166 -8
- package/dist/scaler/pending-scale-sweeper.d.ts +35 -0
- package/dist/scaler/types.d.ts +75 -6
- package/dist/secrets/backend-registry.d.ts +32 -1
- package/dist/secrets/dashboard-encryption-key.d.ts +48 -0
- package/dist/secrets/ephemeral-keys.d.ts +16 -0
- package/dist/secrets/pg-secret-store.d.ts +10 -0
- package/dist/secrets/rbac.d.ts +5 -1
- package/dist/secrets/routing-key-scope.d.ts +6 -0
- package/dist/secrets/scope-routing.d.ts +126 -0
- package/dist/secrets/secret-resolver.d.ts +1 -14
- package/dist/secrets/token-manager.d.ts +5 -1
- package/dist/security/contributor-cache.d.ts +9 -1
- package/dist/security/trust-policy-gate.d.ts +117 -0
- package/dist/security/trust-policy-store.d.ts +78 -0
- package/dist/server.js +36074 -25052
- package/dist/sources/source-manager.d.ts +24 -0
- package/dist/stale-detector/stale-run-detector.d.ts +7 -0
- package/dist/standalone.js +35203 -25387
- package/dist/storage/filesystem.d.ts +17 -0
- package/dist/storage/key-discriminator.d.ts +20 -0
- package/dist/storage/s3.d.ts +2 -0
- package/dist/storage/types.d.ts +16 -0
- package/dist/webhook/dedup.d.ts +9 -1
- package/dist/webhook/event-log.d.ts +13 -2
- package/dist/webhook/generic-sources-listener.d.ts +4 -0
- package/dist/webhook/ingest-admission.d.ts +140 -0
- package/dist/webhook/ingest-overflow-buffer.d.ts +27 -0
- package/dist/webhook/ingest-overflow-replayer.d.ts +49 -0
- package/dist/webhook/ingest-overflow-types.d.ts +73 -0
- package/dist/webhook/loop-lag-source.d.ts +40 -0
- package/dist/webhook/observed-relay-guard.d.ts +40 -0
- package/dist/webhook/org-ingest-cap-reader.d.ts +24 -0
- package/dist/webhook/register-source-bundle.d.ts +3 -0
- package/dist/webhook/relay-reinject.d.ts +43 -0
- package/dist/worker/in-memory-job-queue.d.ts +8 -3
- package/dist/worker-core.d.ts +10 -0
- package/dist/ws/agent-api-registry.d.ts +20 -0
- package/dist/ws/agent-handler.d.ts +63 -7
- package/dist/ws/bringup-api.d.ts +99 -0
- package/dist/ws/dashboard-context-handler.d.ts +28 -10
- package/dist/ws/dashboard-run-state-handler.d.ts +31 -0
- package/dist/ws/failure-messages.d.ts +29 -0
- package/dist/ws/oidc-token-relay.d.ts +9 -0
- package/dist/ws/ownership-gate.d.ts +22 -0
- package/dist/ws/platform-client.d.ts +96 -1
- package/dist/ws/replay-chunker.d.ts +37 -0
- package/installer-image-digests.json +3 -3
- package/package.json +22 -21
- package/sbom.spdx.json +1240 -1788
package/dist/app.d.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* - Request ID and logging middleware
|
|
11
11
|
* - 25MB body size limit
|
|
12
12
|
*
|
|
13
|
-
* Pattern follows packages/platform/src/app.ts: returns { app,
|
|
13
|
+
* Pattern follows packages/platform/src/app.ts: returns { app, wss }.
|
|
14
14
|
*/
|
|
15
15
|
import type { Kysely } from 'kysely';
|
|
16
16
|
import type pg from 'pg';
|
|
@@ -21,6 +21,7 @@ import type { Database } from './db/types.js';
|
|
|
21
21
|
import type { AgentRegistry } from './agent/registry.js';
|
|
22
22
|
import type { Dispatcher } from './agent/dispatcher.js';
|
|
23
23
|
import type { RunCoordinator } from './cluster/coordinator.js';
|
|
24
|
+
import type { ClusterSettingsReader } from './cluster/cluster-settings-reader.js';
|
|
24
25
|
import type { PeerRegistry } from './cluster/peer-registry.js';
|
|
25
26
|
import type { JobQueue } from './queue/job-queue.js';
|
|
26
27
|
import type { DedupCache } from './webhook/dedup.js';
|
|
@@ -32,6 +33,7 @@ import type { SourceCache } from './cache/index.js';
|
|
|
32
33
|
import type { BuildCoordinator } from './cache/index.js';
|
|
33
34
|
import type { DepCache } from './cache/index.js';
|
|
34
35
|
import type { UserCache } from './cache/index.js';
|
|
36
|
+
import type { ArtifactStore } from './artifacts/artifact-store.js';
|
|
35
37
|
import type { DispatchCacheRefTracker } from './cache/index.js';
|
|
36
38
|
import type { PendingBuildTracker } from './cache/index.js';
|
|
37
39
|
import type { PendingInitTracker } from './cache/index.js';
|
|
@@ -39,7 +41,7 @@ import type { PendingDynamicTracker } from './cache/index.js';
|
|
|
39
41
|
import type { CacheStorage } from './storage/types.js';
|
|
40
42
|
import type { ProvenanceTrustRoot } from './provenance/trust-root.js';
|
|
41
43
|
import type { LocalSigner } from './oidc/local-dev-signer.js';
|
|
42
|
-
import {
|
|
44
|
+
import type { CheckRunReporter } from './reporting/check-run-reporter.js';
|
|
43
45
|
import type { ExecutionTracker } from './reporting/execution-tracker.js';
|
|
44
46
|
import type { LogWriter } from './reporting/log-writer.js';
|
|
45
47
|
import type { LogStorage } from './reporting/log-storage.js';
|
|
@@ -62,6 +64,12 @@ import type { RegistrationStore } from './registration/registration-store.js';
|
|
|
62
64
|
import type { RegistrationIndex } from './registration/registration-index.js';
|
|
63
65
|
import type { CronScheduler } from './cron/cron-scheduler.js';
|
|
64
66
|
import { type ConfigRouteDeps } from './routes/admin-config.js';
|
|
67
|
+
import { WebhookIngestOutcome } from './pipeline/process-webhook.js';
|
|
68
|
+
import type { IngestOverflowBuffer } from './webhook/ingest-overflow-buffer.js';
|
|
69
|
+
import { type OverflowDelivery } from './webhook/ingest-overflow-types.js';
|
|
70
|
+
import type { IngestAdmissionController } from './webhook/ingest-admission.js';
|
|
71
|
+
import type { OrgIngestCapReader } from './webhook/org-ingest-cap-reader.js';
|
|
72
|
+
import type { SandboxAllowListReader } from './pipeline/sandbox-allowlist-reader.js';
|
|
65
73
|
import type { ConcurrencyGroupTracker } from './concurrency/group-tracker.js';
|
|
66
74
|
import type { ConcurrencyQueueManager } from './concurrency/queue-manager.js';
|
|
67
75
|
import type { EventRouter } from './events/event-router.js';
|
|
@@ -85,6 +93,8 @@ export interface AppDependencies {
|
|
|
85
93
|
config: AppConfig;
|
|
86
94
|
db: Kysely<Database>;
|
|
87
95
|
pool: pg.Pool;
|
|
96
|
+
/** Fleet-wide settings reader; threads the live lock-file cap into warm-added universal-git sources. */
|
|
97
|
+
clusterSettings?: ClusterSettingsReader;
|
|
88
98
|
registry: AgentRegistry;
|
|
89
99
|
/**
|
|
90
100
|
* Warmth latch surfaced on `GET /ready`. Returns `true` only once the
|
|
@@ -100,6 +110,22 @@ export interface AppDependencies {
|
|
|
100
110
|
lockFileCache: LockFileCache;
|
|
101
111
|
providerRegistry: ProviderRegistry;
|
|
102
112
|
platformClient?: PlatformClient;
|
|
113
|
+
/**
|
|
114
|
+
* Webhook-ingest admission controller (shared with the WS relay path). When
|
|
115
|
+
* present, the HTTP ingest closure admits before running the pipeline and
|
|
116
|
+
* sheds (429 + Retry-After) when the controller is saturated.
|
|
117
|
+
*/
|
|
118
|
+
ingestController?: IngestAdmissionController;
|
|
119
|
+
/** Resolves the fairness key + per-org cap for a routing key (cached, DB-degraded). */
|
|
120
|
+
ingestCapReader?: OrgIngestCapReader;
|
|
121
|
+
/** Reads the per-org container-sandbox escape-hatch allow-list at dispatch (uncached, DB-degraded). */
|
|
122
|
+
sandboxAllowListReader?: SandboxAllowListReader;
|
|
123
|
+
/**
|
|
124
|
+
* Durable overflow buffer (capture side). When present and
|
|
125
|
+
* `config.ingestOverflowEnabled`, a shed HTTP delivery is additively persisted
|
|
126
|
+
* for later replay; absent → capture disabled.
|
|
127
|
+
*/
|
|
128
|
+
ingestOverflowBuffer?: IngestOverflowBuffer;
|
|
103
129
|
/**
|
|
104
130
|
* Fulfil deferred attestations on demand (mints in this process, which owns
|
|
105
131
|
* the Platform WS). Backs `POST /api/v1/admin/attestations/retry`. Wired only
|
|
@@ -122,6 +148,8 @@ export interface AppDependencies {
|
|
|
122
148
|
depCache?: DepCache;
|
|
123
149
|
/** User-facing cache (ctx.cache / declarative job-step cache). Optional — requires cache storage. */
|
|
124
150
|
userCache?: UserCache;
|
|
151
|
+
/** User-facing artifact store (ctx.artifacts). Optional — requires cache storage + DB. */
|
|
152
|
+
artifactStore?: ArtifactStore;
|
|
125
153
|
/**
|
|
126
154
|
* Server-side jobId -> user-cache-namespace store. Written at dispatch time
|
|
127
155
|
* (orchestrator-core's buildOnDispatch); read by the agent-WS handler to
|
|
@@ -140,6 +168,29 @@ export interface AppDependencies {
|
|
|
140
168
|
* is registered so `ctx.kici.oidc.token()` mints a `kici-local` dev token.
|
|
141
169
|
*/
|
|
142
170
|
localOidcSigner?: LocalSigner;
|
|
171
|
+
/**
|
|
172
|
+
* Orchestrator-owned provenance signing (Phase 1 root of trust). Present when
|
|
173
|
+
* `KICI_ORCHESTRATOR_PROVENANCE_ISSUER` is configured: the orchestrator mints +
|
|
174
|
+
* signs identity tokens locally with its own ES256 key, and serves its own
|
|
175
|
+
* OIDC discovery + JWKS + native verify endpoint. `resolveOrchestratorSigner`
|
|
176
|
+
* lazily reconciles the active signing key (leader-election-race-safe); the
|
|
177
|
+
* repo backs the `.well-known` + verify routes.
|
|
178
|
+
*/
|
|
179
|
+
provenanceSigning?: {
|
|
180
|
+
issuer: string;
|
|
181
|
+
resolveSigner: () => Promise<import('./oidc/signer.js').Signer | null>;
|
|
182
|
+
repo: import('./db/repos/signing-keys-repo.js').OrchestratorSigningKeyRepo;
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* Dashboard-encryption (X25519) key custody. Present whenever KICI_SECRET_KEY
|
|
186
|
+
* is configured. `repo` backs the JWKS enc-key publication; `resolve` lazily
|
|
187
|
+
* reconciles the active key (leader-election-race-safe) for the WS decrypt
|
|
188
|
+
* handler.
|
|
189
|
+
*/
|
|
190
|
+
dashboardEncryption?: {
|
|
191
|
+
repo: import('./db/repos/dashboard-encryption-keys-repo.js').DashboardEncryptionKeyRepo;
|
|
192
|
+
resolve: () => Promise<import('./secrets/dashboard-encryption-key.js').ResolvedDashboardEncryptionKey | null>;
|
|
193
|
+
};
|
|
143
194
|
/**
|
|
144
195
|
* Filesystem cache backend handle. Only set when KICI_STORAGE_TYPE is
|
|
145
196
|
* `filesystem`. Drives the /api/v1/cache/blob/* HTTP route that serves and
|
|
@@ -300,11 +351,12 @@ export declare class SourceLocationStore {
|
|
|
300
351
|
* Create Hono application with all routes and middleware.
|
|
301
352
|
*
|
|
302
353
|
* @param deps - Application dependencies (injected for testability)
|
|
303
|
-
* @returns Object with Hono app instance and
|
|
354
|
+
* @returns Object with Hono app instance and the configured WebSocket server
|
|
304
355
|
*/
|
|
305
356
|
export declare function createApp(deps: AppDependencies): {
|
|
306
357
|
app: import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, import("hono/types").BlankSchema, string, string>;
|
|
307
|
-
|
|
358
|
+
wss: import("ws").Server<typeof import("ws").WebSocket, typeof import("http").IncomingMessage>;
|
|
359
|
+
reinjectDirect: (d: OverflowDelivery) => Promise<WebhookIngestOutcome>;
|
|
308
360
|
onSourceLocationsExtracted: (workflowName: string, jobName: string, locations: Array<{
|
|
309
361
|
file: string;
|
|
310
362
|
line: number;
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import type { Kysely } from 'kysely';
|
|
2
|
+
import type { ArtifactRejectReason } from '@kici-dev/engine';
|
|
3
|
+
import type { Database } from '../db/types.js';
|
|
4
|
+
import type { CacheStorage } from '../storage/types.js';
|
|
5
|
+
/**
|
|
6
|
+
* The presigned PUT never landed an object, so there is nothing to record.
|
|
7
|
+
* Distinct from a transient storage/DB error: a caller retrying the commit
|
|
8
|
+
* would keep finding the object absent, so this failure is terminal and is
|
|
9
|
+
* reported straight back to the agent (which fails the workflow step).
|
|
10
|
+
*/
|
|
11
|
+
export declare class ArtifactObjectMissingError extends Error {
|
|
12
|
+
readonly storageKey: string;
|
|
13
|
+
constructor(storageKey: string);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The requested artifact name violates the shared name contract. Terminal: the
|
|
17
|
+
* name is fixed for the life of the request, so a retry would fail identically.
|
|
18
|
+
*/
|
|
19
|
+
export declare class ArtifactInvalidNameError extends Error {
|
|
20
|
+
constructor(detail: string);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Map a `completeUpload` failure onto a message safe to send to the agent — which
|
|
24
|
+
* runs untrusted workflow code, so the reason reaches the workflow author and its
|
|
25
|
+
* step logs.
|
|
26
|
+
*
|
|
27
|
+
* An invalid-name error already carries a safe message: its constructor formats
|
|
28
|
+
* the schema's own fixed detail, so it passes through unchanged. An object-missing
|
|
29
|
+
* error is a genuinely actionable terminal case and keeps its own category, but
|
|
30
|
+
* the storage key its message embeds does not travel. Anything else is an internal
|
|
31
|
+
* failure the author cannot act on, so it collapses to one literal; the raw
|
|
32
|
+
* exception stays in the orchestrator's own log line.
|
|
33
|
+
*/
|
|
34
|
+
export declare function classifyArtifactCommitFailure(err: unknown): string;
|
|
35
|
+
/** Cluster-wide default per-org artifact byte quota: 20 GiB. */
|
|
36
|
+
export declare const DEFAULT_ARTIFACT_QUOTA_BYTES: number;
|
|
37
|
+
/** Cluster-wide default per-artifact TTL: 30 days. */
|
|
38
|
+
export declare const DEFAULT_ARTIFACT_TTL_MS: number;
|
|
39
|
+
/** Cluster-wide default per-artifact size cap: 1 GiB. */
|
|
40
|
+
export declare const DEFAULT_ARTIFACT_MAX_BYTES: number;
|
|
41
|
+
/** Cluster-wide default per-run artifact count cap. */
|
|
42
|
+
export declare const DEFAULT_ARTIFACT_MAX_PER_RUN = 50;
|
|
43
|
+
/**
|
|
44
|
+
* Storage key for a run's named artifact.
|
|
45
|
+
*
|
|
46
|
+
* Injective over names: distinct names always produce distinct keys, so a
|
|
47
|
+
* second upload can never silently overwrite the first while both rows keep
|
|
48
|
+
* their own hash.
|
|
49
|
+
*
|
|
50
|
+
* The trailing discriminator is a hash of the exact name, and it is what keeps
|
|
51
|
+
* the keys apart on a CASE-INSENSITIVE object namespace — the filesystem
|
|
52
|
+
* backend on a macOS or Windows host. There `bundle` and `Bundle` would
|
|
53
|
+
* otherwise be two keys resolving to one file; because their discriminators
|
|
54
|
+
* differ, the keys differ by more than case and stay two objects. That is why
|
|
55
|
+
* the discriminator is wide (see `KEY_DISCRIMINATOR_LENGTH`): under case
|
|
56
|
+
* folding it carries the whole separation on its own. The readable stem is kept
|
|
57
|
+
* so an operator browsing the bucket can still tell which artifact an object
|
|
58
|
+
* is.
|
|
59
|
+
*
|
|
60
|
+
* Hashing the EXACT name rather than the sanitized one is deliberate:
|
|
61
|
+
* sanitizing is many-to-one, so a discriminator over its output would fold
|
|
62
|
+
* `a/b` and `a_b` back together.
|
|
63
|
+
*
|
|
64
|
+
* Changing this format does not strand existing artifacts — the key is
|
|
65
|
+
* persisted in `artifacts.storage_key` and the download paths read that column
|
|
66
|
+
* rather than re-deriving. Only the grant and commit paths derive, and both do
|
|
67
|
+
* so at upload time.
|
|
68
|
+
*/
|
|
69
|
+
export declare function artifactStorageKey(runId: string, name: string): string;
|
|
70
|
+
/**
|
|
71
|
+
* Per-org override of the artifact limits, read from `org_settings`. Each field
|
|
72
|
+
* is optional; an undefined field falls back to the cluster-wide default.
|
|
73
|
+
*/
|
|
74
|
+
export interface ArtifactOrgLimits {
|
|
75
|
+
quotaBytes?: number;
|
|
76
|
+
ttlMs?: number;
|
|
77
|
+
maxBytes?: number;
|
|
78
|
+
maxPerRun?: number;
|
|
79
|
+
}
|
|
80
|
+
/** Resolves the per-org artifact limits (e.g. an `org_settings` read). */
|
|
81
|
+
export type ArtifactOrgLimitsReader = (customerId: string) => Promise<ArtifactOrgLimits>;
|
|
82
|
+
/** Outcome of a begin-upload grant request. */
|
|
83
|
+
export interface ArtifactBeginUploadResult {
|
|
84
|
+
outcome: 'granted' | 'rejected';
|
|
85
|
+
uploadUrl?: string;
|
|
86
|
+
storageKey?: string;
|
|
87
|
+
reason?: ArtifactRejectReason;
|
|
88
|
+
/**
|
|
89
|
+
* Free-text rejection detail carried when no enforcement `reason` applies —
|
|
90
|
+
* today, a name that violates the artifact-name contract.
|
|
91
|
+
*/
|
|
92
|
+
error?: string;
|
|
93
|
+
}
|
|
94
|
+
/** Outcome of a download lookup. */
|
|
95
|
+
export interface ArtifactDownloadResult {
|
|
96
|
+
outcome: 'found' | 'not_found';
|
|
97
|
+
downloadUrl?: string;
|
|
98
|
+
sizeBytes?: number;
|
|
99
|
+
sha256?: string;
|
|
100
|
+
}
|
|
101
|
+
/** A run's artifact as surfaced to the dashboard. */
|
|
102
|
+
export interface ArtifactListEntry {
|
|
103
|
+
name: string;
|
|
104
|
+
jobId: string;
|
|
105
|
+
sizeBytes: number;
|
|
106
|
+
sha256: string;
|
|
107
|
+
createdAt: string;
|
|
108
|
+
/**
|
|
109
|
+
* Presigned GET for the backing object. Present on the run-detail listing
|
|
110
|
+
* (`listForRunWithUrls`); omitted when the object could not be resolved
|
|
111
|
+
* (expired / gone).
|
|
112
|
+
*/
|
|
113
|
+
downloadUrl?: string;
|
|
114
|
+
}
|
|
115
|
+
export declare class ArtifactStore {
|
|
116
|
+
private readonly storage;
|
|
117
|
+
private readonly db;
|
|
118
|
+
private readonly defaultQuotaBytes;
|
|
119
|
+
private readonly defaultTtlMs;
|
|
120
|
+
private readonly maxBytes;
|
|
121
|
+
private readonly maxPerRun;
|
|
122
|
+
private readonly orgLimitsReader?;
|
|
123
|
+
constructor(opts: {
|
|
124
|
+
storage: CacheStorage;
|
|
125
|
+
db: Kysely<Database>;
|
|
126
|
+
/** Cluster-wide default quota (env default). */
|
|
127
|
+
quotaBytes?: number;
|
|
128
|
+
/** Cluster-wide default TTL (env default). */
|
|
129
|
+
ttlMs?: number;
|
|
130
|
+
/** Per-artifact size cap. */
|
|
131
|
+
maxBytes?: number;
|
|
132
|
+
/** Per-run artifact count cap. */
|
|
133
|
+
maxPerRun?: number;
|
|
134
|
+
/** Per-org override reader (org_settings). When unset, defaults apply. */
|
|
135
|
+
orgLimitsReader?: ArtifactOrgLimitsReader;
|
|
136
|
+
});
|
|
137
|
+
/**
|
|
138
|
+
* Resolve the effective quota, TTL, per-artifact size cap, and per-run count
|
|
139
|
+
* cap for an org. Each value is the per-org `org_settings` override when set,
|
|
140
|
+
* otherwise the cluster-wide default.
|
|
141
|
+
*/
|
|
142
|
+
private resolveLimits;
|
|
143
|
+
/** ISO cutoff for TTL filtering: rows created before this are expired. */
|
|
144
|
+
private cutoff;
|
|
145
|
+
/**
|
|
146
|
+
* Grant or refuse a presigned PUT for a named artifact. Order: name contract →
|
|
147
|
+
* resolve limits → size cap → duplicate name → per-run count cap → org quota.
|
|
148
|
+
* The size cap and per-run count cap are the resolved per-org override when
|
|
149
|
+
* set, otherwise the cluster-wide default. No presigned URL is minted for a
|
|
150
|
+
* request that would violate any gate.
|
|
151
|
+
*
|
|
152
|
+
* The name is checked first, and here rather than only in the SDK, because the
|
|
153
|
+
* agent runs untrusted customer workflow code: a name that bypassed the SDK
|
|
154
|
+
* check would be sanitized onto another name's storage key, letting a second
|
|
155
|
+
* upload overwrite the first object while both rows keep their own hash. A
|
|
156
|
+
* contract violation is not an enforcement rejection, so it carries a
|
|
157
|
+
* free-text `error` and no `reason`.
|
|
158
|
+
*/
|
|
159
|
+
beginUpload(args: {
|
|
160
|
+
customerId: string;
|
|
161
|
+
runId: string;
|
|
162
|
+
name: string;
|
|
163
|
+
declaredSizeBytes: number;
|
|
164
|
+
}): Promise<ArtifactBeginUploadResult>;
|
|
165
|
+
/**
|
|
166
|
+
* Commit a completed upload: write the object metadata sidecar, then insert
|
|
167
|
+
* the DB row. The `UNIQUE (run_id, name)` constraint (via onConflict-do-nothing)
|
|
168
|
+
* is the immutability backstop for a racing duplicate that slipped past the
|
|
169
|
+
* pre-mint check.
|
|
170
|
+
*
|
|
171
|
+
* Neither agent-supplied value is trusted: the storage key is re-derived from
|
|
172
|
+
* the server-resolved `runId` + `name`, and the recorded size is the real byte
|
|
173
|
+
* size of the stored object read back from the storage backend. Agents run
|
|
174
|
+
* untrusted customer workflow code, so an echoed key could otherwise point a
|
|
175
|
+
* row at another tenant's object, and a declared size could under-account the
|
|
176
|
+
* per-org quota (a presigned PUT does not bind content length).
|
|
177
|
+
*
|
|
178
|
+
* The name is re-validated here, not only at `beginUpload`: a commit is its
|
|
179
|
+
* own inbound message, so an agent can send one for a name it never got a
|
|
180
|
+
* grant for. Without the check, a non-conforming name would derive the
|
|
181
|
+
* storage key of a *different*, already-committed artifact and record a second
|
|
182
|
+
* row against that same object with its own hash.
|
|
183
|
+
*
|
|
184
|
+
* Throws when the commit cannot be recorded — `ArtifactInvalidNameError` for a
|
|
185
|
+
* name that violates the contract, `ArtifactObjectMissingError` when the
|
|
186
|
+
* presigned PUT never landed an object, or the underlying storage / DB error
|
|
187
|
+
* otherwise. The caller reports the failure back to the agent, which fails the
|
|
188
|
+
* workflow step rather than leaving a green run with no artifact.
|
|
189
|
+
*/
|
|
190
|
+
completeUpload(args: {
|
|
191
|
+
customerId: string;
|
|
192
|
+
runId: string;
|
|
193
|
+
jobId: string;
|
|
194
|
+
name: string;
|
|
195
|
+
/** Agent-declared size. Advisory — the stored object is stat'd instead. */
|
|
196
|
+
sizeBytes: number;
|
|
197
|
+
sha256: string;
|
|
198
|
+
/** Agent-echoed key. Ignored — the key is re-derived server-side. */
|
|
199
|
+
storageKey: string;
|
|
200
|
+
}): Promise<void>;
|
|
201
|
+
/** Load a single artifact row (any TTL state) for a run + name. */
|
|
202
|
+
private loadRow;
|
|
203
|
+
private isExpired;
|
|
204
|
+
/**
|
|
205
|
+
* Resolve a named artifact of a run to a presigned GET + its size/sha256, or
|
|
206
|
+
* `not_found` when the name was never uploaded, has expired, or its backing
|
|
207
|
+
* object is gone.
|
|
208
|
+
*/
|
|
209
|
+
download(args: {
|
|
210
|
+
customerId: string;
|
|
211
|
+
runId: string;
|
|
212
|
+
name: string;
|
|
213
|
+
}): Promise<ArtifactDownloadResult>;
|
|
214
|
+
/** ISO string for a row's created_at (Date or already-string). */
|
|
215
|
+
private createdAtIso;
|
|
216
|
+
/** Load a run's non-expired artifact rows, newest first, given the org TTL. */
|
|
217
|
+
private loadRunRows;
|
|
218
|
+
/**
|
|
219
|
+
* List a run's non-expired artifacts with a presigned GET per entry, newest
|
|
220
|
+
* first — the shape the dashboard run-detail panel renders. Resolves the org
|
|
221
|
+
* TTL once, then mints one presigned URL per row; a row whose backing object
|
|
222
|
+
* is gone lists its metadata with `downloadUrl` omitted rather than being
|
|
223
|
+
* dropped. Also reports the presigned-URL expiry (seconds) — the storage
|
|
224
|
+
* backend's `getUrl` signature TTL, NOT the artifact-retention `ttlMs` — so
|
|
225
|
+
* the dashboard can refresh a rendered `downloadUrl` before its signature
|
|
226
|
+
* expires.
|
|
227
|
+
*/
|
|
228
|
+
listForRunWithUrls(customerId: string, runId: string): Promise<{
|
|
229
|
+
artifacts: ArtifactListEntry[];
|
|
230
|
+
downloadUrlExpiresInSeconds: number;
|
|
231
|
+
}>;
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=artifact-store.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe, fixed messages the orchestrator sends to the agent (and through it to
|
|
3
|
+
* the workflow author) when a user-artifact request is refused for something
|
|
4
|
+
* other than an enforcement gate or a genuine lookup miss — an internal failure,
|
|
5
|
+
* or a request that violates the artifact-name contract.
|
|
6
|
+
*
|
|
7
|
+
* These are presentation strings, not a wire vocabulary: the protocol carries
|
|
8
|
+
* them in the free-text `error` field of `artifacts.upload.response` /
|
|
9
|
+
* `artifacts.download.response` and in the free-text `reason` field of
|
|
10
|
+
* `artifacts.upload.complete.ack`, so an orchestrator is free to reword them
|
|
11
|
+
* without any agent-side change. They live here — rather than inline at each
|
|
12
|
+
* send site — so the handler and its tests share one definition.
|
|
13
|
+
*
|
|
14
|
+
* Raw exception text is never one of these. Exceptions stay in the
|
|
15
|
+
* orchestrator's own logs; the author sees only "this is an orchestrator or
|
|
16
|
+
* configuration problem", never a database endpoint or a stack frame.
|
|
17
|
+
*/
|
|
18
|
+
export declare const ArtifactInternalFailure: Readonly<{
|
|
19
|
+
/** Upload requested but the orchestrator has no artifact store configured. */
|
|
20
|
+
readonly uploadNotConfigured: 'artifact uploads are not configured on this orchestrator';
|
|
21
|
+
/** Download requested but the orchestrator has no artifact store configured. */
|
|
22
|
+
readonly downloadNotConfigured: 'artifact downloads are not configured on this orchestrator';
|
|
23
|
+
/** The job's run could not be resolved server-side (upload and download). */
|
|
24
|
+
readonly unresolvableRun: 'the run for this job could not be resolved on the orchestrator';
|
|
25
|
+
/** `beginUpload` threw. */
|
|
26
|
+
readonly uploadFailed: 'the orchestrator hit an internal error while starting the upload';
|
|
27
|
+
/** `download` threw. */
|
|
28
|
+
readonly downloadFailed: 'the orchestrator hit an internal error while resolving the download';
|
|
29
|
+
/** `completeUpload` threw with no more specific classification. */
|
|
30
|
+
readonly commitFailed: 'the orchestrator hit an internal error while committing the upload';
|
|
31
|
+
/** The uploaded object was absent from storage at commit time. */
|
|
32
|
+
readonly commitObjectMissing: 'the uploaded artifact object was not found in storage — the upload may not have completed';
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* The artifact-name rejection prefix and message builder are defined in
|
|
36
|
+
* `@kici-dev/engine`, beside `ArtifactNameSchema` itself, so the orchestrator and
|
|
37
|
+
* the agent sandbox render one wording. Such a rejection is neither an
|
|
38
|
+
* enforcement gate (nothing about the org's usage refuses it) nor an internal
|
|
39
|
+
* failure — the sandbox validates the same contract at the call site, so a name
|
|
40
|
+
* only reaches this path from an agent that bypassed or predates that check.
|
|
41
|
+
*
|
|
42
|
+
* Re-exported here because this module is where the orchestrator's artifact
|
|
43
|
+
* failure messages live — callers keep their existing import path.
|
|
44
|
+
*/
|
|
45
|
+
export { ARTIFACT_INVALID_NAME_PREFIX, artifactInvalidNameError } from '@kici-dev/engine';
|
|
46
|
+
//# sourceMappingURL=failure-messages.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Kysely } from 'kysely';
|
|
1
|
+
import type { Kysely, Transaction } from 'kysely';
|
|
2
2
|
import { type ColdStore } from '@kici-dev/shared';
|
|
3
3
|
import { type AccessLogAction, type AccessLogItem, type AccessLogOutcome, type AccessLogRateLimiter, type AccessLogSource, type AccessLogTargetType, type ActorPrincipal, type ActorType } from '@kici-dev/engine';
|
|
4
4
|
import type { Database } from '../db/types.js';
|
|
@@ -70,6 +70,23 @@ export declare class AccessLogWriter {
|
|
|
70
70
|
*/
|
|
71
71
|
setColdStore(coldStore: ColdStore | null): void;
|
|
72
72
|
record(entry: AccessLogRecord): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Transactional variant: writes the row through the caller's executor so it
|
|
75
|
+
* commits or rolls back with the mutation it audits.
|
|
76
|
+
*
|
|
77
|
+
* Unlike `record`, failures PROPAGATE. The best-effort swallow exists so a
|
|
78
|
+
* broken `access_log` cannot take down dashboard reads; a caller that opted
|
|
79
|
+
* into a transaction is asserting the opposite — the mutation must not land
|
|
80
|
+
* unaudited — so the error has to reach the transaction and abort it.
|
|
81
|
+
*
|
|
82
|
+
* The per-action `POLICY_BY_ACTION` gate still applies, so a `sample` /
|
|
83
|
+
* `rate_limit` action would be dropped here silently and the caller's
|
|
84
|
+
* mutation would commit unaudited after all. Callers must therefore use an
|
|
85
|
+
* action whose policy is `always` — which is why `trust_policy.updated` is
|
|
86
|
+
* one.
|
|
87
|
+
*/
|
|
88
|
+
recordInTransaction(executor: Kysely<Database> | Transaction<Database>, entry: AccessLogRecord): Promise<void>;
|
|
89
|
+
private insert;
|
|
73
90
|
/**
|
|
74
91
|
* Phase D: delegates to `loadAccessLogRange` so cold-store rows are
|
|
75
92
|
* merged transparently when pagination crosses the warm cutoff. The
|
|
@@ -8,13 +8,28 @@
|
|
|
8
8
|
* Cache key format: deps/{platform}-{arch}/{lockfileHash}.tar.gz
|
|
9
9
|
*/
|
|
10
10
|
import type { CacheStorage } from '../storage/types.js';
|
|
11
|
+
import type { ClusterSettingsReader } from '../cluster/cluster-settings-reader.js';
|
|
11
12
|
export declare class DepCache {
|
|
12
13
|
private readonly storage;
|
|
13
14
|
private readonly maxTarballBytes;
|
|
15
|
+
private readonly cacheTtlDaysFallback;
|
|
16
|
+
private readonly clusterSettings?;
|
|
14
17
|
constructor(options: {
|
|
15
18
|
storage: CacheStorage;
|
|
16
19
|
maxTarballBytes?: number;
|
|
20
|
+
/** Cluster default for the dependency-cache entry TTL, in days. */
|
|
21
|
+
cacheTtlDaysFallback?: number;
|
|
22
|
+
/** Reader for the fleet-wide `cache_max_tarball_bytes` / `cache_ttl_days` overrides. */
|
|
23
|
+
clusterSettings?: ClusterSettingsReader;
|
|
17
24
|
});
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the live dependency-cache entry TTL as a per-operation override
|
|
27
|
+
* (ms) from `cluster_settings.cache_ttl_days`, falling back to the cluster
|
|
28
|
+
* default. `undefined` when no reader is wired, so the storage backend uses
|
|
29
|
+
* its own configured TTL. Passed to read/expiry operations so an operator's
|
|
30
|
+
* `cache_ttl_days` change takes effect on the next lookup.
|
|
31
|
+
*/
|
|
32
|
+
private resolveTtlMsOverride;
|
|
18
33
|
/** Check if a dep tarball exists in cache. */
|
|
19
34
|
has(lockfileHash: string, platform: string, arch: string): Promise<boolean>;
|
|
20
35
|
/**
|
|
@@ -88,7 +88,44 @@ export declare class UserCache {
|
|
|
88
88
|
private writePrefix;
|
|
89
89
|
/** Namespace prefixes the ref may READ, in priority order. Isolated reads its own run scope, then shared. */
|
|
90
90
|
private readPrefixes;
|
|
91
|
+
/**
|
|
92
|
+
* Object key for a committed cache entry.
|
|
93
|
+
*
|
|
94
|
+
* The trailing discriminator is a hash of the EXACT cache key, and it is what
|
|
95
|
+
* keeps `build` and `Build` apart on a case-insensitive namespace — the
|
|
96
|
+
* filesystem backend on a macOS or Windows host, where the two would
|
|
97
|
+
* otherwise resolve to one object and a restore could return the other key's
|
|
98
|
+
* tarball.
|
|
99
|
+
*
|
|
100
|
+
* It is deliberately a SUFFIX: `restoreByPrefix` matches `restoreKeys` by
|
|
101
|
+
* string prefix, so appending leaves those semantics untouched. The only
|
|
102
|
+
* parse that has to know about it is the `matchedKey` slice.
|
|
103
|
+
*/
|
|
91
104
|
private finalKey;
|
|
105
|
+
/**
|
|
106
|
+
* The pre-discriminator object key.
|
|
107
|
+
*
|
|
108
|
+
* @deprecated Read-only compatibility path for entries written before the key
|
|
109
|
+
* carried a discriminator. Nothing writes this format; it is removed at the
|
|
110
|
+
* next major, by which point every such entry has aged out of the cache TTL.
|
|
111
|
+
*/
|
|
112
|
+
private legacyFinalKey;
|
|
113
|
+
/**
|
|
114
|
+
* Restore an entry still stored in the pre-discriminator key format.
|
|
115
|
+
*
|
|
116
|
+
* Two gates, and BOTH are load-bearing — dropping either re-creates the
|
|
117
|
+
* wrong-cache-hit this change fixes:
|
|
118
|
+
*
|
|
119
|
+
* 1. `unambiguousLegacyKey` statically rules out any key that could have
|
|
120
|
+
* collided with a case variant in the old format.
|
|
121
|
+
* 2. The listed name must match byte-exactly. A case-insensitive backend
|
|
122
|
+
* resolves `getUrl('build')` to an object created as `Build`, but its
|
|
123
|
+
* *listing* reports the real created name — so comparing against the
|
|
124
|
+
* listing is what detects that the object is not really ours.
|
|
125
|
+
*
|
|
126
|
+
* @deprecated Removed at the next major; see `legacyFinalKey`.
|
|
127
|
+
*/
|
|
128
|
+
private restoreLegacyExact;
|
|
92
129
|
/** Restore: try the exact key across read prefixes, then restoreKeys prefix scan (newest wins). */
|
|
93
130
|
restore(ref: UserCacheRef & {
|
|
94
131
|
key: string;
|
|
@@ -41,6 +41,11 @@ export interface CancelRunResult {
|
|
|
41
41
|
agentsNotified: number;
|
|
42
42
|
/** Number of pending/queued execution_jobs rows marked cancelled. */
|
|
43
43
|
pendingCancelled: number;
|
|
44
|
+
/**
|
|
45
|
+
* True when the run was already in a terminal status, so the cancel was a
|
|
46
|
+
* no-op: no agent was notified and no row was written.
|
|
47
|
+
*/
|
|
48
|
+
alreadyTerminal: boolean;
|
|
44
49
|
}
|
|
45
50
|
/**
|
|
46
51
|
* Cancel a whole run, recording `reason` on its cancelled jobs and (if not
|
|
@@ -50,9 +55,11 @@ export interface CancelRunResult {
|
|
|
50
55
|
* the run to its terminal status immediately so the run does not linger in
|
|
51
56
|
* `cancelling`.
|
|
52
57
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
58
|
+
* A cancel targeting a run that is already terminal is a no-op: the run's
|
|
59
|
+
* status is read first and, when terminal, the function returns
|
|
60
|
+
* `alreadyTerminal: true` having written nothing. Entry points map that to
|
|
61
|
+
* their own convention (the operator route answers 409; the dashboard/MCP path
|
|
62
|
+
* returns a structured already-terminal result).
|
|
56
63
|
*/
|
|
57
64
|
export declare function cancelRunWithReason(deps: CancelRunDeps, runId: string, reason: string, options?: CancelRunOptions): Promise<CancelRunResult>;
|
|
58
65
|
//# sourceMappingURL=cancel-run.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The cancel handler behind the dashboard, the `kici runs cancel` CLI, and the
|
|
3
|
+
* MCP `cancel_run` tool.
|
|
4
|
+
*
|
|
5
|
+
* It delegates to `cancelRunWithReason` so the customer-facing cancel follows
|
|
6
|
+
* the same mechanics as the operator-facing one: an already-terminal run is a
|
|
7
|
+
* no-op, only OPEN agent sockets are notified, queued dispatch rows are
|
|
8
|
+
* cancelled, pending jobs are marked cancelled, and a run with no outstanding
|
|
9
|
+
* agent work is driven terminal.
|
|
10
|
+
*
|
|
11
|
+
* `cancelledJobs` counts notified agents plus pending/queued job rows marked
|
|
12
|
+
* cancelled, matching the operator route.
|
|
13
|
+
*/
|
|
14
|
+
import { type CancelRunDeps } from './cancel-run.js';
|
|
15
|
+
export declare function createDashboardCancelHandler(deps: CancelRunDeps): (runId: string, cancelledBy: string | null, cancelledByAgentLabel: string | null, force?: boolean) => Promise<{
|
|
16
|
+
cancelledJobs: number;
|
|
17
|
+
alreadyTerminal: boolean;
|
|
18
|
+
}>;
|
|
19
|
+
//# sourceMappingURL=dashboard-cancel-handler.d.ts.map
|
package/dist/cli/api-client.d.ts
CHANGED
|
@@ -63,6 +63,28 @@ export interface GenericSourceResponse {
|
|
|
63
63
|
/** Universal-git config; raw JSON string or parsed object (pg driver dependent). */
|
|
64
64
|
git_config?: string | GenericSourceGitConfigPayload | null;
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* `fetch` rejects with a bare `TypeError: fetch failed` when it cannot reach the
|
|
68
|
+
* host — it names neither the address dialled nor the knob that sets it. Printed
|
|
69
|
+
* through the CLI's `Error: ${message}` handler that becomes `Error: fetch
|
|
70
|
+
* failed`, which reads like a fault in the subcommand rather than a misaddressed
|
|
71
|
+
* client, and sends the operator debugging the wrong thing.
|
|
72
|
+
*
|
|
73
|
+
* The trap is sharpened by two details of this CLI. The base URL comes from
|
|
74
|
+
* `KICI_ADMIN_URL`, not the `KICI_ORCHESTRATOR_URL` an operator is likelier to
|
|
75
|
+
* have exported; and subcommands accepting `--database-url` fall back to direct
|
|
76
|
+
* DB access, so on a host with `KICI_DATABASE_URL` set they keep working while
|
|
77
|
+
* the HTTP-only ones fail — making it look like specific subcommands are broken.
|
|
78
|
+
*
|
|
79
|
+
* So: name the address, name the variable, and name the near-miss.
|
|
80
|
+
*/
|
|
81
|
+
/**
|
|
82
|
+
* Best-effort one-line detail from a rejected `fetch`. Returns '' when nothing
|
|
83
|
+
* useful is available, so the caller can omit the parenthetical rather than
|
|
84
|
+
* print an empty one.
|
|
85
|
+
*/
|
|
86
|
+
export declare function firstCauseMessage(err: unknown): string;
|
|
87
|
+
export declare function fetchAdminApi(url: string, init: RequestInit, baseUrl: string): Promise<Response>;
|
|
66
88
|
export declare class AdminApiClient {
|
|
67
89
|
private readonly baseUrl;
|
|
68
90
|
private readonly token;
|
|
@@ -106,7 +128,14 @@ export declare class AdminApiClient {
|
|
|
106
128
|
logWindowHours?: number;
|
|
107
129
|
timeoutSeconds?: number;
|
|
108
130
|
}, outPath: string): Promise<void>;
|
|
109
|
-
|
|
131
|
+
/**
|
|
132
|
+
* List secret scopes for an org.
|
|
133
|
+
*
|
|
134
|
+
* @param allBackends - Aggregate every registered backend and return scopes
|
|
135
|
+
* in qualified `<backend>:<path>` form. Default (false) returns the bare,
|
|
136
|
+
* pg-only listing; that default flips at v1.0.0.
|
|
137
|
+
*/
|
|
138
|
+
listScopes(orgId: string, allBackends?: boolean): Promise<{
|
|
110
139
|
scopes: string[];
|
|
111
140
|
}>;
|
|
112
141
|
listKeys(orgId: string, scope: string): Promise<{
|
|
@@ -150,6 +179,8 @@ export declare class AdminApiClient {
|
|
|
150
179
|
reEncrypted: number;
|
|
151
180
|
reEncryptedConfigs: number;
|
|
152
181
|
skippedConfigs: number;
|
|
182
|
+
reEncryptedBackends: number;
|
|
183
|
+
skippedBackends: number;
|
|
153
184
|
}>;
|
|
154
185
|
createGenericSource(data: {
|
|
155
186
|
orgId: string;
|
|
@@ -223,6 +254,8 @@ export declare class AdminApiClient {
|
|
|
223
254
|
label: string;
|
|
224
255
|
role: string;
|
|
225
256
|
routingKey?: string;
|
|
257
|
+
/** Optional absolute expiry as an ISO datetime string. */
|
|
258
|
+
expiresAt?: string;
|
|
226
259
|
}): Promise<{
|
|
227
260
|
token: string;
|
|
228
261
|
id: string;
|
|
@@ -294,6 +327,16 @@ export declare class AdminApiClient {
|
|
|
294
327
|
version?: number;
|
|
295
328
|
errors?: string[];
|
|
296
329
|
}>;
|
|
330
|
+
/** Flip the coordinator drain flag on ('drain') or off ('resume'). */
|
|
331
|
+
drain(action: 'drain' | 'resume'): Promise<{
|
|
332
|
+
draining: boolean;
|
|
333
|
+
jobsRunning: number;
|
|
334
|
+
}>;
|
|
335
|
+
/** Report the coordinator's current drain state without changing it. */
|
|
336
|
+
drainStatus(): Promise<{
|
|
337
|
+
draining: boolean;
|
|
338
|
+
jobsRunning: number;
|
|
339
|
+
}>;
|
|
297
340
|
createApiKey(opts: {
|
|
298
341
|
label?: string;
|
|
299
342
|
routingKeys?: string[];
|