@kici-dev/engine 0.4.0 → 0.6.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.
Files changed (81) hide show
  1. package/dist/audit/access-log-policy.js +1 -0
  2. package/dist/audit/retention-policy.js +2 -0
  3. package/dist/context/held-run-job-id.d.ts +26 -10
  4. package/dist/context/held-run-job-id.js +30 -11
  5. package/dist/context/host-match.js +2 -1
  6. package/dist/context/index.d.ts +1 -1
  7. package/dist/context/index.js +3 -3
  8. package/dist/context/types.d.ts +10 -1
  9. package/dist/context/types.js +10 -1
  10. package/dist/index.d.ts +6 -2
  11. package/dist/index.js +17 -12
  12. package/dist/labels/compile.d.ts +2 -7
  13. package/dist/labels/compile.js +1 -10
  14. package/dist/labels.d.ts +74 -12
  15. package/dist/labels.js +82 -17
  16. package/dist/mcp/held-run-resolve.d.ts +40 -0
  17. package/dist/mcp/held-run-resolve.js +68 -15
  18. package/dist/mcp/tool-schemas.d.ts +4 -0
  19. package/dist/mcp/tool-schemas.js +13 -1
  20. package/dist/metrics/catalog-policy.d.ts +17 -3
  21. package/dist/metrics/catalog-policy.js +44 -13
  22. package/dist/metrics/metric-catalog.generated.d.ts +140 -0
  23. package/dist/metrics/metric-catalog.generated.js +168 -0
  24. package/dist/protocol/dashboard-global-workflows.js +2 -2
  25. package/dist/protocol/event-log-payload.js +1 -1
  26. package/dist/protocol/messages/access-log.d.ts +5 -0
  27. package/dist/protocol/messages/access-log.js +1 -0
  28. package/dist/protocol/messages/actor.d.ts +13 -2
  29. package/dist/protocol/messages/actor.js +16 -5
  30. package/dist/protocol/messages/common.js +1 -1
  31. package/dist/protocol/messages/dashboard-global-workflows.d.ts +29 -3
  32. package/dist/protocol/messages/dashboard-global-workflows.js +48 -4
  33. package/dist/protocol/messages/dashboard.d.ts +48 -7
  34. package/dist/protocol/messages/dashboard.js +62 -6
  35. package/dist/protocol/messages/execution-status.d.ts +44 -0
  36. package/dist/protocol/messages/execution-status.js +69 -2
  37. package/dist/protocol/messages/git-credential-relay.d.ts +78 -0
  38. package/dist/protocol/messages/git-credential-relay.js +86 -0
  39. package/dist/protocol/messages/orchestrator-agent.d.ts +138 -0
  40. package/dist/protocol/messages/orchestrator-agent.js +131 -3
  41. package/dist/protocol/messages/peer.d.ts +7 -0
  42. package/dist/protocol/messages/peer.js +18 -1
  43. package/dist/protocol/messages/platform-orchestrator.d.ts +155 -2
  44. package/dist/protocol/messages/platform-orchestrator.js +178 -19
  45. package/dist/protocol/version.d.ts +19 -2
  46. package/dist/protocol/version.js +20 -3
  47. package/dist/provenance/verify.js +11 -10
  48. package/dist/provider/check-status-poster.d.ts +37 -2
  49. package/dist/provider/contributor-resolver.d.ts +11 -3
  50. package/dist/provider/file-contents-fetcher.d.ts +39 -0
  51. package/dist/provider/file-contents-fetcher.js +2 -0
  52. package/dist/provider/git-credential.d.ts +77 -0
  53. package/dist/provider/git-credential.js +10 -0
  54. package/dist/provider/index.d.ts +4 -0
  55. package/dist/provider/index.js +2 -1
  56. package/dist/provider/webhook-normalizer.d.ts +12 -12
  57. package/dist/repo/pattern-negation.d.ts +73 -0
  58. package/dist/repo/pattern-negation.js +86 -0
  59. package/dist/safe-regex.d.ts +16 -0
  60. package/dist/safe-regex.js +24 -0
  61. package/dist/scaler/registry-auth.d.ts +18 -0
  62. package/dist/scaler/registry-auth.js +28 -0
  63. package/dist/scaler/scaler-backend-type.d.ts +35 -0
  64. package/dist/scaler/scaler-backend-type.js +39 -2
  65. package/dist/scaler/scaler-events.d.ts +79 -0
  66. package/dist/scaler/scaler-events.js +87 -0
  67. package/dist/trigger/compiled-matchers.d.ts +21 -1
  68. package/dist/trigger/compiled-matchers.js +30 -3
  69. package/dist/trigger/content-requirements.d.ts +31 -0
  70. package/dist/trigger/content-requirements.js +125 -0
  71. package/dist/trigger/decision-trace.d.ts +168 -0
  72. package/dist/trigger/decision-trace.js +207 -4
  73. package/dist/trigger/jsonpath-matcher.js +5 -1
  74. package/dist/trigger/matcher.js +61 -10
  75. package/dist/trigger/text-match.d.ts +27 -0
  76. package/dist/trigger/text-match.js +86 -0
  77. package/dist/trigger/types.d.ts +265 -23
  78. package/dist/trigger/types.js +37 -5
  79. package/dist/ws/rate-limiter.js +3 -3
  80. package/package.json +20 -3
  81. package/sbom.spdx.json +40 -15
@@ -27,11 +27,21 @@ const CacheRefScope = z.enum(["shared", "isolated"]);
27
27
  * - `groups` maps a dynamic group name to its ordered member job names.
28
28
  * - `statuses` maps an upstream job name to its terminal status, so the
29
29
  * generator's `ctx.needs.<job>.status` reflects the frozen upstream outcome.
30
+ * - `invokeResults` maps an invoke-gate job name to its ordered per-run results,
31
+ * so the generator's `ctx.needs.<gate>.result` reflects each summoned run.
30
32
  */
33
+ const invokeResultSchema = z.object({
34
+ repo: z.string(),
35
+ workflow: z.string(),
36
+ runId: z.string(),
37
+ status: z.string(),
38
+ outputs: z.record(z.string(), z.unknown())
39
+ });
31
40
  const upstreamSnapshotSchema = z.object({
32
41
  jobs: z.record(z.string(), z.record(z.string(), z.unknown())),
33
42
  groups: z.record(z.string(), z.array(z.string())),
34
- statuses: z.record(z.string(), ExecutionJobStatus).optional()
43
+ statuses: z.record(z.string(), ExecutionJobStatus).optional(),
44
+ invokeResults: z.record(z.string(), z.array(invokeResultSchema)).optional()
35
45
  });
36
46
  /**
37
47
  * Structured git-clone auth material. Carries everything the agent needs to
@@ -108,6 +118,15 @@ const jobDispatchSchema = z.object({
108
118
  /** Terminal status of each upstream job (keyed by job name; per-child for fan-out). Powers `ctx.needs.<job>.status`. */
109
119
  upstreamJobStatuses: z.record(z.string(), ExecutionJobStatus).optional(),
110
120
  /**
121
+ * Per-invoke-gate results for any upstream gate this job `needs`, keyed by
122
+ * gate job name. One {@link invokeResultSchema} entry per run the gate
123
+ * triggered, carrying the invoked run's non-secret declared outputs. Powers
124
+ * a standard downstream job's `ctx.needs['<gate>'].result`. Additive and
125
+ * optional — older orchestrators omit it and the agent resolves the gate
126
+ * need through the fan-out group shape instead.
127
+ */
128
+ upstreamInvokeResults: z.record(z.string(), z.array(invokeResultSchema)).optional(),
129
+ /**
111
130
  * Structured clone auth for the source repo. Preferred over `token` (which
112
131
  * remains as a backward-compat field for same-provider GitHub App flows
113
132
  * during the transition to universal-git / cross-provider global workflows).
@@ -143,6 +162,20 @@ const jobDispatchSchema = z.object({
143
162
  token: z.string().min(1)
144
163
  })).optional(),
145
164
  /**
165
+ * Registry credentials for pulling this job's container image, already
166
+ * resolved by the orchestrator (the lock carries secret NAMES; the agent
167
+ * never resolves them itself).
168
+ *
169
+ * Optional for backward compatibility with older orchestrators, which do
170
+ * not send it — an agent that receives no auth pulls anonymously, exactly
171
+ * as it did before.
172
+ */
173
+ containerRegistryAuth: z.object({
174
+ username: z.string().min(1),
175
+ password: z.string().min(1),
176
+ serveraddress: z.string().min(1)
177
+ }).optional(),
178
+ /**
146
179
  * Extra resolved secrets to project as env vars on the install
147
180
  * subprocess. Keyed by the bare secret name (the qualified env: prefix
148
181
  * is stripped at resolution time). For use with a customer-committed
@@ -204,6 +237,23 @@ const registerAckSchema = z.object({
204
237
  */
205
238
  pendingDispatch: z.boolean().optional(),
206
239
  /**
240
+ * Set when this agent was pre-spawned to wait for work (a warm pool) rather
241
+ * than for a specific queued job. Such an agent MUST NOT arm any
242
+ * idle-shutdown timer on register: it is meant to sit ready until the
243
+ * orchestrator either dispatches a job to it or destroys it.
244
+ *
245
+ * The orchestrator's warm-pool reaper is the sole authority on its lifetime.
246
+ * An agent that also ran its own idle timer would self-terminate behind the
247
+ * reaper's back, re-creating the spawn/reap churn that reaping only surplus
248
+ * agents exists to prevent.
249
+ *
250
+ * Absent on orchestrators that predate warm pools. An agent that does not
251
+ * understand this field arms the short KICI_SCALER_IDLE_TIMEOUT timer exactly
252
+ * as before — so warm pools do not work against it, which is today's
253
+ * behaviour rather than a regression.
254
+ */
255
+ warmPool: z.boolean().optional(),
256
+ /**
207
257
  * Optional agent-facing capabilities this orchestrator supports (absent on
208
258
  * pre-capability orchestrators). The agent reads it to decide whether to
209
259
  * await optional acks like `artifacts.upload.complete.ack`.
@@ -288,6 +338,39 @@ const jobStatusSchema = z.object({
288
338
  encrypted: z.string()
289
339
  })).optional()
290
340
  });
341
+ /**
342
+ * One candidate workflow's verdict from the pre-run global eval round — the
343
+ * job the agent runs once per (event × workflow repo) before any run row
344
+ * exists, evaluating each candidate's `filter` and then its `DynamicJobFn`s on
345
+ * a single dual checkout.
346
+ *
347
+ * `jobs` carries `LockJob[]` as an unvalidated pass-through, the same shape and
348
+ * for the same reason as `jobDispatchSchema.jobConfig`: the lock-file job shape
349
+ * has no Zod mirror anywhere in this package, its single source of truth is the
350
+ * `LockJob` interface in `trigger/types.ts`, and a hand-written Zod copy would
351
+ * drift and start rejecting legitimate generated jobs.
352
+ *
353
+ * Every field beyond the verdict itself is `.optional()` so an older peer
354
+ * tolerates the message unchanged.
355
+ */
356
+ const globalEvalCandidateResultSchema = z.object({
357
+ /** The candidate workflow's name, as it appears in the lock file. */
358
+ workflowName: z.string(),
359
+ /** Whether this workflow applies to the source repo that triggered the round. */
360
+ run: z.boolean(),
361
+ jobs: z.array(z.record(z.string(), z.unknown())).optional().describe("Jobs generated by the workflow DynamicJobFns (LockJob[])"),
362
+ /**
363
+ * Set when the verdict could not be established — the filter or a generator
364
+ * threw, or blew the per-candidate budget. `run` is `false` alongside it, but
365
+ * that is a "could not decide", not a clean "does not apply": one bad
366
+ * candidate never fails the round, so its siblings still carry real verdicts.
367
+ */
368
+ indeterminate: z.boolean().optional(),
369
+ /** Human-readable cause, present when `indeterminate` is set. */
370
+ reason: z.string().optional()
371
+ });
372
+ /** Every candidate's verdict from one global eval round, in candidate order. */
373
+ const globalEvalRoundResultSchema = z.object({ candidates: z.array(globalEvalCandidateResultSchema) });
291
374
  /** Reasons an agent can refuse a job.dispatch. */
292
375
  const JobRejectReason = z.enum(["busy", "draining"]);
293
376
  /**
@@ -453,7 +536,16 @@ const cacheUploadRequestSchema = z.object({
453
536
  contentHash: z.string().optional(),
454
537
  lockfileHash: z.string().optional(),
455
538
  platform: z.string(),
456
- arch: z.string()
539
+ arch: z.string(),
540
+ /**
541
+ * SHA-256 of the dependency tarball about to be uploaded. Deps uploads only.
542
+ *
543
+ * The dep tarball is stored under its own content hash, so the orchestrator
544
+ * needs it to sign the upload URL — the agent has already built the tarball
545
+ * and hashed it by the time it asks. Optional so an older agent that omits it
546
+ * still gets a usable (lockfile-keyed) URL during a mixed-version rollout.
547
+ */
548
+ depsHash: z.string().optional()
457
549
  });
458
550
  /** Orchestrator -> Agent: return the pre-signed upload URL. */
459
551
  const cacheUploadResponseSchema = z.object({
@@ -742,6 +834,40 @@ const eventEmitResponseSchema = z.object({
742
834
  /** Error description (present on failure). */
743
835
  error: z.string().optional()
744
836
  });
837
+ /**
838
+ * Agent -> Orchestrator: exchanges a single-use claim code (delivered on a
839
+ * `kici.scaler.scale-up` event) for freshly minted ephemeral agent credentials.
840
+ * A provisioned agent normally sends this itself to self-bootstrap — the claim
841
+ * code is the authorization, so it may send it before it authenticates or
842
+ * registers. A provisioning workflow can also send it to obtain the token
843
+ * directly. Additive/negotiated by presence — older peers that never emit it
844
+ * are unaffected, so it needs no `PROTOCOL_VERSION` bump of its own.
845
+ */
846
+ const scalerClaimCredentialsSchema = z.object({
847
+ type: z.literal("scaler.claim-credentials"),
848
+ /** Correlates to the response for this claim. */
849
+ requestId: z.string(),
850
+ /** Single-use code from the scale-up event's payload. */
851
+ claimCode: z.string()
852
+ });
853
+ /**
854
+ * Orchestrator -> Agent: minted ephemeral credentials for a claimed provision,
855
+ * or an error. The token appears only here — never in the persisted event log.
856
+ */
857
+ const scalerClaimCredentialsResponseSchema = z.object({
858
+ type: z.literal("scaler.claim-credentials.response"),
859
+ /** Correlates to the original scaler.claim-credentials requestId. */
860
+ requestId: z.string(),
861
+ /** Minted credentials (present on success). */
862
+ credentials: z.object({
863
+ agentToken: z.string(),
864
+ agentId: z.string(),
865
+ orchestratorUrl: z.string(),
866
+ labels: z.array(z.string())
867
+ }).optional(),
868
+ /** Error description (present on failure). */
869
+ error: z.string().optional()
870
+ });
745
871
  /** Periodic metrics push from agent to orchestrator. */
746
872
  const agentMetricsSchema = z.object({
747
873
  type: z.literal("agent.metrics"),
@@ -906,6 +1032,7 @@ const orchestratorToAgentMessageSchema = z.discriminatedUnion("type", [
906
1032
  artifactsUploadCompleteAckSchema,
907
1033
  artifactsDownloadResponseSchema,
908
1034
  eventEmitResponseSchema,
1035
+ scalerClaimCredentialsResponseSchema,
909
1036
  agentApiResponseSchema,
910
1037
  agentAuthSuccessSchema,
911
1038
  agentAuthFailureSchema,
@@ -937,6 +1064,7 @@ const agentToOrchestratorMessageSchema = z.discriminatedUnion("type", [
937
1064
  artifactsUploadCompleteSchema,
938
1065
  artifactsDownloadRequestSchema,
939
1066
  eventEmitSchema,
1067
+ scalerClaimCredentialsSchema,
940
1068
  agentApiRequestSchema,
941
1069
  agentMetricsSchema,
942
1070
  agentAuthRequestSchema,
@@ -945,6 +1073,6 @@ const agentToOrchestratorMessageSchema = z.discriminatedUnion("type", [
945
1073
  stepApprovalRequestSchema
946
1074
  ]);
947
1075
  //#endregion
948
- export { ArtifactCompleteAckOutcome, ArtifactDownloadOutcome, ArtifactRejectReason, ArtifactUploadOutcome, CacheRefScope, JobRejectReason, StepApprovalOutcome, agentApiRequestSchema, agentApiResponseSchema, agentAuthFailureSchema, agentAuthRequestSchema, agentAuthSuccessSchema, agentLogChunkSchema, agentMetricsSchema, agentRegisterSchema, agentStatusSchema, agentStepStatusSchema, agentToOrchestratorMessageSchema, artifactsDownloadRequestSchema, artifactsDownloadResponseSchema, artifactsUploadCompleteAckSchema, artifactsUploadCompleteSchema, artifactsUploadRequestSchema, artifactsUploadResponseSchema, cacheUserRestoreRequestSchema, cacheUserRestoreResponseSchema, cacheUserSaveCompleteSchema, cacheUserSaveRequestSchema, cacheUserSaveResponseSchema, configAckSchema, eventEmitResponseSchema, eventEmitSchema, fleetBundleChunkSchema, fleetBundleErrorSchema, fleetLogsRequestSchema, gitAuthSchema, jobAckSchema, jobCancelSchema, jobConcurrencyAckSchema, jobConcurrencyReportSchema, jobDispatchSchema, jobRejectSchema, jobStatusSchema, orchestratorToAgentMessageSchema, provenanceUploadCompleteSchema, provenanceUploadDeferSchema, provenanceUploadRequestSchema, provenanceUploadResponseSchema, registerAckSchema, stepApprovalPayloadSchema, stepApprovalRequestSchema, stepApprovalResolvedSchema, upstreamSnapshotSchema };
1076
+ export { ArtifactCompleteAckOutcome, ArtifactDownloadOutcome, ArtifactRejectReason, ArtifactUploadOutcome, CacheRefScope, JobRejectReason, StepApprovalOutcome, agentApiRequestSchema, agentApiResponseSchema, agentAuthFailureSchema, agentAuthRequestSchema, agentAuthSuccessSchema, agentLogChunkSchema, agentMetricsSchema, agentRegisterSchema, agentStatusSchema, agentStepStatusSchema, agentToOrchestratorMessageSchema, artifactsDownloadRequestSchema, artifactsDownloadResponseSchema, artifactsUploadCompleteAckSchema, artifactsUploadCompleteSchema, artifactsUploadRequestSchema, artifactsUploadResponseSchema, cacheUserRestoreRequestSchema, cacheUserRestoreResponseSchema, cacheUserSaveCompleteSchema, cacheUserSaveRequestSchema, cacheUserSaveResponseSchema, configAckSchema, eventEmitResponseSchema, eventEmitSchema, fleetBundleChunkSchema, fleetBundleErrorSchema, fleetLogsRequestSchema, gitAuthSchema, globalEvalCandidateResultSchema, globalEvalRoundResultSchema, invokeResultSchema, jobAckSchema, jobCancelSchema, jobConcurrencyAckSchema, jobConcurrencyReportSchema, jobDispatchSchema, jobRejectSchema, jobStatusSchema, orchestratorToAgentMessageSchema, provenanceUploadCompleteSchema, provenanceUploadDeferSchema, provenanceUploadRequestSchema, provenanceUploadResponseSchema, registerAckSchema, scalerClaimCredentialsResponseSchema, scalerClaimCredentialsSchema, stepApprovalPayloadSchema, stepApprovalRequestSchema, stepApprovalResolvedSchema, upstreamSnapshotSchema };
949
1077
 
950
1078
  //# sourceMappingURL=orchestrator-agent.js.map
@@ -16,6 +16,7 @@ declare const scalerCapacitySummarySchema: z.ZodObject<{
16
16
  activeCount: z.ZodNumber;
17
17
  spawnsOnLocalHost: z.ZodOptional<z.ZodBoolean>;
18
18
  mandatoryLabels: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
19
+ labelSetMandatoryLabels: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
19
20
  }, z.core.$strip>;
20
21
  /** Peer hello: initiator sends ephemeral X25519 public key and nonce. */
21
22
  export declare const peerHelloSchema: z.ZodObject<{
@@ -68,6 +69,7 @@ export declare const peerAuthResponseSchema: z.ZodObject<{
68
69
  activeCount: z.ZodNumber;
69
70
  spawnsOnLocalHost: z.ZodOptional<z.ZodBoolean>;
70
71
  mandatoryLabels: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
72
+ labelSetMandatoryLabels: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
71
73
  }, z.core.$strip>>>;
72
74
  capabilities: z.ZodOptional<z.ZodObject<{
73
75
  s3LogAccess: z.ZodBoolean;
@@ -109,6 +111,7 @@ export declare const peerHeartbeatSchema: z.ZodObject<{
109
111
  activeCount: z.ZodNumber;
110
112
  spawnsOnLocalHost: z.ZodOptional<z.ZodBoolean>;
111
113
  mandatoryLabels: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
114
+ labelSetMandatoryLabels: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
112
115
  }, z.core.$strip>>>;
113
116
  configVersion: z.ZodOptional<z.ZodNumber>;
114
117
  registryVersion: z.ZodOptional<z.ZodNumber>;
@@ -495,6 +498,7 @@ export declare const peerToPeerMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObje
495
498
  activeCount: z.ZodNumber;
496
499
  spawnsOnLocalHost: z.ZodOptional<z.ZodBoolean>;
497
500
  mandatoryLabels: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
501
+ labelSetMandatoryLabels: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
498
502
  }, z.core.$strip>>>;
499
503
  capabilities: z.ZodOptional<z.ZodObject<{
500
504
  s3LogAccess: z.ZodBoolean;
@@ -534,6 +538,7 @@ export declare const peerToPeerMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObje
534
538
  activeCount: z.ZodNumber;
535
539
  spawnsOnLocalHost: z.ZodOptional<z.ZodBoolean>;
536
540
  mandatoryLabels: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
541
+ labelSetMandatoryLabels: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
537
542
  }, z.core.$strip>>>;
538
543
  configVersion: z.ZodOptional<z.ZodNumber>;
539
544
  registryVersion: z.ZodOptional<z.ZodNumber>;
@@ -809,6 +814,7 @@ export declare const peerFromPeerMessageSchema: z.ZodDiscriminatedUnion<[z.ZodOb
809
814
  activeCount: z.ZodNumber;
810
815
  spawnsOnLocalHost: z.ZodOptional<z.ZodBoolean>;
811
816
  mandatoryLabels: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
817
+ labelSetMandatoryLabels: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
812
818
  }, z.core.$strip>>>;
813
819
  capabilities: z.ZodOptional<z.ZodObject<{
814
820
  s3LogAccess: z.ZodBoolean;
@@ -848,6 +854,7 @@ export declare const peerFromPeerMessageSchema: z.ZodDiscriminatedUnion<[z.ZodOb
848
854
  activeCount: z.ZodNumber;
849
855
  spawnsOnLocalHost: z.ZodOptional<z.ZodBoolean>;
850
856
  mandatoryLabels: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
857
+ labelSetMandatoryLabels: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
851
858
  }, z.core.$strip>>>;
852
859
  configVersion: z.ZodOptional<z.ZodNumber>;
853
860
  registryVersion: z.ZodOptional<z.ZodNumber>;
@@ -62,8 +62,25 @@ const scalerCapacitySummarySchema = z.object({
62
62
  * empty the backend has no gate. Cross-peer routing applies the same
63
63
  * rule as the local label matcher: a scaler-capacity entry only
64
64
  * matches when every mandatory label appears in the required label set.
65
+ *
66
+ * @deprecated Use {@link labelSetMandatoryLabels}, which carries one gate
67
+ * per label set. This field is the union across every label set, so a
68
+ * scaler mixing `[linux, gpu]` with `[macos, xcode]` advertises a gate that
69
+ * makes its linux set unroutable. It stays populated for peers that predate
70
+ * the per-label-set field and is removed in v1.0.0.
71
+ */
72
+ mandatoryLabels: z.array(z.string()).optional().default([]),
73
+ /**
74
+ * Per-label-set taint gate, index-aligned with `labelSets`: entry `i` is the
75
+ * gate a job must satisfy to route to `labelSets[i]`.
76
+ *
77
+ * Deliberately `.optional()` with no default. `undefined` is the only value
78
+ * that can mean "this peer predates the field — fall back to the scaler-wide
79
+ * `mandatoryLabels`"; an empty array would read as "every label set is
80
+ * ungated". A consumer also falls back when the length does not equal
81
+ * `labelSets.length`, so a malformed advertisement is never indexed into.
65
82
  */
66
- mandatoryLabels: z.array(z.string()).optional().default([])
83
+ labelSetMandatoryLabels: z.array(z.array(z.string())).optional()
67
84
  });
68
85
  /** Peer hello: initiator sends ephemeral X25519 public key and nonce. */
69
86
  const peerHelloSchema = z.object({
@@ -13,10 +13,91 @@ import { z } from 'zod';
13
13
  * number cannot drift between the two packages that enforce it.
14
14
  */
15
15
  export declare const DEFAULT_APPROVAL_EXPIRY_HOURS = 72;
16
+ /** Seconds in an hour — the one conversion between the two expiry spellings. */
17
+ export declare const SECONDS_PER_HOUR = 3600;
18
+ /**
19
+ * The same documented default as {@link DEFAULT_APPROVAL_EXPIRY_HOURS}, in the
20
+ * granularity the policy actually stores.
21
+ */
22
+ export declare const DEFAULT_APPROVAL_EXPIRY_SECONDS: number;
23
+ /**
24
+ * The shortest expressible security-hold window.
25
+ *
26
+ * One second, not a rounder-looking number: the floor exists to stop a zero or
27
+ * negative value minting an already-expired hold, and any strictly positive
28
+ * integer discharges that. A larger floor would be an invented usability
29
+ * opinion that also puts the window back out of reach of a test.
30
+ */
31
+ export declare const MIN_APPROVAL_EXPIRY_SECONDS = 1;
32
+ /** The longest window the Platform accepts: one year, the bound already applied to hours. */
33
+ export declare const MAX_APPROVAL_EXPIRY_HOURS = 8760;
34
+ /** {@link MAX_APPROVAL_EXPIRY_HOURS} in seconds, so neither spelling outranges the other. */
35
+ export declare const MAX_APPROVAL_EXPIRY_SECONDS: number;
36
+ /**
37
+ * The window a policy actually means, in seconds.
38
+ *
39
+ * `approvalExpirySeconds` is the authority and `approvalExpiryHours` its coarse
40
+ * spelling, so the more specific field wins whenever both are present — the
41
+ * only rule that never discards what an operator asked for. A policy carrying
42
+ * neither (an older peer that sent no window at all) falls back to the
43
+ * documented default.
44
+ */
45
+ export declare function approvalExpirySecondsOf(policy: {
46
+ approvalExpiryHours?: number | null;
47
+ approvalExpirySeconds?: number | null;
48
+ }): number;
49
+ /**
50
+ * The coarse `approvalExpiryHours` view of a window stored in seconds.
51
+ *
52
+ * Rounds UP, and never below one hour. A sub-hour window has no exact hours
53
+ * spelling, and the peer reading this field is one that cannot express the real
54
+ * value anyway — so the choice is which way to be wrong. Rounding up yields a
55
+ * longer hold than asked for, which stays approvable; rounding down yields zero,
56
+ * which is the already-expired hold `MIN_APPROVAL_EXPIRY_SECONDS` exists to
57
+ * prevent.
58
+ */
59
+ export declare function approvalExpiryHoursOf(seconds: number): number;
60
+ /**
61
+ * The org-level fork switch: the setting an org's trust policy carries for how
62
+ * fork pull requests are treated. Each value names what the operator is
63
+ * choosing; which values the orchestrator's trust-policy gate honours, and the
64
+ * mechanism it uses, are owned there rather than here.
65
+ *
66
+ * - `ignore` — the operator declines fork pull requests.
67
+ * - `hold` — the operator requires approval first; the policy's approval expiry
68
+ * bounds how long that approval stays open.
69
+ * - `allow` — the operator permits fork pull requests to run with reduced
70
+ * privilege.
71
+ * - `reject` — deprecated in favour of `ignore`; removed at v1.0.0.
72
+ */
73
+ export declare const ForkPolicy: z.ZodEnum<{
74
+ allow: "allow";
75
+ hold: "hold";
76
+ ignore: "ignore";
77
+ reject: "reject";
78
+ }>;
79
+ export type ForkPolicy = z.infer<typeof ForkPolicy>;
80
+ /**
81
+ * How much CI authority one org member holds.
82
+ *
83
+ * The level the `/kici approve` comment path reads once it has resolved a
84
+ * commenter to a KiCI user id: `write` or `admin` may release a security hold,
85
+ * `read` and `none` may not. Named here rather than spelled inline so the wire
86
+ * schema, the orchestrator's admin route, and `kici-admin` all offer exactly
87
+ * the same four values.
88
+ */
89
+ export declare const CiTrustLevel: z.ZodEnum<{
90
+ admin: "admin";
91
+ none: "none";
92
+ read: "read";
93
+ write: "write";
94
+ }>;
95
+ export type CiTrustLevel = z.infer<typeof CiTrustLevel>;
16
96
  export declare const trustPolicySchema: z.ZodObject<{
17
97
  forkPolicy: z.ZodEnum<{
18
98
  allow: "allow";
19
99
  hold: "hold";
100
+ ignore: "ignore";
20
101
  reject: "reject";
21
102
  }>;
22
103
  unknownContributorPolicy: z.ZodEnum<{
@@ -29,6 +110,7 @@ export declare const trustPolicySchema: z.ZodObject<{
29
110
  reject: "reject";
30
111
  }>;
31
112
  approvalExpiryHours: z.ZodNumber;
113
+ approvalExpirySeconds: z.ZodOptional<z.ZodNumber>;
32
114
  }, z.core.$strip>;
33
115
  export type TrustPolicy = z.infer<typeof trustPolicySchema>;
34
116
  /** Trust policy update pushed from Platform to orchestrator when policy or identity links change. */
@@ -39,6 +121,7 @@ export declare const trustPolicyUpdateSchema: z.ZodObject<{
39
121
  forkPolicy: z.ZodEnum<{
40
122
  allow: "allow";
41
123
  hold: "hold";
124
+ ignore: "ignore";
42
125
  reject: "reject";
43
126
  }>;
44
127
  unknownContributorPolicy: z.ZodEnum<{
@@ -51,6 +134,7 @@ export declare const trustPolicyUpdateSchema: z.ZodObject<{
51
134
  reject: "reject";
52
135
  }>;
53
136
  approvalExpiryHours: z.ZodNumber;
137
+ approvalExpirySeconds: z.ZodOptional<z.ZodNumber>;
54
138
  }, z.core.$strip>;
55
139
  identityLinks: z.ZodArray<z.ZodObject<{
56
140
  userId: z.ZodString;
@@ -215,6 +299,7 @@ export declare const staleCheckrunCleanupSchema: z.ZodObject<{
215
299
  repoIdentifier: z.ZodString;
216
300
  sha: z.ZodString;
217
301
  workflowName: z.ZodString;
302
+ workflowRepoIdentifier: z.ZodOptional<z.ZodString>;
218
303
  jobNames: z.ZodArray<z.ZodString>;
219
304
  }, z.core.$strip>>;
220
305
  }, z.core.$strip>;
@@ -274,6 +359,50 @@ export declare const orchMetricsSchema: z.ZodObject<{
274
359
  timestamp: z.ZodNumber;
275
360
  }, z.core.$strip>;
276
361
  export type OrchMetrics = z.infer<typeof orchMetricsSchema>;
362
+ /** Largest worker-peer snapshot accepted on one frame. */
363
+ export declare const CLUSTER_MEMBERSHIP_MAX_WORKERS = 512;
364
+ /**
365
+ * Worker-peer membership snapshot, sent by a coordinator to the Platform.
366
+ *
367
+ * A snapshot rather than a delta: a dropped or reordered frame self-heals on
368
+ * the next send instead of corrupting a running tally. The Platform stores the
369
+ * reported size on `platform_connections` and aggregates it into the org's
370
+ * combined orchestrator count.
371
+ *
372
+ * The array bound is the first line of defence, for the same reason
373
+ * `orchMetricsSchema` bounds its own arrays: a malformed or hostile push must
374
+ * fail Zod parse at the WS edge and never reach the aggregate.
375
+ */
376
+ export declare const clusterMembershipSchema: z.ZodObject<{
377
+ type: z.ZodLiteral<"cluster.membership">;
378
+ workers: z.ZodArray<z.ZodObject<{
379
+ instanceId: z.ZodString;
380
+ }, z.core.$strip>>;
381
+ timestamp: z.ZodNumber;
382
+ }, z.core.$strip>;
383
+ export type ClusterMembership = z.infer<typeof clusterMembershipSchema>;
384
+ /**
385
+ * Per-coordinator orchestrator ceiling, pushed by the Platform.
386
+ *
387
+ * `maxWorkerPeers` is an ABSOLUTE ceiling on this coordinator's connected
388
+ * worker peers, not a remaining allowance. The Platform computes it by
389
+ * excluding this connection's own workers from the org total, so it does not
390
+ * move when a local worker joins or leaves — the coordinator can enforce
391
+ * against its live peer count with no round trip and no staleness window.
392
+ *
393
+ * `orgLimit` and `orgTotal` are informational: they let the coordinator's
394
+ * rejection reason say why, rather than closing opaquely. `evictExcess` is set
395
+ * once the org has been over its limit for longer than the grace window, and
396
+ * asks the coordinator to drain its newest workers down to the ceiling.
397
+ */
398
+ export declare const planHeadroomSchema: z.ZodObject<{
399
+ type: z.ZodLiteral<"plan.headroom">;
400
+ maxWorkerPeers: z.ZodNumber;
401
+ orgLimit: z.ZodNumber;
402
+ orgTotal: z.ZodNumber;
403
+ evictExcess: z.ZodBoolean;
404
+ }, z.core.$strip>;
405
+ export type PlanHeadroom = z.infer<typeof planHeadroomSchema>;
277
406
  /**
278
407
  * Acknowledgment that a webhook was received and processing started.
279
408
  *
@@ -474,6 +603,7 @@ export declare const platformToOrchestratorMessageSchema: z.ZodDiscriminatedUnio
474
603
  forkPolicy: z.ZodEnum<{
475
604
  allow: "allow";
476
605
  hold: "hold";
606
+ ignore: "ignore";
477
607
  reject: "reject";
478
608
  }>;
479
609
  unknownContributorPolicy: z.ZodEnum<{
@@ -486,6 +616,7 @@ export declare const platformToOrchestratorMessageSchema: z.ZodDiscriminatedUnio
486
616
  reject: "reject";
487
617
  }>;
488
618
  approvalExpiryHours: z.ZodNumber;
619
+ approvalExpirySeconds: z.ZodOptional<z.ZodNumber>;
489
620
  }, z.core.$strip>;
490
621
  identityLinks: z.ZodArray<z.ZodObject<{
491
622
  userId: z.ZodString;
@@ -562,6 +693,7 @@ export declare const platformToOrchestratorMessageSchema: z.ZodDiscriminatedUnio
562
693
  repoIdentifier: z.ZodString;
563
694
  sha: z.ZodString;
564
695
  workflowName: z.ZodString;
696
+ workflowRepoIdentifier: z.ZodOptional<z.ZodString>;
565
697
  jobNames: z.ZodArray<z.ZodString>;
566
698
  }, z.core.$strip>>;
567
699
  }, z.core.$strip>, z.ZodObject<{
@@ -586,6 +718,12 @@ export declare const platformToOrchestratorMessageSchema: z.ZodDiscriminatedUnio
586
718
  orchMetrics: z.ZodOptional<z.ZodBoolean>;
587
719
  oidcMint: z.ZodOptional<z.ZodBoolean>;
588
720
  }, z.core.$loose>;
721
+ }, z.core.$strip>, z.ZodObject<{
722
+ type: z.ZodLiteral<"plan.headroom">;
723
+ maxWorkerPeers: z.ZodNumber;
724
+ orgLimit: z.ZodNumber;
725
+ orgTotal: z.ZodNumber;
726
+ evictExcess: z.ZodBoolean;
589
727
  }, z.core.$strip>, z.ZodObject<{
590
728
  type: z.ZodLiteral<"nack">;
591
729
  messageId: z.ZodOptional<z.ZodString>;
@@ -2762,7 +2900,6 @@ export declare const platformToOrchestratorMessageSchema: z.ZodDiscriminatedUnio
2762
2900
  type: z.ZodLiteral<"system">;
2763
2901
  component: z.ZodString;
2764
2902
  }, z.core.$strip>], "type">;
2765
- enabled: z.ZodOptional<z.ZodBoolean>;
2766
2903
  allowedRepos: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
2767
2904
  routingKey: z.ZodOptional<z.ZodString>;
2768
2905
  pattern: z.ZodString;
@@ -2775,7 +2912,7 @@ export declare const platformToOrchestratorMessageSchema: z.ZodDiscriminatedUnio
2775
2912
  routingKey: z.ZodOptional<z.ZodString>;
2776
2913
  pattern: z.ZodString;
2777
2914
  }, z.core.$strip>>>>;
2778
- }, z.core.$strip>, z.ZodObject<{
2915
+ }, z.core.$strict>, z.ZodObject<{
2779
2916
  type: z.ZodLiteral<"dashboard.access-log.list">;
2780
2917
  requestId: z.ZodString;
2781
2918
  actor: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -2892,6 +3029,7 @@ export declare const platformToOrchestratorMessageSchema: z.ZodDiscriminatedUnio
2892
3029
  "source_override.set": "source_override.set";
2893
3030
  "sources.list.read": "sources.list.read";
2894
3031
  "step.logs.read": "step.logs.read";
3032
+ "trust_directory.updated": "trust_directory.updated";
2895
3033
  "trust_policy.updated": "trust_policy.updated";
2896
3034
  }>>;
2897
3035
  source: z.ZodOptional<z.ZodEnum<{
@@ -3207,6 +3345,8 @@ export declare const orchestratorToPlatformMessageSchema: z.ZodDiscriminatedUnio
3207
3345
  }>;
3208
3346
  routingKey: z.ZodOptional<z.ZodString>;
3209
3347
  repoIdentifier: z.ZodOptional<z.ZodString>;
3348
+ workflowRepoIdentifier: z.ZodOptional<z.ZodString>;
3349
+ isGlobalEvalRound: z.ZodOptional<z.ZodBoolean>;
3210
3350
  repoProvider: z.ZodOptional<z.ZodString>;
3211
3351
  localWorkingTree: z.ZodOptional<z.ZodBoolean>;
3212
3352
  sha: z.ZodOptional<z.ZodString>;
@@ -3332,6 +3472,12 @@ export declare const orchestratorToPlatformMessageSchema: z.ZodDiscriminatedUnio
3332
3472
  message: z.ZodString;
3333
3473
  jobName: z.ZodOptional<z.ZodString>;
3334
3474
  }, z.core.$strip>>;
3475
+ jobKind: z.ZodOptional<z.ZodEnum<{
3476
+ gate: "gate";
3477
+ proxy: "proxy";
3478
+ standard: "standard";
3479
+ }>>;
3480
+ summonedRunId: z.ZodOptional<z.ZodString>;
3335
3481
  }, z.core.$strip>, z.ZodObject<{
3336
3482
  type: z.ZodLiteral<"state.replay">;
3337
3483
  messageId: z.ZodString;
@@ -3349,6 +3495,7 @@ export declare const orchestratorToPlatformMessageSchema: z.ZodDiscriminatedUnio
3349
3495
  }>;
3350
3496
  routingKey: z.ZodOptional<z.ZodString>;
3351
3497
  repoIdentifier: z.ZodOptional<z.ZodString>;
3498
+ workflowRepoIdentifier: z.ZodOptional<z.ZodString>;
3352
3499
  sha: z.ZodOptional<z.ZodString>;
3353
3500
  ref: z.ZodOptional<z.ZodString>;
3354
3501
  triggerEvent: z.ZodOptional<z.ZodString>;
@@ -3633,6 +3780,12 @@ export declare const orchestratorToPlatformMessageSchema: z.ZodDiscriminatedUnio
3633
3780
  deferred: "deferred";
3634
3781
  "offline-backfill": "offline-backfill";
3635
3782
  }>>;
3783
+ }, z.core.$strip>, z.ZodObject<{
3784
+ type: z.ZodLiteral<"cluster.membership">;
3785
+ workers: z.ZodArray<z.ZodObject<{
3786
+ instanceId: z.ZodString;
3787
+ }, z.core.$strip>>;
3788
+ timestamp: z.ZodNumber;
3636
3789
  }, z.core.$strip>, z.ZodObject<{
3637
3790
  type: z.ZodLiteral<"nack">;
3638
3791
  messageId: z.ZodOptional<z.ZodString>;