@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.
- package/dist/approval/types.d.ts +11 -4
- package/dist/approval/types.js +11 -4
- package/dist/artifacts/name.d.ts +60 -0
- package/dist/artifacts/name.js +71 -0
- package/dist/audit/access-log-policy.d.ts +1 -1
- package/dist/audit/access-log-policy.js +20 -11
- package/dist/audit/activity.d.ts +12 -12
- package/dist/audit/retention-policy.js +40 -22
- package/dist/billing/plan-type.d.ts +53 -0
- package/dist/billing/plan-type.js +70 -0
- package/dist/bundler/rolldown-config.d.ts +3 -3
- package/dist/check-mode.d.ts +1 -1
- package/dist/context/concurrency-strategy.d.ts +34 -0
- package/dist/context/concurrency-strategy.js +35 -0
- package/dist/context/held-run-job-id.d.ts +45 -0
- package/dist/context/held-run-job-id.js +56 -0
- package/dist/context/held-run-status.d.ts +33 -0
- package/dist/context/held-run-status.js +37 -0
- package/dist/context/hold-expiry.d.ts +20 -0
- package/dist/context/hold-expiry.js +25 -0
- package/dist/context/hold-reason.d.ts +33 -0
- package/dist/context/hold-reason.js +23 -0
- package/dist/context/hold-type.d.ts +40 -0
- package/dist/context/hold-type.js +61 -0
- package/dist/{environment → context}/host-match.js +1 -1
- package/dist/context/index.d.ts +14 -0
- package/dist/context/index.js +12 -0
- package/dist/context/multi-context.d.ts +30 -0
- package/dist/context/multi-context.js +38 -0
- package/dist/context/scope-name.d.ts +29 -0
- package/dist/context/scope-name.js +49 -0
- package/dist/context/scope-resolver.d.ts +79 -0
- package/dist/{environment → context}/scope-resolver.js +47 -17
- package/dist/{environment → context}/scope-template.js +1 -1
- package/dist/{environment → context}/types.d.ts +25 -22
- package/dist/{environment → context}/types.js +3 -3
- package/dist/dev-ops/operations.d.ts +9 -1
- package/dist/dev-ops/operations.js +37 -20
- package/dist/diagnostics/infra-alert.d.ts +71 -0
- package/dist/diagnostics/infra-alert.js +60 -0
- package/dist/env/environment-allowlist.d.ts +26 -3
- package/dist/env/environment-allowlist.js +35 -1
- package/dist/fanout/materialize.d.ts +16 -0
- package/dist/fanout/materialize.js +34 -5
- package/dist/index.d.ts +16 -7
- package/dist/index.js +38 -23
- package/dist/inputs/descriptor.d.ts +9 -9
- package/dist/inventory.d.ts +4 -4
- package/dist/labels.d.ts +82 -2
- package/dist/labels.js +119 -1
- package/dist/matrix/expand.d.ts +49 -2
- package/dist/matrix/expand.js +102 -13
- package/dist/matrix/format.d.ts +6 -1
- package/dist/matrix/format.js +6 -1
- package/dist/mcp/held-run-resolve.d.ts +7 -10
- package/dist/mcp/held-run-resolve.js +33 -7
- package/dist/metrics/catalog-policy.js +4 -4
- package/dist/metrics/metric-catalog.generated.d.ts +954 -734
- package/dist/metrics/metric-catalog.generated.js +296 -32
- package/dist/metrics/metric-kind-compat.d.ts +26 -0
- package/dist/metrics/metric-kind-compat.js +33 -0
- package/dist/protocol/analytics-events.d.ts +6 -6
- package/dist/protocol/dashboard-api-errors.d.ts +13 -0
- package/dist/protocol/dashboard-api-errors.js +17 -0
- package/dist/protocol/dashboard-write-operations.d.ts +143 -86
- package/dist/protocol/dashboard-write-operations.js +143 -69
- package/dist/protocol/messages/access-log.d.ts +438 -388
- package/dist/protocol/messages/access-log.js +24 -14
- package/dist/protocol/messages/actor.d.ts +2 -2
- package/dist/protocol/messages/agent-dev-ops.d.ts +4 -2
- package/dist/protocol/messages/agent-dev-ops.js +2 -5
- package/dist/protocol/messages/agent-run-result.d.ts +74 -64
- package/dist/protocol/messages/agent-run-result.js +1 -1
- package/dist/protocol/messages/auth.d.ts +35 -23
- package/dist/protocol/messages/browser.d.ts +81 -5
- package/dist/protocol/messages/browser.js +53 -2
- package/dist/protocol/messages/capabilities.d.ts +106 -31
- package/dist/protocol/messages/capabilities.js +94 -10
- package/dist/protocol/messages/common.d.ts +45 -2
- package/dist/protocol/messages/common.js +64 -3
- package/dist/protocol/messages/dashboard-sealed-write.d.ts +52 -0
- package/dist/protocol/messages/dashboard-sealed-write.js +57 -0
- package/dist/protocol/messages/dashboard.d.ts +1232 -706
- package/dist/protocol/messages/dashboard.js +387 -220
- package/dist/protocol/messages/deployment-identity.d.ts +37 -10
- package/dist/protocol/messages/deployment-identity.js +30 -3
- package/dist/protocol/messages/event-log.d.ts +5 -5
- package/dist/protocol/messages/execution-status.d.ts +198 -62
- package/dist/protocol/messages/execution-status.js +114 -46
- package/dist/protocol/messages/heartbeat-health.d.ts +83 -0
- package/dist/protocol/messages/heartbeat-health.js +87 -0
- package/dist/protocol/messages/log-stream.d.ts +18 -0
- package/dist/protocol/messages/log-stream.js +19 -0
- package/dist/protocol/messages/oidc-mint.d.ts +7 -0
- package/dist/protocol/messages/oidc-mint.js +7 -0
- package/dist/protocol/messages/orchestrator-agent.d.ts +264 -67
- package/dist/protocol/messages/orchestrator-agent.js +170 -5
- package/dist/protocol/messages/pat-kind.d.ts +1 -1
- package/dist/protocol/messages/peer.d.ts +122 -58
- package/dist/protocol/messages/peer.js +37 -2
- package/dist/protocol/messages/platform-orchestrator.d.ts +603 -258
- package/dist/protocol/messages/platform-orchestrator.js +131 -21
- package/dist/protocol/messages/run-events.d.ts +5 -5
- package/dist/protocol/messages/scaler-event.d.ts +3 -3
- package/dist/protocol/messages/source-registration.d.ts +56 -13
- package/dist/protocol/messages/source-registration.js +49 -6
- package/dist/protocol/session-policy.d.ts +20 -0
- package/dist/protocol/session-policy.js +25 -0
- package/dist/protocol/source-origin.d.ts +1 -1
- package/dist/provenance/attestation-origin.d.ts +1 -1
- package/dist/provenance/schema.d.ts +11 -11
- package/dist/provenance/verify.js +2 -1
- package/dist/provider/changed-files-fetcher.d.ts +21 -2
- package/dist/provider/check-run-conclusion.d.ts +2 -2
- package/dist/provider/check-status-poster.d.ts +23 -0
- package/dist/provider/index.d.ts +2 -2
- package/dist/registration/registerable-trigger-type.d.ts +14 -13
- package/dist/registration/registerable-trigger-type.js +1 -0
- package/dist/sandbox/capabilities.d.ts +6 -0
- package/dist/sandbox/capabilities.js +57 -0
- package/dist/scaler/scaler-backend-type.d.ts +1 -1
- package/dist/status/presentation.d.ts +89 -0
- package/dist/status/presentation.js +163 -0
- package/dist/trigger/compiled-matchers.d.ts +13 -0
- package/dist/trigger/compiled-matchers.js +44 -0
- package/dist/trigger/event-buckets.d.ts +44 -0
- package/dist/trigger/event-buckets.js +93 -0
- package/dist/trigger/matcher.d.ts +7 -3
- package/dist/trigger/matcher.js +53 -15
- package/dist/trigger/schedule-key.d.ts +14 -0
- package/dist/trigger/schedule-key.js +21 -0
- package/dist/trigger/trigger-event-type.d.ts +1 -1
- package/dist/trigger/trigger-event-type.js +2 -0
- package/dist/trigger/types.d.ts +178 -47
- package/dist/trigger/types.js +82 -24
- package/dist/webhook/event-types.d.ts +56 -0
- package/dist/webhook/event-types.js +59 -0
- package/dist/ws/ws-like.d.ts +13 -0
- package/package.json +26 -10
- package/sbom.spdx.json +10 -10
- package/dist/environment/index.d.ts +0 -6
- package/dist/environment/index.js +0 -5
- package/dist/environment/multi-env.d.ts +0 -30
- package/dist/environment/multi-env.js +0 -38
- package/dist/environment/scope-resolver.d.ts +0 -46
- package/dist/package-manager.d.ts +0 -20
- package/dist/protocol/messages/observe.d.ts +0 -76
- package/dist/protocol/messages/saas-orchestrator.d.ts +0 -2179
- package/dist/protocol/messages/test-run.d.ts +0 -59
- package/dist/state-machine/index.d.ts +0 -2
- package/dist/state-machine/index.js +0 -3
- package/dist/state-machine/machine.d.ts +0 -34
- package/dist/state-machine/machine.js +0 -103
- package/dist/state-machine/types.d.ts +0 -34
- package/dist/state-machine/types.js +0 -15
- /package/dist/{environment → context}/host-match.d.ts +0 -0
- /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/
|
|
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
|