@kici-dev/engine 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit/access-log-policy.js +1 -0
- package/dist/audit/retention-policy.js +2 -0
- package/dist/context/held-run-job-id.d.ts +26 -10
- package/dist/context/held-run-job-id.js +30 -11
- package/dist/context/index.d.ts +1 -1
- package/dist/context/index.js +3 -3
- package/dist/context/types.d.ts +10 -1
- package/dist/context/types.js +10 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +14 -11
- package/dist/labels.d.ts +66 -12
- package/dist/labels.js +74 -17
- package/dist/mcp/held-run-resolve.d.ts +40 -0
- package/dist/mcp/held-run-resolve.js +68 -15
- package/dist/mcp/tool-schemas.d.ts +4 -0
- package/dist/mcp/tool-schemas.js +13 -1
- package/dist/metrics/catalog-policy.d.ts +6 -3
- package/dist/metrics/catalog-policy.js +31 -10
- package/dist/metrics/metric-catalog.generated.d.ts +110 -0
- package/dist/metrics/metric-catalog.generated.js +132 -0
- package/dist/protocol/dashboard-global-workflows.js +2 -2
- package/dist/protocol/event-log-payload.js +1 -1
- package/dist/protocol/messages/access-log.d.ts +5 -0
- package/dist/protocol/messages/access-log.js +1 -0
- package/dist/protocol/messages/actor.d.ts +13 -2
- package/dist/protocol/messages/actor.js +16 -5
- package/dist/protocol/messages/common.js +1 -1
- package/dist/protocol/messages/dashboard-global-workflows.d.ts +21 -0
- package/dist/protocol/messages/dashboard-global-workflows.js +28 -1
- package/dist/protocol/messages/dashboard.d.ts +46 -5
- package/dist/protocol/messages/dashboard.js +67 -7
- package/dist/protocol/messages/execution-status.d.ts +41 -0
- package/dist/protocol/messages/execution-status.js +53 -2
- package/dist/protocol/messages/git-credential-relay.d.ts +78 -0
- package/dist/protocol/messages/git-credential-relay.js +86 -0
- package/dist/protocol/messages/orchestrator-agent.d.ts +89 -0
- package/dist/protocol/messages/orchestrator-agent.js +98 -3
- package/dist/protocol/messages/peer.d.ts +7 -0
- package/dist/protocol/messages/peer.js +18 -1
- package/dist/protocol/messages/platform-orchestrator.d.ts +150 -0
- package/dist/protocol/messages/platform-orchestrator.js +164 -19
- package/dist/protocol/version.d.ts +19 -2
- package/dist/protocol/version.js +20 -3
- package/dist/provenance/verify.js +11 -10
- package/dist/provider/check-status-poster.d.ts +24 -3
- package/dist/provider/contributor-resolver.d.ts +11 -3
- package/dist/provider/git-credential.d.ts +77 -0
- package/dist/provider/git-credential.js +10 -0
- package/dist/provider/index.d.ts +2 -0
- package/dist/provider/index.js +2 -1
- package/dist/provider/webhook-normalizer.d.ts +12 -12
- package/dist/repo/pattern-negation.d.ts +73 -0
- package/dist/repo/pattern-negation.js +86 -0
- package/dist/scaler/registry-auth.d.ts +18 -0
- package/dist/scaler/registry-auth.js +28 -0
- package/dist/scaler/scaler-backend-type.d.ts +35 -0
- package/dist/scaler/scaler-backend-type.js +39 -2
- package/dist/scaler/scaler-events.d.ts +79 -0
- package/dist/scaler/scaler-events.js +87 -0
- package/dist/trigger/content-requirements.js +1 -1
- package/dist/trigger/decision-trace.d.ts +79 -0
- package/dist/trigger/decision-trace.js +116 -8
- package/dist/trigger/matcher.js +4 -2
- package/dist/trigger/types.d.ts +87 -7
- package/dist/trigger/types.js +6 -1
- package/dist/ws/rate-limiter.js +3 -3
- package/package.json +11 -3
- package/sbom.spdx.json +15 -15
|
@@ -6,15 +6,37 @@ import { describeTextMatch } from "./text-match.js";
|
|
|
6
6
|
* Records every check performed during trigger evaluation.
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
9
|
+
* Max characters of any free-text field a trace entry carries, so an
|
|
10
|
+
* essay-length input stays bounded.
|
|
11
|
+
*
|
|
12
|
+
* The entry count is capped separately, downstream, but a count bound alone
|
|
13
|
+
* bounds nothing: a single `paths` entry names every changed file in the push
|
|
14
|
+
* and a single `bodyMatch` entry quotes a comment body an outsider authored, so
|
|
15
|
+
* fifty entries can still be megabytes. The forwarded trace rides one WebSocket
|
|
16
|
+
* frame to the Platform, and a frame past the server's payload ceiling closes
|
|
17
|
+
* the connection — stalling every delivery for that organization until it
|
|
18
|
+
* reconnects. Bounding at the point each field is minted is what makes the
|
|
19
|
+
* downstream size guards a backstop rather than the only limit.
|
|
20
|
+
*/
|
|
21
|
+
const TRACE_TEXT_MAX = 200;
|
|
22
|
+
/** Clamp one free-text trace field, marking a clamped value with an ellipsis. */
|
|
23
|
+
function truncateTraceText(text) {
|
|
24
|
+
return text.length > 200 ? `${text.slice(0, 200)}…` : text;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
9
27
|
* Create a new trace entry.
|
|
28
|
+
*
|
|
29
|
+
* Every free-text field is clamped here rather than at each call site: the
|
|
30
|
+
* fields are fed from event content of unbounded size, and one unclamped call
|
|
31
|
+
* site is enough to reintroduce an unbounded frame.
|
|
10
32
|
*/
|
|
11
33
|
function createTraceEntry(check, pattern, value, passed, reason) {
|
|
12
34
|
return {
|
|
13
35
|
check,
|
|
14
|
-
pattern,
|
|
15
|
-
value,
|
|
36
|
+
pattern: truncateTraceText(pattern),
|
|
37
|
+
value: truncateTraceText(value),
|
|
16
38
|
passed,
|
|
17
|
-
reason
|
|
39
|
+
reason: reason === void 0 ? void 0 : truncateTraceText(reason)
|
|
18
40
|
};
|
|
19
41
|
}
|
|
20
42
|
/**
|
|
@@ -35,7 +57,9 @@ const TraceCheck = {
|
|
|
35
57
|
/** Tier-2 `filter` predicate, run by an agent in the global eval round. */
|
|
36
58
|
GlobalFilter: "filter",
|
|
37
59
|
/** Tier-0 declarative `commitMessage` filter, read from the normalized event. */
|
|
38
|
-
CommitMessage: "commitMessage"
|
|
60
|
+
CommitMessage: "commitMessage",
|
|
61
|
+
/** Materialization of a matched workflow's jobs, on the way to dispatch. */
|
|
62
|
+
Dispatch: "dispatch"
|
|
39
63
|
};
|
|
40
64
|
/**
|
|
41
65
|
* Verdict vocabulary shared by both gates.
|
|
@@ -74,6 +98,18 @@ function createGlobalFilterTraceEntry(args) {
|
|
|
74
98
|
return createTraceEntry(TraceCheck.GlobalFilter, "filter(context) === true", verdictFor(args.run, args.indeterminate === true), args.run, args.reason);
|
|
75
99
|
}
|
|
76
100
|
/**
|
|
101
|
+
* Record that a matched workflow could not be materialized into jobs.
|
|
102
|
+
*
|
|
103
|
+
* A workflow whose triggers matched and whose build then threw is absent from
|
|
104
|
+
* every other record: no run row is created and no job is queued. Omitting it
|
|
105
|
+
* from the trace as well leaves its author unable to tell it apart from a
|
|
106
|
+
* workflow that was never registered — the exact indistinguishability the trace
|
|
107
|
+
* exists to remove.
|
|
108
|
+
*/
|
|
109
|
+
function createDispatchFailureTraceEntry(reason) {
|
|
110
|
+
return createTraceEntry(TraceCheck.Dispatch, "jobs materialize", TraceVerdict.Excluded, false, reason);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
77
113
|
* Return a copy of `decision` with `entries` appended to its checks.
|
|
78
114
|
*
|
|
79
115
|
* A decision is treated as a value, never mutated in place: the same object is
|
|
@@ -94,8 +130,6 @@ function appendChecks(decision, entries) {
|
|
|
94
130
|
summary: failed ? failed.reason ?? `Excluded by the ${failed.check} check` : decision.summary
|
|
95
131
|
};
|
|
96
132
|
}
|
|
97
|
-
/** Max characters of the message recorded in a trace, so an essay-length body stays bounded. */
|
|
98
|
-
const TRACE_TEXT_MAX = 200;
|
|
99
133
|
/**
|
|
100
134
|
* Record the Tier-0 `commitMessage` filter's verdict for one trigger.
|
|
101
135
|
*
|
|
@@ -104,10 +138,84 @@ const TRACE_TEXT_MAX = 200;
|
|
|
104
138
|
* would tell an author their filter said no when nothing ever read it.
|
|
105
139
|
*/
|
|
106
140
|
function createCommitMessageTraceEntry(args) {
|
|
107
|
-
const shown = args.text === void 0 ? "(absent)" : args.text.length >
|
|
141
|
+
const shown = args.text === void 0 ? "(absent)" : args.text.length > 200 ? `${args.text.slice(0, 200)}…` : args.text;
|
|
108
142
|
return createTraceEntry(TraceCheck.CommitMessage, describeTextMatch(args.match), verdictFor(args.passed, args.indeterminate === true), args.passed, args.reason ?? `message: ${JSON.stringify(shown)}`);
|
|
109
143
|
}
|
|
110
144
|
/**
|
|
145
|
+
* What a withheld trace field is replaced with when the reader does not hold
|
|
146
|
+
* `event_log:read_payload`.
|
|
147
|
+
*
|
|
148
|
+
* Lives here rather than beside the Platform's redactor because three packages
|
|
149
|
+
* read it: the Platform writes it, the dashboard renders it, and the E2E suite
|
|
150
|
+
* asserts the permission boundary against it. A literal repeated at each site
|
|
151
|
+
* would drift into a marker one of them no longer recognizes.
|
|
152
|
+
*/
|
|
153
|
+
const REDACTED_TRACE_FIELD = "[redacted — requires event_log:read_payload]";
|
|
154
|
+
/**
|
|
155
|
+
* Workflow name the truncation marker carries.
|
|
156
|
+
*
|
|
157
|
+
* A reserved sentinel rather than a real workflow: it is written by one package
|
|
158
|
+
* and read back by two others, so a literal repeated at each site would drift
|
|
159
|
+
* into a marker nobody recognizes.
|
|
160
|
+
*/
|
|
161
|
+
const TRACE_TRUNCATION_WORKFLOW_NAME = "(trace truncated)";
|
|
162
|
+
/**
|
|
163
|
+
* Build the marker that stands in for the decisions a size budget dropped.
|
|
164
|
+
*
|
|
165
|
+
* The trace is truncated rather than discarded: a reader who is told nothing
|
|
166
|
+
* cannot tell "matching never ran" from "the trace was too large to keep", and
|
|
167
|
+
* those two have opposite answers to "why did my workflow not fire".
|
|
168
|
+
*/
|
|
169
|
+
function createTraceTruncationMarker(omitted) {
|
|
170
|
+
return {
|
|
171
|
+
workflowName: TRACE_TRUNCATION_WORKFLOW_NAME,
|
|
172
|
+
matched: false,
|
|
173
|
+
traceTruncated: true,
|
|
174
|
+
decisionsOmitted: omitted,
|
|
175
|
+
checks: [],
|
|
176
|
+
checksCount: 0,
|
|
177
|
+
summary: (omitted === 1 ? "1 further workflow decision was dropped: " : `${omitted} further workflow decisions were dropped: `) + "the trace exceeded the size budget for this delivery."
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* UTF-8 byte length of `text`.
|
|
182
|
+
*
|
|
183
|
+
* Byte length, never `String.length`: the latter counts UTF-16 code units, so a
|
|
184
|
+
* CJK-heavy comment body measures at roughly a third of the bytes it actually
|
|
185
|
+
* costs on the wire and in the stored row.
|
|
186
|
+
*/
|
|
187
|
+
function utf8ByteLength(text) {
|
|
188
|
+
return new TextEncoder().encode(text).length;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Drop trailing decisions until the serialized array fits `maxBytes`, appending
|
|
192
|
+
* a marker naming how many were dropped.
|
|
193
|
+
*
|
|
194
|
+
* Shared by the orchestrator, which bounds what it puts on the wire, and the
|
|
195
|
+
* Platform, which bounds what it stores. Two independent budgets over one
|
|
196
|
+
* shape: keeping one implementation is what stops them from disagreeing about
|
|
197
|
+
* what a truncated trace looks like.
|
|
198
|
+
*/
|
|
199
|
+
function truncateDecisionsToByteBudget(decisions, maxBytes) {
|
|
200
|
+
if (utf8ByteLength(JSON.stringify(decisions)) <= maxBytes) return {
|
|
201
|
+
decisions: [...decisions],
|
|
202
|
+
omitted: 0
|
|
203
|
+
};
|
|
204
|
+
let used = 3 + utf8ByteLength(JSON.stringify(createTraceTruncationMarker(decisions.length)));
|
|
205
|
+
const kept = [];
|
|
206
|
+
for (const decision of decisions) {
|
|
207
|
+
const cost = utf8ByteLength(JSON.stringify(decision)) + 1;
|
|
208
|
+
if (used + cost > maxBytes) break;
|
|
209
|
+
used += cost;
|
|
210
|
+
kept.push(decision);
|
|
211
|
+
}
|
|
212
|
+
const omitted = decisions.length - kept.length;
|
|
213
|
+
return {
|
|
214
|
+
decisions: [...kept, createTraceTruncationMarker(omitted)],
|
|
215
|
+
omitted
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
111
219
|
* Create a workflow decision record.
|
|
112
220
|
*/
|
|
113
221
|
function createWorkflowDecision(workflowName, matched, checks, matchedTrigger, summary) {
|
|
@@ -120,6 +228,6 @@ function createWorkflowDecision(workflowName, matched, checks, matchedTrigger, s
|
|
|
120
228
|
};
|
|
121
229
|
}
|
|
122
230
|
//#endregion
|
|
123
|
-
export { TraceCheck, TraceVerdict, appendChecks, createCommitMessageTraceEntry, createContentRequirementsTraceEntry, createGlobalFilterTraceEntry, createTraceEntry, createWorkflowDecision };
|
|
231
|
+
export { REDACTED_TRACE_FIELD, TRACE_TEXT_MAX, TRACE_TRUNCATION_WORKFLOW_NAME, TraceCheck, TraceVerdict, appendChecks, createCommitMessageTraceEntry, createContentRequirementsTraceEntry, createDispatchFailureTraceEntry, createGlobalFilterTraceEntry, createTraceEntry, createTraceTruncationMarker, createWorkflowDecision, truncateDecisionsToByteBudget, truncateTraceText, utf8ByteLength };
|
|
124
232
|
|
|
125
233
|
//# sourceMappingURL=decision-trace.js.map
|
package/dist/trigger/matcher.js
CHANGED
|
@@ -542,12 +542,14 @@ function matchKiciEventTrigger(trigger, event, traces) {
|
|
|
542
542
|
traces.push(createTraceEntry("event name", trigger.eventName, eventName, nameMatches));
|
|
543
543
|
if (!nameMatches) return false;
|
|
544
544
|
if (trigger.match && Object.keys(trigger.match).length > 0) {
|
|
545
|
-
const
|
|
545
|
+
const eventPayload = event.payload.payload ?? {};
|
|
546
|
+
const matches = matchJsonPath(eventPayload, trigger.match);
|
|
546
547
|
traces.push(createTraceEntry("jsonpath match", JSON.stringify(trigger.match), "(payload)", matches));
|
|
547
548
|
if (!matches) return false;
|
|
548
549
|
}
|
|
549
550
|
if (trigger.not && Object.keys(trigger.not).length > 0) {
|
|
550
|
-
const
|
|
551
|
+
const eventPayload = event.payload.payload ?? {};
|
|
552
|
+
const passes = matchJsonPathNot(eventPayload, trigger.not);
|
|
551
553
|
traces.push(createTraceEntry("jsonpath not", JSON.stringify(trigger.not), "(payload)", passes));
|
|
552
554
|
if (!passes) return false;
|
|
553
555
|
}
|
package/dist/trigger/types.d.ts
CHANGED
|
@@ -33,6 +33,11 @@
|
|
|
33
33
|
* Schema version 34 (additive): adds LockWorkflow.hasFilter (workflow-level pre-dispatch filter predicate).
|
|
34
34
|
* Schema version 35 (additive): adds `commitMessage` (LockTextMatch) to the push/pr/tag
|
|
35
35
|
* git-event triggers, and contains/notContains/notMatches to LockContentRequirement.
|
|
36
|
+
* Schema version 36 (additive): adds LockJob.invoke (invokeSource gate, incl. optional).
|
|
37
|
+
* Schema version 37 (additive): adds LockJob.gitCredentials (named git credential refs).
|
|
38
|
+
* Schema version 38 (additive): adds container.auth (private-registry credentials for the job image).
|
|
39
|
+
* Schema version 39 (additive): adds container.dockerfile/context/target/args (build the
|
|
40
|
+
* job's image from a Dockerfile in the repo) and container.auth.registry.
|
|
36
41
|
*/
|
|
37
42
|
import { z } from 'zod';
|
|
38
43
|
import type { ProviderType } from '../provider/types.js';
|
|
@@ -45,7 +50,7 @@ import { ExecutionJobStatus } from '../protocol/messages/execution-status.js';
|
|
|
45
50
|
* schema change (additive or breaking); the bump-history comment above records
|
|
46
51
|
* which. See `BREAKING_FLOOR` for the compatibility-window semantics.
|
|
47
52
|
*/
|
|
48
|
-
export declare const SCHEMA_VERSION:
|
|
53
|
+
export declare const SCHEMA_VERSION: 39;
|
|
49
54
|
/**
|
|
50
55
|
* Oldest lock schema version this codebase can still read correctly — the lower
|
|
51
56
|
* bound of the acceptance window.
|
|
@@ -736,9 +741,34 @@ export interface ResolvedSandboxGrant {
|
|
|
736
741
|
/** Run the container as this user (operator-config path only in Phase 2). */
|
|
737
742
|
user?: string;
|
|
738
743
|
}
|
|
744
|
+
/**
|
|
745
|
+
* Invoke-gate action carried on a lock job (compiled from `invokeSource()`).
|
|
746
|
+
* A job carrying this never runs steps on an agent: the orchestrator emits the
|
|
747
|
+
* named kici event at the source repo and gates on the runs it triggers.
|
|
748
|
+
*/
|
|
749
|
+
export interface LockInvoke {
|
|
750
|
+
/** The kici event name to emit; source-repo workflows subscribe with `kiciEvent({ name })`. */
|
|
751
|
+
readonly event: string;
|
|
752
|
+
/** Target scope. `'source'` targets exactly the source repo (the only v1 scope). */
|
|
753
|
+
readonly scope: 'source';
|
|
754
|
+
/** Optional event payload delivered to subscribers. */
|
|
755
|
+
readonly payload?: Readonly<Record<string, unknown>>;
|
|
756
|
+
/**
|
|
757
|
+
* When true, a zero-subscriber emit succeeds immediately (the repo may opt
|
|
758
|
+
* out). Absent/false (the default) fails the gate on zero subscribers.
|
|
759
|
+
*/
|
|
760
|
+
readonly optional?: boolean;
|
|
761
|
+
}
|
|
739
762
|
export interface LockJob {
|
|
740
763
|
readonly _type: 'static';
|
|
741
764
|
readonly name: string;
|
|
765
|
+
/**
|
|
766
|
+
* Invoke-gate action. When set, the job is a gate: it never dispatches steps
|
|
767
|
+
* to an agent; the orchestrator emits `invoke.event` at the source repo and
|
|
768
|
+
* tracks each triggered run as a proxy child. Additive — an older
|
|
769
|
+
* orchestrator that does not understand it ignores it (the gate stays inert).
|
|
770
|
+
*/
|
|
771
|
+
readonly invoke?: LockInvoke;
|
|
742
772
|
/** Single-agent targeting matchers. Absent when the job uses `runsOnAll` instead. */
|
|
743
773
|
readonly runsOn?: readonly LabelMatcher[];
|
|
744
774
|
readonly excludeLabels?: readonly LabelMatcher[];
|
|
@@ -748,6 +778,16 @@ export interface LockJob {
|
|
|
748
778
|
* `any` picks any available agent. Absent on a `runsOnAll` fan-out job.
|
|
749
779
|
*/
|
|
750
780
|
readonly runsOnPick?: RunsOnPick;
|
|
781
|
+
/**
|
|
782
|
+
* Named git credentials for this job, as SECRET NAMES in qualified
|
|
783
|
+
* `<context>:<secret-name>` form — never credential material.
|
|
784
|
+
*
|
|
785
|
+
* `default` is used when a call names no credential; any other key is
|
|
786
|
+
* referenced by name. Additive: an older orchestrator that does not
|
|
787
|
+
* understand it simply passes it through in `jobConfig`, and an older agent
|
|
788
|
+
* ignores it (git falls back to its own mechanisms, exactly as before).
|
|
789
|
+
*/
|
|
790
|
+
readonly gitCredentials?: Readonly<Record<string, Readonly<Record<string, string>>>>;
|
|
751
791
|
/**
|
|
752
792
|
* Host fan-out predicate (mutually exclusive with `runsOn`). When set, the job
|
|
753
793
|
* fans out to every roster host matching the predicate, one pinned child per host.
|
|
@@ -814,15 +854,55 @@ export interface LockJob {
|
|
|
814
854
|
readonly resources?: import('../scaler/resource-types.js').ResourceRequest;
|
|
815
855
|
/**
|
|
816
856
|
* Container image selecting the container execution backend on the agent. A
|
|
817
|
-
* bare image string or an object
|
|
818
|
-
*
|
|
819
|
-
*
|
|
820
|
-
*
|
|
821
|
-
*
|
|
857
|
+
* bare image string, or an object naming exactly one image source: a
|
|
858
|
+
* finalized `image`, or a `dockerfile` the agent builds from the cloned tree
|
|
859
|
+
* before the job starts. When set, the agent's `determineExecutionMode`
|
|
860
|
+
* routes the job to the container sandbox (top priority), so the orchestrator
|
|
861
|
+
* threads it through dispatch as `jobConfig.container`. (Shape mirrors the SDK
|
|
862
|
+
* `string | ContainerConfig`, including `ContainerRegistryAuth`; the engine
|
|
863
|
+
* cannot import the SDK, so it is inlined here.)
|
|
822
864
|
*/
|
|
823
865
|
readonly container?: string | {
|
|
824
|
-
|
|
866
|
+
/** Finalized image to pull. Exactly one of `image` / `dockerfile` is set. */
|
|
867
|
+
readonly image?: string;
|
|
868
|
+
/**
|
|
869
|
+
* Repo-relative Dockerfile the agent builds before the job runs.
|
|
870
|
+
*
|
|
871
|
+
* The agent re-validates this path against the resolved workdir: a lock
|
|
872
|
+
* file is repo content, so a path that escapes the tree must be refused
|
|
873
|
+
* on the agent too, not only by the SDK that wrote it.
|
|
874
|
+
*/
|
|
875
|
+
readonly dockerfile?: string;
|
|
876
|
+
/** Repo-relative build context. Defaults to the repository root. */
|
|
877
|
+
readonly context?: string;
|
|
878
|
+
/** Build stage to stop at. */
|
|
879
|
+
readonly target?: string;
|
|
880
|
+
/**
|
|
881
|
+
* Build arguments. Plain strings — never secret references, because a
|
|
882
|
+
* build argument is recorded in the built image's history.
|
|
883
|
+
*/
|
|
884
|
+
readonly args?: Record<string, string>;
|
|
825
885
|
readonly env?: Record<string, string>;
|
|
886
|
+
/**
|
|
887
|
+
* Private-registry credentials for pulling `image`.
|
|
888
|
+
*
|
|
889
|
+
* Flattened `Sourced<Name>` pairs: exactly one half of each pair is
|
|
890
|
+
* set — `*Secret` names a `<context>:<secret-name>` entry to resolve,
|
|
891
|
+
* `*Value` carries material supplied at run time.
|
|
892
|
+
*/
|
|
893
|
+
readonly auth?: {
|
|
894
|
+
readonly username?: string;
|
|
895
|
+
readonly usernameSecret?: string;
|
|
896
|
+
readonly usernameValue?: string;
|
|
897
|
+
readonly tokenSecret?: string;
|
|
898
|
+
readonly tokenValue?: string;
|
|
899
|
+
/**
|
|
900
|
+
* Registry host the credentials belong to. Derived from `image` when
|
|
901
|
+
* one is set; REQUIRED with `dockerfile`, whose base image is named
|
|
902
|
+
* inside the Dockerfile and cannot be read back out reliably.
|
|
903
|
+
*/
|
|
904
|
+
readonly registry?: string;
|
|
905
|
+
};
|
|
826
906
|
};
|
|
827
907
|
/**
|
|
828
908
|
* Workflow-declared per-job sandbox escape-hatch request (container jobs
|
package/dist/trigger/types.js
CHANGED
|
@@ -38,13 +38,18 @@ import { z } from "zod";
|
|
|
38
38
|
* Schema version 34 (additive): adds LockWorkflow.hasFilter (workflow-level pre-dispatch filter predicate).
|
|
39
39
|
* Schema version 35 (additive): adds `commitMessage` (LockTextMatch) to the push/pr/tag
|
|
40
40
|
* git-event triggers, and contains/notContains/notMatches to LockContentRequirement.
|
|
41
|
+
* Schema version 36 (additive): adds LockJob.invoke (invokeSource gate, incl. optional).
|
|
42
|
+
* Schema version 37 (additive): adds LockJob.gitCredentials (named git credential refs).
|
|
43
|
+
* Schema version 38 (additive): adds container.auth (private-registry credentials for the job image).
|
|
44
|
+
* Schema version 39 (additive): adds container.dockerfile/context/target/args (build the
|
|
45
|
+
* job's image from a Dockerfile in the repo) and container.auth.registry.
|
|
41
46
|
*/
|
|
42
47
|
/**
|
|
43
48
|
* Schema version the compiler emits into every lock file. Incremented on ANY
|
|
44
49
|
* schema change (additive or breaking); the bump-history comment above records
|
|
45
50
|
* which. See `BREAKING_FLOOR` for the compatibility-window semantics.
|
|
46
51
|
*/
|
|
47
|
-
const SCHEMA_VERSION =
|
|
52
|
+
const SCHEMA_VERSION = 39;
|
|
48
53
|
/**
|
|
49
54
|
* Oldest lock schema version this codebase can still read correctly — the lower
|
|
50
55
|
* bound of the acceptance window.
|
package/dist/ws/rate-limiter.js
CHANGED
|
@@ -79,10 +79,10 @@ var WsRateLimiter = class {
|
|
|
79
79
|
bytesCapacity;
|
|
80
80
|
disconnectAfterMs;
|
|
81
81
|
constructor(config) {
|
|
82
|
-
const bytesCapacity = config?.bytesCapacity ??
|
|
82
|
+
const bytesCapacity = config?.bytesCapacity ?? 2097152;
|
|
83
83
|
this.messages = new TokenBucket(config?.messageCapacity ?? 200, config?.messageRefillRate ?? 100);
|
|
84
|
-
this.bytes = new TokenBucket(bytesCapacity, config?.bytesRefillRate ??
|
|
85
|
-
this.maxMessageSize = config?.maxMessageSize ??
|
|
84
|
+
this.bytes = new TokenBucket(bytesCapacity, config?.bytesRefillRate ?? 512e3);
|
|
85
|
+
this.maxMessageSize = config?.maxMessageSize ?? 4194304;
|
|
86
86
|
this.bytesCapacity = bytesCapacity;
|
|
87
87
|
this.disconnectAfterMs = config?.disconnectAfterMs ?? 5e3;
|
|
88
88
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kici-dev/engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
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",
|
|
@@ -53,6 +53,10 @@
|
|
|
53
53
|
"import": "./dist/webhook/signature.js",
|
|
54
54
|
"types": "./dist/webhook/signature.d.ts"
|
|
55
55
|
},
|
|
56
|
+
"./scaler/registry-auth": {
|
|
57
|
+
"import": "./dist/scaler/registry-auth.js",
|
|
58
|
+
"types": "./dist/scaler/registry-auth.d.ts"
|
|
59
|
+
},
|
|
56
60
|
"./safe-regex": {
|
|
57
61
|
"import": "./dist/safe-regex.js",
|
|
58
62
|
"types": "./dist/safe-regex.d.ts"
|
|
@@ -105,6 +109,10 @@
|
|
|
105
109
|
"import": "./dist/protocol/messages/oidc-mint.js",
|
|
106
110
|
"types": "./dist/protocol/messages/oidc-mint.d.ts"
|
|
107
111
|
},
|
|
112
|
+
"./protocol/messages/git-credential-relay": {
|
|
113
|
+
"import": "./dist/protocol/messages/git-credential-relay.js",
|
|
114
|
+
"types": "./dist/protocol/messages/git-credential-relay.d.ts"
|
|
115
|
+
},
|
|
108
116
|
"./provenance/schema": {
|
|
109
117
|
"import": "./dist/provenance/schema.js",
|
|
110
118
|
"types": "./dist/provenance/schema.d.ts"
|
|
@@ -139,9 +147,9 @@
|
|
|
139
147
|
}
|
|
140
148
|
},
|
|
141
149
|
"dependencies": {
|
|
142
|
-
"jose": "^6.
|
|
150
|
+
"jose": "^6.2.10",
|
|
143
151
|
"jsonpath-plus": "^10.4.0",
|
|
144
|
-
"picomatch": "^4.0.
|
|
152
|
+
"picomatch": "^4.0.7",
|
|
145
153
|
"safe-regex": "^2.1.1",
|
|
146
154
|
"yaml": "^2.9.0",
|
|
147
155
|
"zod": "^4.4.3"
|
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.
|
|
6
|
-
"documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fengine/0.
|
|
5
|
+
"name": "@kici-dev/engine@0.6.1",
|
|
6
|
+
"documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fengine/0.6.1/3af2cc4e-0d26-40f2-8700-367133e0f64c",
|
|
7
7
|
"creationInfo": {
|
|
8
|
-
"created": "2026-
|
|
8
|
+
"created": "2026-09-02T03:01:17Z",
|
|
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.
|
|
57
|
+
"versionInfo": "0.6.1",
|
|
58
58
|
"downloadLocation": "NOASSERTION",
|
|
59
59
|
"filesAnalyzed": false,
|
|
60
60
|
"licenseConcluded": "NOASSERTION",
|
|
@@ -65,17 +65,17 @@
|
|
|
65
65
|
{
|
|
66
66
|
"referenceCategory": "PACKAGE-MANAGER",
|
|
67
67
|
"referenceType": "purl",
|
|
68
|
-
"referenceLocator": "pkg:npm/%40kici-dev/engine@0.
|
|
68
|
+
"referenceLocator": "pkg:npm/%40kici-dev/engine@0.6.1"
|
|
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
74
|
{
|
|
75
|
-
"SPDXID": "SPDXRef-Package-jose-6.2.
|
|
75
|
+
"SPDXID": "SPDXRef-Package-jose-6.2.10",
|
|
76
76
|
"name": "jose",
|
|
77
|
-
"versionInfo": "6.2.
|
|
78
|
-
"downloadLocation": "https://registry.npmjs.org/jose/-/jose-6.2.
|
|
77
|
+
"versionInfo": "6.2.10",
|
|
78
|
+
"downloadLocation": "https://registry.npmjs.org/jose/-/jose-6.2.10.tgz",
|
|
79
79
|
"filesAnalyzed": false,
|
|
80
80
|
"licenseConcluded": "NOASSERTION",
|
|
81
81
|
"licenseDeclared": "MIT",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
{
|
|
86
86
|
"referenceCategory": "PACKAGE-MANAGER",
|
|
87
87
|
"referenceType": "purl",
|
|
88
|
-
"referenceLocator": "pkg:npm/jose@6.2.
|
|
88
|
+
"referenceLocator": "pkg:npm/jose@6.2.10"
|
|
89
89
|
}
|
|
90
90
|
],
|
|
91
91
|
"description": "JWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes",
|
|
@@ -132,10 +132,10 @@
|
|
|
132
132
|
"homepage": "https://github.com/s3u/JSONPath"
|
|
133
133
|
},
|
|
134
134
|
{
|
|
135
|
-
"SPDXID": "SPDXRef-Package-picomatch-4.0.
|
|
135
|
+
"SPDXID": "SPDXRef-Package-picomatch-4.0.7",
|
|
136
136
|
"name": "picomatch",
|
|
137
|
-
"versionInfo": "4.0.
|
|
138
|
-
"downloadLocation": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.
|
|
137
|
+
"versionInfo": "4.0.7",
|
|
138
|
+
"downloadLocation": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
|
|
139
139
|
"filesAnalyzed": false,
|
|
140
140
|
"licenseConcluded": "NOASSERTION",
|
|
141
141
|
"licenseDeclared": "MIT",
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
{
|
|
146
146
|
"referenceCategory": "PACKAGE-MANAGER",
|
|
147
147
|
"referenceType": "purl",
|
|
148
|
-
"referenceLocator": "pkg:npm/picomatch@4.0.
|
|
148
|
+
"referenceLocator": "pkg:npm/picomatch@4.0.7"
|
|
149
149
|
}
|
|
150
150
|
],
|
|
151
151
|
"description": "Blazing fast and accurate glob matcher written in JavaScript, with no dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions.",
|
|
@@ -250,7 +250,7 @@
|
|
|
250
250
|
},
|
|
251
251
|
{
|
|
252
252
|
"spdxElementId": "SPDXRef-RootPackage",
|
|
253
|
-
"relatedSpdxElement": "SPDXRef-Package-jose-6.2.
|
|
253
|
+
"relatedSpdxElement": "SPDXRef-Package-jose-6.2.10",
|
|
254
254
|
"relationshipType": "DEPENDS_ON"
|
|
255
255
|
},
|
|
256
256
|
{
|
|
@@ -260,7 +260,7 @@
|
|
|
260
260
|
},
|
|
261
261
|
{
|
|
262
262
|
"spdxElementId": "SPDXRef-RootPackage",
|
|
263
|
-
"relatedSpdxElement": "SPDXRef-Package-picomatch-4.0.
|
|
263
|
+
"relatedSpdxElement": "SPDXRef-Package-picomatch-4.0.7",
|
|
264
264
|
"relationshipType": "DEPENDS_ON"
|
|
265
265
|
},
|
|
266
266
|
{
|