@kici-dev/engine 0.1.15 → 0.1.17

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.
Files changed (102) hide show
  1. package/dist/approval/types.d.ts +56 -0
  2. package/dist/approval/types.js +42 -0
  3. package/dist/audit/access-log-policy.js +5 -1
  4. package/dist/audit/activity.js +1 -1
  5. package/dist/audit/retention-policy.js +9 -1
  6. package/dist/bundler/index.js +1 -1
  7. package/dist/bundler/rolldown-config.js +1 -1
  8. package/dist/env/environment-allowlist.js +1 -1
  9. package/dist/environment/index.js +1 -1
  10. package/dist/environment/scope-resolver.js +1 -1
  11. package/dist/environment/types.d.ts +8 -0
  12. package/dist/environment/types.js +1 -1
  13. package/dist/fanout/materialize.d.ts +67 -0
  14. package/dist/fanout/materialize.js +119 -0
  15. package/dist/index.d.ts +4 -2
  16. package/dist/index.js +10 -8
  17. package/dist/labels.js +1 -1
  18. package/dist/matrix/expand.d.ts +43 -0
  19. package/dist/matrix/expand.js +66 -0
  20. package/dist/matrix/format.d.ts +10 -0
  21. package/dist/matrix/format.js +19 -0
  22. package/dist/metrics/catalog-policy.js +8 -3
  23. package/dist/metrics/metric-catalog.generated.d.ts +1 -1
  24. package/dist/metrics/metric-catalog.generated.js +2 -2
  25. package/dist/protocol/analytics-events.js +1 -1
  26. package/dist/protocol/cluster-name.js +1 -1
  27. package/dist/protocol/dashboard-global-workflows.js +1 -1
  28. package/dist/protocol/dashboard-write-operations.js +1 -1
  29. package/dist/protocol/event-log-payload.js +1 -1
  30. package/dist/protocol/messages/access-log.d.ts +25 -5
  31. package/dist/protocol/messages/access-log.js +5 -1
  32. package/dist/protocol/messages/actor.js +1 -1
  33. package/dist/protocol/messages/auth.d.ts +1 -0
  34. package/dist/protocol/messages/auth.js +11 -2
  35. package/dist/protocol/messages/browser.js +1 -1
  36. package/dist/protocol/messages/capabilities.js +1 -1
  37. package/dist/protocol/messages/common.js +1 -1
  38. package/dist/protocol/messages/dashboard-global-workflows.js +1 -1
  39. package/dist/protocol/messages/dashboard.d.ts +1030 -50
  40. package/dist/protocol/messages/dashboard.js +377 -7
  41. package/dist/protocol/messages/event-log.js +1 -1
  42. package/dist/protocol/messages/execution-status.d.ts +13 -1
  43. package/dist/protocol/messages/execution-status.js +13 -3
  44. package/dist/protocol/messages/join.js +1 -1
  45. package/dist/protocol/messages/log-pull.js +1 -1
  46. package/dist/protocol/messages/observe.d.ts +1 -0
  47. package/dist/protocol/messages/oidc-token-relay.d.ts +31 -0
  48. package/dist/protocol/messages/oidc-token-relay.js +34 -0
  49. package/dist/protocol/messages/orchestrator-agent.d.ts +161 -0
  50. package/dist/protocol/messages/orchestrator-agent.js +117 -4
  51. package/dist/protocol/messages/peer.d.ts +76 -0
  52. package/dist/protocol/messages/peer.js +37 -2
  53. package/dist/protocol/messages/platform-orchestrator.d.ts +187 -10
  54. package/dist/protocol/messages/platform-orchestrator.js +13 -2
  55. package/dist/protocol/messages/run-events.js +1 -1
  56. package/dist/protocol/messages/scaler-event.js +1 -1
  57. package/dist/protocol/messages/source-registration.d.ts +7 -6
  58. package/dist/protocol/messages/source-registration.js +7 -6
  59. package/dist/protocol/version.js +1 -1
  60. package/dist/provenance/bundle.d.ts +54 -0
  61. package/dist/provenance/bundle.js +53 -0
  62. package/dist/provenance/dsse.d.ts +39 -0
  63. package/dist/provenance/dsse.js +53 -0
  64. package/dist/provenance/schema.d.ts +407 -0
  65. package/dist/provenance/schema.js +143 -0
  66. package/dist/provenance/verify.d.ts +71 -0
  67. package/dist/provenance/verify.js +135 -0
  68. package/dist/provider/changed-files-fetcher.js +1 -1
  69. package/dist/provider/check-run-conclusion.js +1 -1
  70. package/dist/provider/check-status-poster.js +1 -1
  71. package/dist/provider/clone-token-provider.js +1 -1
  72. package/dist/provider/contributor-resolver.js +1 -1
  73. package/dist/provider/index.js +1 -1
  74. package/dist/provider/lock-file-fetcher.js +1 -1
  75. package/dist/provider/lock-file-parse-error.js +3 -1
  76. package/dist/provider/repo-url-builder.js +1 -1
  77. package/dist/provider/types.d.ts +2 -2
  78. package/dist/provider/types.js +1 -1
  79. package/dist/provider/webhook-normalizer.js +1 -1
  80. package/dist/registration/registerable-trigger-type.js +1 -1
  81. package/dist/scaler/resource-types.js +1 -1
  82. package/dist/scaler/scaler-backend-type.js +1 -1
  83. package/dist/secrets/index.js +1 -1
  84. package/dist/secrets/types.js +1 -1
  85. package/dist/state-machine/index.js +1 -1
  86. package/dist/state-machine/machine.js +1 -1
  87. package/dist/state-machine/types.js +1 -1
  88. package/dist/trigger/decision-trace.js +1 -1
  89. package/dist/trigger/jsonpath-matcher.js +1 -1
  90. package/dist/trigger/matcher.js +1 -1
  91. package/dist/trigger/trigger-event-type.js +1 -1
  92. package/dist/trigger/types.d.ts +34 -1
  93. package/dist/trigger/types.js +14 -5
  94. package/dist/webhook/signature.js +1 -1
  95. package/dist/ws/close-codes.js +1 -1
  96. package/dist/ws/rate-limiter.js +3 -1
  97. package/dist/ws/ws-like.js +1 -1
  98. package/package.json +23 -1
  99. package/sbom.spdx.json +55 -5
  100. package/dist/protocol/messages/observe.js +0 -70
  101. package/dist/protocol/messages/test-run.js +0 -52
  102. /package/dist/{chunk-gOLHoazu.js → chunk-BTugEXQM.js} +0 -0
@@ -0,0 +1,135 @@
1
+ import "../chunk-BTugEXQM.js";
2
+ import { dssePae } from "./dsse.js";
3
+ import { kiciBundleSchema } from "./bundle.js";
4
+ import { kiciProvenanceStatementSchema } from "./schema.js";
5
+ import { calculateJwkThumbprint, createLocalJWKSet, importJWK, jwtVerify } from "jose";
6
+ //#region src/provenance/verify.ts
7
+ /**
8
+ * Shared, browser-safe verification core for KiCI provenance bundles (Mode A).
9
+ *
10
+ * Given a KiCI-signed bundle, the Platform JWKS, and an out-of-band trusted
11
+ * issuer, `verifyKiciBundle` establishes the full Mode-A chain offline:
12
+ *
13
+ * - the identity JWT verifies against the supplied JWKS with `iss` PINNED to
14
+ * the caller-supplied `expectedIssuer` (never the token's own `iss`) and the
15
+ * audience checked;
16
+ * - the DSSE envelope verifies against the ephemeral public key carried in the
17
+ * bundle, whose `keyid` must equal its RFC 7638 JWK thumbprint;
18
+ * - the in-toto statement's build context must equal the (server-truth) JWT
19
+ * claims — a mismatch is a HARD FAIL, the check that makes the agent-built
20
+ * statement sound;
21
+ * - when an artifact digest is supplied, a subject digest must match it.
22
+ *
23
+ * The core uses only `jose` (isomorphic) and `crypto.subtle`/`atob`/`TextDecoder`
24
+ * (present in modern browsers and Node 24) — no `node:fs`, no `fetch`, no
25
+ * `Buffer` — so the exact same function runs in the `kici verify-attestation`
26
+ * CLI and the dashboard's verified badge. Exported at the subpath
27
+ * `@kici-dev/engine/provenance/verify`; it is deliberately NOT re-exported from
28
+ * the engine barrel (the barrel must stay free of the `jose` dependency).
29
+ */
30
+ /** Browser-safe base64 → bytes (no Buffer — this module is imported by the dashboard). */
31
+ function b64ToBytes(b64) {
32
+ return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
33
+ }
34
+ /**
35
+ * Verify a KiCI provenance bundle offline. Returns a structured result; throws
36
+ * only on a programming-level error, never for a verification failure (a failed
37
+ * verification is `verified:false` with populated `failures`).
38
+ */
39
+ async function verifyKiciBundle(opts) {
40
+ const checks = {
41
+ schema: "skipped",
42
+ jwt: "skipped",
43
+ dsse: "skipped",
44
+ buildContext: "skipped",
45
+ digest: "skipped"
46
+ };
47
+ const failures = [];
48
+ if (opts.bundle?.mediaType !== "application/vnd.kici.provenance.bundle+json;version=0.1") return {
49
+ verified: false,
50
+ mode: "sigstore",
51
+ checks,
52
+ failures: ["mode_b_unsupported"]
53
+ };
54
+ const parsed = kiciBundleSchema.safeParse(opts.bundle);
55
+ if (!parsed.success) {
56
+ checks.schema = "fail";
57
+ return {
58
+ verified: false,
59
+ mode: "kici",
60
+ checks,
61
+ failures: ["bundle_schema_invalid"]
62
+ };
63
+ }
64
+ const bundle = parsed.data;
65
+ checks.schema = "pass";
66
+ const statementBytes = b64ToBytes(bundle.dsseEnvelope.payload);
67
+ let statement;
68
+ const stmt = kiciProvenanceStatementSchema.safeParse(JSON.parse(new TextDecoder().decode(statementBytes)));
69
+ if (!stmt.success) {
70
+ checks.schema = "fail";
71
+ failures.push("statement_schema_invalid");
72
+ } else statement = stmt.data;
73
+ let claims;
74
+ try {
75
+ const { payload } = await jwtVerify(bundle.verificationMaterial.identityToken, createLocalJWKSet(opts.jwks), {
76
+ issuer: opts.expectedIssuer,
77
+ audience: opts.expectedAudience
78
+ });
79
+ claims = payload;
80
+ checks.jwt = "pass";
81
+ } catch {
82
+ checks.jwt = "fail";
83
+ failures.push("identity_token_invalid");
84
+ }
85
+ try {
86
+ const pubJwk = bundle.verificationMaterial.publicKey;
87
+ const thumbprint = await calculateJwkThumbprint(pubJwk, "sha256");
88
+ if (bundle.dsseEnvelope.signatures[0].keyid !== thumbprint) throw new Error("keyid does not match public-key thumbprint");
89
+ const key = await importJWK(pubJwk, "ES256");
90
+ if (!await crypto.subtle.verify({
91
+ name: "ECDSA",
92
+ hash: "SHA-256"
93
+ }, key, b64ToBytes(bundle.dsseEnvelope.signatures[0].sig), dssePae(bundle.dsseEnvelope.payloadType, statementBytes))) throw new Error("bad signature");
94
+ checks.dsse = "pass";
95
+ } catch {
96
+ checks.dsse = "fail";
97
+ failures.push("dsse_signature_invalid");
98
+ }
99
+ if (statement && claims) {
100
+ const ok = crossCheckBuildContext(statement, claims);
101
+ checks.buildContext = ok ? "pass" : "fail";
102
+ if (!ok) failures.push("build_context_mismatch");
103
+ } else {
104
+ checks.buildContext = "fail";
105
+ failures.push("build_context_uncheckable");
106
+ }
107
+ if (opts.expectedDigest && statement) {
108
+ const ok = checkSubjectDigest(statement, opts.expectedDigest);
109
+ checks.digest = ok ? "pass" : "fail";
110
+ if (!ok) failures.push("subject_digest_mismatch");
111
+ }
112
+ return {
113
+ verified: checks.schema === "pass" && checks.jwt === "pass" && checks.dsse === "pass" && checks.buildContext === "pass" && checks.digest !== "fail",
114
+ mode: "kici",
115
+ checks,
116
+ claims,
117
+ statement,
118
+ failures
119
+ };
120
+ }
121
+ /** The statement's build context must equal the (server-truth) JWT claims. */
122
+ function crossCheckBuildContext(statement, claims) {
123
+ const bd = statement.predicate.buildDefinition;
124
+ const wf = bd.externalParameters.workflow;
125
+ const ip = bd.internalParameters ?? {};
126
+ return wf.repository === claims.repository && wf.ref === claims.ref && wf.path === claims.workflow_ref && ip.commit === claims.sha && ip.runId === claims.kici_run_id && ip.jobId === claims.kici_job_id;
127
+ }
128
+ /** At least one subject must carry a digest matching the supplied artifact digest. */
129
+ function checkSubjectDigest(statement, expected) {
130
+ return statement.subject.some((s) => s.digest[expected.alg] === expected.hex);
131
+ }
132
+ //#endregion
133
+ export { verifyKiciBundle };
134
+
135
+ //# sourceMappingURL=verify.js.map
@@ -1,2 +1,2 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  export {};
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  import { z } from "zod";
3
3
  //#region src/provider/check-run-conclusion.ts
4
4
  /**
@@ -1,2 +1,2 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  export {};
@@ -1,2 +1,2 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  export {};
@@ -1,2 +1,2 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  export {};
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  import { LockFileParseError } from "./lock-file-parse-error.js";
3
3
  import { CheckRunConclusion } from "./check-run-conclusion.js";
4
4
  export { CheckRunConclusion, LockFileParseError };
@@ -1,2 +1,2 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  export {};
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  //#region src/provider/lock-file-parse-error.ts
3
3
  /**
4
4
  * Thrown by a LockFileFetcher when a lock file is present at the repo ref but
@@ -8,6 +8,8 @@ import "../chunk-gOLHoazu.js";
8
8
  * `lock_resolution` init-failure run.
9
9
  */
10
10
  var LockFileParseError = class LockFileParseError extends Error {
11
+ repoIdentifier;
12
+ ref;
11
13
  name = "LockFileParseError";
12
14
  constructor(repoIdentifier, ref, message) {
13
15
  super(message);
@@ -1,2 +1,2 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  export {};
@@ -4,6 +4,6 @@
4
4
  * These types are the foundation for all provider interfaces.
5
5
  * Keep this minimal -- only types needed by multiple interfaces belong here.
6
6
  */
7
- /** Identifies a git hosting provider, generic webhook source, or internal test provider. */
8
- export type ProviderType = 'github' | 'gitlab' | 'bitbucket' | 'generic' | 'internal';
7
+ /** Identifies a git hosting provider, generic webhook source, or local filesystem (`file://`) source. */
8
+ export type ProviderType = 'github' | 'gitlab' | 'bitbucket' | 'generic' | 'local';
9
9
  //# sourceMappingURL=types.d.ts.map
@@ -1,2 +1,2 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  export {};
@@ -1,2 +1,2 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  export {};
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  import { z } from "zod";
3
3
  //#region src/registration/registerable-trigger-type.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  import { z } from "zod";
3
3
  //#region src/scaler/resource-types.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  import { z } from "zod";
3
3
  //#region src/scaler/scaler-backend-type.ts
4
4
  /**
@@ -1,2 +1,2 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  export {};
@@ -1,2 +1,2 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  export {};
@@ -1,3 +1,3 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  import { isTerminal, transition } from "./machine.js";
3
3
  export { isTerminal, transition };
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  import { TERMINAL_STATES } from "./types.js";
3
3
  //#region src/state-machine/machine.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  //#region src/state-machine/types.ts
3
3
  /**
4
4
  * States from which no further transitions are possible.
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  //#region src/trigger/decision-trace.ts
3
3
  /**
4
4
  * Create a new trace entry.
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  import { JSONPath } from "jsonpath-plus";
3
3
  //#region src/trigger/jsonpath-matcher.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  import { createTraceEntry, createWorkflowDecision } from "./decision-trace.js";
3
3
  import { matchJsonPath, matchJsonPathNot } from "./jsonpath-matcher.js";
4
4
  import picomatch from "picomatch";
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  //#region src/trigger/trigger-event-type.ts
3
3
  /**
4
4
  * Canonical trigger event types with human-readable metadata.
@@ -10,11 +10,27 @@
10
10
  * Schema version 11: adds LockInlineValue type for pure function inline evaluation.
11
11
  * Schema version 14: adds declarative cache specs to LockJob and LockStep.
12
12
  * Schema version 15: adds per-job init config(s) to LockJob.
13
+ * Schema version 16: adds normalized approval config to LockWorkflow/LockJob/LockStep.
14
+ * Schema version 17: widens LockJob.init to typed presets ('mise' / { mise }) and 'auto' detection.
13
15
  */
14
16
  import { z } from 'zod';
15
17
  import type { ProviderType } from '../provider/types.js';
18
+ import type { ApproverClause } from '../approval/types.js';
16
19
  /** Schema version - increment on breaking changes */
17
- export declare const SCHEMA_VERSION: 15;
20
+ export declare const SCHEMA_VERSION: 17;
21
+ /**
22
+ * Normalized approval config carried in the lock file. Produced by the compiler
23
+ * from an SDK `requireApproval` at any of the three levels; consumed by the
24
+ * orchestrator dispatch gate (and the agent step round-trip for step scope).
25
+ */
26
+ export interface LockApproval {
27
+ /** AND list of approver clauses; empty means "any approval-capable member". */
28
+ readonly clauses: ApproverClause[];
29
+ /** Human label for the gate. */
30
+ readonly reason?: string;
31
+ /** Per-gate expiry override (seconds); falls back to the org default. */
32
+ readonly timeoutSeconds?: number;
33
+ }
18
34
  /**
19
35
  * Source file reference with meaningful path.
20
36
  * Format: file is relative path from git root, export uses hash syntax.
@@ -315,6 +331,8 @@ export interface LockStep {
315
331
  readonly line: number;
316
332
  readonly column: number;
317
333
  };
334
+ /** Normalized approval gate; when set the step pauses for a human approval. */
335
+ readonly approval?: LockApproval;
318
336
  }
319
337
  /**
320
338
  * Inline expression value for pure dynamic functions.
@@ -329,6 +347,17 @@ export interface LockInlineValue {
329
347
  }
330
348
  /** Type guard for inline expression values */
331
349
  export declare function isLockInlineValue(value: unknown): value is LockInlineValue;
350
+ /**
351
+ * Per-edge failure policy for a `needs` dependency: `skip` propagates an
352
+ * upstream failure to the downstream job (default), `run` runs the downstream
353
+ * job regardless of the upstream outcome. Single source of truth for this
354
+ * value across lock-file schemas and protocol messages.
355
+ */
356
+ export declare const IfFailedPolicy: z.ZodEnum<{
357
+ run: "run";
358
+ skip: "skip";
359
+ }>;
360
+ export type IfFailedPolicy = z.infer<typeof IfFailedPolicy>;
332
361
  /**
333
362
  * Needs entry with per-edge failure policy.
334
363
  * Used in lock file needs arrays for explicit ifFailed override.
@@ -391,6 +420,8 @@ export interface LockJob {
391
420
  * (`requests`) and kernel-side enforcement (`limits`) on the spawned agent.
392
421
  */
393
422
  readonly resources?: import('../scaler/resource-types.js').ResourceRequest;
423
+ /** Normalized approval gate; when set the job is held before dispatch. */
424
+ readonly approval?: LockApproval;
394
425
  }
395
426
  /**
396
427
  * Dynamic job generator reference.
@@ -460,6 +491,8 @@ export interface LockWorkflow {
460
491
  };
461
492
  /** Whole-run wall-clock timeout in milliseconds. Read by the orchestrator at run creation to set the run deadline. */
462
493
  readonly timeout?: number;
494
+ /** Normalized approval gate; when set the whole run is held before any job dispatches. */
495
+ readonly approval?: LockApproval;
463
496
  }
464
497
  /**
465
498
  * Complete lock file structure.
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  import { z } from "zod";
3
3
  //#region src/trigger/types.ts
4
4
  /**
@@ -13,20 +13,29 @@ import { z } from "zod";
13
13
  * Schema version 11: adds LockInlineValue type for pure function inline evaluation.
14
14
  * Schema version 14: adds declarative cache specs to LockJob and LockStep.
15
15
  * Schema version 15: adds per-job init config(s) to LockJob.
16
+ * Schema version 16: adds normalized approval config to LockWorkflow/LockJob/LockStep.
17
+ * Schema version 17: widens LockJob.init to typed presets ('mise' / { mise }) and 'auto' detection.
16
18
  */
17
19
  /** Schema version - increment on breaking changes */
18
- const SCHEMA_VERSION = 15;
20
+ const SCHEMA_VERSION = 17;
19
21
  /** Type guard for inline expression values */
20
22
  function isLockInlineValue(value) {
21
23
  return typeof value === "object" && value !== null && value._type === "inline";
22
24
  }
23
25
  /**
26
+ * Per-edge failure policy for a `needs` dependency: `skip` propagates an
27
+ * upstream failure to the downstream job (default), `run` runs the downstream
28
+ * job regardless of the upstream outcome. Single source of truth for this
29
+ * value across lock-file schemas and protocol messages.
30
+ */
31
+ const IfFailedPolicy = z.enum(["skip", "run"]);
32
+ /**
24
33
  * Needs entry with per-edge failure policy.
25
34
  * Used in lock file needs arrays for explicit ifFailed override.
26
35
  */
27
36
  const NeedsEntrySchema = z.object({
28
37
  name: z.string(),
29
- ifFailed: z.enum(["skip", "run"]).default("skip")
38
+ ifFailed: IfFailedPolicy.default(IfFailedPolicy.enum.skip)
30
39
  });
31
40
  /**
32
41
  * Needs group entry with per-edge failure policy.
@@ -34,7 +43,7 @@ const NeedsEntrySchema = z.object({
34
43
  */
35
44
  const NeedsGroupEntrySchema = z.object({
36
45
  group: z.string(),
37
- ifFailed: z.enum(["skip", "run"]).default("skip")
46
+ ifFailed: IfFailedPolicy.default(IfFailedPolicy.enum.skip)
38
47
  });
39
48
  /** Type guard for static jobs */
40
49
  function isLockStaticJob(job) {
@@ -45,6 +54,6 @@ function isLockDynamicJobFn(job) {
45
54
  return job._type === "dynamic";
46
55
  }
47
56
  //#endregion
48
- export { NeedsEntrySchema, NeedsGroupEntrySchema, SCHEMA_VERSION, isLockDynamicJobFn, isLockInlineValue, isLockStaticJob };
57
+ export { IfFailedPolicy, NeedsEntrySchema, NeedsGroupEntrySchema, SCHEMA_VERSION, isLockDynamicJobFn, isLockInlineValue, isLockStaticJob };
49
58
 
50
59
  //# sourceMappingURL=types.js.map
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  import { createHmac, timingSafeEqual } from "node:crypto";
3
3
  //#region src/webhook/signature.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  //#region src/ws/close-codes.ts
3
3
  /**
4
4
  * Unified WebSocket close codes for KiCI connections.
@@ -1,4 +1,4 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  //#region src/ws/rate-limiter.ts
3
3
  /**
4
4
  * WebSocket rate limiter with two-tier token bucket (messages + bytes).
@@ -18,6 +18,8 @@ import "../chunk-gOLHoazu.js";
18
18
  * When tokens are exhausted, returns a retryAfterMs estimate.
19
19
  */
20
20
  var TokenBucket = class {
21
+ capacity;
22
+ refillRate;
21
23
  tokens;
22
24
  lastRefill;
23
25
  constructor(capacity, refillRate) {
@@ -1,2 +1,2 @@
1
- import "../chunk-gOLHoazu.js";
1
+ import "../chunk-BTugEXQM.js";
2
2
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kici-dev/engine",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Shared business logic for the KiCI CI/CD stack: protocol, triggers, state machine, and provider interfaces used by the Platform relay, orchestrator, and compiler.",
5
5
  "keywords": [
6
6
  "ci",
@@ -65,6 +65,26 @@
65
65
  "import": "./dist/protocol/cluster-name.js",
66
66
  "types": "./dist/protocol/cluster-name.d.ts"
67
67
  },
68
+ "./protocol/messages/oidc-token-relay": {
69
+ "import": "./dist/protocol/messages/oidc-token-relay.js",
70
+ "types": "./dist/protocol/messages/oidc-token-relay.d.ts"
71
+ },
72
+ "./provenance/schema": {
73
+ "import": "./dist/provenance/schema.js",
74
+ "types": "./dist/provenance/schema.d.ts"
75
+ },
76
+ "./provenance/dsse": {
77
+ "import": "./dist/provenance/dsse.js",
78
+ "types": "./dist/provenance/dsse.d.ts"
79
+ },
80
+ "./provenance/bundle": {
81
+ "import": "./dist/provenance/bundle.js",
82
+ "types": "./dist/provenance/bundle.d.ts"
83
+ },
84
+ "./provenance/verify": {
85
+ "import": "./dist/provenance/verify.js",
86
+ "types": "./dist/provenance/verify.d.ts"
87
+ },
68
88
  "./metrics/catalog": {
69
89
  "import": "./dist/metrics/metric-catalog.generated.js",
70
90
  "types": "./dist/metrics/metric-catalog.generated.d.ts"
@@ -75,6 +95,8 @@
75
95
  }
76
96
  },
77
97
  "dependencies": {
98
+ "fast-cartesian": "^9.0.1",
99
+ "jose": "^6.1.0",
78
100
  "jsonpath-plus": "^10.4.0",
79
101
  "picomatch": "^4.0.4",
80
102
  "zod": "^4.3.6"
package/sbom.spdx.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "spdxVersion": "SPDX-2.3",
3
3
  "dataLicense": "CC0-1.0",
4
4
  "SPDXID": "SPDXRef-DOCUMENT",
5
- "name": "@kici-dev/engine@0.1.15",
6
- "documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fengine/0.1.15/f9f3b4dd-cddc-43ee-a94e-621967a6b013",
5
+ "name": "@kici-dev/engine@0.1.17",
6
+ "documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fengine/0.1.17/6284c0d2-b9a6-423e-bed6-92121170fef3",
7
7
  "creationInfo": {
8
- "created": "2026-06-11T03:03:20Z",
8
+ "created": "2026-06-14T12:30:15Z",
9
9
  "creators": [
10
10
  "Tool: kici-sbom-generator"
11
11
  ]
@@ -54,7 +54,7 @@
54
54
  {
55
55
  "SPDXID": "SPDXRef-RootPackage",
56
56
  "name": "@kici-dev/engine",
57
- "versionInfo": "0.1.15",
57
+ "versionInfo": "0.1.17",
58
58
  "downloadLocation": "NOASSERTION",
59
59
  "filesAnalyzed": false,
60
60
  "licenseConcluded": "NOASSERTION",
@@ -65,12 +65,52 @@
65
65
  {
66
66
  "referenceCategory": "PACKAGE-MANAGER",
67
67
  "referenceType": "purl",
68
- "referenceLocator": "pkg:npm/%40kici-dev/engine@0.1.15"
68
+ "referenceLocator": "pkg:npm/%40kici-dev/engine@0.1.17"
69
69
  }
70
70
  ],
71
71
  "description": "Shared business logic for the KiCI CI/CD stack: protocol, triggers, state machine, and provider interfaces used by the Platform relay, orchestrator, and compiler.",
72
72
  "homepage": "https://kici.dev"
73
73
  },
74
+ {
75
+ "SPDXID": "SPDXRef-Package-fast-cartesian-9.0.1",
76
+ "name": "fast-cartesian",
77
+ "versionInfo": "9.0.1",
78
+ "downloadLocation": "https://registry.npmjs.org/fast-cartesian/-/fast-cartesian-9.0.1.tgz",
79
+ "filesAnalyzed": false,
80
+ "licenseConcluded": "NOASSERTION",
81
+ "licenseDeclared": "Apache-2.0",
82
+ "copyrightText": "NOASSERTION",
83
+ "supplier": "NOASSERTION",
84
+ "externalRefs": [
85
+ {
86
+ "referenceCategory": "PACKAGE-MANAGER",
87
+ "referenceType": "purl",
88
+ "referenceLocator": "pkg:npm/fast-cartesian@9.0.1"
89
+ }
90
+ ],
91
+ "description": "Fast cartesian product",
92
+ "homepage": "https://www.github.com/ehmicky/fast-cartesian"
93
+ },
94
+ {
95
+ "SPDXID": "SPDXRef-Package-jose-6.2.3",
96
+ "name": "jose",
97
+ "versionInfo": "6.2.3",
98
+ "downloadLocation": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz",
99
+ "filesAnalyzed": false,
100
+ "licenseConcluded": "NOASSERTION",
101
+ "licenseDeclared": "MIT",
102
+ "copyrightText": "NOASSERTION",
103
+ "supplier": "NOASSERTION",
104
+ "externalRefs": [
105
+ {
106
+ "referenceCategory": "PACKAGE-MANAGER",
107
+ "referenceType": "purl",
108
+ "referenceLocator": "pkg:npm/jose@6.2.3"
109
+ }
110
+ ],
111
+ "description": "JWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes",
112
+ "homepage": "https://github.com/panva/jose"
113
+ },
74
114
  {
75
115
  "SPDXID": "SPDXRef-Package-jsep-1.4.0",
76
116
  "name": "jsep",
@@ -168,6 +208,16 @@
168
208
  "relatedSpdxElement": "SPDXRef-Package-jsep-1.4.0",
169
209
  "relationshipType": "DEPENDS_ON"
170
210
  },
211
+ {
212
+ "spdxElementId": "SPDXRef-RootPackage",
213
+ "relatedSpdxElement": "SPDXRef-Package-fast-cartesian-9.0.1",
214
+ "relationshipType": "DEPENDS_ON"
215
+ },
216
+ {
217
+ "spdxElementId": "SPDXRef-RootPackage",
218
+ "relatedSpdxElement": "SPDXRef-Package-jose-6.2.3",
219
+ "relationshipType": "DEPENDS_ON"
220
+ },
171
221
  {
172
222
  "spdxElementId": "SPDXRef-RootPackage",
173
223
  "relatedSpdxElement": "SPDXRef-Package-jsonpath-plus-10.4.0",