@xemahq/kernel-contracts 0.2.0 → 0.2.2
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/agent-workspace/awp-spec.json +1 -1
- package/dist/biome/index.d.ts +5 -0
- package/dist/biome/index.d.ts.map +1 -1
- package/dist/biome/index.js +5 -0
- package/dist/biome/index.js.map +1 -1
- package/dist/biome/lib/biome-audience.d.ts +8 -0
- package/dist/biome/lib/biome-audience.d.ts.map +1 -0
- package/dist/biome/lib/biome-audience.js +12 -0
- package/dist/biome/lib/biome-audience.js.map +1 -0
- package/dist/biome/lib/biome-availability-grant.d.ts +10 -0
- package/dist/biome/lib/biome-availability-grant.d.ts.map +1 -0
- package/dist/biome/lib/biome-availability-grant.js +12 -0
- package/dist/biome/lib/biome-availability-grant.js.map +1 -0
- package/dist/biome/lib/biome-origin.d.ts +8 -0
- package/dist/biome/lib/biome-origin.d.ts.map +1 -0
- package/dist/biome/lib/biome-origin.js +12 -0
- package/dist/biome/lib/biome-origin.js.map +1 -0
- package/dist/biome/lib/biome-target.d.ts +7 -0
- package/dist/biome/lib/biome-target.d.ts.map +1 -0
- package/dist/biome/lib/biome-target.js +11 -0
- package/dist/biome/lib/biome-target.js.map +1 -0
- package/dist/biome/lib/biome-tier.d.ts +10 -0
- package/dist/biome/lib/biome-tier.d.ts.map +1 -0
- package/dist/biome/lib/biome-tier.js +19 -0
- package/dist/biome/lib/biome-tier.js.map +1 -0
- package/dist/contribution/lib/contribution-kind.d.ts +2 -1
- package/dist/contribution/lib/contribution-kind.d.ts.map +1 -1
- package/dist/contribution/lib/contribution-kind.js +1 -0
- package/dist/contribution/lib/contribution-kind.js.map +1 -1
- package/dist/distribution/index.d.ts +5 -0
- package/dist/distribution/index.d.ts.map +1 -0
- package/dist/distribution/index.js +21 -0
- package/dist/distribution/index.js.map +1 -0
- package/dist/distribution/lib/distribution-lock.d.ts +24 -0
- package/dist/distribution/lib/distribution-lock.d.ts.map +1 -0
- package/dist/distribution/lib/distribution-lock.js +34 -0
- package/dist/distribution/lib/distribution-lock.js.map +1 -0
- package/dist/distribution/lib/distribution-selector.d.ts +12 -0
- package/dist/distribution/lib/distribution-selector.d.ts.map +1 -0
- package/dist/distribution/lib/distribution-selector.js +13 -0
- package/dist/distribution/lib/distribution-selector.js.map +1 -0
- package/dist/distribution/lib/distribution.d.ts +21 -0
- package/dist/distribution/lib/distribution.d.ts.map +1 -0
- package/dist/distribution/lib/distribution.js +30 -0
- package/dist/distribution/lib/distribution.js.map +1 -0
- package/dist/distribution/lib/image-lock.d.ts +20 -0
- package/dist/distribution/lib/image-lock.d.ts.map +1 -0
- package/dist/distribution/lib/image-lock.js +30 -0
- package/dist/distribution/lib/image-lock.js.map +1 -0
- package/dist/inquiry/lib/enums.d.ts +4 -0
- package/dist/inquiry/lib/enums.d.ts.map +1 -1
- package/dist/inquiry/lib/enums.js +6 -1
- package/dist/inquiry/lib/enums.js.map +1 -1
- package/dist/inquiry/lib/inquiry.d.ts +5 -9
- package/dist/inquiry/lib/inquiry.d.ts.map +1 -1
- package/dist/inquiry/lib/inquiry.js +4 -2
- package/dist/inquiry/lib/inquiry.js.map +1 -1
- package/dist/invocation/index.d.ts +10 -0
- package/dist/invocation/index.d.ts.map +1 -0
- package/dist/invocation/index.js +26 -0
- package/dist/invocation/index.js.map +1 -0
- package/dist/invocation/lib/execution-requirements.d.ts +24 -0
- package/dist/invocation/lib/execution-requirements.d.ts.map +1 -0
- package/dist/invocation/lib/execution-requirements.js +25 -0
- package/dist/invocation/lib/execution-requirements.js.map +1 -0
- package/dist/invocation/lib/invocation-decision.d.ts +8 -0
- package/dist/invocation/lib/invocation-decision.d.ts.map +1 -0
- package/dist/invocation/lib/invocation-decision.js +10 -0
- package/dist/invocation/lib/invocation-decision.js.map +1 -0
- package/dist/invocation/lib/invocation-mode.d.ts +8 -0
- package/dist/invocation/lib/invocation-mode.d.ts.map +1 -0
- package/dist/invocation/lib/invocation-mode.js +12 -0
- package/dist/invocation/lib/invocation-mode.js.map +1 -0
- package/dist/invocation/lib/invocation-priority.d.ts +8 -0
- package/dist/invocation/lib/invocation-priority.d.ts.map +1 -0
- package/dist/invocation/lib/invocation-priority.js +12 -0
- package/dist/invocation/lib/invocation-priority.js.map +1 -0
- package/dist/invocation/lib/invocation-record.d.ts +27 -0
- package/dist/invocation/lib/invocation-record.d.ts.map +1 -0
- package/dist/invocation/lib/invocation-record.js +29 -0
- package/dist/invocation/lib/invocation-record.js.map +1 -0
- package/dist/invocation/lib/invocation-status.d.ts +13 -0
- package/dist/invocation/lib/invocation-status.d.ts.map +1 -0
- package/dist/invocation/lib/invocation-status.js +17 -0
- package/dist/invocation/lib/invocation-status.js.map +1 -0
- package/dist/invocation/lib/invoke-request.d.ts +13 -0
- package/dist/invocation/lib/invoke-request.d.ts.map +1 -0
- package/dist/invocation/lib/invoke-request.js +15 -0
- package/dist/invocation/lib/invoke-request.js.map +1 -0
- package/dist/invocation/lib/invoke-response.d.ts +17 -0
- package/dist/invocation/lib/invoke-response.d.ts.map +1 -0
- package/dist/invocation/lib/invoke-response.js +19 -0
- package/dist/invocation/lib/invoke-response.js.map +1 -0
- package/dist/invocation/lib/isolation-level.d.ts +7 -0
- package/dist/invocation/lib/isolation-level.d.ts.map +1 -0
- package/dist/invocation/lib/isolation-level.js +11 -0
- package/dist/invocation/lib/isolation-level.js.map +1 -0
- package/dist/mail-source/index.d.ts +2 -0
- package/dist/mail-source/index.d.ts.map +1 -0
- package/dist/mail-source/index.js +18 -0
- package/dist/mail-source/index.js.map +1 -0
- package/dist/mail-source/lib/mail-event.d.ts +58 -0
- package/dist/mail-source/lib/mail-event.d.ts.map +1 -0
- package/dist/mail-source/lib/mail-event.js +41 -0
- package/dist/mail-source/lib/mail-event.js.map +1 -0
- package/dist/policy/index.d.ts +1 -0
- package/dist/policy/index.d.ts.map +1 -1
- package/dist/policy/index.js +1 -0
- package/dist/policy/index.js.map +1 -1
- package/dist/policy/lib/egress-allowlist.d.ts +18 -0
- package/dist/policy/lib/egress-allowlist.d.ts.map +1 -0
- package/dist/policy/lib/egress-allowlist.js +130 -0
- package/dist/policy/lib/egress-allowlist.js.map +1 -0
- package/dist/policy/lib/obligations.d.ts +12 -1
- package/dist/policy/lib/obligations.d.ts.map +1 -1
- package/dist/policy/lib/obligations.js +14 -1
- package/dist/policy/lib/obligations.js.map +1 -1
- package/package.json +1 -1
- package/src/biome/index.ts +5 -0
- package/src/biome/lib/biome-audience.ts +27 -0
- package/src/biome/lib/biome-availability-grant.ts +42 -0
- package/src/biome/lib/biome-origin.ts +26 -0
- package/src/biome/lib/biome-target.ts +16 -0
- package/src/biome/lib/biome-tier.ts +44 -0
- package/src/contribution/lib/contribution-kind.ts +14 -0
- package/src/distribution/index.ts +4 -0
- package/src/distribution/lib/distribution-lock.ts +88 -0
- package/src/distribution/lib/distribution-selector.ts +35 -0
- package/src/distribution/lib/distribution.ts +82 -0
- package/src/distribution/lib/image-lock.ts +77 -0
- package/src/inquiry/lib/enums.ts +13 -0
- package/src/inquiry/lib/inquiry.ts +22 -4
- package/src/invocation/index.ts +9 -0
- package/src/invocation/lib/execution-requirements.ts +61 -0
- package/src/invocation/lib/invocation-decision.ts +21 -0
- package/src/invocation/lib/invocation-mode.ts +26 -0
- package/src/invocation/lib/invocation-priority.ts +16 -0
- package/src/invocation/lib/invocation-record.ts +59 -0
- package/src/invocation/lib/invocation-status.ts +32 -0
- package/src/invocation/lib/invoke-request.ts +34 -0
- package/src/invocation/lib/invoke-response.ts +39 -0
- package/src/invocation/lib/isolation-level.ts +20 -0
- package/src/mail-source/index.ts +1 -0
- package/src/mail-source/lib/mail-event.ts +106 -0
- package/src/policy/index.ts +1 -0
- package/src/policy/lib/egress-allowlist.ts +239 -0
- package/src/policy/lib/obligations.ts +61 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import {
|
|
3
|
+
BiomeTierSchema,
|
|
4
|
+
BiomeOriginSchema,
|
|
5
|
+
type BiomeTier,
|
|
6
|
+
type BiomeOrigin,
|
|
7
|
+
} from '../../biome';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A `DistributionSelector` declares which biomes an `include[]` entry pulls
|
|
11
|
+
* into a distribution. Exactly one of the three forms:
|
|
12
|
+
*
|
|
13
|
+
* - `{ tier }` — every biome of that dependency tier (maps to the manifest
|
|
14
|
+
* `xema.scope` field). NEVER pulls `audience: operator`
|
|
15
|
+
* biomes — those require explicit `{ biome }` naming.
|
|
16
|
+
* - `{ origin }` — every biome of that provenance posture (first/third-party).
|
|
17
|
+
* - `{ biome }` — one biome by id, optional semver `version` range. This is
|
|
18
|
+
* the ONLY form that can pull an `audience: operator` biome
|
|
19
|
+
* (the "force it in" mechanism for our internal distribution).
|
|
20
|
+
*
|
|
21
|
+
* Selector matching is resolved against the global biome index; the resolver,
|
|
22
|
+
* not any consumer, applies these rules (the lockfile is the hard boundary).
|
|
23
|
+
*/
|
|
24
|
+
export type DistributionSelector =
|
|
25
|
+
| { tier: BiomeTier }
|
|
26
|
+
| { origin: BiomeOrigin }
|
|
27
|
+
| { biome: string; version?: string };
|
|
28
|
+
|
|
29
|
+
export const DistributionSelectorSchema = z.union([
|
|
30
|
+
z.object({ tier: BiomeTierSchema }).strict(),
|
|
31
|
+
z.object({ origin: BiomeOriginSchema }).strict(),
|
|
32
|
+
z
|
|
33
|
+
.object({ biome: z.string().min(1), version: z.string().min(1).optional() })
|
|
34
|
+
.strict(),
|
|
35
|
+
]) as z.ZodType<DistributionSelector>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { BiomeOriginSchema, type BiomeOrigin } from '../../biome';
|
|
3
|
+
import {
|
|
4
|
+
DistributionSelectorSchema,
|
|
5
|
+
type DistributionSelector,
|
|
6
|
+
} from './distribution-selector';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Schema-versioning seed for `xema-distribution.json`. Bumped via a coordinated
|
|
10
|
+
* PR on an incompatible shape change; consumers refuse versions they do not
|
|
11
|
+
* understand (fail-fast — no best-effort parse).
|
|
12
|
+
*/
|
|
13
|
+
export type DistributionSchemaVersion = 1;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Trust policy of a distribution — gates which provenance postures may ship.
|
|
17
|
+
* E.g. a locked appliance distribution allows only `first-party`. Gates on
|
|
18
|
+
* `BiomeOrigin` (the posture carried on the manifest at build time), NOT on
|
|
19
|
+
* the richer install-time `BiomeTrustTier`.
|
|
20
|
+
*/
|
|
21
|
+
export interface DistributionTrustPolicy {
|
|
22
|
+
allow: readonly BiomeOrigin[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const DistributionTrustPolicySchema = z.object({
|
|
26
|
+
allow: z.array(BiomeOriginSchema).readonly(),
|
|
27
|
+
}) as z.ZodType<DistributionTrustPolicy>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* `Distribution` — the top-level shape of `xema-distribution.json`: the
|
|
31
|
+
* PACKAGING primitive that declares which biomes a given Xema build ships.
|
|
32
|
+
*
|
|
33
|
+
* This is orthogonal to a biome's dependency tier (`BiomeTier`) and to where it
|
|
34
|
+
* is deployed (the deployment plane). It contains PACKAGING fields only — no
|
|
35
|
+
* infra/deploy/values config (that lives in the deployment overlay).
|
|
36
|
+
*
|
|
37
|
+
* Composition: `extends` names a parent distribution; the resolver composes
|
|
38
|
+
* parent → child, with the child's `include`/`exclude` overriding. The resolver
|
|
39
|
+
* enforces (fail-fast): kernel-tier biomes are always included and cannot be
|
|
40
|
+
* excluded; an included biome whose `requires` are absent is an error; selectors
|
|
41
|
+
* never pull `audience: operator` biomes. The deterministic resolved output is a
|
|
42
|
+
* `DistributionLock` — the single artifact every consumer reads.
|
|
43
|
+
*/
|
|
44
|
+
export interface Distribution {
|
|
45
|
+
schemaVersion: DistributionSchemaVersion;
|
|
46
|
+
id: string;
|
|
47
|
+
displayName: string;
|
|
48
|
+
description?: string;
|
|
49
|
+
/** Parent distribution id this one composes onto. */
|
|
50
|
+
extends?: string;
|
|
51
|
+
include: readonly DistributionSelector[];
|
|
52
|
+
/** Biome ids to remove after composition. Cannot remove a kernel-tier biome. */
|
|
53
|
+
exclude?: readonly string[];
|
|
54
|
+
trustPolicy?: DistributionTrustPolicy;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const DistributionSchema = z.object({
|
|
58
|
+
schemaVersion: z.literal(1),
|
|
59
|
+
id: z.string().min(1),
|
|
60
|
+
displayName: z.string().min(1),
|
|
61
|
+
description: z.string().min(1).optional(),
|
|
62
|
+
extends: z.string().min(1).optional(),
|
|
63
|
+
include: z.array(DistributionSelectorSchema).readonly(),
|
|
64
|
+
exclude: z.array(z.string().min(1)).readonly().optional(),
|
|
65
|
+
trustPolicy: DistributionTrustPolicySchema.optional(),
|
|
66
|
+
}) as z.ZodType<Distribution>;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Parse + validate a raw `xema-distribution.json`. Fail-fast on any shape error
|
|
70
|
+
* — never best-effort. Mirrors `parseBiomeManifest`.
|
|
71
|
+
*/
|
|
72
|
+
export function parseDistribution(raw: unknown): Distribution {
|
|
73
|
+
const result = DistributionSchema.safeParse(raw);
|
|
74
|
+
if (!result.success) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`Invalid xema-distribution.json: ${result.error.issues
|
|
77
|
+
.map((i) => `[${i.path.join('.')}] ${i.message}`)
|
|
78
|
+
.join('; ')}`,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
return result.data;
|
|
82
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { BiomeTargetSchema, type BiomeTarget } from '../../biome';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A single deployable image as resolved by the image-manifest step
|
|
6
|
+
* (`images.lock.json`). Images are CONTENT-ADDRESSED: `contentHash` is a
|
|
7
|
+
* deterministic sha256 over the biome's source directory tree, so the SAME
|
|
8
|
+
* biome source produces the SAME hash (and therefore the same image tag)
|
|
9
|
+
* across every customer/distribution. This is the delta key — CI builds an
|
|
10
|
+
* image only when its `contentHash` is not already present in the registry.
|
|
11
|
+
*
|
|
12
|
+
* `imageRef` is the untagged repository reference; the build-time tag is
|
|
13
|
+
* `${imageRef}:${contentHash}`.
|
|
14
|
+
*/
|
|
15
|
+
export interface LockedImage {
|
|
16
|
+
/** The biome this image is built from. */
|
|
17
|
+
biomeId: string;
|
|
18
|
+
/** Runtime surface — only `server` biomes produce a container image. */
|
|
19
|
+
target: BiomeTarget;
|
|
20
|
+
/** Untagged image repository reference, e.g. `ghcr.io/xema-dev/<biomeId>`. */
|
|
21
|
+
imageRef: string;
|
|
22
|
+
/** sha256 over the biome source tree — identical source ⇒ identical hash. */
|
|
23
|
+
contentHash: string;
|
|
24
|
+
/** Source repo segment the biome was resolved from (provenance for the build). */
|
|
25
|
+
repo: string;
|
|
26
|
+
/** Source directory path (repo-root-relative) the biome was resolved from. */
|
|
27
|
+
path: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const LockedImageSchema = z.object({
|
|
31
|
+
biomeId: z.string().min(1),
|
|
32
|
+
target: BiomeTargetSchema,
|
|
33
|
+
imageRef: z.string().min(1),
|
|
34
|
+
contentHash: z.string().min(1),
|
|
35
|
+
repo: z.string().min(1),
|
|
36
|
+
path: z.string().min(1),
|
|
37
|
+
}) as z.ZodType<LockedImage>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* `ImageLock` — the deterministic, content-addressed image manifest for a
|
|
41
|
+
* distribution. Resolved from `distribution.lock.json` by the image-manifest
|
|
42
|
+
* tooling; the delta-build planner reads it to decide which images are NEW vs
|
|
43
|
+
* already-built. Like `DistributionLock`, `resolvedAt` is stamped by the
|
|
44
|
+
* tooling (kernel contracts hold no clock) and is optional so the type is
|
|
45
|
+
* usable mid-resolution.
|
|
46
|
+
*/
|
|
47
|
+
export interface ImageLock {
|
|
48
|
+
schemaVersion: 1;
|
|
49
|
+
distributionId: string;
|
|
50
|
+
images: readonly LockedImage[];
|
|
51
|
+
/** ISO-8601 timestamp the resolver stamped (tooling-supplied). */
|
|
52
|
+
resolvedAt?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const ImageLockSchema = z.object({
|
|
56
|
+
schemaVersion: z.literal(1),
|
|
57
|
+
distributionId: z.string().min(1),
|
|
58
|
+
images: z.array(LockedImageSchema).readonly(),
|
|
59
|
+
resolvedAt: z.string().min(1).optional(),
|
|
60
|
+
}) as z.ZodType<ImageLock>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Parse + validate a raw `images.lock.json`. Fail-fast on any shape error —
|
|
64
|
+
* the image lock is the hard boundary the delta-build planner reads, so a
|
|
65
|
+
* malformed lock must never be silently tolerated.
|
|
66
|
+
*/
|
|
67
|
+
export function parseImageLock(raw: unknown): ImageLock {
|
|
68
|
+
const result = ImageLockSchema.safeParse(raw);
|
|
69
|
+
if (!result.success) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
`Invalid images.lock.json: ${result.error.issues
|
|
72
|
+
.map((i) => `[${i.path.join('.')}] ${i.message}`)
|
|
73
|
+
.join('; ')}`,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
return result.data;
|
|
77
|
+
}
|
package/src/inquiry/lib/enums.ts
CHANGED
|
@@ -101,3 +101,16 @@ export enum InquiryTimeoutAction {
|
|
|
101
101
|
APPROVE = 'approve',
|
|
102
102
|
ESCALATE = 'escalate',
|
|
103
103
|
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Terminal action when an inquiry's `escalationChain` is exhausted (the
|
|
107
|
+
* final step's deadline passed with no terminal verdict). A deliberately
|
|
108
|
+
* NARROWER closed set than `InquiryTimeoutAction`: `ESCALATE` is not
|
|
109
|
+
* representable here — escalating past the last chain step would be an
|
|
110
|
+
* infinite loop. Defaults to `REJECT` so a misconfigured chain never
|
|
111
|
+
* silently approves.
|
|
112
|
+
*/
|
|
113
|
+
export enum EscalationExhaustionAction {
|
|
114
|
+
REJECT = 'reject',
|
|
115
|
+
APPROVE = 'approve',
|
|
116
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
EscalationExhaustionAction,
|
|
4
5
|
InquiryKind,
|
|
5
6
|
InquiryRecipientStatus,
|
|
6
7
|
InquiryStatus,
|
|
@@ -51,6 +52,17 @@ export const InquirySchema = z.object({
|
|
|
51
52
|
workflowRunId: z.string().min(1),
|
|
52
53
|
jobRunId: z.string().min(1),
|
|
53
54
|
kind: z.nativeEnum(InquiryKind),
|
|
55
|
+
/**
|
|
56
|
+
* Optional domain approval-card discriminator. Distinct from the
|
|
57
|
+
* structural `kind` (which selects policy + gate semantics): an
|
|
58
|
+
* `inquiryKind` selects a biome-contributed approval-card variant
|
|
59
|
+
* (custom fields + verdict shape) on the FE and a domain descriptor on
|
|
60
|
+
* the engine. `null`/absent = the generic card for the structural
|
|
61
|
+
* `kind`, which is a valid state — never a silent error. When present,
|
|
62
|
+
* the value MUST match a `ContributionKind.InquiryKind` descriptor
|
|
63
|
+
* registered with the engine (validated fail-fast at create time).
|
|
64
|
+
*/
|
|
65
|
+
inquiryKind: z.string().min(1).nullable(),
|
|
54
66
|
title: z.string(),
|
|
55
67
|
prompt: z.record(z.string(), z.unknown()),
|
|
56
68
|
policy: ReplyPolicySchema,
|
|
@@ -66,10 +78,10 @@ export const InquirySchema = z.object({
|
|
|
66
78
|
/**
|
|
67
79
|
* Action when the escalation chain is exhausted (i.e. the final
|
|
68
80
|
* step's deadline passes with no terminal verdict). Closed set:
|
|
69
|
-
* `REJECT` (default) or `APPROVE`. `ESCALATE` is
|
|
70
|
-
* the
|
|
81
|
+
* `REJECT` (default) or `APPROVE`. `ESCALATE` is not representable —
|
|
82
|
+
* escalating past the last chain step would be a runtime infinite loop.
|
|
71
83
|
*/
|
|
72
|
-
onEscalationExhaustion: z.
|
|
84
|
+
onEscalationExhaustion: z.nativeEnum(EscalationExhaustionAction),
|
|
73
85
|
/**
|
|
74
86
|
* Zero-based pointer into `escalationChain`. Bumped each time the
|
|
75
87
|
* engine advances. `0` means "still on the original recipients";
|
|
@@ -120,6 +132,12 @@ export const CreateInquiryInputSchema = z
|
|
|
120
132
|
workflowRunId: z.string().min(1),
|
|
121
133
|
jobRunId: z.string().min(1),
|
|
122
134
|
kind: z.nativeEnum(InquiryKind),
|
|
135
|
+
/**
|
|
136
|
+
* Optional domain approval-card discriminator (see `InquirySchema`).
|
|
137
|
+
* Omitted = generic card for the structural `kind`. When present, the
|
|
138
|
+
* engine refuses an unregistered value fail-fast.
|
|
139
|
+
*/
|
|
140
|
+
inquiryKind: z.string().min(1).optional(),
|
|
123
141
|
title: z.string(),
|
|
124
142
|
prompt: z.record(z.string(), z.unknown()),
|
|
125
143
|
policy: ReplyPolicySchema,
|
|
@@ -127,7 +145,7 @@ export const CreateInquiryInputSchema = z
|
|
|
127
145
|
expiresAtIso: z.string(),
|
|
128
146
|
onTimeout: z.nativeEnum(InquiryTimeoutAction),
|
|
129
147
|
escalationChain: z.array(EscalationStepSchema).optional(),
|
|
130
|
-
onEscalationExhaustion: z.
|
|
148
|
+
onEscalationExhaustion: z.nativeEnum(EscalationExhaustionAction).optional(),
|
|
131
149
|
})
|
|
132
150
|
.superRefine((value, ctx) => {
|
|
133
151
|
// ESCALATE without a chain is meaningless — would have to fall back
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './lib/invocation-mode';
|
|
2
|
+
export * from './lib/isolation-level';
|
|
3
|
+
export * from './lib/invocation-status';
|
|
4
|
+
export * from './lib/invocation-priority';
|
|
5
|
+
export * from './lib/execution-requirements';
|
|
6
|
+
export * from './lib/invocation-decision';
|
|
7
|
+
export * from './lib/invoke-request';
|
|
8
|
+
export * from './lib/invoke-response';
|
|
9
|
+
export * from './lib/invocation-record';
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { InvocationMode, InvocationModeSchema } from './invocation-mode';
|
|
3
|
+
import { IsolationLevel, IsolationLevelSchema } from './isolation-level';
|
|
4
|
+
import {
|
|
5
|
+
InvocationPriority,
|
|
6
|
+
InvocationPrioritySchema,
|
|
7
|
+
} from './invocation-priority';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Per-invocation hard limits. None are required at the contract level; an
|
|
11
|
+
* absent field means "no caller-declared limit on this axis" (the platform may
|
|
12
|
+
* still apply its own). These map directly onto the existing `composition.limits`
|
|
13
|
+
* consumed by `CompositionBudgetEnforcer` — no new enforcement engine.
|
|
14
|
+
*/
|
|
15
|
+
export interface InvocationLimits {
|
|
16
|
+
readonly maxDurationMs?: number;
|
|
17
|
+
readonly maxTokens?: number;
|
|
18
|
+
readonly maxToolCalls?: number;
|
|
19
|
+
readonly maxRetries?: number;
|
|
20
|
+
readonly maxCostUsd?: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const InvocationLimitsSchema = z.object({
|
|
24
|
+
maxDurationMs: z.number().int().nonnegative().optional(),
|
|
25
|
+
maxTokens: z.number().int().nonnegative().optional(),
|
|
26
|
+
maxToolCalls: z.number().int().nonnegative().optional(),
|
|
27
|
+
maxRetries: z.number().int().nonnegative().optional(),
|
|
28
|
+
maxCostUsd: z.number().nonnegative().optional(),
|
|
29
|
+
}) as z.ZodType<InvocationLimits>;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* What a biome DECLARES about how its invocation should run; the platform
|
|
33
|
+
* ENFORCES. `mode` is a hint the platform may override by policy; `isolation`
|
|
34
|
+
* defaults to `Strict` (fresh thread per invocation).
|
|
35
|
+
*/
|
|
36
|
+
export interface ExecutionRequirements {
|
|
37
|
+
/** Hint; the platform may override the execution mode by policy. */
|
|
38
|
+
readonly mode?: InvocationMode;
|
|
39
|
+
/** Thread-context isolation; default `Strict`. */
|
|
40
|
+
readonly isolation: IsolationLevel;
|
|
41
|
+
readonly latencyTargetMs?: number;
|
|
42
|
+
readonly priority?: InvocationPriority;
|
|
43
|
+
/** Strategy / modelClass hint for model resolution. */
|
|
44
|
+
readonly modelCapability?: string;
|
|
45
|
+
/** Deliverable-spec / JSON-schema ref the root output is validated against. */
|
|
46
|
+
readonly outputSchemaRef?: string;
|
|
47
|
+
readonly idempotencyKey?: string;
|
|
48
|
+
/** Maps to the existing `composition.limits` budget axes. */
|
|
49
|
+
readonly limits?: InvocationLimits;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const ExecutionRequirementsSchema = z.object({
|
|
53
|
+
mode: InvocationModeSchema.optional(),
|
|
54
|
+
isolation: IsolationLevelSchema,
|
|
55
|
+
latencyTargetMs: z.number().int().nonnegative().optional(),
|
|
56
|
+
priority: InvocationPrioritySchema.optional(),
|
|
57
|
+
modelCapability: z.string().min(1).optional(),
|
|
58
|
+
outputSchemaRef: z.string().min(1).optional(),
|
|
59
|
+
idempotencyKey: z.string().min(1).optional(),
|
|
60
|
+
limits: InvocationLimitsSchema.optional(),
|
|
61
|
+
}) as z.ZodType<ExecutionRequirements>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* One structured decision produced by a composition invocation. An invocation
|
|
5
|
+
* MAY emit multiple decisions (e.g. a classify step and a route step).
|
|
6
|
+
*
|
|
7
|
+
* `kind` is free-form at the contract layer because the set of decision kinds
|
|
8
|
+
* is open and biome-owned (e.g. `'classification'`, `'route'`); the runtime
|
|
9
|
+
* does not interpret it. `payload` carries the decision body verbatim.
|
|
10
|
+
*/
|
|
11
|
+
export interface InvocationDecision {
|
|
12
|
+
readonly kind: string;
|
|
13
|
+
readonly payload: Record<string, unknown>;
|
|
14
|
+
readonly confidence?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const InvocationDecisionSchema = z.object({
|
|
18
|
+
kind: z.string().min(1),
|
|
19
|
+
payload: z.record(z.string(), z.unknown()),
|
|
20
|
+
confidence: z.number().optional(),
|
|
21
|
+
}) as z.ZodType<InvocationDecision>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* How the Composition Invocation Runtime executes an invocation.
|
|
5
|
+
*
|
|
6
|
+
* The platform owns mode selection (deterministic `selectMode`): a biome MAY
|
|
7
|
+
* hint a mode via `ExecutionRequirements.mode`, but policy may override it.
|
|
8
|
+
*
|
|
9
|
+
* - `Sync` — the caller holds the request open until the composition produces
|
|
10
|
+
* its root structured output. The smallest correct slice (Phase 1).
|
|
11
|
+
* - `Async` — the runtime returns immediately with a `Queued`/`Running`
|
|
12
|
+
* invocation; the caller polls the Invocation record for the terminal state.
|
|
13
|
+
* - `Event` — the runtime returns without an `output`; the result is delivered
|
|
14
|
+
* later as a completion event the consumer subscribes to (the default at
|
|
15
|
+
* high throughput).
|
|
16
|
+
*
|
|
17
|
+
* Closed set — adding a mode is a coordinated kernel change so producer and
|
|
18
|
+
* consumer stay in lockstep.
|
|
19
|
+
*/
|
|
20
|
+
export enum InvocationMode {
|
|
21
|
+
Sync = 'sync',
|
|
22
|
+
Async = 'async',
|
|
23
|
+
Event = 'event',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const InvocationModeSchema = z.nativeEnum(InvocationMode);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Scheduling priority a biome may hint on an invocation. The platform owns the
|
|
5
|
+
* actual queue ordering; this is an advisory dimension carried on
|
|
6
|
+
* `ExecutionRequirements`.
|
|
7
|
+
*
|
|
8
|
+
* Closed set — adding a priority is a coordinated kernel change.
|
|
9
|
+
*/
|
|
10
|
+
export enum InvocationPriority {
|
|
11
|
+
Low = 'low',
|
|
12
|
+
Normal = 'normal',
|
|
13
|
+
High = 'high',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const InvocationPrioritySchema = z.nativeEnum(InvocationPriority);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { InvocationMode, InvocationModeSchema } from './invocation-mode';
|
|
3
|
+
import { InvocationStatus, InvocationStatusSchema } from './invocation-status';
|
|
4
|
+
import {
|
|
5
|
+
InvocationDecision,
|
|
6
|
+
InvocationDecisionSchema,
|
|
7
|
+
} from './invocation-decision';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The durable Invocation unit — the projection of one row the runtime persists
|
|
11
|
+
* per invocation. This is the source of truth for an invocation's lifecycle
|
|
12
|
+
* (never the underlying session).
|
|
13
|
+
*
|
|
14
|
+
* `inputRef`/`outputRef` are blob/JSON references (inline JSON in Phase 1,
|
|
15
|
+
* artifact-store refs once payloads grow). Timestamps are ISO-8601 strings.
|
|
16
|
+
*/
|
|
17
|
+
export interface InvocationRecord {
|
|
18
|
+
readonly id: string;
|
|
19
|
+
readonly compositionRef: string;
|
|
20
|
+
readonly orgId: string;
|
|
21
|
+
readonly projectId: string | null;
|
|
22
|
+
readonly threadKey: string;
|
|
23
|
+
readonly correlationId: string;
|
|
24
|
+
readonly idempotencyKey: string | null;
|
|
25
|
+
readonly mode: InvocationMode;
|
|
26
|
+
readonly status: InvocationStatus;
|
|
27
|
+
readonly inputRef: string;
|
|
28
|
+
readonly outputRef: string | null;
|
|
29
|
+
readonly decisions: readonly InvocationDecision[];
|
|
30
|
+
readonly costUsd: number | null;
|
|
31
|
+
readonly durationMs: number | null;
|
|
32
|
+
readonly modelRef: string | null;
|
|
33
|
+
readonly auditId: string | null;
|
|
34
|
+
readonly sessionId: string | null;
|
|
35
|
+
readonly createdAt: string;
|
|
36
|
+
readonly lastActiveAt: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const InvocationRecordSchema = z.object({
|
|
40
|
+
id: z.string().min(1),
|
|
41
|
+
compositionRef: z.string().min(1),
|
|
42
|
+
orgId: z.string().min(1),
|
|
43
|
+
projectId: z.string().min(1).nullable(),
|
|
44
|
+
threadKey: z.string().min(1),
|
|
45
|
+
correlationId: z.string().min(1),
|
|
46
|
+
idempotencyKey: z.string().min(1).nullable(),
|
|
47
|
+
mode: InvocationModeSchema,
|
|
48
|
+
status: InvocationStatusSchema,
|
|
49
|
+
inputRef: z.string().min(1),
|
|
50
|
+
outputRef: z.string().min(1).nullable(),
|
|
51
|
+
decisions: z.array(InvocationDecisionSchema).readonly(),
|
|
52
|
+
costUsd: z.number().nullable(),
|
|
53
|
+
durationMs: z.number().nullable(),
|
|
54
|
+
modelRef: z.string().min(1).nullable(),
|
|
55
|
+
auditId: z.string().min(1).nullable(),
|
|
56
|
+
sessionId: z.string().min(1).nullable(),
|
|
57
|
+
createdAt: z.string().min(1),
|
|
58
|
+
lastActiveAt: z.string().min(1),
|
|
59
|
+
}) as z.ZodType<InvocationRecord>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The runtime's durable invocation lifecycle.
|
|
5
|
+
*
|
|
6
|
+
* DISTINCT from the capability gateway's allow/deny `InvocationStatus`: the
|
|
7
|
+
* funnel decides whether a call is allowed; THIS status tracks the execution
|
|
8
|
+
* lifecycle of an allowed invocation. Do not conflate the two.
|
|
9
|
+
*
|
|
10
|
+
* - `Pending` — record created, not yet scheduled.
|
|
11
|
+
* - `Queued` — accepted onto an async/event queue.
|
|
12
|
+
* - `Running` — the composition is executing.
|
|
13
|
+
* - `Succeeded` — terminal: produced a schema-valid output.
|
|
14
|
+
* - `Failed` — terminal: execution or output-schema validation failed.
|
|
15
|
+
* - `Denied` — terminal: refused (e.g. by policy/limits) before/at execution.
|
|
16
|
+
* - `TimedOut` — terminal: exceeded a hard duration limit.
|
|
17
|
+
* - `Cancelled` — terminal: cancelled by a caller/operator.
|
|
18
|
+
*
|
|
19
|
+
* Closed set — adding a state is a coordinated kernel change.
|
|
20
|
+
*/
|
|
21
|
+
export enum InvocationStatus {
|
|
22
|
+
Pending = 'pending',
|
|
23
|
+
Queued = 'queued',
|
|
24
|
+
Running = 'running',
|
|
25
|
+
Succeeded = 'succeeded',
|
|
26
|
+
Failed = 'failed',
|
|
27
|
+
Denied = 'denied',
|
|
28
|
+
TimedOut = 'timed-out',
|
|
29
|
+
Cancelled = 'cancelled',
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const InvocationStatusSchema = z.nativeEnum(InvocationStatus);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import {
|
|
3
|
+
ExecutionRequirements,
|
|
4
|
+
ExecutionRequirementsSchema,
|
|
5
|
+
} from './execution-requirements';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The wire body for `composition:invoke@1` — what a caller sends through the
|
|
9
|
+
* capability funnel to execute a published composition.
|
|
10
|
+
*
|
|
11
|
+
* `CompositionInvokeRequestSchema` is the fail-fast validator the runtime
|
|
12
|
+
* applies at the wire boundary before any execution.
|
|
13
|
+
*/
|
|
14
|
+
export interface CompositionInvokeRequest {
|
|
15
|
+
/** Composition slug or `slug@version`. */
|
|
16
|
+
readonly compositionRef: string;
|
|
17
|
+
readonly orgId: string;
|
|
18
|
+
readonly projectId?: string;
|
|
19
|
+
/** Stable execution-context key — org+mailbox+emailThreadId for mail. */
|
|
20
|
+
readonly threadKey: string;
|
|
21
|
+
readonly correlationId?: string;
|
|
22
|
+
readonly input: Record<string, unknown>;
|
|
23
|
+
readonly requirements: ExecutionRequirements;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const CompositionInvokeRequestSchema = z.object({
|
|
27
|
+
compositionRef: z.string().min(1),
|
|
28
|
+
orgId: z.string().min(1),
|
|
29
|
+
projectId: z.string().min(1).optional(),
|
|
30
|
+
threadKey: z.string().min(1),
|
|
31
|
+
correlationId: z.string().min(1).optional(),
|
|
32
|
+
input: z.record(z.string(), z.unknown()),
|
|
33
|
+
requirements: ExecutionRequirementsSchema,
|
|
34
|
+
}) as z.ZodType<CompositionInvokeRequest>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { InvocationMode, InvocationModeSchema } from './invocation-mode';
|
|
3
|
+
import { InvocationStatus, InvocationStatusSchema } from './invocation-status';
|
|
4
|
+
import {
|
|
5
|
+
InvocationDecision,
|
|
6
|
+
InvocationDecisionSchema,
|
|
7
|
+
} from './invocation-decision';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The response the runtime returns for a `composition:invoke@1` call.
|
|
11
|
+
*
|
|
12
|
+
* In `Sync` mode `output` carries the composition root structured output. In
|
|
13
|
+
* `Event` mode `output` is omitted and the consumer subscribes to the result
|
|
14
|
+
* completion event instead.
|
|
15
|
+
*/
|
|
16
|
+
export interface CompositionInvokeResponse {
|
|
17
|
+
readonly invocationId: string;
|
|
18
|
+
readonly status: InvocationStatus;
|
|
19
|
+
readonly mode: InvocationMode;
|
|
20
|
+
/** Sync: composition root structured output. Omitted in event mode. */
|
|
21
|
+
readonly output?: Record<string, unknown>;
|
|
22
|
+
readonly decisions?: readonly InvocationDecision[];
|
|
23
|
+
readonly costUsd?: number;
|
|
24
|
+
readonly durationMs?: number;
|
|
25
|
+
readonly modelRef?: string;
|
|
26
|
+
readonly auditId?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const CompositionInvokeResponseSchema = z.object({
|
|
30
|
+
invocationId: z.string().min(1),
|
|
31
|
+
status: InvocationStatusSchema,
|
|
32
|
+
mode: InvocationModeSchema,
|
|
33
|
+
output: z.record(z.string(), z.unknown()).optional(),
|
|
34
|
+
decisions: z.array(InvocationDecisionSchema).readonly().optional(),
|
|
35
|
+
costUsd: z.number().optional(),
|
|
36
|
+
durationMs: z.number().optional(),
|
|
37
|
+
modelRef: z.string().min(1).optional(),
|
|
38
|
+
auditId: z.string().min(1).optional(),
|
|
39
|
+
}) as z.ZodType<CompositionInvokeResponse>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Thread-context isolation an invocation requires.
|
|
5
|
+
*
|
|
6
|
+
* - `Strict` — a fresh, never-reused thread context per invocation. The
|
|
7
|
+
* default for mail (org+mailbox+emailThreadId): thread context is NEVER
|
|
8
|
+
* reused across unrelated emails.
|
|
9
|
+
* - `PooledThread` — reuse a warm thread within the same `threadKey` (a warm
|
|
10
|
+
* session-pool optimization; future, Phase 3).
|
|
11
|
+
*
|
|
12
|
+
* Closed set on purpose — both levels are honored by the runtime's pool/thread
|
|
13
|
+
* management; adding a level is a coordinated kernel change.
|
|
14
|
+
*/
|
|
15
|
+
export enum IsolationLevel {
|
|
16
|
+
Strict = 'strict',
|
|
17
|
+
PooledThread = 'pooled-thread',
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const IsolationLevelSchema = z.nativeEnum(IsolationLevel);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lib/mail-event';
|