@kici-dev/orchestrator 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__test-helpers__/scratch-db.d.ts +16 -0
- package/dist/agent/registry.d.ts +1 -8
- package/dist/app-on-error.d.ts +1 -1
- package/dist/artifacts/artifact-store.d.ts +0 -2
- package/dist/audit/access-log.d.ts +1 -1
- package/dist/cache/source-cache.d.ts +1 -1
- package/dist/cache/user-cache.d.ts +0 -28
- package/dist/cli/api-client.d.ts +27 -1
- package/dist/cli/commands/access-log.d.ts +1 -1
- package/dist/cli/commands/cold-store-impl.d.ts +7 -84
- package/dist/cli/commands/db.d.ts +1 -0
- package/dist/cli/commands/orchestrator-service/status.d.ts +2 -0
- package/dist/cli/commands/org.d.ts +12 -0
- package/dist/cli/commands/scaler.d.ts +14 -0
- package/dist/cli/commands/secret.d.ts +1 -45
- package/dist/cli/commands/service-health.d.ts +21 -13
- package/dist/cli/commands/shared/cli-action.d.ts +17 -0
- package/dist/cli/commands/shared/db.d.ts +5 -5
- package/dist/cli/commands/shared/org-id.d.ts +5 -0
- package/dist/cli/commands/shared/service-verbs.d.ts +19 -0
- package/dist/cli/commands/shared/table.d.ts +3 -0
- package/dist/cli/commands/shared/unbound-context-warning.d.ts +2 -22
- package/dist/cli/commands/trust-policy.d.ts +7 -31
- package/dist/cli/kici-admin.d.ts +1 -1
- package/dist/cli.js +9863 -8201
- package/dist/cluster/coordinator.d.ts +2 -2
- package/dist/cluster/peer-client.d.ts +27 -1
- package/dist/cluster/peer-forget.d.ts +4 -9
- package/dist/cluster/peer-handler.d.ts +11 -1
- package/dist/cluster/peer-request-waiters.d.ts +26 -0
- package/dist/cluster/scaler-orphans-peer.d.ts +4 -9
- package/dist/cluster/scaler-reload-fanout.d.ts +29 -0
- package/dist/cluster/scaler-reload-peer.d.ts +16 -0
- package/dist/cluster/worker-cluster-settings.d.ts +1 -0
- package/dist/cold-store/load-access-log-range.d.ts +3 -3
- package/dist/cold-store/tables/access-log.d.ts +4 -12
- package/dist/cold-store/tables/event-log.d.ts +8 -19
- package/dist/cold-store/tables/execution-jobs.d.ts +7 -24
- package/dist/cold-store/tables/execution-runs.d.ts +6 -20
- package/dist/cold-store/tables/execution-steps.d.ts +8 -26
- package/dist/cold-store/tables/secret-audit-log.d.ts +4 -11
- package/dist/config/env-overlay.d.ts +3 -8
- package/dist/config/reload.d.ts +9 -2
- package/dist/config/schema.d.ts +2 -2
- package/dist/config/types.d.ts +2 -2
- package/dist/config.d.ts +13 -17
- package/dist/contexts/held-runs.d.ts +3 -6
- package/dist/dashboard/cursor.d.ts +12 -0
- package/dist/dashboard/handler.d.ts +5 -12
- package/dist/db/deferred-index-build.d.ts +42 -0
- package/dist/db/deferred-indexes.d.ts +3 -37
- package/dist/db/migrations/100_held_runs_hold_type_vocabulary.d.ts +3 -5
- package/dist/db/migrations/158_normalize_legacy_values.d.ts +4 -0
- package/dist/db/repos/org-ids-repo.d.ts +87 -0
- package/dist/db/schema-snapshot.generated.d.ts +3 -0
- package/dist/db/types.d.ts +5 -22
- package/dist/fault-injection-types.d.ts +0 -6
- package/dist/git/dispatch-git-auth.d.ts +6 -12
- package/dist/helpers/json.d.ts +3 -0
- package/dist/index.js +133 -136
- package/dist/metrics/prometheus.d.ts +0 -5
- package/dist/oidc/id-token-claims.d.ts +1 -1
- package/dist/oidc/resolve-signer.d.ts +2 -4
- package/dist/orchestrator-core.d.ts +10 -3
- package/dist/pipeline/global-eval-round.d.ts +2 -26
- package/dist/pipeline/install-secrets-resolver.d.ts +0 -3
- package/dist/pipeline/manual-schedule.d.ts +1 -7
- package/dist/provenance/dispatch-context.d.ts +5 -7
- package/dist/provenance/pending-attestations-repo.d.ts +1 -1
- package/dist/provenance/trust-root.d.ts +4 -5
- package/dist/provenance/verify-deferred-capture.d.ts +3 -3
- package/dist/provider-registry.d.ts +13 -40
- package/dist/providers/universal-git/ssh-auth.d.ts +0 -5
- package/dist/reporting/check-run-reporter.d.ts +8 -21
- package/dist/reporting/check-run-summary.d.ts +2 -2
- package/dist/reporting/execution-tracker.d.ts +1 -1
- package/dist/reporting/log-chunk-sink.d.ts +1 -1
- package/dist/reporting/run-summary-fields.d.ts +25 -0
- package/dist/reporting/s3-log-storage.d.ts +2 -2
- package/dist/routes/admin-access-log.d.ts +2 -9
- package/dist/routes/admin-backends.d.ts +2 -9
- package/dist/routes/admin-cluster-name.d.ts +2 -8
- package/dist/routes/admin-cluster-settings.d.ts +2 -8
- package/dist/routes/admin-config.d.ts +0 -3
- package/dist/routes/admin-contexts.d.ts +3 -11
- package/dist/routes/admin-db.d.ts +2 -9
- package/dist/routes/admin-env.d.ts +33 -0
- package/dist/routes/admin-event-dlq.d.ts +2 -9
- package/dist/routes/admin-event-inspect.d.ts +2 -9
- package/dist/routes/admin-event-log.d.ts +2 -9
- package/dist/routes/admin-events.d.ts +3 -13
- package/dist/routes/admin-held-runs.d.ts +2 -8
- package/dist/routes/admin-list-limit.d.ts +3 -0
- package/dist/routes/admin-maintenance.d.ts +2 -9
- package/dist/routes/admin-orchestrator-drain.d.ts +2 -9
- package/dist/routes/admin-org-settings.d.ts +2 -8
- package/dist/routes/admin-orgs.d.ts +27 -0
- package/dist/routes/admin-peer-forget.d.ts +2 -9
- package/dist/routes/admin-queue-execution.d.ts +3 -10
- package/dist/routes/admin-registrations.d.ts +3 -14
- package/dist/routes/admin-runs.d.ts +3 -14
- package/dist/routes/admin-scaler-orphans.d.ts +2 -9
- package/dist/routes/admin-scaler-reload.d.ts +41 -0
- package/dist/routes/admin-scheduled-jobs.d.ts +2 -9
- package/dist/routes/admin-signing-keys.d.ts +2 -9
- package/dist/routes/admin-sources.d.ts +2 -9
- package/dist/routes/admin-trust-policy.d.ts +2 -8
- package/dist/routes/admin.d.ts +15 -13
- package/dist/scaler/config.d.ts +12 -84
- package/dist/scaler/file-reload.d.ts +48 -0
- package/dist/scaler/manager.d.ts +47 -33
- package/dist/scaler/scaler-state-store.d.ts +5 -0
- package/dist/scaler/types.d.ts +1 -4
- package/dist/secrets/job-secret-gate.d.ts +2 -5
- package/dist/secrets/secret-resolver.d.ts +2 -4
- package/dist/security/trust-policy-gate.d.ts +0 -4
- package/dist/server.d.ts +6 -17
- package/dist/server.js +6693 -8005
- package/dist/standalone.js +5826 -6555
- package/dist/worker/reroute-dispatch.d.ts +1 -0
- package/dist/worker/reroute-spawn-control.d.ts +1 -3
- package/dist/worker-core.d.ts +9 -2
- package/dist/ws/agent-handler.d.ts +3 -3
- package/dist/ws/dashboard-access.d.ts +57 -0
- package/dist/ws/dashboard-backends-handler.d.ts +1 -6
- package/dist/ws/dashboard-context-handler.d.ts +10 -15
- package/dist/ws/dashboard-fleet-write-handler.d.ts +1 -6
- package/dist/ws/dashboard-global-workflows-handler.d.ts +1 -6
- package/dist/ws/dashboard-registrations-handler.d.ts +1 -7
- package/dist/ws/platform-client.d.ts +85 -330
- package/installer-image-digests.json +3 -3
- package/package.json +4 -4
- package/sbom.spdx.json +53 -53
- package/dist/cache/legacy-prefixes.d.ts +0 -19
- package/dist/cli/commands/agent-service/logs.d.ts +0 -14
- package/dist/cli/commands/agent-service/restart.d.ts +0 -12
- package/dist/cli/commands/agent-service/start.d.ts +0 -12
- package/dist/cli/commands/agent-service/stop.d.ts +0 -12
- package/dist/cli/commands/agent-service/uninstall.d.ts +0 -13
- package/dist/cli/commands/cache.d.ts +0 -51
- package/dist/cli/commands/orchestrator-service/logs.d.ts +0 -14
- package/dist/cli/commands/orchestrator-service/restart.d.ts +0 -12
- package/dist/cli/commands/orchestrator-service/start.d.ts +0 -12
- package/dist/cli/commands/orchestrator-service/stop.d.ts +0 -12
- package/dist/cli/commands/orchestrator-service/uninstall.d.ts +0 -13
- package/dist/git/inherited-secret.d.ts +0 -29
|
@@ -212,8 +212,8 @@ export declare class RunCoordinator {
|
|
|
212
212
|
* timer: whichever fires first removes the tracking entry.
|
|
213
213
|
* - `final: false` — the worker is retrying. Re-arm the window for one more
|
|
214
214
|
* attempt plus the backoff; treat the `maxAttempts`-th such relay as final.
|
|
215
|
-
* - no verdict —
|
|
216
|
-
*
|
|
215
|
+
* - no verdict — a repeated report of one failed spawn. The window armed at
|
|
216
|
+
* the reroute keeps running unchanged.
|
|
217
217
|
*
|
|
218
218
|
* Two guards make the re-dispatch safe. First, source provenance: the failure
|
|
219
219
|
* must come from `fromPeerId === tracked.peerId` (the authenticated connection
|
|
@@ -14,10 +14,12 @@
|
|
|
14
14
|
* frame after acceptance uses an application key that needs the shared secret.
|
|
15
15
|
* A server that does not offer mutual-v2 gets no proof at all.
|
|
16
16
|
*/
|
|
17
|
-
import { type PeerHeartbeat, type PeerToPeerMessage, type JobReroute, type JobProgress, type JobProgressAck, type PeerJobCancel, type PeerLogChunk, type PeerCacheUploadRequest, type PeerCacheUploadResponse, type PeerConfigReload, type PeerConfigReloadResponse, type PeerScalerOrphansRequest, type PeerForgetRequest, type PeerForgetResponse, type PeerScalerOrphansResponse, type PeerClusterSettingsRequest, type PeerClusterSettingsResponse, type PeerLogsCollectRequest, type PeerLeaving, type PeerAgentTokenRevoke, type RaftVoteRequest, type RaftVoteResponse, type RaftAppendEntries } from '@kici-dev/engine';
|
|
17
|
+
import { type PeerHeartbeat, type PeerToPeerMessage, type JobReroute, type JobProgress, type JobProgressAck, type PeerJobCancel, type PeerLogChunk, type PeerCacheUploadRequest, type PeerCacheUploadResponse, type PeerConfigReload, type PeerConfigReloadResponse, type PeerScalerOrphansRequest, type PeerForgetRequest, type PeerForgetResponse, type PeerScalerOrphansResponse, type PeerClusterSettingsRequest, type PeerClusterSettingsResponse, type PeerLogsCollectRequest, type PeerLeaving, type PeerAgentTokenRevoke, type RaftVoteRequest, type RaftVoteResponse, type RaftAppendEntries, type PeerScalerReloadRequest, type PeerScalerReloadResponse } from '@kici-dev/engine';
|
|
18
18
|
import { type PeerRegistry } from './peer-registry.js';
|
|
19
19
|
import { type PEER_FORGET_TIMEOUT, type PeerForgetRequestHandler } from './peer-forget.js';
|
|
20
20
|
import { type SCALER_ORPHANS_TIMEOUT, type ScalerOrphansRequestHandler } from './scaler-orphans-peer.js';
|
|
21
|
+
import type { PEER_REQUEST_TIMEOUT } from './peer-request-waiters.js';
|
|
22
|
+
import type { ScalerFileReload } from '../scaler/file-reload.js';
|
|
21
23
|
import type { PeerAuthCoordinator } from './peer-auth-coordinator.js';
|
|
22
24
|
/** Logged when this instance has neither a credential file nor a join token. */
|
|
23
25
|
export declare const NO_AUTH_METHOD_MESSAGE = "No peer auth method: this instance has no credential file and no join token";
|
|
@@ -140,6 +142,12 @@ export interface PeerClientOptions {
|
|
|
140
142
|
* requests are answered with ok=false.
|
|
141
143
|
*/
|
|
142
144
|
onScalerOrphansRequest?: ScalerOrphansRequestHandler;
|
|
145
|
+
/**
|
|
146
|
+
* Reloads this node's scaler config for a peer.scaler.reload.request the
|
|
147
|
+
* connected coordinator sent (`kici-admin scaler reload`). If undefined,
|
|
148
|
+
* requests are answered `rejected`.
|
|
149
|
+
*/
|
|
150
|
+
onScalerReloadRequest?: ScalerFileReload;
|
|
143
151
|
/**
|
|
144
152
|
* Forgets a departed peer the connected coordinator forgot (`kici-admin peer
|
|
145
153
|
* forget`). If undefined, requests are answered with outcome `error`.
|
|
@@ -173,6 +181,7 @@ export declare class PeerClient {
|
|
|
173
181
|
private readonly cacheWaiters;
|
|
174
182
|
private readonly configReloadWaiters;
|
|
175
183
|
private readonly scalerOrphansWaiters;
|
|
184
|
+
private readonly scalerReloadWaiters;
|
|
176
185
|
private readonly peerForgetWaiters;
|
|
177
186
|
private readonly clusterSettingsWaiters;
|
|
178
187
|
/** Correlates peer.logs.collect.request with the peer's chunked subtree response. */
|
|
@@ -211,6 +220,7 @@ export declare class PeerClient {
|
|
|
211
220
|
private readonly onAuthenticated?;
|
|
212
221
|
private readonly onLogsCollectRequest?;
|
|
213
222
|
private readonly onScalerOrphansRequest?;
|
|
223
|
+
private readonly onScalerReloadRequest?;
|
|
214
224
|
private readonly onPeerForgetRequest?;
|
|
215
225
|
constructor(options: PeerClientOptions);
|
|
216
226
|
/** Current connection state. */
|
|
@@ -266,6 +276,14 @@ export declare class PeerClient {
|
|
|
266
276
|
* response arrived within `timeoutMs`.
|
|
267
277
|
*/
|
|
268
278
|
sendScalerOrphansAndWait(msg: PeerScalerOrphansRequest, timeoutMs: number): Promise<PeerScalerOrphansResponse | null | typeof SCALER_ORPHANS_TIMEOUT>;
|
|
279
|
+
/**
|
|
280
|
+
* Send a peer.scaler.reload.request to the connected peer and wait for the
|
|
281
|
+
* matching response.
|
|
282
|
+
*
|
|
283
|
+
* @returns the response; null when not connected; `'timeout'` when no
|
|
284
|
+
* response arrived within `timeoutMs`.
|
|
285
|
+
*/
|
|
286
|
+
sendScalerReloadAndWait(msg: PeerScalerReloadRequest, timeoutMs: number): Promise<PeerScalerReloadResponse | null | typeof PEER_REQUEST_TIMEOUT>;
|
|
269
287
|
/**
|
|
270
288
|
* Send a peer.clusterSettings.request to the connected coordinator and wait for
|
|
271
289
|
* the matching peer.clusterSettings.response carrying the worker-settings snapshot.
|
|
@@ -342,6 +360,14 @@ export declare class PeerClient {
|
|
|
342
360
|
* client never reads or writes the credential file directly.
|
|
343
361
|
*/
|
|
344
362
|
private sendAuthRequest;
|
|
363
|
+
/**
|
|
364
|
+
* Route the operator-relay pairs (`scaler orphans --target`, `peer forget`,
|
|
365
|
+
* `scaler reload`): answer a request from the coordinator this client
|
|
366
|
+
* dialled, or hand a response to the request waiting for it.
|
|
367
|
+
*
|
|
368
|
+
* @returns whether `msg` was one of them.
|
|
369
|
+
*/
|
|
370
|
+
private routeOperatorRelay;
|
|
345
371
|
private routeMessage;
|
|
346
372
|
private startHeartbeat;
|
|
347
373
|
private stopHeartbeat;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PeerForgetOutcome, type PeerForgetRequest, type PeerForgetResponse } from '@kici-dev/engine';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import type { PeerRegistry } from './peer-registry.js';
|
|
4
|
+
import { PeerRequestWaiters } from './peer-request-waiters.js';
|
|
4
5
|
/** What forgetting did on one coordinator. */
|
|
5
6
|
export interface PeerForgetResult {
|
|
6
7
|
/** The coordinator that answered. */
|
|
@@ -125,14 +126,8 @@ export declare function forgetAcrossCoordinators(registry: PeerRegistry, selfIns
|
|
|
125
126
|
* link to: registered coordinators whose connection is down.
|
|
126
127
|
*/
|
|
127
128
|
export declare function disconnectedCoordinatorIds(registry: PeerRegistry, selfInstanceId: string): string[];
|
|
128
|
-
/** Pending forget requests sent to siblings
|
|
129
|
-
export declare class PeerForgetWaiters {
|
|
130
|
-
|
|
131
|
-
/** Wait for the response to `messageId`, or {@link PEER_FORGET_TIMEOUT}. */
|
|
132
|
-
wait(messageId: string, timeoutMs: number): Promise<PeerForgetResponse | typeof PEER_FORGET_TIMEOUT>;
|
|
133
|
-
/** Hand a response to the request waiting for it. An unknown id is dropped. */
|
|
134
|
-
resolve(response: PeerForgetResponse): void;
|
|
135
|
-
/** End every pending wait with an `error` response naming `reason`. */
|
|
136
|
-
rejectAll(reason: string): void;
|
|
129
|
+
/** Pending forget requests sent to siblings; a close answers each `error` naming the reason. */
|
|
130
|
+
export declare class PeerForgetWaiters extends PeerRequestWaiters<PeerForgetResponse> {
|
|
131
|
+
constructor();
|
|
137
132
|
}
|
|
138
133
|
//# sourceMappingURL=peer-forget.d.ts.map
|
|
@@ -11,10 +11,12 @@
|
|
|
11
11
|
* with PEER_MUTUAL_AUTH_REQUIRED_REASON. Registers the peer in PeerRegistry and
|
|
12
12
|
* routes messages bidirectionally. Sends periodic heartbeats to the peer.
|
|
13
13
|
*/
|
|
14
|
-
import { type PeerHeartbeat, type PeerToPeerMessage, type JobReroute, type JobProgress, type JobProgressAck, type PeerScalerEvent, type PeerJobCancel, type PeerLogChunk, type PeerCacheUploadRequest, type PeerCacheUploadResponse, type PeerConfigReload, type PeerConfigReloadResponse, type PeerScalerOrphansRequest, type PeerForgetRequest, type PeerForgetResponse, type PeerScalerOrphansResponse, type PeerClusterSettingsRequest, type WorkerClusterSettings, type PeerLogsCollectRequest, type PeerLeaving, type PeerAgentTokenRevoke, type RaftVoteRequest, type RaftVoteResponse, type RaftAppendEntries } from '@kici-dev/engine';
|
|
14
|
+
import { type PeerHeartbeat, type PeerToPeerMessage, type JobReroute, type JobProgress, type JobProgressAck, type PeerScalerEvent, type PeerJobCancel, type PeerLogChunk, type PeerCacheUploadRequest, type PeerCacheUploadResponse, type PeerConfigReload, type PeerConfigReloadResponse, type PeerScalerOrphansRequest, type PeerForgetRequest, type PeerForgetResponse, type PeerScalerOrphansResponse, type PeerClusterSettingsRequest, type WorkerClusterSettings, type PeerLogsCollectRequest, type PeerLeaving, type PeerAgentTokenRevoke, type RaftVoteRequest, type RaftVoteResponse, type RaftAppendEntries, type PeerScalerReloadRequest, type PeerScalerReloadResponse } from '@kici-dev/engine';
|
|
15
15
|
import { type PeerRegistry } from './peer-registry.js';
|
|
16
16
|
import { type PEER_FORGET_TIMEOUT, type PeerForgetRequestHandler } from './peer-forget.js';
|
|
17
17
|
import { type SCALER_ORPHANS_TIMEOUT, type ScalerOrphansRequestHandler } from './scaler-orphans-peer.js';
|
|
18
|
+
import type { PEER_REQUEST_TIMEOUT } from './peer-request-waiters.js';
|
|
19
|
+
import type { ScalerFileReload } from '../scaler/file-reload.js';
|
|
18
20
|
import type { PeerCredentialStore } from './peer-credentials.js';
|
|
19
21
|
import { type JoinTokenManager } from './join-token.js';
|
|
20
22
|
/**
|
|
@@ -118,6 +120,13 @@ export interface PeerHandlerDeps {
|
|
|
118
120
|
* requests are answered with ok=false.
|
|
119
121
|
*/
|
|
120
122
|
onScalerOrphansRequest?: ScalerOrphansRequestHandler;
|
|
123
|
+
/**
|
|
124
|
+
* Reloads this node's scaler config for a peer.scaler.reload.request
|
|
125
|
+
* (`kici-admin scaler reload`). A request from a peer that is not a
|
|
126
|
+
* coordinator is refused before it reaches the handler. If undefined,
|
|
127
|
+
* requests are answered `rejected`.
|
|
128
|
+
*/
|
|
129
|
+
onScalerReloadRequest?: ScalerFileReload;
|
|
121
130
|
/**
|
|
122
131
|
* Forgets a departed peer a sibling coordinator forgot (`kici-admin peer
|
|
123
132
|
* forget`). A request from a peer that is not a coordinator is refused. If
|
|
@@ -155,6 +164,7 @@ export declare function createPeerHandler(deps: PeerHandlerDeps): {
|
|
|
155
164
|
sendAndWaitAck: (targetInstanceId: string, msg: JobReroute, timeoutMs?: number) => Promise<boolean>;
|
|
156
165
|
sendConfigReloadAndWait: (targetInstanceId: string, msg: PeerConfigReload, timeoutMs?: number) => Promise<PeerConfigReloadResponse | null>;
|
|
157
166
|
sendScalerOrphansAndWait: (targetInstanceId: string, msg: PeerScalerOrphansRequest, timeoutMs: number) => Promise<PeerScalerOrphansResponse | null | typeof SCALER_ORPHANS_TIMEOUT>;
|
|
167
|
+
sendScalerReloadAndWait: (targetInstanceId: string, msg: PeerScalerReloadRequest, timeoutMs: number) => Promise<PeerScalerReloadResponse | null | typeof PEER_REQUEST_TIMEOUT>;
|
|
158
168
|
sendPeerForgetAndWait: (targetInstanceId: string, msg: PeerForgetRequest, timeoutMs: number) => Promise<PeerForgetResponse | null | typeof PEER_FORGET_TIMEOUT>;
|
|
159
169
|
sendLogsCollectAndWait: (targetInstanceId: string, msg: PeerLogsCollectRequest, timeoutMs: number) => Promise<Buffer>;
|
|
160
170
|
getConnectionCount: () => number;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Correlates a peer request with its response by message id. Shared by every
|
|
3
|
+
* request/response pair the outgoing `PeerClient` and the incoming peer handler
|
|
4
|
+
* carry, so each pair needs only its response type and its close-time answer.
|
|
5
|
+
*/
|
|
6
|
+
/** A wait that ended without a response. */
|
|
7
|
+
export declare const PEER_REQUEST_TIMEOUT = "timeout";
|
|
8
|
+
/** Pending peer requests of one message pair, keyed by message id. */
|
|
9
|
+
export declare class PeerRequestWaiters<TResponse extends {
|
|
10
|
+
messageId: string;
|
|
11
|
+
}> {
|
|
12
|
+
private readonly closedResponse;
|
|
13
|
+
private readonly waiters;
|
|
14
|
+
/**
|
|
15
|
+
* @param closedResponse the answer each pending wait gets when the connection
|
|
16
|
+
* closes, built from its message id and the close reason.
|
|
17
|
+
*/
|
|
18
|
+
constructor(closedResponse: (messageId: string, reason: string) => TResponse);
|
|
19
|
+
/** Wait for the response to `messageId`, or {@link PEER_REQUEST_TIMEOUT}. */
|
|
20
|
+
wait(messageId: string, timeoutMs: number): Promise<TResponse | typeof PEER_REQUEST_TIMEOUT>;
|
|
21
|
+
/** Hand a response to the request waiting for it. An unknown id is dropped. */
|
|
22
|
+
resolve(response: TResponse): void;
|
|
23
|
+
/** End every pending wait with the close-time answer naming `reason`. */
|
|
24
|
+
rejectAll(reason: string): void;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=peer-request-waiters.d.ts.map
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
import type { PeerScalerOrphansRequest, PeerScalerOrphansResponse } from '@kici-dev/engine';
|
|
9
9
|
import type { ScalerOrphansAnswer } from '../scaler/orphan-requests.js';
|
|
10
|
+
import { PeerRequestWaiters } from './peer-request-waiters.js';
|
|
10
11
|
/** Answers a forwarded request from this node's own host and tracking. */
|
|
11
12
|
export type ScalerOrphansRequestHandler = (msg: PeerScalerOrphansRequest) => Promise<ScalerOrphansAnswer>;
|
|
12
13
|
/** The answer of a peer that has no handler wired. */
|
|
@@ -27,14 +28,8 @@ export declare const SCALER_ORPHANS_TIMEOUT: "timeout";
|
|
|
27
28
|
* out its timeout for a peer that cannot answer.
|
|
28
29
|
*/
|
|
29
30
|
export declare function replyToScalerOrphansRequest(msg: PeerScalerOrphansRequest, handler: ScalerOrphansRequestHandler | undefined, send: (response: PeerScalerOrphansResponse) => void, logFields?: Record<string, unknown>): void;
|
|
30
|
-
/** Pending scaler orphan requests
|
|
31
|
-
export declare class ScalerOrphansWaiters {
|
|
32
|
-
|
|
33
|
-
/** Wait for the response to `messageId`, or {@link SCALER_ORPHANS_TIMEOUT}. */
|
|
34
|
-
wait(messageId: string, timeoutMs: number): Promise<PeerScalerOrphansResponse | typeof SCALER_ORPHANS_TIMEOUT>;
|
|
35
|
-
/** Hand a response to the request waiting for it. An unknown id is dropped. */
|
|
36
|
-
resolve(response: PeerScalerOrphansResponse): void;
|
|
37
|
-
/** End every pending wait with an `ok: false` response naming `reason`. */
|
|
38
|
-
rejectAll(reason: string): void;
|
|
31
|
+
/** Pending scaler orphan requests; a close answers each `ok: false` naming the reason. */
|
|
32
|
+
export declare class ScalerOrphansWaiters extends PeerRequestWaiters<PeerScalerOrphansResponse> {
|
|
33
|
+
constructor();
|
|
39
34
|
}
|
|
40
35
|
//# sourceMappingURL=scaler-orphans-peer.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type PeerScalerReloadRequest, type PeerScalerReloadResponse, type ScalerReloadInstanceResult } from '@kici-dev/engine';
|
|
2
|
+
import type { ScalerFileReload } from '../scaler/file-reload.js';
|
|
3
|
+
import type { PeerRegistry } from './peer-registry.js';
|
|
4
|
+
import { PEER_REQUEST_TIMEOUT } from './peer-request-waiters.js';
|
|
5
|
+
/**
|
|
6
|
+
* Sends one scaler reload request to a peer and waits for its answer. Resolves
|
|
7
|
+
* null when no connection reached the peer, and {@link PEER_REQUEST_TIMEOUT}
|
|
8
|
+
* when it did not answer within `timeoutMs`.
|
|
9
|
+
*/
|
|
10
|
+
export type SendScalerReload = (instanceId: string, msg: PeerScalerReloadRequest, timeoutMs: number) => Promise<PeerScalerReloadResponse | null | typeof PEER_REQUEST_TIMEOUT>;
|
|
11
|
+
export interface ScalerReloadAcrossClusterOptions {
|
|
12
|
+
selfInstanceId: string;
|
|
13
|
+
selfRole: 'coordinator' | 'worker';
|
|
14
|
+
registry: Pick<PeerRegistry, 'getAllPeers'>;
|
|
15
|
+
local: ScalerFileReload;
|
|
16
|
+
send: SendScalerReload;
|
|
17
|
+
/** Reload this orchestrator only. */
|
|
18
|
+
single: boolean;
|
|
19
|
+
/** How long to wait for each peer's answer. */
|
|
20
|
+
timeoutMs: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Reload this orchestrator and every peer in its registry. A connected peer
|
|
24
|
+
* (coordinator or worker) gets the request; a known peer that is not connected
|
|
25
|
+
* is reported `unreachable` without one. The local reload and the peer
|
|
26
|
+
* requests run at the same time; the first result is this orchestrator's.
|
|
27
|
+
*/
|
|
28
|
+
export declare function reloadScalersAcrossCluster(opts: ScalerReloadAcrossClusterOptions): Promise<ScalerReloadInstanceResult[]>;
|
|
29
|
+
//# sourceMappingURL=scaler-reload-fanout.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type PeerScalerReloadRequest, type PeerScalerReloadResponse } from '@kici-dev/engine';
|
|
2
|
+
import type { ScalerFileReload } from '../scaler/file-reload.js';
|
|
3
|
+
import { PeerRequestWaiters } from './peer-request-waiters.js';
|
|
4
|
+
/** The answer to a request a worker sent: a worker never directs another node's scalers. */
|
|
5
|
+
export declare const SCALER_RELOAD_COORDINATORS_ONLY_DETAIL = "scaler reload requests are accepted from coordinators only";
|
|
6
|
+
/**
|
|
7
|
+
* Answer one request through `send`. A missing handler and a handler failure
|
|
8
|
+
* are both answered `rejected`, so the requester never waits out its timeout
|
|
9
|
+
* for a peer that cannot answer.
|
|
10
|
+
*/
|
|
11
|
+
export declare function replyToScalerReloadRequest(msg: PeerScalerReloadRequest, handler: ScalerFileReload | undefined, send: (response: PeerScalerReloadResponse) => void, logFields?: Record<string, unknown>): void;
|
|
12
|
+
/** Pending scaler reload requests; a close answers each `unreachable` naming the reason. */
|
|
13
|
+
export declare class ScalerReloadWaiters extends PeerRequestWaiters<PeerScalerReloadResponse> {
|
|
14
|
+
constructor();
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=scaler-reload-peer.d.ts.map
|
|
@@ -13,6 +13,7 @@ import type { ClusterSettingsReader } from './cluster-settings-reader.js';
|
|
|
13
13
|
export interface WorkerClusterSettingDefaults {
|
|
14
14
|
agentTokenTtlMs: number;
|
|
15
15
|
firecrackerApiSocketWaitMs: number;
|
|
16
|
+
concurrencyWaitTimeoutMs: number;
|
|
16
17
|
}
|
|
17
18
|
/** A worker snapshot and the `cluster_settings.version` its values belong to. */
|
|
18
19
|
export interface WorkerClusterSettingsSnapshot {
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
* the hot tuple comparison `(created_at, id) < (cursor.createdAt, cursor.id)`.
|
|
15
15
|
* The cursor also carries a `source: 'hot' | 'cold'` discriminator so a
|
|
16
16
|
* cursor minted while the page boundary was inside cold can resume in
|
|
17
|
-
* the cold stream on the next request.
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* the cold stream on the next request. A cursor without a valid `source` is
|
|
18
|
+
* invalid, like any other unparsable cursor, and the read starts from the
|
|
19
|
+
* first page.
|
|
20
20
|
*/
|
|
21
21
|
import { type Kysely, type Selectable } from 'kysely';
|
|
22
22
|
import { type ColdStore } from '@kici-dev/shared';
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `access_log` cold-store adapter (Orchestrator side).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
4
|
* Contract:
|
|
6
5
|
* - tenant column: `org_id` (NULL → synthetic `__orchestrator__`)
|
|
7
6
|
* - partition column: `created_at`
|
|
8
7
|
* - warm TTL: 30 days
|
|
9
8
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* indefinitely.
|
|
9
|
+
* Rows older than 30 days live in S3 indefinitely; there is no
|
|
10
|
+
* `expires_at`-based hard delete.
|
|
13
11
|
*
|
|
14
12
|
* Synthetic tenant: orchestrator-level access events (e.g. scheduler
|
|
15
13
|
* tick failures, admin-triggered scheduled jobs) carry `org_id IS
|
|
@@ -21,20 +19,18 @@
|
|
|
21
19
|
* audit row per ~50K-row chunk.
|
|
22
20
|
*/
|
|
23
21
|
import { type Kysely, type Selectable } from 'kysely';
|
|
24
|
-
import { type ChunkCommitMetadata, type ColdRetention, type ColdStoreTableConfig, type EligiblePartition, type TableAdapter } from '@kici-dev/shared';
|
|
22
|
+
import { type ChunkCommitMetadata, type ColdRetention, type ColdStoreTableConfig, type EligiblePartition, type TableAdapter, PgTableAdapterBase } from '@kici-dev/shared';
|
|
25
23
|
import type { AccessLogTable, Database } from '../../db/types.js';
|
|
26
24
|
export type AccessLogColdStoreRow = Selectable<AccessLogTable>;
|
|
27
25
|
export interface AccessLogAdapterOptions {
|
|
28
26
|
overrides?: Partial<ColdStoreTableConfig>;
|
|
29
27
|
}
|
|
30
|
-
export declare class AccessLogAdapter implements TableAdapter<AccessLogColdStoreRow> {
|
|
31
|
-
private readonly kdb;
|
|
28
|
+
export declare class AccessLogAdapter extends PgTableAdapterBase<Database> implements TableAdapter<AccessLogColdStoreRow> {
|
|
32
29
|
private readonly instanceId;
|
|
33
30
|
readonly db: 'orchestrator';
|
|
34
31
|
readonly table = "access_log";
|
|
35
32
|
readonly tenantColumn = "org_id";
|
|
36
33
|
readonly partitionColumn = "created_at";
|
|
37
|
-
readonly config: ColdStoreTableConfig;
|
|
38
34
|
constructor(kdb: Kysely<Database>, instanceId: string, opts?: AccessLogAdapterOptions);
|
|
39
35
|
listEligiblePartitions(args: {
|
|
40
36
|
warmCutoff: Date;
|
|
@@ -43,10 +39,6 @@ export declare class AccessLogAdapter implements TableAdapter<AccessLogColdStore
|
|
|
43
39
|
tenantId: string;
|
|
44
40
|
warmCutoff: Date;
|
|
45
41
|
}): Promise<number>;
|
|
46
|
-
withPartitionLock<T>(args: {
|
|
47
|
-
tenantId: string;
|
|
48
|
-
partitionDate: string;
|
|
49
|
-
}, fn: () => Promise<T>): Promise<T | null>;
|
|
50
42
|
selectEligible(args: {
|
|
51
43
|
tenantId: string;
|
|
52
44
|
partitionDate: string;
|
|
@@ -7,34 +7,27 @@
|
|
|
7
7
|
* - partition column: `received_at`
|
|
8
8
|
* - warm TTL: 30 days (rows are archived, not hard-deleted)
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* S3 indefinitely so the dashboard delivery-detail page resolves
|
|
15
|
-
* payload reads identically for hot and cold rows. Nothing deletes the
|
|
16
|
-
* row and the payload blob in lock-step.
|
|
10
|
+
* Each row's `payload_key` points at a gzipped webhook body in object
|
|
11
|
+
* storage. Archiving moves the row, `payload_key` included, and leaves the
|
|
12
|
+
* body where it is, so the delivery-detail page reads payloads the same way
|
|
13
|
+
* for hot and cold rows.
|
|
17
14
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* access_log rows themselves get archived in a later cycle by the
|
|
21
|
-
* AccessLogAdapter, bounded.
|
|
15
|
+
* Each archived chunk writes one `access_log` audit row, which the
|
|
16
|
+
* AccessLogAdapter archives in a later cycle.
|
|
22
17
|
*/
|
|
23
18
|
import { type Kysely, type Selectable } from 'kysely';
|
|
24
|
-
import { type ChunkCommitMetadata, type ColdStoreTableConfig, type EligiblePartition, type TableAdapter } from '@kici-dev/shared';
|
|
19
|
+
import { type ChunkCommitMetadata, type ColdStoreTableConfig, type EligiblePartition, type TableAdapter, PgTableAdapterBase } from '@kici-dev/shared';
|
|
25
20
|
import type { Database, EventLogTable } from '../../db/types.js';
|
|
26
21
|
export type EventLogColdStoreRow = Selectable<EventLogTable>;
|
|
27
22
|
export interface EventLogAdapterOptions {
|
|
28
23
|
overrides?: Partial<ColdStoreTableConfig>;
|
|
29
24
|
}
|
|
30
|
-
export declare class EventLogAdapter implements TableAdapter<EventLogColdStoreRow> {
|
|
31
|
-
private readonly kdb;
|
|
25
|
+
export declare class EventLogAdapter extends PgTableAdapterBase<Database> implements TableAdapter<EventLogColdStoreRow> {
|
|
32
26
|
private readonly instanceId;
|
|
33
27
|
readonly db: 'orchestrator';
|
|
34
28
|
readonly table = "event_log";
|
|
35
29
|
readonly tenantColumn = "routing_key";
|
|
36
30
|
readonly partitionColumn = "received_at";
|
|
37
|
-
readonly config: ColdStoreTableConfig;
|
|
38
31
|
constructor(kdb: Kysely<Database>, instanceId: string, opts?: EventLogAdapterOptions);
|
|
39
32
|
listEligiblePartitions(args: {
|
|
40
33
|
warmCutoff: Date;
|
|
@@ -43,10 +36,6 @@ export declare class EventLogAdapter implements TableAdapter<EventLogColdStoreRo
|
|
|
43
36
|
tenantId: string;
|
|
44
37
|
warmCutoff: Date;
|
|
45
38
|
}): Promise<number>;
|
|
46
|
-
withPartitionLock<T>(args: {
|
|
47
|
-
tenantId: string;
|
|
48
|
-
partitionDate: string;
|
|
49
|
-
}, fn: () => Promise<T>): Promise<T | null>;
|
|
50
39
|
selectEligible(args: {
|
|
51
40
|
tenantId: string;
|
|
52
41
|
partitionDate: string;
|
|
@@ -1,39 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `execution_jobs` cold-store adapter (Orchestrator side).
|
|
3
3
|
*
|
|
4
|
+
* Tenant column `routing_key`, partition column `created_at`, warm TTL 30
|
|
5
|
+
* days. Eligible: a terminal job with no live step rows for its (run, job).
|
|
4
6
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - warm TTL: 30 days
|
|
9
|
-
* - eligibility: terminal job status AND no live steps remain for this
|
|
10
|
-
* (run, job)
|
|
11
|
-
*
|
|
12
|
-
* Order: registered AFTER `ExecutionStepsAdapter`, BEFORE
|
|
13
|
-
* `ExecutionRunsAdapter` (within one cycle: steps → jobs → runs). The
|
|
14
|
-
* "no live steps" predicate makes the ordering self-correcting across
|
|
15
|
-
* cycle interruptions.
|
|
16
|
-
*
|
|
17
|
-
* FK ordering on the orchestrator side: `execution_jobs.run_id` is a
|
|
18
|
-
* FK to `execution_runs(run_id)`. Deleting a job is safe from the FK's
|
|
19
|
-
* perspective (the FK only constrains job → run direction). The runs
|
|
20
|
-
* adapter's eligibility predicate handles the dependent-rows check.
|
|
7
|
+
* Registered between the steps and runs adapters (steps → jobs → runs).
|
|
8
|
+
* Deleting a job never trips the `execution_jobs.run_id → execution_runs`
|
|
9
|
+
* FK; the runs adapter skips runs that still have jobs.
|
|
21
10
|
*/
|
|
22
11
|
import { type Kysely, type Selectable } from 'kysely';
|
|
23
|
-
import { type ChunkCommitMetadata, type ColdStoreTableConfig, type EligiblePartition, type TableAdapter } from '@kici-dev/shared';
|
|
12
|
+
import { type ChunkCommitMetadata, type ColdStoreTableConfig, type EligiblePartition, type TableAdapter, PgTableAdapterBase } from '@kici-dev/shared';
|
|
24
13
|
import type { Database, ExecutionJobTable } from '../../db/types.js';
|
|
25
14
|
export type ExecutionJobRow = Selectable<ExecutionJobTable>;
|
|
26
15
|
export interface ExecutionJobsAdapterOptions {
|
|
27
16
|
overrides?: Partial<ColdStoreTableConfig>;
|
|
28
17
|
}
|
|
29
|
-
export declare class ExecutionJobsAdapter implements TableAdapter<ExecutionJobRow> {
|
|
30
|
-
private readonly kdb;
|
|
18
|
+
export declare class ExecutionJobsAdapter extends PgTableAdapterBase<Database> implements TableAdapter<ExecutionJobRow> {
|
|
31
19
|
private readonly instanceId;
|
|
32
20
|
readonly db: 'orchestrator';
|
|
33
21
|
readonly table = "execution_jobs";
|
|
34
22
|
readonly tenantColumn = "routing_key";
|
|
35
23
|
readonly partitionColumn = "created_at";
|
|
36
|
-
readonly config: ColdStoreTableConfig;
|
|
37
24
|
constructor(kdb: Kysely<Database>, instanceId: string, opts?: ExecutionJobsAdapterOptions);
|
|
38
25
|
listEligiblePartitions(args: {
|
|
39
26
|
warmCutoff: Date;
|
|
@@ -42,10 +29,6 @@ export declare class ExecutionJobsAdapter implements TableAdapter<ExecutionJobRo
|
|
|
42
29
|
tenantId: string;
|
|
43
30
|
warmCutoff: Date;
|
|
44
31
|
}): Promise<number>;
|
|
45
|
-
withPartitionLock<T>(args: {
|
|
46
|
-
tenantId: string;
|
|
47
|
-
partitionDate: string;
|
|
48
|
-
}, fn: () => Promise<T>): Promise<T | null>;
|
|
49
32
|
selectEligible(args: {
|
|
50
33
|
tenantId: string;
|
|
51
34
|
partitionDate: string;
|
|
@@ -1,34 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `execution_runs` cold-store adapter (Orchestrator side).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - warm TTL: 30 days
|
|
9
|
-
* - eligibility: terminal run status AND no live jobs reference this run
|
|
10
|
-
*
|
|
11
|
-
* Order: registered LAST in the orchestrator cold-store. Within one
|
|
12
|
-
* cycle the framework iterates adapters steps → jobs → runs; this
|
|
13
|
-
* adapter goes last so the FK `execution_jobs.run_id →
|
|
14
|
-
* execution_runs(run_id)` doesn't fire on DELETE. The "no live jobs"
|
|
15
|
-
* predicate enforces the same invariant across cycle interruptions.
|
|
4
|
+
* Tenant column `routing_key`, partition column `created_at`, warm TTL 30
|
|
5
|
+
* days. Eligible: a terminal run that no live job references. Registered
|
|
6
|
+
* last (steps → jobs → runs) so the `execution_jobs.run_id` FK never fires
|
|
7
|
+
* on DELETE.
|
|
16
8
|
*/
|
|
17
9
|
import { type Kysely, type Selectable } from 'kysely';
|
|
18
|
-
import { type ChunkCommitMetadata, type ColdStoreTableConfig, type EligiblePartition, type TableAdapter } from '@kici-dev/shared';
|
|
10
|
+
import { type ChunkCommitMetadata, type ColdStoreTableConfig, type EligiblePartition, type TableAdapter, PgTableAdapterBase } from '@kici-dev/shared';
|
|
19
11
|
import type { Database, ExecutionRunTable } from '../../db/types.js';
|
|
20
12
|
export type ExecutionRunRow = Selectable<ExecutionRunTable>;
|
|
21
13
|
export interface ExecutionRunsAdapterOptions {
|
|
22
14
|
overrides?: Partial<ColdStoreTableConfig>;
|
|
23
15
|
}
|
|
24
|
-
export declare class ExecutionRunsAdapter implements TableAdapter<ExecutionRunRow> {
|
|
25
|
-
private readonly kdb;
|
|
16
|
+
export declare class ExecutionRunsAdapter extends PgTableAdapterBase<Database> implements TableAdapter<ExecutionRunRow> {
|
|
26
17
|
private readonly instanceId;
|
|
27
18
|
readonly db: 'orchestrator';
|
|
28
19
|
readonly table = "execution_runs";
|
|
29
20
|
readonly tenantColumn = "routing_key";
|
|
30
21
|
readonly partitionColumn = "created_at";
|
|
31
|
-
readonly config: ColdStoreTableConfig;
|
|
32
22
|
constructor(kdb: Kysely<Database>, instanceId: string, opts?: ExecutionRunsAdapterOptions);
|
|
33
23
|
listEligiblePartitions(args: {
|
|
34
24
|
warmCutoff: Date;
|
|
@@ -37,10 +27,6 @@ export declare class ExecutionRunsAdapter implements TableAdapter<ExecutionRunRo
|
|
|
37
27
|
tenantId: string;
|
|
38
28
|
warmCutoff: Date;
|
|
39
29
|
}): Promise<number>;
|
|
40
|
-
withPartitionLock<T>(args: {
|
|
41
|
-
tenantId: string;
|
|
42
|
-
partitionDate: string;
|
|
43
|
-
}, fn: () => Promise<T>): Promise<T | null>;
|
|
44
30
|
selectEligible(args: {
|
|
45
31
|
tenantId: string;
|
|
46
32
|
partitionDate: string;
|
|
@@ -1,41 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `execution_steps` cold-store adapter (Orchestrator side).
|
|
3
3
|
*
|
|
4
|
+
* Tenant column `routing_key`, partition column `created_at`, warm TTL 30
|
|
5
|
+
* days. Steps are append-only, so age alone makes a row eligible.
|
|
4
6
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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>'.
|
|
7
|
+
* Registered first: the framework archives in registration order (steps →
|
|
8
|
+
* jobs → runs), which keeps the `execution_jobs.run_id → execution_runs` FK
|
|
9
|
+
* chain intact. The archive audit row goes to `access_log`, the
|
|
10
|
+
* orchestrator's audit surface, as actor `cold-store-archive:<instanceId>`.
|
|
23
11
|
*/
|
|
24
12
|
import { type Kysely, type Selectable } from 'kysely';
|
|
25
|
-
import { type ChunkCommitMetadata, type ColdStoreTableConfig, type EligiblePartition, type TableAdapter } from '@kici-dev/shared';
|
|
13
|
+
import { type ChunkCommitMetadata, type ColdStoreTableConfig, type EligiblePartition, type TableAdapter, PgTableAdapterBase } from '@kici-dev/shared';
|
|
26
14
|
import type { Database, ExecutionStepTable } from '../../db/types.js';
|
|
27
15
|
export type ExecutionStepRow = Selectable<ExecutionStepTable>;
|
|
28
16
|
export interface ExecutionStepsAdapterOptions {
|
|
29
17
|
overrides?: Partial<ColdStoreTableConfig>;
|
|
30
18
|
}
|
|
31
|
-
export declare class ExecutionStepsAdapter implements TableAdapter<ExecutionStepRow> {
|
|
32
|
-
private readonly kdb;
|
|
19
|
+
export declare class ExecutionStepsAdapter extends PgTableAdapterBase<Database> implements TableAdapter<ExecutionStepRow> {
|
|
33
20
|
private readonly instanceId;
|
|
34
21
|
readonly db: 'orchestrator';
|
|
35
22
|
readonly table = "execution_steps";
|
|
36
23
|
readonly tenantColumn = "routing_key";
|
|
37
24
|
readonly partitionColumn = "created_at";
|
|
38
|
-
readonly config: ColdStoreTableConfig;
|
|
39
25
|
constructor(kdb: Kysely<Database>, instanceId: string, opts?: ExecutionStepsAdapterOptions);
|
|
40
26
|
listEligiblePartitions(args: {
|
|
41
27
|
warmCutoff: Date;
|
|
@@ -44,10 +30,6 @@ export declare class ExecutionStepsAdapter implements TableAdapter<ExecutionStep
|
|
|
44
30
|
tenantId: string;
|
|
45
31
|
warmCutoff: Date;
|
|
46
32
|
}): Promise<number>;
|
|
47
|
-
withPartitionLock<T>(args: {
|
|
48
|
-
tenantId: string;
|
|
49
|
-
partitionDate: string;
|
|
50
|
-
}, fn: () => Promise<T>): Promise<T | null>;
|
|
51
33
|
selectEligible(args: {
|
|
52
34
|
tenantId: string;
|
|
53
35
|
partitionDate: string;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `secret_audit_log` cold-store adapter (Orchestrator side).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
4
|
* Contract:
|
|
6
5
|
* - tenant column: `routing_key` (NULL → synthetic `__orchestrator__`)
|
|
7
6
|
* - partition column: `timestamp`
|
|
8
|
-
* - warm TTL:
|
|
9
|
-
*
|
|
7
|
+
* - warm TTL: `minSecretAuditLogWarmDays()` table-wide, tightened per row
|
|
8
|
+
* by `secretAuditLogWarmSqlCase()`
|
|
10
9
|
*
|
|
11
10
|
* Synthetic tenant: rows without `routing_key` (e.g. orchestrator-level
|
|
12
11
|
* key rotations done before any source is bound) collapse to a single
|
|
@@ -14,21 +13,19 @@
|
|
|
14
13
|
* used for `event_log` payload keys when the routing key is missing.
|
|
15
14
|
*/
|
|
16
15
|
import { type Kysely } from 'kysely';
|
|
17
|
-
import { type ChunkCommitMetadata, type ColdRetention, type ColdStoreTableConfig, type EligiblePartition, type TableAdapter } from '@kici-dev/shared';
|
|
16
|
+
import { type ChunkCommitMetadata, type ColdRetention, type ColdStoreTableConfig, type EligiblePartition, type TableAdapter, PgTableAdapterBase } from '@kici-dev/shared';
|
|
18
17
|
import type { Database, SecretAuditLogRow } from '../../db/types.js';
|
|
19
18
|
/** Re-exported rather than re-declared — see the note in `load-event-log-range`. */
|
|
20
19
|
export type { SecretAuditLogRow };
|
|
21
20
|
export interface SecretAuditLogAdapterOptions {
|
|
22
21
|
overrides?: Partial<ColdStoreTableConfig>;
|
|
23
22
|
}
|
|
24
|
-
export declare class SecretAuditLogAdapter implements TableAdapter<SecretAuditLogRow> {
|
|
25
|
-
private readonly kdb;
|
|
23
|
+
export declare class SecretAuditLogAdapter extends PgTableAdapterBase<Database> implements TableAdapter<SecretAuditLogRow> {
|
|
26
24
|
private readonly instanceId;
|
|
27
25
|
readonly db: 'orchestrator';
|
|
28
26
|
readonly table = "secret_audit_log";
|
|
29
27
|
readonly tenantColumn = "routing_key";
|
|
30
28
|
readonly partitionColumn = "timestamp";
|
|
31
|
-
readonly config: ColdStoreTableConfig;
|
|
32
29
|
constructor(kdb: Kysely<Database>, instanceId: string, opts?: SecretAuditLogAdapterOptions);
|
|
33
30
|
listEligiblePartitions(args: {
|
|
34
31
|
warmCutoff: Date;
|
|
@@ -37,10 +34,6 @@ export declare class SecretAuditLogAdapter implements TableAdapter<SecretAuditLo
|
|
|
37
34
|
tenantId: string;
|
|
38
35
|
warmCutoff: Date;
|
|
39
36
|
}): Promise<number>;
|
|
40
|
-
withPartitionLock<T>(args: {
|
|
41
|
-
tenantId: string;
|
|
42
|
-
partitionDate: string;
|
|
43
|
-
}, fn: () => Promise<T>): Promise<T | null>;
|
|
44
37
|
selectEligible(args: {
|
|
45
38
|
tenantId: string;
|
|
46
39
|
partitionDate: string;
|
|
@@ -3,20 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Converts KICI_-prefixed env vars to nested config paths and applies
|
|
5
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
6
|
*/
|
|
11
7
|
/**
|
|
12
8
|
* Convert a KICI_ env var key to a config path array.
|
|
13
9
|
* Returns null for non-KICI_ keys or unknown mappings.
|
|
14
10
|
*
|
|
15
11
|
* Handles three patterns:
|
|
16
|
-
* 1.
|
|
17
|
-
* 2.
|
|
18
|
-
* 3.
|
|
19
|
-
* ['providers', 'github', '<name-lowered>', '<camelField>'])
|
|
12
|
+
* 1. Unprefixed names the startup loader reads (NODE_ENV -> ['nodeEnv'])
|
|
13
|
+
* 2. Direct mappings (KICI_DATABASE_URL -> ['database', 'url'])
|
|
14
|
+
* 3. Startup names whose overlay spelling differs (KICI_PORT -> ['server', 'port'])
|
|
20
15
|
*/
|
|
21
16
|
export declare function envKeyToConfigPath(key: string): string[] | null;
|
|
22
17
|
/**
|