@kici-dev/engine 0.14.2 → 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/approval/expiry-duration.d.ts +11 -0
- package/dist/approval/expiry-duration.js +29 -0
- package/dist/audit/access-log-policy.js +2 -0
- package/dist/audit/retention-policy.d.ts +1 -1
- package/dist/audit/retention-policy.js +5 -1
- package/dist/auth/permissions.d.ts +69 -0
- package/dist/auth/permissions.js +51 -0
- package/dist/context/hold-type.d.ts +0 -19
- package/dist/context/hold-type.js +1 -37
- package/dist/context/index.d.ts +1 -1
- package/dist/context/index.js +2 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +20 -15
- package/dist/labels.d.ts +2 -17
- package/dist/labels.js +3 -33
- package/dist/mcp/held-run-resolve.d.ts +2 -5
- package/dist/mcp/held-run-resolve.js +3 -4
- package/dist/metrics/metric-catalog.generated.d.ts +0 -5
- package/dist/metrics/metric-catalog.generated.js +0 -6
- package/dist/protocol/messages/access-log.d.ts +10 -0
- package/dist/protocol/messages/access-log.js +2 -0
- package/dist/protocol/messages/auth.d.ts +7 -8
- package/dist/protocol/messages/auth.js +12 -17
- package/dist/protocol/messages/browser.js +1 -1
- package/dist/protocol/messages/capabilities.d.ts +21 -100
- package/dist/protocol/messages/capabilities.js +22 -124
- package/dist/protocol/messages/dashboard.d.ts +64 -22
- package/dist/protocol/messages/dashboard.js +43 -40
- package/dist/protocol/messages/execution-status.d.ts +3 -3
- package/dist/protocol/messages/execution-status.js +7 -12
- package/dist/protocol/messages/join.d.ts +73 -2
- package/dist/protocol/messages/join.js +101 -12
- package/dist/protocol/messages/orchestrator-agent.d.ts +35 -40
- package/dist/protocol/messages/orchestrator-agent.js +63 -96
- package/dist/protocol/messages/peer.d.ts +278 -26
- package/dist/protocol/messages/peer.js +120 -65
- package/dist/protocol/messages/platform-orchestrator.d.ts +36 -141
- package/dist/protocol/messages/platform-orchestrator.js +24 -86
- package/dist/protocol/messages/source-registration.d.ts +0 -13
- package/dist/protocol/messages/source-registration.js +9 -10
- package/dist/protocol/version.d.ts +9 -15
- package/dist/protocol/version.js +9 -15
- package/dist/provenance/id-token-claim-names.d.ts +3 -5
- package/dist/provenance/id-token-claim-names.js +3 -5
- package/dist/status/presentation.d.ts +2 -14
- package/dist/status/presentation.js +3 -23
- package/dist/trigger/types.d.ts +125 -34
- package/dist/trigger/types.js +9 -24
- package/dist/util/date.d.ts +7 -0
- package/dist/util/date.js +14 -0
- package/dist/util/parse-duration.d.ts +6 -0
- package/dist/util/parse-duration.js +21 -0
- package/dist/util/sleep.d.ts +3 -0
- package/dist/util/sleep.js +10 -0
- package/dist/webhook/webhook-url-format.d.ts +2 -2
- package/dist/webhook/webhook-url-format.js +2 -2
- package/package.json +1 -1
- package/sbom.spdx.json +5 -5
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "../../rolldown-runtime-ClRpJifh.js";
|
|
2
2
|
import { provenanceContextSchema } from "../../provenance/id-token-event-claims.js";
|
|
3
|
+
import { agentCapabilitiesSchema, orchAgentCapabilitiesSchema } from "./capabilities.js";
|
|
4
|
+
import { LogStream } from "./log-stream.js";
|
|
3
5
|
import { ExecutionJobStatus, ExecutionStepStatus, StepConcurrencyKind } from "./execution-status.js";
|
|
4
6
|
import { dsseEnvelopeSchema } from "../../provenance/dsse.js";
|
|
5
7
|
import { approvalTimeoutSecondsSchema, approverClauseSchema } from "../../approval/types.js";
|
|
6
|
-
import { agentCapabilitiesSchema, orchAgentCapabilitiesSchema } from "./capabilities.js";
|
|
7
|
-
import { LogStream } from "./log-stream.js";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
//#region src/protocol/messages/orchestrator-agent.ts
|
|
10
10
|
/**
|
|
@@ -88,8 +88,6 @@ const jobDispatchSchema = z.object({
|
|
|
88
88
|
/** Pass-through job configuration. Shape is `LockJob | LockDynamicJobFn` from the lock file. */
|
|
89
89
|
jobConfig: z.record(z.string(), z.unknown()).describe("Job configuration from the lock file (LockJob | LockDynamicJobFn)"),
|
|
90
90
|
timestamp: z.number(),
|
|
91
|
-
/** Short-lived GitHub installation token for private repo clone auth. */
|
|
92
|
-
token: z.string().optional(),
|
|
93
91
|
/** Orchestrator-provided secrets to merge into step environment. */
|
|
94
92
|
secrets: z.record(z.string(), z.string()).optional(),
|
|
95
93
|
/** Namespaced secrets by context name: { 'context-name': { KEY: 'value' } } */
|
|
@@ -98,8 +96,8 @@ const jobDispatchSchema = z.object({
|
|
|
98
96
|
maxLogSizeBytes: z.coerce.number().optional(),
|
|
99
97
|
/**
|
|
100
98
|
* Orchestrator-resolved concurrency-slot wait timeout (ms), from the
|
|
101
|
-
* fleet-wide `cluster_settings.concurrency_wait_timeout_ms`.
|
|
102
|
-
* back to its own env/config default (1h) when absent
|
|
99
|
+
* fleet-wide `cluster_settings.concurrency_wait_timeout_ms`. The agent falls
|
|
100
|
+
* back to its own env/config default (1h) when absent.
|
|
103
101
|
*/
|
|
104
102
|
concurrencyWaitTimeoutMs: z.coerce.number().optional(),
|
|
105
103
|
/** URL or file:// path to a pre-packed `.kici/` source tarball. If present, agent extracts it into workDir instead of cloning the repo. */
|
|
@@ -129,9 +127,10 @@ const jobDispatchSchema = z.object({
|
|
|
129
127
|
* HEAD branch where the claim is the BASE branch, and `workflowRef` here is
|
|
130
128
|
* the `<name>@<sha>` claim rather than a global workflow's clone ref.
|
|
131
129
|
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
130
|
+
* Absent when the orchestrator has no provenance issuer configured, or when
|
|
131
|
+
* a worker dispatches a rerouted job. The agent then falls back to its local
|
|
132
|
+
* guess. That fallback statement fails the capture cross-check, so the
|
|
133
|
+
* defer is dropped rather than stored unchecked.
|
|
135
134
|
*/
|
|
136
135
|
provenanceContext: provenanceContextSchema.optional(),
|
|
137
136
|
/** Plain outputs from upstream jobs (keyed by job name, then by step name). Populated for downstream jobs with `needs` dependencies. */
|
|
@@ -142,20 +141,14 @@ const jobDispatchSchema = z.object({
|
|
|
142
141
|
* Per-invoke-gate results for any upstream gate this job `needs`, keyed by
|
|
143
142
|
* gate job name. One {@link invokeResultSchema} entry per run the gate
|
|
144
143
|
* triggered, carrying the invoked run's non-secret declared outputs. Powers
|
|
145
|
-
* a standard downstream job's `ctx.needs['<gate>'].result`.
|
|
146
|
-
*
|
|
147
|
-
* need through the fan-out group shape
|
|
144
|
+
* a standard downstream job's `ctx.needs['<gate>'].result`. Absent when the
|
|
145
|
+
* job needs no invoke gate, or when a worker dispatches a rerouted job; the
|
|
146
|
+
* agent then resolves the gate need through the fan-out group shape.
|
|
148
147
|
*/
|
|
149
148
|
upstreamInvokeResults: z.record(z.string(), z.array(invokeResultSchema)).optional(),
|
|
150
149
|
/**
|
|
151
|
-
* Structured clone auth for the source repo.
|
|
152
|
-
*
|
|
153
|
-
* during the transition to universal-git / cross-provider global workflows).
|
|
154
|
-
*
|
|
155
|
-
* When both `token` and `sourceAuth` are set, a Zod refinement enforces
|
|
156
|
-
* that they agree (`sourceAuth.kind === 'basic'` and
|
|
157
|
-
* `sourceAuth.secret === token`) — otherwise the dispatch is rejected to
|
|
158
|
-
* prevent silent credential mismatches.
|
|
150
|
+
* Structured clone auth for the source repo. Absent when the job's provider
|
|
151
|
+
* mints no clone credential (a public or local repository).
|
|
159
152
|
*/
|
|
160
153
|
sourceAuth: gitAuthSchema.optional(),
|
|
161
154
|
/**
|
|
@@ -187,9 +180,8 @@ const jobDispatchSchema = z.object({
|
|
|
187
180
|
* resolved by the orchestrator (the lock carries secret NAMES; the agent
|
|
188
181
|
* never resolves them itself).
|
|
189
182
|
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
* as it did before.
|
|
183
|
+
* Absent when the job's image needs no registry credential — the agent
|
|
184
|
+
* then pulls anonymously.
|
|
193
185
|
*/
|
|
194
186
|
containerRegistryAuth: z.object({
|
|
195
187
|
username: z.string().min(1),
|
|
@@ -214,19 +206,6 @@ const jobDispatchSchema = z.object({
|
|
|
214
206
|
* as `isolated` by the agent (fail-closed).
|
|
215
207
|
*/
|
|
216
208
|
cacheRefScope: CacheRefScope.optional()
|
|
217
|
-
}).superRefine((val, ctx) => {
|
|
218
|
-
if (val.token && val.sourceAuth) {
|
|
219
|
-
if (val.sourceAuth.kind !== "basic") ctx.addIssue({
|
|
220
|
-
code: z.ZodIssueCode.custom,
|
|
221
|
-
path: ["sourceAuth", "kind"],
|
|
222
|
-
message: "token is set; sourceAuth.kind must be \"basic\" to agree"
|
|
223
|
-
});
|
|
224
|
-
else if (val.sourceAuth.secret !== val.token) ctx.addIssue({
|
|
225
|
-
code: z.ZodIssueCode.custom,
|
|
226
|
-
path: ["sourceAuth", "secret"],
|
|
227
|
-
message: "token and sourceAuth.secret must match when both are set"
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
209
|
});
|
|
231
210
|
/** Cancel a running or queued job. */
|
|
232
211
|
const jobCancelSchema = z.object({
|
|
@@ -268,17 +247,10 @@ const registerAckSchema = z.object({
|
|
|
268
247
|
* reaper's back, re-creating the spawn/reap churn that reaping only surplus
|
|
269
248
|
* agents exists to prevent.
|
|
270
249
|
*
|
|
271
|
-
* Absent
|
|
272
|
-
* understand this field arms the short KICI_SCALER_IDLE_TIMEOUT timer exactly
|
|
273
|
-
* as before — so warm pools do not work against it, which is today's
|
|
274
|
-
* behaviour rather than a regression.
|
|
250
|
+
* Absent for a job-bound spawn and for a static agent.
|
|
275
251
|
*/
|
|
276
252
|
warmPool: z.boolean().optional(),
|
|
277
|
-
/**
|
|
278
|
-
* Optional agent-facing capabilities this orchestrator supports (absent on
|
|
279
|
-
* pre-capability orchestrators). The agent reads it to decide whether to
|
|
280
|
-
* await optional acks like `artifacts.upload.complete.ack`.
|
|
281
|
-
*/
|
|
253
|
+
/** Agent-facing capabilities this orchestrator advertises; none are defined at protocol 4. */
|
|
282
254
|
capabilities: orchAgentCapabilitiesSchema.optional()
|
|
283
255
|
});
|
|
284
256
|
/** Agent registration with capabilities and capacity. */
|
|
@@ -291,7 +263,7 @@ const agentRegisterSchema = z.object({
|
|
|
291
263
|
platform: z.string().optional(),
|
|
292
264
|
/** Agent architecture (os.arch(), e.g. 'x64', 'arm64') */
|
|
293
265
|
arch: z.string().optional(),
|
|
294
|
-
/** Agent version (e.g. "0.0.1").
|
|
266
|
+
/** Agent version (e.g. "0.0.1"). Absent when the agent cannot read its own package version. */
|
|
295
267
|
version: z.string().optional(),
|
|
296
268
|
/** Maximum concurrent jobs this agent can handle. Defaults to 1 if not specified. */
|
|
297
269
|
maxConcurrency: z.number().int().positive().optional(),
|
|
@@ -326,11 +298,7 @@ const agentRegisterSchema = z.object({
|
|
|
326
298
|
z.number(),
|
|
327
299
|
z.boolean()
|
|
328
300
|
])).optional(),
|
|
329
|
-
/**
|
|
330
|
-
* Optional agent behaviours this agent build implements (absent on
|
|
331
|
-
* pre-capability agents, which the orchestrator treats as supporting none).
|
|
332
|
-
* The orchestrator reads it to route work that depends on one of them.
|
|
333
|
-
*/
|
|
301
|
+
/** Optional agent behaviours this agent advertises; none are defined at protocol 4. */
|
|
334
302
|
capabilities: agentCapabilitiesSchema.optional()
|
|
335
303
|
});
|
|
336
304
|
/** Periodic agent status update. */
|
|
@@ -377,8 +345,8 @@ const jobStatusSchema = z.object({
|
|
|
377
345
|
* `LockJob` interface in `trigger/types.ts`, and a hand-written Zod copy would
|
|
378
346
|
* drift and start rejecting legitimate generated jobs.
|
|
379
347
|
*
|
|
380
|
-
* Every field beyond the verdict itself is `.optional()
|
|
381
|
-
*
|
|
348
|
+
* Every field beyond the verdict itself is `.optional()`: an undecided or
|
|
349
|
+
* job-less verdict omits them.
|
|
382
350
|
*/
|
|
383
351
|
const globalEvalCandidateResultSchema = z.object({
|
|
384
352
|
/** The candidate workflow's name, as it appears in the lock file. */
|
|
@@ -451,11 +419,8 @@ const agentLogChunkSchema = z.object({
|
|
|
451
419
|
stepIndex: z.number(),
|
|
452
420
|
lines: z.array(z.string()),
|
|
453
421
|
timestamp: z.number(),
|
|
454
|
-
/**
|
|
455
|
-
|
|
456
|
-
* with agents that do not send it; absent is read as `stdout`.
|
|
457
|
-
*/
|
|
458
|
-
stream: LogStream.optional()
|
|
422
|
+
/** Which stream these lines came from. */
|
|
423
|
+
stream: LogStream
|
|
459
424
|
});
|
|
460
425
|
/** Step-level execution state report (agent -> orchestrator). */
|
|
461
426
|
const agentStepStatusSchema = z.object({
|
|
@@ -553,37 +518,37 @@ const configAckSchema = z.object({
|
|
|
553
518
|
messageId: z.string(),
|
|
554
519
|
agentId: z.string()
|
|
555
520
|
});
|
|
556
|
-
/**
|
|
557
|
-
|
|
521
|
+
/**
|
|
522
|
+
* Agent -> Orchestrator: request a pre-signed upload URL for cache storage.
|
|
523
|
+
*
|
|
524
|
+
* Each tarball is stored under its own content hash, so the orchestrator needs
|
|
525
|
+
* that hash to sign the upload URL: `sourceTarDigest` for a source upload,
|
|
526
|
+
* `depsHash` for a deps upload. The agent has already packed and hashed the
|
|
527
|
+
* tarball by the time it asks.
|
|
528
|
+
*/
|
|
529
|
+
const cacheUploadRequestSchema = z.discriminatedUnion("cacheType", [z.object({
|
|
558
530
|
type: z.literal("cache.upload.request"),
|
|
559
531
|
messageId: z.string(),
|
|
560
532
|
jobId: z.string(),
|
|
561
|
-
cacheType: z.
|
|
533
|
+
cacheType: z.literal("source"),
|
|
562
534
|
contentHash: z.string().optional(),
|
|
535
|
+
platform: z.string(),
|
|
536
|
+
arch: z.string(),
|
|
537
|
+
/** SHA-256 of the source tarball about to be uploaded. */
|
|
538
|
+
sourceTarDigest: z.string()
|
|
539
|
+
}), z.object({
|
|
540
|
+
type: z.literal("cache.upload.request"),
|
|
541
|
+
messageId: z.string(),
|
|
542
|
+
jobId: z.string(),
|
|
543
|
+
cacheType: z.literal("deps"),
|
|
563
544
|
lockfileHash: z.string().optional(),
|
|
564
545
|
platform: z.string(),
|
|
565
546
|
arch: z.string(),
|
|
566
|
-
/**
|
|
567
|
-
|
|
568
|
-
*
|
|
569
|
-
* The dep tarball is stored under its own content hash, so the orchestrator
|
|
570
|
-
* needs it to sign the upload URL — the agent has already built the tarball
|
|
571
|
-
* and hashed it by the time it asks. Optional so an older agent that omits it
|
|
572
|
-
* still gets a usable (lockfile-keyed) URL during a mixed-version rollout.
|
|
573
|
-
*/
|
|
574
|
-
depsHash: z.string().optional(),
|
|
575
|
-
/**
|
|
576
|
-
* SHA-256 of the source tarball about to be uploaded. Source uploads only.
|
|
577
|
-
*
|
|
578
|
-
* The source tarball is stored under its own content hash, so the
|
|
579
|
-
* orchestrator needs it to sign the upload URL — the agent has already packed
|
|
580
|
-
* and hashed it by the time it asks. Optional so an older agent that omits it
|
|
581
|
-
* still gets a usable URL during a mixed-version rollout.
|
|
582
|
-
*/
|
|
583
|
-
sourceTarDigest: z.string().optional(),
|
|
547
|
+
/** SHA-256 of the dependency tarball about to be uploaded. */
|
|
548
|
+
depsHash: z.string(),
|
|
584
549
|
/** In-repo `workspace:` sibling closure digest; part of the dep pointer key. */
|
|
585
550
|
siblingsDigest: z.string().optional()
|
|
586
|
-
});
|
|
551
|
+
})]);
|
|
587
552
|
/** Orchestrator -> Agent: return the pre-signed upload URL. */
|
|
588
553
|
const cacheUploadResponseSchema = z.object({
|
|
589
554
|
type: z.literal("cache.upload.response"),
|
|
@@ -591,22 +556,29 @@ const cacheUploadResponseSchema = z.object({
|
|
|
591
556
|
uploadUrl: z.string()
|
|
592
557
|
});
|
|
593
558
|
/** Agent -> Orchestrator: confirm upload complete (for metadata update). */
|
|
594
|
-
const cacheUploadCompleteSchema = z.object({
|
|
559
|
+
const cacheUploadCompleteSchema = z.discriminatedUnion("cacheType", [z.object({
|
|
595
560
|
type: z.literal("cache.upload.complete"),
|
|
596
561
|
messageId: z.string(),
|
|
597
562
|
jobId: z.string(),
|
|
598
|
-
cacheType: z.
|
|
563
|
+
cacheType: z.literal("source"),
|
|
599
564
|
contentHash: z.string().optional(),
|
|
565
|
+
platform: z.string(),
|
|
566
|
+
arch: z.string(),
|
|
567
|
+
/** SHA-256 of the source tarball's own bytes. */
|
|
568
|
+
sourceTarDigest: z.string()
|
|
569
|
+
}), z.object({
|
|
570
|
+
type: z.literal("cache.upload.complete"),
|
|
571
|
+
messageId: z.string(),
|
|
572
|
+
jobId: z.string(),
|
|
573
|
+
cacheType: z.literal("deps"),
|
|
600
574
|
lockfileHash: z.string().optional(),
|
|
601
575
|
platform: z.string(),
|
|
602
576
|
arch: z.string(),
|
|
603
|
-
/** SHA-256 hash of the dependency tarball for integrity verification.
|
|
604
|
-
depsHash: z.string()
|
|
605
|
-
/** SHA-256 of the source tarball's own bytes. Only present for source uploads. */
|
|
606
|
-
sourceTarDigest: z.string().optional(),
|
|
577
|
+
/** SHA-256 hash of the dependency tarball for integrity verification. */
|
|
578
|
+
depsHash: z.string(),
|
|
607
579
|
/** In-repo `workspace:` sibling closure digest; part of the dep pointer key. */
|
|
608
580
|
siblingsDigest: z.string().optional()
|
|
609
|
-
});
|
|
581
|
+
})]);
|
|
610
582
|
/** Agent -> Orchestrator: request a user-cache restore (presigned download). */
|
|
611
583
|
const cacheUserRestoreRequestSchema = z.object({
|
|
612
584
|
type: z.literal("cache.user.restore.request"),
|
|
@@ -765,8 +737,7 @@ const artifactsUploadResponseSchema = z.object({
|
|
|
765
737
|
* uploads are not configured on the orchestrator, the job's run could not be
|
|
766
738
|
* resolved, the job is not owned by this agent, or the orchestrator hit an
|
|
767
739
|
* internal error. A safe, fixed,
|
|
768
|
-
* human-readable string; never a raw exception.
|
|
769
|
-
* and fall back to a generic rejection message.
|
|
740
|
+
* human-readable string; never a raw exception.
|
|
770
741
|
*/
|
|
771
742
|
error: z.string().optional()
|
|
772
743
|
});
|
|
@@ -793,9 +764,7 @@ const artifactsUploadCompleteSchema = z.object({
|
|
|
793
764
|
const ArtifactCompleteAckOutcome = z.enum(["committed", "failed"]);
|
|
794
765
|
/**
|
|
795
766
|
* Orchestrator -> Agent: the outcome of committing an
|
|
796
|
-
* `artifacts.upload.complete`.
|
|
797
|
-
* `artifactCompleteAck` capability on `register.ack`; the agent awaits it and
|
|
798
|
-
* fails the workflow step on `failed`/timeout, so a lost commit surfaces as a
|
|
767
|
+
* `artifacts.upload.complete`. The agent awaits it and fails the workflow step on `failed`/timeout, so a lost commit surfaces as a
|
|
799
768
|
* failed step instead of a green run with a missing artifact. `requestId`
|
|
800
769
|
* echoes the complete message's `messageId`.
|
|
801
770
|
*/
|
|
@@ -841,8 +810,7 @@ const artifactsDownloadResponseSchema = z.object({
|
|
|
841
810
|
* the job's run could not be resolved, the job is not owned by this agent, or
|
|
842
811
|
* the orchestrator hit an internal error — rather than a genuinely missing
|
|
843
812
|
* artifact. A safe, fixed,
|
|
844
|
-
* human-readable string; never a raw exception.
|
|
845
|
-
* and render the plain not-found message.
|
|
813
|
+
* human-readable string; never a raw exception.
|
|
846
814
|
*/
|
|
847
815
|
error: z.string().optional()
|
|
848
816
|
});
|
|
@@ -876,8 +844,7 @@ const eventEmitResponseSchema = z.object({
|
|
|
876
844
|
* A provisioned agent normally sends this itself to self-bootstrap — the claim
|
|
877
845
|
* code is the authorization, so it may send it before it authenticates or
|
|
878
846
|
* registers. A provisioning workflow can also send it to obtain the token
|
|
879
|
-
* directly.
|
|
880
|
-
* are unaffected, so it needs no `PROTOCOL_VERSION` bump of its own.
|
|
847
|
+
* directly.
|
|
881
848
|
*/
|
|
882
849
|
const scalerClaimCredentialsSchema = z.object({
|
|
883
850
|
type: z.literal("scaler.claim-credentials"),
|