@kici-dev/engine 0.1.26 → 0.2.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 (157) hide show
  1. package/dist/approval/types.d.ts +11 -4
  2. package/dist/approval/types.js +11 -4
  3. package/dist/artifacts/name.d.ts +60 -0
  4. package/dist/artifacts/name.js +71 -0
  5. package/dist/audit/access-log-policy.d.ts +1 -1
  6. package/dist/audit/access-log-policy.js +20 -11
  7. package/dist/audit/activity.d.ts +12 -12
  8. package/dist/audit/retention-policy.js +40 -22
  9. package/dist/billing/plan-type.d.ts +53 -0
  10. package/dist/billing/plan-type.js +70 -0
  11. package/dist/bundler/rolldown-config.d.ts +3 -3
  12. package/dist/check-mode.d.ts +1 -1
  13. package/dist/context/concurrency-strategy.d.ts +34 -0
  14. package/dist/context/concurrency-strategy.js +35 -0
  15. package/dist/context/held-run-job-id.d.ts +45 -0
  16. package/dist/context/held-run-job-id.js +56 -0
  17. package/dist/context/held-run-status.d.ts +33 -0
  18. package/dist/context/held-run-status.js +37 -0
  19. package/dist/context/hold-expiry.d.ts +20 -0
  20. package/dist/context/hold-expiry.js +25 -0
  21. package/dist/context/hold-reason.d.ts +33 -0
  22. package/dist/context/hold-reason.js +23 -0
  23. package/dist/context/hold-type.d.ts +40 -0
  24. package/dist/context/hold-type.js +61 -0
  25. package/dist/{environment → context}/host-match.js +1 -1
  26. package/dist/context/index.d.ts +14 -0
  27. package/dist/context/index.js +12 -0
  28. package/dist/context/multi-context.d.ts +30 -0
  29. package/dist/context/multi-context.js +38 -0
  30. package/dist/context/scope-name.d.ts +29 -0
  31. package/dist/context/scope-name.js +49 -0
  32. package/dist/context/scope-resolver.d.ts +79 -0
  33. package/dist/{environment → context}/scope-resolver.js +47 -17
  34. package/dist/{environment → context}/scope-template.js +1 -1
  35. package/dist/{environment → context}/types.d.ts +25 -22
  36. package/dist/{environment → context}/types.js +3 -3
  37. package/dist/dev-ops/operations.d.ts +9 -1
  38. package/dist/dev-ops/operations.js +37 -20
  39. package/dist/diagnostics/infra-alert.d.ts +71 -0
  40. package/dist/diagnostics/infra-alert.js +60 -0
  41. package/dist/env/environment-allowlist.d.ts +26 -3
  42. package/dist/env/environment-allowlist.js +35 -1
  43. package/dist/fanout/materialize.d.ts +16 -0
  44. package/dist/fanout/materialize.js +34 -5
  45. package/dist/index.d.ts +16 -7
  46. package/dist/index.js +38 -23
  47. package/dist/inputs/descriptor.d.ts +9 -9
  48. package/dist/inventory.d.ts +4 -4
  49. package/dist/labels.d.ts +82 -2
  50. package/dist/labels.js +119 -1
  51. package/dist/matrix/expand.d.ts +49 -2
  52. package/dist/matrix/expand.js +102 -13
  53. package/dist/matrix/format.d.ts +6 -1
  54. package/dist/matrix/format.js +6 -1
  55. package/dist/mcp/held-run-resolve.d.ts +7 -10
  56. package/dist/mcp/held-run-resolve.js +33 -7
  57. package/dist/metrics/catalog-policy.js +4 -4
  58. package/dist/metrics/metric-catalog.generated.d.ts +954 -734
  59. package/dist/metrics/metric-catalog.generated.js +296 -32
  60. package/dist/metrics/metric-kind-compat.d.ts +26 -0
  61. package/dist/metrics/metric-kind-compat.js +33 -0
  62. package/dist/protocol/analytics-events.d.ts +6 -6
  63. package/dist/protocol/dashboard-api-errors.d.ts +13 -0
  64. package/dist/protocol/dashboard-api-errors.js +17 -0
  65. package/dist/protocol/dashboard-write-operations.d.ts +143 -86
  66. package/dist/protocol/dashboard-write-operations.js +143 -69
  67. package/dist/protocol/messages/access-log.d.ts +438 -388
  68. package/dist/protocol/messages/access-log.js +24 -14
  69. package/dist/protocol/messages/actor.d.ts +2 -2
  70. package/dist/protocol/messages/agent-dev-ops.d.ts +4 -2
  71. package/dist/protocol/messages/agent-dev-ops.js +2 -5
  72. package/dist/protocol/messages/agent-run-result.d.ts +74 -64
  73. package/dist/protocol/messages/agent-run-result.js +1 -1
  74. package/dist/protocol/messages/auth.d.ts +35 -23
  75. package/dist/protocol/messages/browser.d.ts +81 -5
  76. package/dist/protocol/messages/browser.js +53 -2
  77. package/dist/protocol/messages/capabilities.d.ts +106 -31
  78. package/dist/protocol/messages/capabilities.js +94 -10
  79. package/dist/protocol/messages/common.d.ts +45 -2
  80. package/dist/protocol/messages/common.js +64 -3
  81. package/dist/protocol/messages/dashboard-sealed-write.d.ts +52 -0
  82. package/dist/protocol/messages/dashboard-sealed-write.js +57 -0
  83. package/dist/protocol/messages/dashboard.d.ts +1232 -706
  84. package/dist/protocol/messages/dashboard.js +387 -220
  85. package/dist/protocol/messages/deployment-identity.d.ts +37 -10
  86. package/dist/protocol/messages/deployment-identity.js +30 -3
  87. package/dist/protocol/messages/event-log.d.ts +5 -5
  88. package/dist/protocol/messages/execution-status.d.ts +198 -62
  89. package/dist/protocol/messages/execution-status.js +114 -46
  90. package/dist/protocol/messages/heartbeat-health.d.ts +83 -0
  91. package/dist/protocol/messages/heartbeat-health.js +87 -0
  92. package/dist/protocol/messages/log-stream.d.ts +18 -0
  93. package/dist/protocol/messages/log-stream.js +19 -0
  94. package/dist/protocol/messages/oidc-mint.d.ts +7 -0
  95. package/dist/protocol/messages/oidc-mint.js +7 -0
  96. package/dist/protocol/messages/orchestrator-agent.d.ts +264 -67
  97. package/dist/protocol/messages/orchestrator-agent.js +170 -5
  98. package/dist/protocol/messages/pat-kind.d.ts +1 -1
  99. package/dist/protocol/messages/peer.d.ts +122 -58
  100. package/dist/protocol/messages/peer.js +37 -2
  101. package/dist/protocol/messages/platform-orchestrator.d.ts +603 -258
  102. package/dist/protocol/messages/platform-orchestrator.js +131 -21
  103. package/dist/protocol/messages/run-events.d.ts +5 -5
  104. package/dist/protocol/messages/scaler-event.d.ts +3 -3
  105. package/dist/protocol/messages/source-registration.d.ts +56 -13
  106. package/dist/protocol/messages/source-registration.js +49 -6
  107. package/dist/protocol/session-policy.d.ts +20 -0
  108. package/dist/protocol/session-policy.js +25 -0
  109. package/dist/protocol/source-origin.d.ts +1 -1
  110. package/dist/provenance/attestation-origin.d.ts +1 -1
  111. package/dist/provenance/schema.d.ts +11 -11
  112. package/dist/provenance/verify.js +2 -1
  113. package/dist/provider/changed-files-fetcher.d.ts +21 -2
  114. package/dist/provider/check-run-conclusion.d.ts +2 -2
  115. package/dist/provider/check-status-poster.d.ts +23 -0
  116. package/dist/provider/index.d.ts +2 -2
  117. package/dist/registration/registerable-trigger-type.d.ts +14 -13
  118. package/dist/registration/registerable-trigger-type.js +1 -0
  119. package/dist/sandbox/capabilities.d.ts +6 -0
  120. package/dist/sandbox/capabilities.js +57 -0
  121. package/dist/scaler/scaler-backend-type.d.ts +1 -1
  122. package/dist/status/presentation.d.ts +89 -0
  123. package/dist/status/presentation.js +163 -0
  124. package/dist/trigger/compiled-matchers.d.ts +13 -0
  125. package/dist/trigger/compiled-matchers.js +44 -0
  126. package/dist/trigger/event-buckets.d.ts +44 -0
  127. package/dist/trigger/event-buckets.js +93 -0
  128. package/dist/trigger/matcher.d.ts +7 -3
  129. package/dist/trigger/matcher.js +53 -15
  130. package/dist/trigger/schedule-key.d.ts +14 -0
  131. package/dist/trigger/schedule-key.js +21 -0
  132. package/dist/trigger/trigger-event-type.d.ts +1 -1
  133. package/dist/trigger/trigger-event-type.js +2 -0
  134. package/dist/trigger/types.d.ts +178 -47
  135. package/dist/trigger/types.js +82 -24
  136. package/dist/webhook/event-types.d.ts +56 -0
  137. package/dist/webhook/event-types.js +59 -0
  138. package/dist/ws/ws-like.d.ts +13 -0
  139. package/package.json +26 -10
  140. package/sbom.spdx.json +10 -10
  141. package/dist/environment/index.d.ts +0 -6
  142. package/dist/environment/index.js +0 -5
  143. package/dist/environment/multi-env.d.ts +0 -30
  144. package/dist/environment/multi-env.js +0 -38
  145. package/dist/environment/scope-resolver.d.ts +0 -46
  146. package/dist/package-manager.d.ts +0 -20
  147. package/dist/protocol/messages/observe.d.ts +0 -76
  148. package/dist/protocol/messages/saas-orchestrator.d.ts +0 -2179
  149. package/dist/protocol/messages/test-run.d.ts +0 -59
  150. package/dist/state-machine/index.d.ts +0 -2
  151. package/dist/state-machine/index.js +0 -3
  152. package/dist/state-machine/machine.d.ts +0 -34
  153. package/dist/state-machine/machine.js +0 -103
  154. package/dist/state-machine/types.d.ts +0 -34
  155. package/dist/state-machine/types.js +0 -15
  156. /package/dist/{environment → context}/host-match.d.ts +0 -0
  157. /package/dist/{environment → context}/scope-template.d.ts +0 -0
@@ -0,0 +1,34 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * What a context does with a run that arrives while its concurrency limit is
4
+ * saturated. Single source of truth shared by the dashboard protection form, the
5
+ * context domain type, the orchestrator's context store and protection
6
+ * aggregate, and the concurrency gate.
7
+ *
8
+ * - `queue` — hold the run until a slot frees. The strategy applied when a
9
+ * context sets a limit but no explicit strategy.
10
+ * - `cancel-pending` — drop the already-waiting run in favour of the new one.
11
+ *
12
+ * Not to be confused with the protection gates' `action` vocabulary
13
+ * (`'hold' | 'wait' | 'queue'` on `ProtectionGateResult`), which shares the
14
+ * `queue` spelling and means something else entirely.
15
+ *
16
+ * The orchestrator's `contexts.concurrency_strategy` column stays typed as
17
+ * `string` so a row written by a different orchestrator version never fails to
18
+ * map; this enum is the vocabulary every writer validates against.
19
+ *
20
+ * Pure Zod, no `node:*` imports — safe for the browser-facing engine barrel.
21
+ */
22
+ export declare const ConcurrencyStrategy: z.ZodEnum<{
23
+ "cancel-pending": "cancel-pending";
24
+ queue: "queue";
25
+ }>;
26
+ export type ConcurrencyStrategy = z.infer<typeof ConcurrencyStrategy>;
27
+ /**
28
+ * The strategy applied when a context carries an effective concurrency limit but
29
+ * no explicit strategy. Lives beside the enum so the dashboard form and the
30
+ * orchestrator aggregate cannot pick different defaults — a mismatch reads as a
31
+ * permanently dirty protection form.
32
+ */
33
+ export declare const DEFAULT_CONCURRENCY_STRATEGY: ConcurrencyStrategy;
34
+ //# sourceMappingURL=concurrency-strategy.d.ts.map
@@ -0,0 +1,35 @@
1
+ import "../rolldown-runtime-ClRpJifh.js";
2
+ import { z } from "zod";
3
+ //#region src/context/concurrency-strategy.ts
4
+ /**
5
+ * What a context does with a run that arrives while its concurrency limit is
6
+ * saturated. Single source of truth shared by the dashboard protection form, the
7
+ * context domain type, the orchestrator's context store and protection
8
+ * aggregate, and the concurrency gate.
9
+ *
10
+ * - `queue` — hold the run until a slot frees. The strategy applied when a
11
+ * context sets a limit but no explicit strategy.
12
+ * - `cancel-pending` — drop the already-waiting run in favour of the new one.
13
+ *
14
+ * Not to be confused with the protection gates' `action` vocabulary
15
+ * (`'hold' | 'wait' | 'queue'` on `ProtectionGateResult`), which shares the
16
+ * `queue` spelling and means something else entirely.
17
+ *
18
+ * The orchestrator's `contexts.concurrency_strategy` column stays typed as
19
+ * `string` so a row written by a different orchestrator version never fails to
20
+ * map; this enum is the vocabulary every writer validates against.
21
+ *
22
+ * Pure Zod, no `node:*` imports — safe for the browser-facing engine barrel.
23
+ */
24
+ const ConcurrencyStrategy = z.enum(["queue", "cancel-pending"]);
25
+ /**
26
+ * The strategy applied when a context carries an effective concurrency limit but
27
+ * no explicit strategy. Lives beside the enum so the dashboard form and the
28
+ * orchestrator aggregate cannot pick different defaults — a mismatch reads as a
29
+ * permanently dirty protection form.
30
+ */
31
+ const DEFAULT_CONCURRENCY_STRATEGY = ConcurrencyStrategy.enum.queue;
32
+ //#endregion
33
+ export { ConcurrencyStrategy, DEFAULT_CONCURRENCY_STRATEGY };
34
+
35
+ //# sourceMappingURL=concurrency-strategy.js.map
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Run-wide sentinel values for `held_runs.job_id`.
3
+ *
4
+ * The column normally carries the held job's expanded name (a matrix child
5
+ * keeps its own `build (18)` form), which is what the dashboard approval queue
6
+ * renders and what `kici approve --job <name>` resolves. Some holds are not
7
+ * scoped to a single job and use a sentinel instead: the workflow install gate,
8
+ * and the PR-wide security holds the org trust policy raises.
9
+ *
10
+ * The orchestrator writes these values and the dashboard reads them back to
11
+ * render a human-meaningful row label, so they live here rather than as a
12
+ * literal on each side — a rename on the writer must not silently stop the
13
+ * reader from recognising the sentinel.
14
+ */
15
+ /** Sentinel `job_id` for the PR-wide workflow-modification security hold. */
16
+ export declare const WORKFLOW_MODIFICATION_JOB_ID = "__workflow_modification__";
17
+ /**
18
+ * Sentinel `job_id` per PR-wide security-hold reason, written when the org
19
+ * trust policy holds a run.
20
+ *
21
+ * `workflow_modification` keeps its historical value so holds created before
22
+ * the policy was enforced still resolve by job id.
23
+ *
24
+ * Covers the org trust policy's own three arms ONLY. `context_trust` is
25
+ * deliberately absent: that hold comes from the per-context minimum-trust gate,
26
+ * which writes the real expanded job name (a matrix child keeps its `build (18)`
27
+ * form) so the operator can approve that job specifically. A sentinel for it
28
+ * would be a value nothing ever writes.
29
+ *
30
+ * Keyed by the orchestrator's `TrustPolicyHoldReason`; the key set is asserted
31
+ * against that type in the orchestrator's own test rather than importing it
32
+ * here (the engine must not depend on the orchestrator).
33
+ */
34
+ export declare const SECURITY_HOLD_JOB_IDS: {
35
+ readonly workflow_modification: "__workflow_modification__";
36
+ readonly fork_pr: '__fork_pr__';
37
+ readonly unknown_contributor: '__unknown_contributor__';
38
+ };
39
+ /** Human-meaningful label per security-hold sentinel, rendered by the dashboard. */
40
+ export declare const SECURITY_HOLD_JOB_LABELS: Record<string, string>;
41
+ /** Sentinel `job_id` prefix for the workflow install gate, suffixed by the workflow name. */
42
+ export declare const INSTALL_JOB_ID_PREFIX = "__install__";
43
+ /** The install-gate sentinel `job_id` for a workflow. */
44
+ export declare function installGateJobId(workflowName: string): string;
45
+ //# sourceMappingURL=held-run-job-id.d.ts.map
@@ -0,0 +1,56 @@
1
+ import "../rolldown-runtime-ClRpJifh.js";
2
+ //#region src/context/held-run-job-id.ts
3
+ /**
4
+ * Run-wide sentinel values for `held_runs.job_id`.
5
+ *
6
+ * The column normally carries the held job's expanded name (a matrix child
7
+ * keeps its own `build (18)` form), which is what the dashboard approval queue
8
+ * renders and what `kici approve --job <name>` resolves. Some holds are not
9
+ * scoped to a single job and use a sentinel instead: the workflow install gate,
10
+ * and the PR-wide security holds the org trust policy raises.
11
+ *
12
+ * The orchestrator writes these values and the dashboard reads them back to
13
+ * render a human-meaningful row label, so they live here rather than as a
14
+ * literal on each side — a rename on the writer must not silently stop the
15
+ * reader from recognising the sentinel.
16
+ */
17
+ /** Sentinel `job_id` for the PR-wide workflow-modification security hold. */
18
+ const WORKFLOW_MODIFICATION_JOB_ID = "__workflow_modification__";
19
+ /**
20
+ * Sentinel `job_id` per PR-wide security-hold reason, written when the org
21
+ * trust policy holds a run.
22
+ *
23
+ * `workflow_modification` keeps its historical value so holds created before
24
+ * the policy was enforced still resolve by job id.
25
+ *
26
+ * Covers the org trust policy's own three arms ONLY. `context_trust` is
27
+ * deliberately absent: that hold comes from the per-context minimum-trust gate,
28
+ * which writes the real expanded job name (a matrix child keeps its `build (18)`
29
+ * form) so the operator can approve that job specifically. A sentinel for it
30
+ * would be a value nothing ever writes.
31
+ *
32
+ * Keyed by the orchestrator's `TrustPolicyHoldReason`; the key set is asserted
33
+ * against that type in the orchestrator's own test rather than importing it
34
+ * here (the engine must not depend on the orchestrator).
35
+ */
36
+ const SECURITY_HOLD_JOB_IDS = {
37
+ workflow_modification: WORKFLOW_MODIFICATION_JOB_ID,
38
+ fork_pr: "__fork_pr__",
39
+ unknown_contributor: "__unknown_contributor__"
40
+ };
41
+ /** Human-meaningful label per security-hold sentinel, rendered by the dashboard. */
42
+ const SECURITY_HOLD_JOB_LABELS = {
43
+ [SECURITY_HOLD_JOB_IDS.workflow_modification]: "workflow modification",
44
+ [SECURITY_HOLD_JOB_IDS.fork_pr]: "fork pull request",
45
+ [SECURITY_HOLD_JOB_IDS.unknown_contributor]: "unknown contributor"
46
+ };
47
+ /** Sentinel `job_id` prefix for the workflow install gate, suffixed by the workflow name. */
48
+ const INSTALL_JOB_ID_PREFIX = "__install__";
49
+ /** The install-gate sentinel `job_id` for a workflow. */
50
+ function installGateJobId(workflowName) {
51
+ return `${INSTALL_JOB_ID_PREFIX}${workflowName}`;
52
+ }
53
+ //#endregion
54
+ export { INSTALL_JOB_ID_PREFIX, SECURITY_HOLD_JOB_IDS, SECURITY_HOLD_JOB_LABELS, WORKFLOW_MODIFICATION_JOB_ID, installGateJobId };
55
+
56
+ //# sourceMappingURL=held-run-job-id.js.map
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Held-run status vocabulary — the single definition of what a held run's
3
+ * `status` can be.
4
+ *
5
+ * Lives beside `hold-type.ts` and `concurrency-strategy.ts` (the other shared
6
+ * context vocabularies) rather than in the protocol module, so both the domain
7
+ * types here and the wire schema in `protocol/messages/dashboard.ts` name the
8
+ * same enum instead of each carrying its own copy. A duplicated copy is exactly
9
+ * how `released` came to be persisted by the orchestrator but absent from the
10
+ * wire schema.
11
+ *
12
+ * This is the *known* vocabulary — the set the dashboard renders a labelled
13
+ * badge and a queue tab for, and the set a client may filter a list by. It is
14
+ * deliberately NOT the wire type of the response field: `held_runs.status` is a
15
+ * plain-text column owned by a customer-deployed orchestrator, so the response
16
+ * carries `z.string()`.
17
+ */
18
+ import { z } from 'zod';
19
+ /**
20
+ * Known held-run statuses.
21
+ *
22
+ * `released` is written by the orchestrator's `releaseDueWaitHolds()` when a
23
+ * workflow-scope wait timer elapses and the run proceeds.
24
+ */
25
+ export declare const HeldRunStatus: z.ZodEnum<{
26
+ approved: "approved";
27
+ expired: "expired";
28
+ pending: "pending";
29
+ rejected: "rejected";
30
+ released: "released";
31
+ }>;
32
+ export type HeldRunStatus = z.infer<typeof HeldRunStatus>;
33
+ //# sourceMappingURL=held-run-status.d.ts.map
@@ -0,0 +1,37 @@
1
+ import "../rolldown-runtime-ClRpJifh.js";
2
+ import { z } from "zod";
3
+ //#region src/context/held-run-status.ts
4
+ /**
5
+ * Held-run status vocabulary — the single definition of what a held run's
6
+ * `status` can be.
7
+ *
8
+ * Lives beside `hold-type.ts` and `concurrency-strategy.ts` (the other shared
9
+ * context vocabularies) rather than in the protocol module, so both the domain
10
+ * types here and the wire schema in `protocol/messages/dashboard.ts` name the
11
+ * same enum instead of each carrying its own copy. A duplicated copy is exactly
12
+ * how `released` came to be persisted by the orchestrator but absent from the
13
+ * wire schema.
14
+ *
15
+ * This is the *known* vocabulary — the set the dashboard renders a labelled
16
+ * badge and a queue tab for, and the set a client may filter a list by. It is
17
+ * deliberately NOT the wire type of the response field: `held_runs.status` is a
18
+ * plain-text column owned by a customer-deployed orchestrator, so the response
19
+ * carries `z.string()`.
20
+ */
21
+ /**
22
+ * Known held-run statuses.
23
+ *
24
+ * `released` is written by the orchestrator's `releaseDueWaitHolds()` when a
25
+ * workflow-scope wait timer elapses and the run proceeds.
26
+ */
27
+ const HeldRunStatus = z.enum([
28
+ "pending",
29
+ "approved",
30
+ "rejected",
31
+ "expired",
32
+ "released"
33
+ ]);
34
+ //#endregion
35
+ export { HeldRunStatus };
36
+
37
+ //# sourceMappingURL=held-run-status.js.map
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Hold window applied when a context carries no explicit hold expiry.
3
+ *
4
+ * `contexts.hold_expiry_seconds` is nullable, and a cleared column means "no
5
+ * explicit expiry" rather than "expire instantly" — without this fallback a
6
+ * cleared value would reach `evaluateReviewerGate` as `null`, whose
7
+ * `null * 1000` puts `holdUntil` at the current instant, so every reviewer hold
8
+ * would be created already overdue and swept to `expired` on the next stale
9
+ * scan, cancelling the job the hold was meant to gate.
10
+ *
11
+ * It lives here, beside `DEFAULT_CONCURRENCY_STRATEGY`, because the same three
12
+ * modules resolve both: the orchestrator's context store, its protection
13
+ * aggregate, and the dispatch path. The column carries no DDL default, so a
14
+ * context created without a hold expiry and one whose expiry was cleared both
15
+ * land on NULL and resolve through this single constant.
16
+ *
17
+ * Plain number, no `node:*` import — safe for the browser-facing engine barrel.
18
+ */
19
+ export declare const DEFAULT_HOLD_EXPIRY_SECONDS = 3600;
20
+ //# sourceMappingURL=hold-expiry.d.ts.map
@@ -0,0 +1,25 @@
1
+ import "../rolldown-runtime-ClRpJifh.js";
2
+ //#region src/context/hold-expiry.ts
3
+ /**
4
+ * Hold window applied when a context carries no explicit hold expiry.
5
+ *
6
+ * `contexts.hold_expiry_seconds` is nullable, and a cleared column means "no
7
+ * explicit expiry" rather than "expire instantly" — without this fallback a
8
+ * cleared value would reach `evaluateReviewerGate` as `null`, whose
9
+ * `null * 1000` puts `holdUntil` at the current instant, so every reviewer hold
10
+ * would be created already overdue and swept to `expired` on the next stale
11
+ * scan, cancelling the job the hold was meant to gate.
12
+ *
13
+ * It lives here, beside `DEFAULT_CONCURRENCY_STRATEGY`, because the same three
14
+ * modules resolve both: the orchestrator's context store, its protection
15
+ * aggregate, and the dispatch path. The column carries no DDL default, so a
16
+ * context created without a hold expiry and one whose expiry was cleared both
17
+ * land on NULL and resolve through this single constant.
18
+ *
19
+ * Plain number, no `node:*` import — safe for the browser-facing engine barrel.
20
+ */
21
+ const DEFAULT_HOLD_EXPIRY_SECONDS = 3600;
22
+ //#endregion
23
+ export { DEFAULT_HOLD_EXPIRY_SECONDS };
24
+
25
+ //# sourceMappingURL=hold-expiry.js.map
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Protection-gate hold-reason templates — the free-text sentence the trust gate
3
+ * persists into `held_runs.reason` when a contributor is below a context's
4
+ * `minimumTrust`.
5
+ *
6
+ * Single source of truth for the two sentences: the orchestrator's trust gate
7
+ * emits them, the ci-security DB fixture seeds them, and the unit and E2E
8
+ * assertions compare against them. One copy means a copy edit moves every site
9
+ * at once (`.claude/rules/code-style.md` § "Enums over hardcoded strings").
10
+ *
11
+ * `held_runs.reason` is a free-text column, so these are functions rather than
12
+ * an enum: the sentence carries the context name, which is per-hold data.
13
+ *
14
+ * Carries no runtime import on purpose — this module reaches the browser
15
+ * through the engine barrel, which must pull in no Node built-ins
16
+ * (`.claude/rules/engine.md` § "Browser-safe barrel export"). The one import
17
+ * below is type-only and is erased at compile time.
18
+ */
19
+ import type { TrustTier } from './types.js';
20
+ /**
21
+ * Reason a run is held because the context requires `minimumTrust: 'known'`
22
+ * and the contributor's tier is `unknown`.
23
+ */
24
+ export declare function unknownContributorHoldReason(contextName: string): string;
25
+ /**
26
+ * Reason a run is held because the context requires `minimumTrust: 'trusted'`
27
+ * and the contributor's tier is below that. `trustTier` is the contributor's
28
+ * actual tier, which the gate has already narrowed to a tier below `trusted` —
29
+ * so the type excludes `'trusted'`, whose sentence would read as a
30
+ * contradiction.
31
+ */
32
+ export declare function trustedContributorHoldReason(contextName: string, trustTier: Exclude<TrustTier, 'trusted'>): string;
33
+ //# sourceMappingURL=hold-reason.d.ts.map
@@ -0,0 +1,23 @@
1
+ import "../rolldown-runtime-ClRpJifh.js";
2
+ //#region src/context/hold-reason.ts
3
+ /**
4
+ * Reason a run is held because the context requires `minimumTrust: 'known'`
5
+ * and the contributor's tier is `unknown`.
6
+ */
7
+ function unknownContributorHoldReason(contextName) {
8
+ return `Context '${contextName}' requires known contributors (contributor is unknown)`;
9
+ }
10
+ /**
11
+ * Reason a run is held because the context requires `minimumTrust: 'trusted'`
12
+ * and the contributor's tier is below that. `trustTier` is the contributor's
13
+ * actual tier, which the gate has already narrowed to a tier below `trusted` —
14
+ * so the type excludes `'trusted'`, whose sentence would read as a
15
+ * contradiction.
16
+ */
17
+ function trustedContributorHoldReason(contextName, trustTier) {
18
+ return `Context '${contextName}' requires trusted contributors (contributor is ${trustTier})`;
19
+ }
20
+ //#endregion
21
+ export { trustedContributorHoldReason, unknownContributorHoldReason };
22
+
23
+ //# sourceMappingURL=hold-reason.js.map
@@ -0,0 +1,40 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Protection-gate hold-type vocabulary — the reason a run is paused by a
4
+ * context protection gate. Single source of truth for the four gate hold
5
+ * types shared across the engine domain types, the orchestrator gates, and the
6
+ * dashboard held-run UI.
7
+ *
8
+ * The orchestrator persists these verbatim into `held_runs.hold_type`, so the
9
+ * column, the wire and the dashboard all speak one vocabulary. The column and
10
+ * the wire field it rides on stay typed as `string` (see the held-runs list
11
+ * response schema) so an older/newer orchestrator's hold type never rejects the
12
+ * relayed message.
13
+ */
14
+ export declare const HoldType: z.ZodEnum<{
15
+ concurrency: "concurrency";
16
+ reviewer: "reviewer";
17
+ security: "security";
18
+ timer: "timer";
19
+ }>;
20
+ export type HoldType = z.infer<typeof HoldType>;
21
+ /**
22
+ * Map a persisted hold type onto the gate vocabulary.
23
+ *
24
+ * An unrecognised value passes through unchanged rather than being coerced to a
25
+ * default: the wire field is `z.string()` precisely so a newer orchestrator's
26
+ * hold type survives an older reader, and the dashboard's gray fallback badge
27
+ * is the correct rendering for a genuinely unknown type.
28
+ */
29
+ export declare function normalizePersistedHoldType(raw: string): string;
30
+ /**
31
+ * Every spelling `held_runs.hold_type` may hold for one gate hold type — the
32
+ * current one first, then any legacy alias that normalizes onto it.
33
+ *
34
+ * For queries that must match a hold type in SQL, where the row-by-row
35
+ * `normalizePersistedHoldType` cannot run. Feeding this into an `IN (…)` filter
36
+ * keeps a sweep matching rows an un-upgraded orchestrator wrote, and keeps the
37
+ * legacy spellings out of call sites as bare literals.
38
+ */
39
+ export declare function persistedHoldTypeSpellings(type: HoldType): string[];
40
+ //# sourceMappingURL=hold-type.d.ts.map
@@ -0,0 +1,61 @@
1
+ import "../rolldown-runtime-ClRpJifh.js";
2
+ import { z } from "zod";
3
+ //#region src/context/hold-type.ts
4
+ /**
5
+ * Protection-gate hold-type vocabulary — the reason a run is paused by a
6
+ * context protection gate. Single source of truth for the four gate hold
7
+ * types shared across the engine domain types, the orchestrator gates, and the
8
+ * dashboard held-run UI.
9
+ *
10
+ * The orchestrator persists these verbatim into `held_runs.hold_type`, so the
11
+ * column, the wire and the dashboard all speak one vocabulary. The column and
12
+ * the wire field it rides on stay typed as `string` (see the held-runs list
13
+ * response schema) so an older/newer orchestrator's hold type never rejects the
14
+ * relayed message.
15
+ */
16
+ const HoldType = z.enum([
17
+ "reviewer",
18
+ "timer",
19
+ "concurrency",
20
+ "security"
21
+ ]);
22
+ /**
23
+ * Legacy persisted `held_runs.hold_type` spellings → the gate vocabulary.
24
+ *
25
+ * A row written by an un-upgraded orchestrator can carry `approval` for a
26
+ * reviewer hold or `wait_timer` for a workflow-install wait hold. Writers emit
27
+ * the gate vocabulary and a migration backfills the column, so this map exists
28
+ * for those older rows — it is what lets the two sides deploy independently
29
+ * instead of in lockstep.
30
+ */
31
+ const LEGACY_HOLD_TYPES = Object.freeze({
32
+ approval: HoldType.enum.reviewer,
33
+ wait_timer: HoldType.enum.timer
34
+ });
35
+ /**
36
+ * Map a persisted hold type onto the gate vocabulary.
37
+ *
38
+ * An unrecognised value passes through unchanged rather than being coerced to a
39
+ * default: the wire field is `z.string()` precisely so a newer orchestrator's
40
+ * hold type survives an older reader, and the dashboard's gray fallback badge
41
+ * is the correct rendering for a genuinely unknown type.
42
+ */
43
+ function normalizePersistedHoldType(raw) {
44
+ return Object.hasOwn(LEGACY_HOLD_TYPES, raw) ? LEGACY_HOLD_TYPES[raw] : raw;
45
+ }
46
+ /**
47
+ * Every spelling `held_runs.hold_type` may hold for one gate hold type — the
48
+ * current one first, then any legacy alias that normalizes onto it.
49
+ *
50
+ * For queries that must match a hold type in SQL, where the row-by-row
51
+ * `normalizePersistedHoldType` cannot run. Feeding this into an `IN (…)` filter
52
+ * keeps a sweep matching rows an un-upgraded orchestrator wrote, and keeps the
53
+ * legacy spellings out of call sites as bare literals.
54
+ */
55
+ function persistedHoldTypeSpellings(type) {
56
+ return [type, ...Object.keys(LEGACY_HOLD_TYPES).filter((spelling) => LEGACY_HOLD_TYPES[spelling] === type)];
57
+ }
58
+ //#endregion
59
+ export { HoldType, normalizePersistedHoldType, persistedHoldTypeSpellings };
60
+
61
+ //# sourceMappingURL=hold-type.js.map
@@ -1,7 +1,7 @@
1
1
  import "../rolldown-runtime-ClRpJifh.js";
2
2
  import { matcherMatches } from "../labels-match.js";
3
3
  import { assertSafeRegex, toLabelMatcher } from "../labels/compile.js";
4
- //#region src/environment/host-match.ts
4
+ //#region src/context/host-match.ts
5
5
  /** `'**'`, empty, or absent means "matches every host". */
6
6
  function matchesAllHosts(pattern) {
7
7
  return pattern === "" || pattern === "**";
@@ -0,0 +1,14 @@
1
+ export type { Context, ContextBinding, ContextVariable, ContextSourceOverride, ScopedSecret, HeldRun, ProtectionGateResult, TrustTier, } from './types.js';
2
+ export { TrustTierSchema } from './types.js';
3
+ export { HoldType, normalizePersistedHoldType, persistedHoldTypeSpellings } from './hold-type.js';
4
+ export { trustedContributorHoldReason, unknownContributorHoldReason } from './hold-reason.js';
5
+ export { HeldRunStatus } from './held-run-status.js';
6
+ export { WORKFLOW_MODIFICATION_JOB_ID, SECURITY_HOLD_JOB_IDS, SECURITY_HOLD_JOB_LABELS, INSTALL_JOB_ID_PREFIX, installGateJobId, } from './held-run-job-id.js';
7
+ export { ConcurrencyStrategy, DEFAULT_CONCURRENCY_STRATEGY } from './concurrency-strategy.js';
8
+ export { DEFAULT_HOLD_EXPIRY_SECONDS } from './hold-expiry.js';
9
+ export { resolveSecretsForContext, resolveSecretsWithProvenance, matchScopePattern, stripScopePrefix, } from './scope-resolver.js';
10
+ export type { ResolvedSecretCandidate } from './scope-resolver.js';
11
+ export type { HostFacts } from './host-match.js';
12
+ export { mergeOrderedMaps, ContextGateRejectReason } from './multi-context.js';
13
+ export { validateScopeName, assertValidScopeName, ScopeNameError, SCOPE_SEGMENT_PATTERN, SCOPE_NAME_MAX_LENGTH, } from './scope-name.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,12 @@
1
+ import "../rolldown-runtime-ClRpJifh.js";
2
+ import { HeldRunStatus } from "./held-run-status.js";
3
+ import { TrustTierSchema } from "./types.js";
4
+ import { ConcurrencyStrategy, DEFAULT_CONCURRENCY_STRATEGY } from "./concurrency-strategy.js";
5
+ import { HoldType, normalizePersistedHoldType, persistedHoldTypeSpellings } from "./hold-type.js";
6
+ import { trustedContributorHoldReason, unknownContributorHoldReason } from "./hold-reason.js";
7
+ import { INSTALL_JOB_ID_PREFIX, SECURITY_HOLD_JOB_IDS, SECURITY_HOLD_JOB_LABELS, WORKFLOW_MODIFICATION_JOB_ID, installGateJobId } from "./held-run-job-id.js";
8
+ import { DEFAULT_HOLD_EXPIRY_SECONDS } from "./hold-expiry.js";
9
+ import { matchScopePattern, resolveSecretsForContext, resolveSecretsWithProvenance, stripScopePrefix } from "./scope-resolver.js";
10
+ import { ContextGateRejectReason, mergeOrderedMaps } from "./multi-context.js";
11
+ import { SCOPE_NAME_MAX_LENGTH, SCOPE_SEGMENT_PATTERN, ScopeNameError, assertValidScopeName, validateScopeName } from "./scope-name.js";
12
+ export { ConcurrencyStrategy, ContextGateRejectReason, DEFAULT_CONCURRENCY_STRATEGY, DEFAULT_HOLD_EXPIRY_SECONDS, HeldRunStatus, HoldType, INSTALL_JOB_ID_PREFIX, SCOPE_NAME_MAX_LENGTH, SCOPE_SEGMENT_PATTERN, SECURITY_HOLD_JOB_IDS, SECURITY_HOLD_JOB_LABELS, ScopeNameError, TrustTierSchema, WORKFLOW_MODIFICATION_JOB_ID, assertValidScopeName, installGateJobId, matchScopePattern, mergeOrderedMaps, normalizePersistedHoldType, persistedHoldTypeSpellings, resolveSecretsForContext, resolveSecretsWithProvenance, stripScopePrefix, trustedContributorHoldReason, unknownContributorHoldReason, validateScopeName };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Multi-context merge helpers shared across the orchestrator dispatch path.
3
+ *
4
+ * A job may bind several contexts in order; their resolved
5
+ * secrets/variables are folded last-wins (a later context's key overrides an
6
+ * earlier one) and their protection gates combine all-must-pass. This module is
7
+ * browser-safe (pure functions + a Zod enum, no Node built-ins) so it can be
8
+ * exported from the engine context barrel.
9
+ */
10
+ import { z } from 'zod';
11
+ /**
12
+ * Reason a single bound context rejects a run under all-must-pass
13
+ * aggregation. Used to name which context and which rule blocked dispatch.
14
+ */
15
+ export declare const ContextGateRejectReason: z.ZodEnum<{
16
+ branch_restricted: "branch_restricted";
17
+ context_disabled: "context_disabled";
18
+ context_not_found: "context_not_found";
19
+ repo_unmatched: "repo_unmatched";
20
+ trigger_filtered: "trigger_filtered";
21
+ trust_too_low: "trust_too_low";
22
+ }>;
23
+ export type ContextGateRejectReason = z.infer<typeof ContextGateRejectReason>;
24
+ /**
25
+ * Fold an ordered list of per-context resolved maps into one. Later entries
26
+ * override earlier keys (last-wins), matching the documented merge order for
27
+ * `contexts: [...]`.
28
+ */
29
+ export declare function mergeOrderedMaps(maps: ReadonlyArray<Record<string, string>>): Record<string, string>;
30
+ //# sourceMappingURL=multi-context.d.ts.map
@@ -0,0 +1,38 @@
1
+ import "../rolldown-runtime-ClRpJifh.js";
2
+ import { z } from "zod";
3
+ //#region src/context/multi-context.ts
4
+ /**
5
+ * Multi-context merge helpers shared across the orchestrator dispatch path.
6
+ *
7
+ * A job may bind several contexts in order; their resolved
8
+ * secrets/variables are folded last-wins (a later context's key overrides an
9
+ * earlier one) and their protection gates combine all-must-pass. This module is
10
+ * browser-safe (pure functions + a Zod enum, no Node built-ins) so it can be
11
+ * exported from the engine context barrel.
12
+ */
13
+ /**
14
+ * Reason a single bound context rejects a run under all-must-pass
15
+ * aggregation. Used to name which context and which rule blocked dispatch.
16
+ */
17
+ const ContextGateRejectReason = z.enum([
18
+ "branch_restricted",
19
+ "trigger_filtered",
20
+ "repo_unmatched",
21
+ "trust_too_low",
22
+ "context_disabled",
23
+ "context_not_found"
24
+ ]);
25
+ /**
26
+ * Fold an ordered list of per-context resolved maps into one. Later entries
27
+ * override earlier keys (last-wins), matching the documented merge order for
28
+ * `contexts: [...]`.
29
+ */
30
+ function mergeOrderedMaps(maps) {
31
+ const out = {};
32
+ for (const m of maps) Object.assign(out, m);
33
+ return out;
34
+ }
35
+ //#endregion
36
+ export { ContextGateRejectReason, mergeOrderedMaps };
37
+
38
+ //# sourceMappingURL=multi-context.js.map
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Canonical secret-scope-name validation, shared by the orchestrator write
3
+ * paths and the dashboard scope form. The rule runs on the PATH portion of a
4
+ * scope (after any `backend:` prefix has been stripped): non-empty, length
5
+ * bounded, `/`-separated non-empty segments, each segment restricted to
6
+ * `[A-Za-z0-9_.-]`, and no `.`/`..` segments. Kept dependency-free so the
7
+ * engine barrel stays browser-safe.
8
+ *
9
+ * Callers pass a bare path, so that precondition holds trivially: a writer
10
+ * never supplies a backend qualifier. The `<backend>:` prefix is added by the
11
+ * resolver when it merges secrets across backends at read time, and stripped
12
+ * again before any per-backend call.
13
+ */
14
+ /** Allowed characters in a single `/`-separated scope segment. */
15
+ export declare const SCOPE_SEGMENT_PATTERN: RegExp;
16
+ /** Maximum total length of a scope path. */
17
+ export declare const SCOPE_NAME_MAX_LENGTH = 512;
18
+ /**
19
+ * Validate the path portion of a scope name. Returns a human-readable error
20
+ * message, or `null` when the name is valid.
21
+ */
22
+ export declare function validateScopeName(path: string): string | null;
23
+ /** Error thrown by {@link assertValidScopeName} for an invalid scope name. */
24
+ export declare class ScopeNameError extends Error {
25
+ constructor(message: string);
26
+ }
27
+ /** Throw {@link ScopeNameError} when `path` is not a valid scope name. */
28
+ export declare function assertValidScopeName(path: string): void;
29
+ //# sourceMappingURL=scope-name.d.ts.map
@@ -0,0 +1,49 @@
1
+ import "../rolldown-runtime-ClRpJifh.js";
2
+ //#region src/context/scope-name.ts
3
+ /**
4
+ * Canonical secret-scope-name validation, shared by the orchestrator write
5
+ * paths and the dashboard scope form. The rule runs on the PATH portion of a
6
+ * scope (after any `backend:` prefix has been stripped): non-empty, length
7
+ * bounded, `/`-separated non-empty segments, each segment restricted to
8
+ * `[A-Za-z0-9_.-]`, and no `.`/`..` segments. Kept dependency-free so the
9
+ * engine barrel stays browser-safe.
10
+ *
11
+ * Callers pass a bare path, so that precondition holds trivially: a writer
12
+ * never supplies a backend qualifier. The `<backend>:` prefix is added by the
13
+ * resolver when it merges secrets across backends at read time, and stripped
14
+ * again before any per-backend call.
15
+ */
16
+ /** Allowed characters in a single `/`-separated scope segment. */
17
+ const SCOPE_SEGMENT_PATTERN = /^[A-Za-z0-9_.-]+$/;
18
+ /** Maximum total length of a scope path. */
19
+ const SCOPE_NAME_MAX_LENGTH = 512;
20
+ /**
21
+ * Validate the path portion of a scope name. Returns a human-readable error
22
+ * message, or `null` when the name is valid.
23
+ */
24
+ function validateScopeName(path) {
25
+ if (path.length === 0) return "Scope name must not be empty";
26
+ if (path.length > 512) return `Scope name must be at most 512 characters`;
27
+ for (const segment of path.split("/")) {
28
+ if (segment.length === 0) return "Scope name must not contain empty path segments";
29
+ if (segment === "." || segment === "..") return "Scope name segments must not be '.' or '..'";
30
+ if (!SCOPE_SEGMENT_PATTERN.test(segment)) return "Scope name may only contain letters, digits, and _ . - characters, separated by /";
31
+ }
32
+ return null;
33
+ }
34
+ /** Error thrown by {@link assertValidScopeName} for an invalid scope name. */
35
+ var ScopeNameError = class extends Error {
36
+ constructor(message) {
37
+ super(message);
38
+ this.name = "ScopeNameError";
39
+ }
40
+ };
41
+ /** Throw {@link ScopeNameError} when `path` is not a valid scope name. */
42
+ function assertValidScopeName(path) {
43
+ const error = validateScopeName(path);
44
+ if (error !== null) throw new ScopeNameError(error);
45
+ }
46
+ //#endregion
47
+ export { SCOPE_NAME_MAX_LENGTH, SCOPE_SEGMENT_PATTERN, ScopeNameError, assertValidScopeName, validateScopeName };
48
+
49
+ //# sourceMappingURL=scope-name.js.map