@kici-dev/orchestrator 0.0.0 → 0.1.1
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/LICENSE +661 -0
- package/README.md +1 -6
- package/dist/__test-helpers__/mock-db.d.ts +103 -0
- package/dist/__test-helpers__/mock-ws.d.ts +13 -0
- package/dist/agent/dispatcher.d.ts +231 -0
- package/dist/agent/ownership-tracker.d.ts +46 -0
- package/dist/agent/registry.d.ts +255 -0
- package/dist/agent/token-store.d.ts +96 -0
- package/dist/app.d.ts +234 -0
- package/dist/audit/access-log.d.ts +92 -0
- package/dist/audit/sampling-rate-limiter.d.ts +41 -0
- package/dist/cache/build-coordinator.d.ts +42 -0
- package/dist/cache/dep-cache.d.ts +51 -0
- package/dist/cache/index.d.ts +16 -0
- package/dist/cache/pending-builds.d.ts +14 -0
- package/dist/cache/pending-dynamics.d.ts +15 -0
- package/dist/cache/pending-inits.d.ts +19 -0
- package/dist/cache/pending-tracker.d.ts +65 -0
- package/dist/cache/source-cache.d.ts +30 -0
- package/dist/cli/api-client.d.ts +411 -0
- package/dist/cli/commands/access-log.d.ts +30 -0
- package/dist/cli/commands/agent-service/index.d.ts +15 -0
- package/dist/cli/commands/agent-service/install.d.ts +9 -0
- package/dist/cli/commands/agent-service/logs.d.ts +9 -0
- package/dist/cli/commands/agent-service/restart.d.ts +8 -0
- package/dist/cli/commands/agent-service/start.d.ts +8 -0
- package/dist/cli/commands/agent-service/status.d.ts +10 -0
- package/dist/cli/commands/agent-service/stop.d.ts +8 -0
- package/dist/cli/commands/agent-service/uninstall.d.ts +9 -0
- package/dist/cli/commands/agent-service/upgrade.d.ts +11 -0
- package/dist/cli/commands/agent.d.ts +10 -0
- package/dist/cli/commands/api-key.d.ts +12 -0
- package/dist/cli/commands/audit.d.ts +9 -0
- package/dist/cli/commands/backend.d.ts +17 -0
- package/dist/cli/commands/cold-store-impl.d.ts +101 -0
- package/dist/cli/commands/cold-store.d.ts +30 -0
- package/dist/cli/commands/config.d.ts +16 -0
- package/dist/cli/commands/db.d.ts +19 -0
- package/dist/cli/commands/debug-bundle.d.ts +16 -0
- package/dist/cli/commands/diagnose.d.ts +15 -0
- package/dist/cli/commands/environment.d.ts +24 -0
- package/dist/cli/commands/event-dlq.d.ts +19 -0
- package/dist/cli/commands/event-log.d.ts +27 -0
- package/dist/cli/commands/event.d.ts +4 -0
- package/dist/cli/commands/execution.d.ts +17 -0
- package/dist/cli/commands/inspect-bundle.d.ts +16 -0
- package/dist/cli/commands/maintenance.d.ts +4 -0
- package/dist/cli/commands/orchestrator-service/index.d.ts +12 -0
- package/dist/cli/commands/orchestrator-service/install.d.ts +10 -0
- package/dist/cli/commands/orchestrator-service/logs.d.ts +10 -0
- package/dist/cli/commands/orchestrator-service/restart.d.ts +8 -0
- package/dist/cli/commands/orchestrator-service/start.d.ts +8 -0
- package/dist/cli/commands/orchestrator-service/status.d.ts +10 -0
- package/dist/cli/commands/orchestrator-service/stop.d.ts +8 -0
- package/dist/cli/commands/orchestrator-service/uninstall.d.ts +9 -0
- package/dist/cli/commands/orchestrator-service/upgrade.d.ts +12 -0
- package/dist/cli/commands/org-settings.d.ts +17 -0
- package/dist/cli/commands/peer.d.ts +13 -0
- package/dist/cli/commands/queue.d.ts +16 -0
- package/dist/cli/commands/registration.d.ts +18 -0
- package/dist/cli/commands/rotate.d.ts +9 -0
- package/dist/cli/commands/runs.d.ts +34 -0
- package/dist/cli/commands/secret.d.ts +12 -0
- package/dist/cli/commands/shared/db.d.ts +16 -0
- package/dist/cli/commands/shared/versioned-upgrade.d.ts +38 -0
- package/dist/cli/commands/source.d.ts +24 -0
- package/dist/cli/commands/token.d.ts +10 -0
- package/dist/cli/commands/workflow.d.ts +31 -0
- package/dist/cli/join.d.ts +14 -0
- package/dist/cli/kici-admin.d.ts +13 -0
- package/dist/cli/lazy-deps/cache.d.ts +17 -0
- package/dist/cli/lazy-deps/downloader.d.ts +33 -0
- package/dist/cli/lazy-deps/registry.d.ts +43 -0
- package/dist/cli/service/compose.d.ts +25 -0
- package/dist/cli/service/index.d.ts +24 -0
- package/dist/cli/service/launchd.d.ts +34 -0
- package/dist/cli/service/platform-detect.d.ts +59 -0
- package/dist/cli/service/systemd.d.ts +41 -0
- package/dist/cli/service/types.d.ts +91 -0
- package/dist/cli/service/windows.d.ts +20 -0
- package/dist/cli/wizard/agent-wizard.d.ts +24 -0
- package/dist/cli/wizard/orchestrator-wizard.d.ts +38 -0
- package/dist/cli/wizard/prompts.d.ts +23 -0
- package/dist/cli.js +11435 -0
- package/dist/cluster/cluster-identity.d.ts +59 -0
- package/dist/cluster/coordinator.d.ts +204 -0
- package/dist/cluster/health-api.d.ts +30 -0
- package/dist/cluster/index.d.ts +24 -0
- package/dist/cluster/join-client.d.ts +75 -0
- package/dist/cluster/join-handler.d.ts +58 -0
- package/dist/cluster/join-token.d.ts +94 -0
- package/dist/cluster/orphan-recovery.d.ts +67 -0
- package/dist/cluster/peer-client.d.ts +190 -0
- package/dist/cluster/peer-credentials.d.ts +108 -0
- package/dist/cluster/peer-crypto.d.ts +57 -0
- package/dist/cluster/peer-handler.d.ts +97 -0
- package/dist/cluster/peer-registry.d.ts +186 -0
- package/dist/cluster/raft-state.d.ts +36 -0
- package/dist/cluster/raft.d.ts +140 -0
- package/dist/cold-store/load-access-log-range.d.ts +73 -0
- package/dist/cold-store/load-event-log-range.d.ts +62 -0
- package/dist/cold-store/load-secret-audit-log-range.d.ts +38 -0
- package/dist/cold-store/orchestrator-cold-store.d.ts +58 -0
- package/dist/cold-store/tables/access-log.d.ts +80 -0
- package/dist/cold-store/tables/event-log.d.ts +70 -0
- package/dist/cold-store/tables/execution-jobs.d.ts +63 -0
- package/dist/cold-store/tables/execution-runs.d.ts +81 -0
- package/dist/cold-store/tables/execution-steps.d.ts +65 -0
- package/dist/cold-store/tables/secret-audit-log.d.ts +77 -0
- package/dist/concurrency/dispatch-next-queued.d.ts +63 -0
- package/dist/concurrency/group-tracker.d.ts +51 -0
- package/dist/concurrency/index.d.ts +3 -0
- package/dist/concurrency/queue-manager.d.ts +68 -0
- package/dist/concurrency/waiters.d.ts +58 -0
- package/dist/config/encryption.d.ts +82 -0
- package/dist/config/env-overlay.d.ts +45 -0
- package/dist/config/index.d.ts +16 -0
- package/dist/config/loader.d.ts +26 -0
- package/dist/config/reload.d.ts +113 -0
- package/dist/config/resolver.d.ts +47 -0
- package/dist/config/schema.d.ts +210 -0
- package/dist/config/shared-store.d.ts +142 -0
- package/dist/config/types.d.ts +218 -0
- package/dist/config.d.ts +249 -0
- package/dist/cron/cron-scheduler.d.ts +78 -0
- package/dist/cron/cron-store.d.ts +38 -0
- package/dist/dashboard/handler.d.ts +243 -0
- package/dist/db/client.d.ts +13 -0
- package/dist/db/migration-provider.d.ts +9 -0
- package/dist/db/migrations/001_initial.d.ts +8 -0
- package/dist/db/migrations/002_config_versions_key_version.d.ts +16 -0
- package/dist/db/migrations/003_access_log.d.ts +26 -0
- package/dist/db/migrations/004_rename_bundle_to_source.d.ts +19 -0
- package/dist/db/migrations/005_cold_store_chunk_counter.d.ts +19 -0
- package/dist/db/migrations/006_runs_jobs_steps_archived_at.d.ts +38 -0
- package/dist/db/migrations/007_audit_logs_archived_at.d.ts +42 -0
- package/dist/db/migrations/008_event_log_archived_at.d.ts +40 -0
- package/dist/db/migrations/009_access_log_trigram.d.ts +15 -0
- package/dist/db/migrations/010_cold_store_chunks.d.ts +34 -0
- package/dist/db/migrations/011_drop_source_secrets_notify.d.ts +21 -0
- package/dist/db/migrations/012_peer_credentials_active_uniq.d.ts +28 -0
- package/dist/db/migrations/013_execution_log_bytes.d.ts +21 -0
- package/dist/db/migrations/014_kici_events_lease_retry.d.ts +36 -0
- package/dist/db/migrations/015_org_settings_customer_scoped.d.ts +30 -0
- package/dist/db/migrations/016_org_settings_allow_http_npm.d.ts +15 -0
- package/dist/db/migrations/017_org_id_widen.d.ts +4 -0
- package/dist/db/migrations/018_org_id_prefix_backfill.d.ts +4 -0
- package/dist/db/migrator.d.ts +32 -0
- package/dist/db/types.d.ts +1266 -0
- package/dist/diagnostics/bundle-reader.d.ts +48 -0
- package/dist/diagnostics/bundle-writer.d.ts +57 -0
- package/dist/diagnostics/checks/agents.d.ts +10 -0
- package/dist/diagnostics/checks/certs.d.ts +9 -0
- package/dist/diagnostics/checks/config.d.ts +10 -0
- package/dist/diagnostics/checks/db.d.ts +9 -0
- package/dist/diagnostics/checks/disk.d.ts +9 -0
- package/dist/diagnostics/checks/index.d.ts +17 -0
- package/dist/diagnostics/checks/ws.d.ts +9 -0
- package/dist/diagnostics/index.d.ts +13 -0
- package/dist/diagnostics/runner.d.ts +23 -0
- package/dist/diagnostics/types.d.ts +38 -0
- package/dist/entry-helpers.d.ts +93 -0
- package/dist/environments/binding-store.d.ts +27 -0
- package/dist/environments/environment-store.d.ts +74 -0
- package/dist/environments/held-runs.d.ts +64 -0
- package/dist/environments/index.d.ts +10 -0
- package/dist/environments/protection/branch-gate.d.ts +5 -0
- package/dist/environments/protection/concurrency-gate.d.ts +7 -0
- package/dist/environments/protection/pipeline.d.ts +18 -0
- package/dist/environments/protection/reviewer-gate.d.ts +7 -0
- package/dist/environments/protection/trust-gate.d.ts +7 -0
- package/dist/environments/protection/wait-timer-gate.d.ts +7 -0
- package/dist/environments/variable-store.d.ts +39 -0
- package/dist/events/circuit-breaker.d.ts +33 -0
- package/dist/events/event-emitter.d.ts +55 -0
- package/dist/events/event-retry-scanner.d.ts +52 -0
- package/dist/events/event-router.d.ts +183 -0
- package/dist/events/event-store.d.ts +157 -0
- package/dist/events/trust-store.d.ts +54 -0
- package/dist/events/types.d.ts +61 -0
- package/dist/helpers/ip-extraction.d.ts +29 -0
- package/dist/helpers/rate-limiter.d.ts +23 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +772 -0
- package/dist/lockfile-cache.d.ts +39 -0
- package/dist/metrics/agent-metrics-aggregator.d.ts +116 -0
- package/dist/metrics/metrics-reporter.d.ts +40 -0
- package/dist/metrics/prometheus.d.ts +261 -0
- package/dist/metrics/scheduled-jobs.d.ts +20 -0
- package/dist/orchestrator-core.d.ts +193 -0
- package/dist/pipeline/dispatch-matched-workflow.d.ts +102 -0
- package/dist/pipeline/inline-eval.d.ts +28 -0
- package/dist/pipeline/install-secrets-resolver.d.ts +73 -0
- package/dist/pipeline/manual-schedule.d.ts +21 -0
- package/dist/pipeline/needs-scheduler.d.ts +85 -0
- package/dist/pipeline/process-webhook.d.ts +38 -0
- package/dist/pipeline/processor.d.ts +326 -0
- package/dist/pipeline/rerun.d.ts +79 -0
- package/dist/pipeline/test-pipeline.d.ts +110 -0
- package/dist/provider-registry.d.ts +122 -0
- package/dist/providers/generic/index.d.ts +23 -0
- package/dist/providers/generic/normalizer.d.ts +112 -0
- package/dist/providers/generic/verification.d.ts +47 -0
- package/dist/providers/github/auth.d.ts +60 -0
- package/dist/providers/github/changed-files.d.ts +51 -0
- package/dist/providers/github/check-status-poster.d.ts +35 -0
- package/dist/providers/github/contributor-resolver.d.ts +30 -0
- package/dist/providers/github/index.d.ts +20 -0
- package/dist/providers/github/lock-file.d.ts +32 -0
- package/dist/providers/github/normalizer.d.ts +103 -0
- package/dist/providers/github/repo-url.d.ts +35 -0
- package/dist/providers/internal/index.d.ts +32 -0
- package/dist/providers/internal/lock-file-fetcher.d.ts +34 -0
- package/dist/providers/internal/normalizer.d.ts +89 -0
- package/dist/providers/internal/repo-url-builder.d.ts +42 -0
- package/dist/providers/universal-git/changed-files.d.ts +42 -0
- package/dist/providers/universal-git/clone-token.d.ts +83 -0
- package/dist/providers/universal-git/config.d.ts +192 -0
- package/dist/providers/universal-git/index.d.ts +55 -0
- package/dist/providers/universal-git/lock-file.d.ts +71 -0
- package/dist/providers/universal-git/normalizer.d.ts +90 -0
- package/dist/providers/universal-git/repo-url.d.ts +50 -0
- package/dist/providers/universal-git/ssh-auth.d.ts +94 -0
- package/dist/queue/bootstrap.d.ts +50 -0
- package/dist/queue/cleanup.d.ts +41 -0
- package/dist/queue/depth-refresher.d.ts +65 -0
- package/dist/queue/job-queue.d.ts +343 -0
- package/dist/queue/scheduled-job.d.ts +91 -0
- package/dist/registration/extractor.d.ts +44 -0
- package/dist/registration/registration-index.d.ts +162 -0
- package/dist/registration/registration-store.d.ts +111 -0
- package/dist/reporting/check-run-summary.d.ts +102 -0
- package/dist/reporting/commit-status.d.ts +382 -0
- package/dist/reporting/execution-tracker.d.ts +538 -0
- package/dist/reporting/fs-log-storage.d.ts +41 -0
- package/dist/reporting/log-pull-handler.d.ts +35 -0
- package/dist/reporting/log-storage.d.ts +70 -0
- package/dist/reporting/log-writer.d.ts +45 -0
- package/dist/reporting/s3-log-storage.d.ts +42 -0
- package/dist/reporting/step-log-buffer.d.ts +57 -0
- package/dist/routes/admin-access-log.d.ts +34 -0
- package/dist/routes/admin-backends.d.ts +28 -0
- package/dist/routes/admin-config.d.ts +57 -0
- package/dist/routes/admin-db.d.ts +20 -0
- package/dist/routes/admin-environments.d.ts +42 -0
- package/dist/routes/admin-errors.d.ts +4 -0
- package/dist/routes/admin-event-dlq.d.ts +39 -0
- package/dist/routes/admin-event-log.d.ts +42 -0
- package/dist/routes/admin-events.d.ts +46 -0
- package/dist/routes/admin-maintenance.d.ts +22 -0
- package/dist/routes/admin-org-settings.d.ts +29 -0
- package/dist/routes/admin-queue-execution.d.ts +27 -0
- package/dist/routes/admin-registrations.d.ts +37 -0
- package/dist/routes/admin-runs.d.ts +57 -0
- package/dist/routes/admin-scheduled-jobs.d.ts +36 -0
- package/dist/routes/admin-sources.d.ts +18 -0
- package/dist/routes/admin.d.ts +103 -0
- package/dist/routes/capabilities.d.ts +24 -0
- package/dist/routes/diagnostics.d.ts +16 -0
- package/dist/routes/health.d.ts +20 -0
- package/dist/routes/test-trigger.d.ts +41 -0
- package/dist/routes/uploads.d.ts +38 -0
- package/dist/routes/webhooks.d.ts +36 -0
- package/dist/scaler/bare-metal-backend.d.ts +107 -0
- package/dist/scaler/config.d.ts +303 -0
- package/dist/scaler/container-backend.d.ts +125 -0
- package/dist/scaler/file-tail.d.ts +23 -0
- package/dist/scaler/firecracker-api.d.ts +100 -0
- package/dist/scaler/firecracker-backend.d.ts +263 -0
- package/dist/scaler/index.d.ts +24 -0
- package/dist/scaler/ip-allocator.d.ts +177 -0
- package/dist/scaler/label-matcher.d.ts +73 -0
- package/dist/scaler/log-forwarder.d.ts +54 -0
- package/dist/scaler/machine-ledger.d.ts +160 -0
- package/dist/scaler/manager.d.ts +338 -0
- package/dist/scaler/nftables.d.ts +85 -0
- package/dist/scaler/types.d.ts +388 -0
- package/dist/scaler/warm-pool.d.ts +81 -0
- package/dist/secrets/audit-logger.d.ts +65 -0
- package/dist/secrets/backend-health.d.ts +60 -0
- package/dist/secrets/backend-registry.d.ts +68 -0
- package/dist/secrets/backend-sync.d.ts +40 -0
- package/dist/secrets/cleanup.d.ts +40 -0
- package/dist/secrets/config.d.ts +51 -0
- package/dist/secrets/crypto.d.ts +49 -0
- package/dist/secrets/ephemeral-keys.d.ts +49 -0
- package/dist/secrets/index.d.ts +17 -0
- package/dist/secrets/pg-secret-store.d.ts +105 -0
- package/dist/secrets/rbac.d.ts +47 -0
- package/dist/secrets/secret-output-store.d.ts +46 -0
- package/dist/secrets/secret-resolver.d.ts +137 -0
- package/dist/secrets/source-credentials.d.ts +61 -0
- package/dist/secrets/token-manager.d.ts +63 -0
- package/dist/secrets/vault-secret-store.d.ts +85 -0
- package/dist/security/comment-handler.d.ts +67 -0
- package/dist/security/contributor-cache.d.ts +75 -0
- package/dist/security/global-workflow-policy.d.ts +72 -0
- package/dist/security/lock-source.d.ts +34 -0
- package/dist/security/trust-resolver.d.ts +108 -0
- package/dist/security/workflow-diff.d.ts +26 -0
- package/dist/server.d.ts +17 -0
- package/dist/server.js +48055 -0
- package/dist/sources/index.d.ts +10 -0
- package/dist/sources/source-manager.d.ts +63 -0
- package/dist/sources/source-store.d.ts +79 -0
- package/dist/sources/source-validator.d.ts +16 -0
- package/dist/stale-detector/stale-run-detector.d.ts +109 -0
- package/dist/standalone.d.ts +20 -0
- package/dist/standalone.js +41546 -0
- package/dist/storage/blob-routes.d.ts +20 -0
- package/dist/storage/filesystem.d.ts +60 -0
- package/dist/storage/index.d.ts +20 -0
- package/dist/storage/s3.d.ts +68 -0
- package/dist/storage/sign-url.d.ts +45 -0
- package/dist/storage/types.d.ts +98 -0
- package/dist/webhook/dedup.d.ts +44 -0
- package/dist/webhook/event-log.d.ts +83 -0
- package/dist/webhook/generic-sources.d.ts +169 -0
- package/dist/webhook/handler.d.ts +23 -0
- package/dist/webhook/relay-buffer.d.ts +96 -0
- package/dist/webhook/verify-inbound.d.ts +78 -0
- package/dist/worker/in-memory-execution-tracker.d.ts +94 -0
- package/dist/worker/in-memory-job-queue.d.ts +74 -0
- package/dist/worker/static-agent-token-store.d.ts +58 -0
- package/dist/worker/worker-status.d.ts +36 -0
- package/dist/worker-core.d.ts +74 -0
- package/dist/ws/agent-api-registry.d.ts +49 -0
- package/dist/ws/agent-handler.d.ts +176 -0
- package/dist/ws/agent-heartbeat.d.ts +45 -0
- package/dist/ws/dashboard-backends-handler.d.ts +51 -0
- package/dist/ws/dashboard-diagnostics-handler.d.ts +56 -0
- package/dist/ws/dashboard-env-handler.d.ts +107 -0
- package/dist/ws/dashboard-global-workflows-handler.d.ts +72 -0
- package/dist/ws/dashboard-registrations-handler.d.ts +84 -0
- package/dist/ws/event-buffer.d.ts +16 -0
- package/dist/ws/observer-handler.d.ts +42 -0
- package/dist/ws/observer-registry.d.ts +88 -0
- package/dist/ws/platform-client.d.ts +270 -0
- package/dist/ws/server-options.d.ts +15 -0
- package/package.json +87 -6
- package/sbom.spdx.json +14370 -0
- package/index.js +0 -3
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `execution_steps` cold-store adapter (Orchestrator side).
|
|
3
|
+
*
|
|
4
|
+
*
|
|
5
|
+
* Contract:
|
|
6
|
+
* - tenant column: `routing_key` (denormalized in migration 006)
|
|
7
|
+
* - partition column: `created_at`
|
|
8
|
+
* - warm TTL: 30 days (design §5 matrix row 9)
|
|
9
|
+
* - eligibility: created_at < cutoff (steps are append-only and have no
|
|
10
|
+
* terminal-status predicate — there is no UPDATE statement against
|
|
11
|
+
* `execution_steps` in the orchestrator codebase, so age alone is
|
|
12
|
+
* sufficient)
|
|
13
|
+
*
|
|
14
|
+
* Order: registered FIRST in the orchestrator cold-store. Within one
|
|
15
|
+
* cycle the framework iterates adapters in registration order
|
|
16
|
+
* (steps → jobs → runs); steps go first so the FK chain
|
|
17
|
+
* (execution_jobs.run_id → execution_runs.run_id) doesn't break when
|
|
18
|
+
* jobs and runs are archived later.
|
|
19
|
+
*
|
|
20
|
+
* Audit emission: orchestrator-side adapters write to `access_log`
|
|
21
|
+
* (the orchestrator's audit surface; `audit_log` is Platform-side only).
|
|
22
|
+
* The row uses actor_type='system', actor_id='cold-store-archive:<id>'.
|
|
23
|
+
*/
|
|
24
|
+
import { type Kysely, type Selectable } from 'kysely';
|
|
25
|
+
import { type ChunkCommitMetadata, type ColdStoreTableConfig, type EligiblePartition, type TableAdapter } from '@kici-dev/shared';
|
|
26
|
+
import type { Database, ExecutionStepTable } from '../../db/types.js';
|
|
27
|
+
export type ExecutionStepRow = Selectable<ExecutionStepTable>;
|
|
28
|
+
export interface ExecutionStepsAdapterOptions {
|
|
29
|
+
overrides?: Partial<ColdStoreTableConfig>;
|
|
30
|
+
}
|
|
31
|
+
export declare class ExecutionStepsAdapter implements TableAdapter<ExecutionStepRow> {
|
|
32
|
+
private readonly kdb;
|
|
33
|
+
private readonly instanceId;
|
|
34
|
+
readonly db: "orchestrator";
|
|
35
|
+
readonly table = "execution_steps";
|
|
36
|
+
readonly tenantColumn = "routing_key";
|
|
37
|
+
readonly partitionColumn = "created_at";
|
|
38
|
+
readonly config: ColdStoreTableConfig;
|
|
39
|
+
constructor(kdb: Kysely<Database>, instanceId: string, opts?: ExecutionStepsAdapterOptions);
|
|
40
|
+
listEligiblePartitions(args: {
|
|
41
|
+
warmCutoff: Date;
|
|
42
|
+
}): AsyncIterable<EligiblePartition>;
|
|
43
|
+
countTenantWarmBytes(args: {
|
|
44
|
+
tenantId: string;
|
|
45
|
+
warmCutoff: Date;
|
|
46
|
+
}): Promise<number>;
|
|
47
|
+
withPartitionLock<T>(args: {
|
|
48
|
+
tenantId: string;
|
|
49
|
+
partitionDate: string;
|
|
50
|
+
}, fn: () => Promise<T>): Promise<T | null>;
|
|
51
|
+
selectEligible(args: {
|
|
52
|
+
tenantId: string;
|
|
53
|
+
partitionDate: string;
|
|
54
|
+
limit: number;
|
|
55
|
+
}): AsyncIterable<ExecutionStepRow>;
|
|
56
|
+
encodeRow(row: ExecutionStepRow): string;
|
|
57
|
+
decodeRow(line: string): ExecutionStepRow;
|
|
58
|
+
rowId(row: ExecutionStepRow): string | number;
|
|
59
|
+
rowTimestamp(row: ExecutionStepRow): Date | string;
|
|
60
|
+
markArchivedAndDelete(args: {
|
|
61
|
+
rowIds: ReadonlyArray<string | number>;
|
|
62
|
+
chunkMeta: ChunkCommitMetadata;
|
|
63
|
+
}): Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=execution-steps.d.ts.map
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `secret_audit_log` cold-store adapter (Orchestrator side).
|
|
3
|
+
*
|
|
4
|
+
*
|
|
5
|
+
* Contract:
|
|
6
|
+
* - tenant column: `routing_key` (NULL → synthetic `__orchestrator__`)
|
|
7
|
+
* - partition column: `timestamp`
|
|
8
|
+
* - warm TTL: 90 days (longer window than other audit tables — design
|
|
9
|
+
* §5 matrix row 10. Volume is low, forensic value is high)
|
|
10
|
+
*
|
|
11
|
+
* Synthetic tenant: rows without `routing_key` (e.g. orchestrator-level
|
|
12
|
+
* key rotations done before any source is bound) collapse to a single
|
|
13
|
+
* synthetic prefix `__orchestrator__`. Mirrors the same pattern already
|
|
14
|
+
* used for `event_log` payload keys when the routing key is missing.
|
|
15
|
+
*/
|
|
16
|
+
import { type Kysely, type Selectable } from 'kysely';
|
|
17
|
+
import { type ChunkCommitMetadata, type ColdRetention, type ColdStoreTableConfig, type EligiblePartition, type TableAdapter } from '@kici-dev/shared';
|
|
18
|
+
import type { Database, SecretAuditLogTable } from '../../db/types.js';
|
|
19
|
+
export type SecretAuditLogRow = Selectable<SecretAuditLogTable>;
|
|
20
|
+
export interface SecretAuditLogAdapterOptions {
|
|
21
|
+
overrides?: Partial<ColdStoreTableConfig>;
|
|
22
|
+
}
|
|
23
|
+
export declare class SecretAuditLogAdapter implements TableAdapter<SecretAuditLogRow> {
|
|
24
|
+
private readonly kdb;
|
|
25
|
+
private readonly instanceId;
|
|
26
|
+
readonly db: "orchestrator";
|
|
27
|
+
readonly table = "secret_audit_log";
|
|
28
|
+
readonly tenantColumn = "routing_key";
|
|
29
|
+
readonly partitionColumn = "timestamp";
|
|
30
|
+
readonly config: ColdStoreTableConfig;
|
|
31
|
+
constructor(kdb: Kysely<Database>, instanceId: string, opts?: SecretAuditLogAdapterOptions);
|
|
32
|
+
listEligiblePartitions(args: {
|
|
33
|
+
warmCutoff: Date;
|
|
34
|
+
}): AsyncIterable<EligiblePartition>;
|
|
35
|
+
countTenantWarmBytes(args: {
|
|
36
|
+
tenantId: string;
|
|
37
|
+
warmCutoff: Date;
|
|
38
|
+
}): Promise<number>;
|
|
39
|
+
withPartitionLock<T>(args: {
|
|
40
|
+
tenantId: string;
|
|
41
|
+
partitionDate: string;
|
|
42
|
+
}, fn: () => Promise<T>): Promise<T | null>;
|
|
43
|
+
selectEligible(args: {
|
|
44
|
+
tenantId: string;
|
|
45
|
+
partitionDate: string;
|
|
46
|
+
limit: number;
|
|
47
|
+
}): AsyncIterable<SecretAuditLogRow>;
|
|
48
|
+
encodeRow(row: SecretAuditLogRow): string;
|
|
49
|
+
decodeRow(line: string): SecretAuditLogRow;
|
|
50
|
+
rowId(row: SecretAuditLogRow): string | number;
|
|
51
|
+
rowTimestamp(row: SecretAuditLogRow): Date | string;
|
|
52
|
+
/**
|
|
53
|
+
* Phase 2 — per-row cold-retention TTL. Sampled `resolve` /
|
|
54
|
+
* `resolve_named` rows get 180d cold; mutations get `'forever'`. The
|
|
55
|
+
* denied-outcome override promotes to 730d (forensic).
|
|
56
|
+
*
|
|
57
|
+
* `outcome` is a free-form string in PG but the engine helper only
|
|
58
|
+
* branches on `outcome !== 'allowed'`, so any other value
|
|
59
|
+
* (`'denied'`, `'error'`, future categories) lands in the forensic
|
|
60
|
+
* bucket.
|
|
61
|
+
*/
|
|
62
|
+
coldTtlDays(row: SecretAuditLogRow): ColdRetention;
|
|
63
|
+
markArchivedAndDelete(args: {
|
|
64
|
+
rowIds: ReadonlyArray<string | number>;
|
|
65
|
+
chunkMeta: ChunkCommitMetadata;
|
|
66
|
+
}): Promise<void>;
|
|
67
|
+
purgeChunkRecord(args: {
|
|
68
|
+
tenantId: string;
|
|
69
|
+
chunkId: string;
|
|
70
|
+
gzipBytes: number;
|
|
71
|
+
rowCount: number;
|
|
72
|
+
bucket: string;
|
|
73
|
+
maxColdDays: number;
|
|
74
|
+
objectKey: string;
|
|
75
|
+
}): Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=secret-audit-log.d.ts.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slot-release dispatch helpers for the long-poll concurrency protocol.
|
|
3
|
+
*
|
|
4
|
+
* When a concurrency-group slot frees (run completed, run cancelled, run
|
|
5
|
+
* superseded), the orchestrator picks the FIFO-oldest queued row and wakes up
|
|
6
|
+
* the agent that's parked on its second `waitForConcurrencyAck` call. The
|
|
7
|
+
* agent then continues with normal step execution against the same WS
|
|
8
|
+
* connection it received the original dispatch on.
|
|
9
|
+
*
|
|
10
|
+
* If the in-memory waiter is missing (orchestrator restart, agent already
|
|
11
|
+
* disconnected), the dequeued DB row is marked completed so the slot doesn't
|
|
12
|
+
* get permanently stuck on a phantom holder.
|
|
13
|
+
*/
|
|
14
|
+
import type { AgentRegistry } from '../agent/registry.js';
|
|
15
|
+
import type { ConcurrencyGroupTracker } from './group-tracker.js';
|
|
16
|
+
import type { ConcurrencyQueueManager } from './queue-manager.js';
|
|
17
|
+
import type { ConcurrencyWaiters } from './waiters.js';
|
|
18
|
+
export interface DispatchNextQueuedDeps {
|
|
19
|
+
/** In-memory tracker — kept in sync with the DB on dequeue. */
|
|
20
|
+
tracker: ConcurrencyGroupTracker;
|
|
21
|
+
/** DB-backed queue manager. */
|
|
22
|
+
queueManager: ConcurrencyQueueManager;
|
|
23
|
+
/** Agent registry for finding the waiter's WS. */
|
|
24
|
+
registry: AgentRegistry;
|
|
25
|
+
/** In-memory waiter map. */
|
|
26
|
+
waiters: ConcurrencyWaiters;
|
|
27
|
+
/**
|
|
28
|
+
* Default max for `acquireSlot` when re-syncing the in-memory tracker after
|
|
29
|
+
* a dequeue. The runtime concurrency config (per-workflow `max`) is not
|
|
30
|
+
* available at slot-release time; the dequeued waiter has already been
|
|
31
|
+
* accounted for under that policy when it was originally enqueued, so any
|
|
32
|
+
* value `>= 1` is safe here. We pass 1 because the v1 contract documents
|
|
33
|
+
* single-slot semantics (max>1 is out of scope).
|
|
34
|
+
*/
|
|
35
|
+
trackerMaxFallback?: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Try to dequeue the next queued entry for `(group, routingKey)` and notify
|
|
39
|
+
* the waiting agent's WS with `concurrency.ack { action: 'proceed' }`.
|
|
40
|
+
*
|
|
41
|
+
* No-op if the queue is empty. When a dequeued waiter is missing or its
|
|
42
|
+
* agent is gone (orphaned row, agent disconnected), the helper LOOPS to the
|
|
43
|
+
* next queued row instead of stopping — otherwise a single orphan would
|
|
44
|
+
* permanently mask all live waiters behind it (orphans sort first by
|
|
45
|
+
* `created_at ASC`).
|
|
46
|
+
*
|
|
47
|
+
* Bounded by a defensive iteration cap so we never accidentally infinite-loop
|
|
48
|
+
* on a queue manager that returns the same row repeatedly.
|
|
49
|
+
*/
|
|
50
|
+
export declare function tryDispatchNextQueued(deps: DispatchNextQueuedDeps, group: string, routingKey: string): Promise<void>;
|
|
51
|
+
export interface AgentDisconnectDeps {
|
|
52
|
+
waiters: ConcurrencyWaiters;
|
|
53
|
+
queueManager: ConcurrencyQueueManager;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Build the agent-disconnect cleanup callback. Drops every waiter owned by
|
|
57
|
+
* the disconnecting agent and marks their `concurrency_groups` rows as
|
|
58
|
+
* cancelled so the queue manager doesn't try to dispatch a phantom run.
|
|
59
|
+
*
|
|
60
|
+
* Returns a no-arg-async closure suitable for passing to the agent WS handler.
|
|
61
|
+
*/
|
|
62
|
+
export declare function buildOnConcurrencyAgentDisconnect(deps: AgentDisconnectDeps): (agentId: string) => Promise<void>;
|
|
63
|
+
//# sourceMappingURL=dispatch-next-queued.d.ts.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory concurrency group tracker.
|
|
3
|
+
*
|
|
4
|
+
* Tracks active runs per concurrency group, scoped by routing key
|
|
5
|
+
* to prevent cross-repo interference. Supports slot acquisition/release
|
|
6
|
+
* and hydration from DB records on startup.
|
|
7
|
+
*/
|
|
8
|
+
/** Record used to hydrate tracker state from DB on startup. */
|
|
9
|
+
export interface HydrateRecord {
|
|
10
|
+
groupKey: string;
|
|
11
|
+
routingKey: string;
|
|
12
|
+
runId: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class ConcurrencyGroupTracker {
|
|
15
|
+
/**
|
|
16
|
+
* Scoped state: "routingKey::groupKey" -> ordered list of active run IDs.
|
|
17
|
+
* Using an array (not Set) to preserve insertion order for getOldestRun().
|
|
18
|
+
*/
|
|
19
|
+
private readonly groups;
|
|
20
|
+
private scopeKey;
|
|
21
|
+
private getOrCreateGroup;
|
|
22
|
+
/**
|
|
23
|
+
* Try to acquire a slot in the concurrency group.
|
|
24
|
+
* Returns true if under max capacity and the run was added, false otherwise.
|
|
25
|
+
* Idempotent: re-acquiring an already-active run returns true without double-adding.
|
|
26
|
+
*/
|
|
27
|
+
acquireSlot(groupKey: string, routingKey: string, runId: string, opts: {
|
|
28
|
+
max: number;
|
|
29
|
+
}): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Release a slot in the concurrency group.
|
|
32
|
+
* No-op if the run ID is not active.
|
|
33
|
+
*/
|
|
34
|
+
releaseSlot(groupKey: string, routingKey: string, runId: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* Get all active run IDs in a concurrency group.
|
|
37
|
+
* Returns a copy of the array.
|
|
38
|
+
*/
|
|
39
|
+
getActiveRuns(groupKey: string, routingKey: string): string[];
|
|
40
|
+
/**
|
|
41
|
+
* Get the oldest active run in a concurrency group.
|
|
42
|
+
* Used by cancelInProgress mode to determine which run to cancel.
|
|
43
|
+
*/
|
|
44
|
+
getOldestRun(groupKey: string, routingKey: string): string | null;
|
|
45
|
+
/**
|
|
46
|
+
* Hydrate tracker state from DB records.
|
|
47
|
+
* Called on orchestrator startup to restore active concurrency groups.
|
|
48
|
+
*/
|
|
49
|
+
hydrate(records: HydrateRecord[]): void;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=group-tracker.d.ts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DB-backed concurrency queue manager.
|
|
3
|
+
*
|
|
4
|
+
* Persists queued jobs to the concurrency_groups table and dequeues
|
|
5
|
+
* the oldest queued job when a slot opens. Works with ConcurrencyGroupTracker
|
|
6
|
+
* for slot-based coordination.
|
|
7
|
+
*/
|
|
8
|
+
import type { Kysely } from 'kysely';
|
|
9
|
+
import type { Database } from '../db/types.js';
|
|
10
|
+
/** A queued job returned from dequeue operations. */
|
|
11
|
+
export interface QueuedJob {
|
|
12
|
+
id: string;
|
|
13
|
+
groupKey: string;
|
|
14
|
+
routingKey: string;
|
|
15
|
+
runId: string;
|
|
16
|
+
jobId: string;
|
|
17
|
+
}
|
|
18
|
+
/** Options for enqueueing a job. */
|
|
19
|
+
export interface EnqueueOptions {
|
|
20
|
+
groupKey: string;
|
|
21
|
+
routingKey: string;
|
|
22
|
+
runId: string;
|
|
23
|
+
jobId: string;
|
|
24
|
+
}
|
|
25
|
+
export declare class ConcurrencyQueueManager {
|
|
26
|
+
private readonly db;
|
|
27
|
+
constructor(db: Kysely<Database>);
|
|
28
|
+
/**
|
|
29
|
+
* Enqueue a job that is waiting for a concurrency slot.
|
|
30
|
+
* Inserts a row with status='queued' into concurrency_groups.
|
|
31
|
+
*/
|
|
32
|
+
enqueue(opts: EnqueueOptions): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Record an active slot in the DB for persistence across restarts.
|
|
35
|
+
*/
|
|
36
|
+
recordActive(opts: EnqueueOptions): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Dequeue the oldest queued job for a concurrency group.
|
|
39
|
+
* Returns null if no queued jobs exist.
|
|
40
|
+
*/
|
|
41
|
+
dequeueNext(groupKey: string, routingKey: string): Promise<QueuedJob | null>;
|
|
42
|
+
/**
|
|
43
|
+
* Cancel all queued entries for a run.
|
|
44
|
+
* Marks them as 'cancelled' with a completion timestamp.
|
|
45
|
+
*/
|
|
46
|
+
cancelQueued(runId: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Mark a concurrency group entry as completed.
|
|
49
|
+
* Called when a job finishes (success/failed/cancelled).
|
|
50
|
+
*/
|
|
51
|
+
markCompleted(runId: string, groupKey: string, routingKey: string): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Handle job completion: mark completed and return next queued job if any.
|
|
54
|
+
* This is the main coordination point: when a slot opens, the next
|
|
55
|
+
* queued job should be dispatched.
|
|
56
|
+
*/
|
|
57
|
+
onJobComplete(groupKey: string, routingKey: string, runId: string): Promise<QueuedJob | null>;
|
|
58
|
+
/**
|
|
59
|
+
* Load all active entries from DB for hydrating the in-memory tracker.
|
|
60
|
+
* Called on orchestrator startup.
|
|
61
|
+
*/
|
|
62
|
+
loadActiveEntries(): Promise<Array<{
|
|
63
|
+
groupKey: string;
|
|
64
|
+
routingKey: string;
|
|
65
|
+
runId: string;
|
|
66
|
+
}>>;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=queue-manager.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory waiter registry for the long-poll concurrency protocol.
|
|
3
|
+
*
|
|
4
|
+
* When the orchestrator acks a `concurrency.report` with `{ action: 'wait' }`,
|
|
5
|
+
* the agent stays connected on the same WS waiting for an unsolicited follow-up
|
|
6
|
+
* `concurrency.ack`. This module tracks which agent is parked on which queued
|
|
7
|
+
* run so that, when a slot frees, we can find the right WS to wake up.
|
|
8
|
+
*
|
|
9
|
+
* The store is keyed on `(groupKey, routingKey)` tuples and preserves FIFO
|
|
10
|
+
* order within each scope (the same ordering invariant the queue manager uses
|
|
11
|
+
* in `concurrency_groups.created_at`).
|
|
12
|
+
*
|
|
13
|
+
* State is in-memory only — orchestrator restarts drop all WS connections
|
|
14
|
+
* anyway, so a queued waiter that survived a restart would have no agent to
|
|
15
|
+
* notify. The slot-release helper handles the missing-waiter case by marking
|
|
16
|
+
* the just-dequeued entry completed (effectively cancelling it).
|
|
17
|
+
*/
|
|
18
|
+
export interface WaiterEntry {
|
|
19
|
+
/** The run id queued behind a held slot. */
|
|
20
|
+
runId: string;
|
|
21
|
+
/** The job id the agent is parked on. */
|
|
22
|
+
jobId: string;
|
|
23
|
+
/** The agent id holding the WS connection. */
|
|
24
|
+
agentId: string;
|
|
25
|
+
}
|
|
26
|
+
export declare class ConcurrencyWaiters {
|
|
27
|
+
/** Scoped state: `${routingKey}\0${groupKey}` -> ordered FIFO of waiters. */
|
|
28
|
+
private readonly waiters;
|
|
29
|
+
private scopeKey;
|
|
30
|
+
/**
|
|
31
|
+
* Register a waiter for the given (group, routingKey). FIFO order is
|
|
32
|
+
* preserved across multiple registrations.
|
|
33
|
+
*/
|
|
34
|
+
register(groupKey: string, routingKey: string, entry: WaiterEntry): void;
|
|
35
|
+
/**
|
|
36
|
+
* Pop the FIFO-first waiter whose runId matches the given runId. Returns
|
|
37
|
+
* undefined if no waiter for that runId is registered (e.g. after an
|
|
38
|
+
* orchestrator restart, or because the WS already disconnected and called
|
|
39
|
+
* dropForAgent).
|
|
40
|
+
*
|
|
41
|
+
* Matches by runId (not "shift the head") because the queue-manager's
|
|
42
|
+
* `dequeueNext()` may pick a specific row; the in-memory tracker has to
|
|
43
|
+
* follow the DB's verdict, not the in-memory FIFO head independently.
|
|
44
|
+
*/
|
|
45
|
+
popByRunId(groupKey: string, routingKey: string, runId: string): WaiterEntry | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Drop all waiters owned by the given agent. Returns the dropped entries so
|
|
48
|
+
* the caller can `cancelQueued(runId)` the matching DB rows and emit failure
|
|
49
|
+
* events.
|
|
50
|
+
*
|
|
51
|
+
* Called from the agent-handler `onClose` so a disconnect doesn't leave a
|
|
52
|
+
* queued row dangling forever.
|
|
53
|
+
*/
|
|
54
|
+
dropForAgent(agentId: string): WaiterEntry[];
|
|
55
|
+
/** Number of registered waiters. Test-only. */
|
|
56
|
+
size(): number;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=waiters.d.ts.map
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/** Sentinel value used for redacted fields in display/export. */
|
|
2
|
+
export declare const REDACTED_VALUE = "***REDACTED***";
|
|
3
|
+
/**
|
|
4
|
+
* Get a value at a nested path in an object.
|
|
5
|
+
* Returns undefined if the path doesn't exist.
|
|
6
|
+
*
|
|
7
|
+
* @param obj - The object to traverse
|
|
8
|
+
* @param path - Dot-separated path (e.g., 'providers.github.appId')
|
|
9
|
+
*/
|
|
10
|
+
export declare function deepGet(obj: Record<string, unknown>, path: string): unknown;
|
|
11
|
+
/**
|
|
12
|
+
* Set a value at a nested path in an object.
|
|
13
|
+
* Creates intermediate objects as needed.
|
|
14
|
+
*
|
|
15
|
+
* @param obj - The object to modify (mutated in place)
|
|
16
|
+
* @param path - Dot-separated path (e.g., 'providers.github.appId')
|
|
17
|
+
* @param value - The value to set
|
|
18
|
+
*/
|
|
19
|
+
export declare function deepSet(obj: Record<string, unknown>, path: string, value: unknown): void;
|
|
20
|
+
/**
|
|
21
|
+
* Resolve a glob pattern path to concrete paths in an object.
|
|
22
|
+
* Supports '*' as a wildcard for array indices or object keys at one level.
|
|
23
|
+
*
|
|
24
|
+
* Example: 'providers.github.*.privateKey' on an object where
|
|
25
|
+
* providers.github is an array of 2 items resolves to:
|
|
26
|
+
* ['providers.github.0.privateKey', 'providers.github.1.privateKey']
|
|
27
|
+
*
|
|
28
|
+
* @param obj - The object to inspect
|
|
29
|
+
* @param pattern - Dot-separated path with optional '*' wildcards
|
|
30
|
+
* @returns Array of concrete dot-separated paths that exist in the object
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveGlobPaths(obj: Record<string, unknown>, pattern: string): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Encrypt sensitive fields in a config object.
|
|
35
|
+
*
|
|
36
|
+
* Traverses each sensitive field path pattern, resolves glob wildcards,
|
|
37
|
+
* and encrypts string values in place (in the cloned object).
|
|
38
|
+
*
|
|
39
|
+
* @param config - The config object to encrypt (not mutated)
|
|
40
|
+
* @param paths - Array of field path patterns (may contain '*' wildcards)
|
|
41
|
+
* @param key - 32-byte AES-256 encryption key
|
|
42
|
+
* @param keyVersion - Master-key generation that encrypted these values.
|
|
43
|
+
* Stored alongside the ciphertext so rotation can identify and re-seal rows.
|
|
44
|
+
* @returns Object with the encrypted config clone and list of actual encrypted paths
|
|
45
|
+
*/
|
|
46
|
+
export declare function encryptConfigFields(config: Record<string, unknown>, paths: string[], key: Buffer, keyVersion: number): {
|
|
47
|
+
encrypted: Record<string, unknown>;
|
|
48
|
+
encryptedPaths: string[];
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Decrypt sensitive fields in a config object.
|
|
52
|
+
*
|
|
53
|
+
* Uses the encrypted_paths array (stored alongside the config in the DB)
|
|
54
|
+
* to know exactly which paths need decryption.
|
|
55
|
+
*
|
|
56
|
+
* Accepts an optional `oldKey` so rows encrypted under a previous master-key
|
|
57
|
+
* generation continue to decrypt during the rotation grace window — matches
|
|
58
|
+
* `PgSecretStore.decryptWithFallback`.
|
|
59
|
+
*
|
|
60
|
+
* @param config - The config object with encrypted fields (not mutated)
|
|
61
|
+
* @param encryptedPaths - Array of concrete paths that contain encrypted values
|
|
62
|
+
* @param key - Current 32-byte AES-256 encryption key
|
|
63
|
+
* @param keyVersion - Generation stored alongside the row (carried into
|
|
64
|
+
* `EncryptedValue.keyVersion` so the crypto layer can surface key-mismatch
|
|
65
|
+
* telemetry; the AAD fully binds the ciphertext).
|
|
66
|
+
* @param oldKey - Optional previous generation key, tried when the current
|
|
67
|
+
* key fails (undefined/null means no fallback).
|
|
68
|
+
* @returns Decrypted config clone
|
|
69
|
+
*/
|
|
70
|
+
export declare function decryptConfigFields(config: Record<string, unknown>, encryptedPaths: string[], key: Buffer, keyVersion: number, oldKey?: Buffer | null): Record<string, unknown>;
|
|
71
|
+
/**
|
|
72
|
+
* Redact sensitive fields in a config object for safe display.
|
|
73
|
+
*
|
|
74
|
+
* Replaces values at encrypted paths with '***REDACTED***'.
|
|
75
|
+
* Used for CLI export and diff operations.
|
|
76
|
+
*
|
|
77
|
+
* @param config - The config object to redact (not mutated)
|
|
78
|
+
* @param encryptedPaths - Array of concrete paths to redact
|
|
79
|
+
* @returns Redacted config clone
|
|
80
|
+
*/
|
|
81
|
+
export declare function redactConfigFields(config: Record<string, unknown>, encryptedPaths: string[]): Record<string, unknown>;
|
|
82
|
+
//# sourceMappingURL=encryption.d.ts.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KICI_ environment variable to config path mapping and overlay.
|
|
3
|
+
*
|
|
4
|
+
* Converts KICI_-prefixed env vars to nested config paths and applies
|
|
5
|
+
* them as overrides on top of a config object.
|
|
6
|
+
*
|
|
7
|
+
* Multi-app env var convention:
|
|
8
|
+
* - App name in YAML: `main-org` -> env segment: `MAIN_ORG` (hyphen to underscore, uppercased)
|
|
9
|
+
* - Example: KICI_PROVIDERS_GITHUB_MAIN_ORG_APP_ID -> providers.github[name=main-org].appId
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Convert a KICI_ env var key to a config path array.
|
|
13
|
+
* Returns null for non-KICI_ keys or unknown mappings.
|
|
14
|
+
*
|
|
15
|
+
* Handles two patterns:
|
|
16
|
+
* 1. Direct mappings (KICI_DATABASE_URL -> ['database', 'url'])
|
|
17
|
+
* 2. Multi-app GitHub provider (KICI_PROVIDERS_GITHUB_<NAME>_<FIELD> ->
|
|
18
|
+
* ['providers', 'github', '<name-lowered>', '<camelField>'])
|
|
19
|
+
*/
|
|
20
|
+
export declare function envKeyToConfigPath(key: string): string[] | null;
|
|
21
|
+
/**
|
|
22
|
+
* Apply KICI_ env var overrides onto a config object.
|
|
23
|
+
* Iterates all env vars, maps KICI_ ones to paths, and deep-sets values.
|
|
24
|
+
*
|
|
25
|
+
* @param config - Base config object (cloned, not mutated)
|
|
26
|
+
* @param env - Process environment
|
|
27
|
+
* @returns New config object with env overrides applied
|
|
28
|
+
*/
|
|
29
|
+
export declare function applyEnvOverrides(config: Record<string, unknown>, env: NodeJS.ProcessEnv): Record<string, unknown>;
|
|
30
|
+
/**
|
|
31
|
+
* Deep merge two objects. Objects merge recursively, arrays replace,
|
|
32
|
+
* undefined/null values in source do NOT override target.
|
|
33
|
+
*/
|
|
34
|
+
export declare function deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown>;
|
|
35
|
+
/**
|
|
36
|
+
* Set a value at a nested path in an object.
|
|
37
|
+
* Creates intermediate objects as needed.
|
|
38
|
+
*/
|
|
39
|
+
export declare function deepSetByPath(obj: Record<string, unknown>, path: string[], value: unknown): void;
|
|
40
|
+
/**
|
|
41
|
+
* Get a value at a nested path in an object.
|
|
42
|
+
* Returns undefined if path doesn't exist.
|
|
43
|
+
*/
|
|
44
|
+
export declare function deepGetByPath(obj: Record<string, unknown>, path: string[]): unknown;
|
|
45
|
+
//# sourceMappingURL=env-overlay.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Barrel export for the orchestrator config module.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all types, schemas, and loader functions.
|
|
5
|
+
*/
|
|
6
|
+
export type { LocalConfig, SharedConfig, AppConfig, ConfigVersion } from './types.js';
|
|
7
|
+
export { localConfigSchema, sharedConfigSchema, appConfigSchema } from './schema.js';
|
|
8
|
+
export type { LocalConfigSchemaType, SharedConfigSchemaType, AppConfigSchemaType, } from './schema.js';
|
|
9
|
+
export { loadLocalConfig, SENSITIVE_FIELD_PATHS } from './loader.js';
|
|
10
|
+
export { SharedConfigStore, type ConfigVersionMeta } from './shared-store.js';
|
|
11
|
+
export { encryptConfigFields, decryptConfigFields, redactConfigFields, resolveGlobPaths, deepGet, deepSet, REDACTED_VALUE, } from './encryption.js';
|
|
12
|
+
export { envKeyToConfigPath, applyEnvOverrides, deepMerge, deepSetByPath, deepGetByPath, } from './env-overlay.js';
|
|
13
|
+
export { resolveLocalConfig, resolveFullConfig, getDefaults, type LocalPhaseResult, } from './resolver.js';
|
|
14
|
+
export { ConfigReloader } from './reload.js';
|
|
15
|
+
export type { ConfigReloaderDeps, ReloadResult, ReloadOptions, ReloadSource } from './reload.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YAML configuration file loader for the orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* Reads the local YAML config file from a configurable path with fallback:
|
|
5
|
+
* 1. Explicit configPath argument
|
|
6
|
+
* 2. KICI_CONFIG environment variable
|
|
7
|
+
* 3. /etc/kici/orchestrator.yaml default
|
|
8
|
+
*
|
|
9
|
+
* When no YAML file is found and no explicit path was given,
|
|
10
|
+
* returns an empty config (YAML is optional -- env-only mode).
|
|
11
|
+
*/
|
|
12
|
+
import type { LocalConfig } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Shared config field paths that contain sensitive values.
|
|
15
|
+
* Used by SharedConfigStore for encryption before DB storage.
|
|
16
|
+
*/
|
|
17
|
+
export declare const SENSITIVE_FIELD_PATHS: readonly ["platform.token", "secrets.key", "secrets.bootstrapAdminToken", "cluster.joinToken"];
|
|
18
|
+
/**
|
|
19
|
+
* Load and validate the local orchestrator YAML configuration.
|
|
20
|
+
*
|
|
21
|
+
* @param configPath - Explicit path to the config file (highest precedence)
|
|
22
|
+
* @returns Validated LocalConfig
|
|
23
|
+
* @throws Error if explicit path doesn't exist, or if validation fails
|
|
24
|
+
*/
|
|
25
|
+
export declare function loadLocalConfig(configPath?: string): Promise<LocalConfig>;
|
|
26
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hot-reload infrastructure for orchestrator configuration.
|
|
3
|
+
*
|
|
4
|
+
* ConfigReloader handles SIGHUP, HTTP endpoint, and programmatic reload triggers
|
|
5
|
+
* with debounce, mutex serialization, validation-before-swap, drain mode,
|
|
6
|
+
* and Prometheus metrics.
|
|
7
|
+
*
|
|
8
|
+
* Safety guarantees:
|
|
9
|
+
* - Concurrent reloads serialized via mutex (no partial state)
|
|
10
|
+
* - Validation before swap (old config preserved on failure)
|
|
11
|
+
* - Restart-required fields detected but not applied (database.url, server.port)
|
|
12
|
+
* - Drain mode for zero-disruption reload
|
|
13
|
+
*/
|
|
14
|
+
import type { Logger } from '@kici-dev/shared';
|
|
15
|
+
import type { AppConfig, SharedConfig } from './types.js';
|
|
16
|
+
import type { SharedConfigStore } from './shared-store.js';
|
|
17
|
+
/**
|
|
18
|
+
* Source of a reload trigger.
|
|
19
|
+
*/
|
|
20
|
+
export type ReloadSource = 'sighup' | 'http' | 'cluster' | 'cli';
|
|
21
|
+
/**
|
|
22
|
+
* Result of a reload operation.
|
|
23
|
+
*/
|
|
24
|
+
export interface ReloadResult {
|
|
25
|
+
success: boolean;
|
|
26
|
+
version?: number;
|
|
27
|
+
errors?: string[];
|
|
28
|
+
/** Fields that changed but need restart to apply */
|
|
29
|
+
restartRequired?: string[];
|
|
30
|
+
/** Fields that were hot-reloaded */
|
|
31
|
+
fieldsChanged?: string[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Options for executeReload.
|
|
35
|
+
*/
|
|
36
|
+
export interface ReloadOptions {
|
|
37
|
+
/** Whether to drain in-flight work before reloading */
|
|
38
|
+
drain?: boolean;
|
|
39
|
+
/** Reload trigger source for metrics */
|
|
40
|
+
source: ReloadSource;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Dependencies injected into ConfigReloader.
|
|
44
|
+
*/
|
|
45
|
+
export interface ConfigReloaderDeps {
|
|
46
|
+
/** Load local config from YAML + env */
|
|
47
|
+
resolveLocalConfig: () => Promise<{
|
|
48
|
+
local: Record<string, unknown>;
|
|
49
|
+
}>;
|
|
50
|
+
/** Merge all layers into AppConfig */
|
|
51
|
+
resolveFullConfig: (local: Record<string, unknown>, dbConfig: SharedConfig | null) => AppConfig;
|
|
52
|
+
/** Shared config store (null if no DB config) */
|
|
53
|
+
sharedStore: SharedConfigStore | null;
|
|
54
|
+
/** Called after successful reload when provider config changed */
|
|
55
|
+
onProviderChange?: (newConfig: AppConfig, oldConfig: AppConfig) => Promise<void>;
|
|
56
|
+
/** Called to reload scaler configuration */
|
|
57
|
+
onScalerReload?: () => Promise<void>;
|
|
58
|
+
/** Called when Platform connection settings changed */
|
|
59
|
+
onPlatformReconnect?: (newConfig: AppConfig) => Promise<void>;
|
|
60
|
+
/** Atomic swap callback -- replaces the config reference */
|
|
61
|
+
onConfigApplied?: (newConfig: AppConfig) => void;
|
|
62
|
+
/** Start draining in-flight work */
|
|
63
|
+
startDrain?: () => Promise<void>;
|
|
64
|
+
/** Stop drain and resume accepting work */
|
|
65
|
+
stopDrain?: () => void;
|
|
66
|
+
logger: Logger;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* ConfigReloader manages hot-reload of orchestrator configuration.
|
|
70
|
+
*
|
|
71
|
+
* Handles SIGHUP signals, HTTP-triggered reloads, and cluster-triggered reloads
|
|
72
|
+
* with debounce, mutex, validation-before-swap, and Prometheus metrics.
|
|
73
|
+
*/
|
|
74
|
+
export declare class ConfigReloader {
|
|
75
|
+
private currentConfig;
|
|
76
|
+
private reloading;
|
|
77
|
+
private debounceTimer;
|
|
78
|
+
private currentVersion;
|
|
79
|
+
private readonly deps;
|
|
80
|
+
/** Debounce interval in milliseconds */
|
|
81
|
+
static DEBOUNCE_MS: number;
|
|
82
|
+
constructor(initialConfig: AppConfig, deps: ConfigReloaderDeps);
|
|
83
|
+
/**
|
|
84
|
+
* Trigger a reload (debounced).
|
|
85
|
+
* Multiple rapid triggers will be collapsed into a single reload.
|
|
86
|
+
*/
|
|
87
|
+
triggerReload(source: ReloadSource, opts?: {
|
|
88
|
+
drain?: boolean;
|
|
89
|
+
}): void;
|
|
90
|
+
/**
|
|
91
|
+
* Execute reload immediately (no debounce).
|
|
92
|
+
* Used by tests and direct API calls that need synchronous results.
|
|
93
|
+
*/
|
|
94
|
+
executeReload(opts: ReloadOptions): Promise<ReloadResult>;
|
|
95
|
+
/**
|
|
96
|
+
* Get the current effective config.
|
|
97
|
+
*/
|
|
98
|
+
getCurrentConfig(): AppConfig;
|
|
99
|
+
/**
|
|
100
|
+
* Get the current shared config version.
|
|
101
|
+
*/
|
|
102
|
+
getCurrentVersion(): number;
|
|
103
|
+
/**
|
|
104
|
+
* Install SIGHUP handler for signal-triggered reload.
|
|
105
|
+
* SIGHUP triggers unified reload of both orchestrator config AND scaler config.
|
|
106
|
+
*/
|
|
107
|
+
installSignalHandler(): void;
|
|
108
|
+
/**
|
|
109
|
+
* Clean up timers and resources.
|
|
110
|
+
*/
|
|
111
|
+
dispose(): void;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=reload.d.ts.map
|