@nifrajs/agent-protocol 3.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.
@@ -0,0 +1,278 @@
1
+ /**
2
+ * Orchestration value contracts: declarative run plans, content-free run evidence, artifact
3
+ * references, and the effect-key identity. Additive to the session protocol; carries no behavior,
4
+ * no runtime dependency, and - by construction - no payload content.
5
+ *
6
+ * The privacy invariant lives in the parsers here: {@link parseRunEvidence} and
7
+ * {@link parseArtifactRef} accept only the declared content-free keys and reject any record over
8
+ * {@link EVIDENCE_MAX_BYTES}. A prompt, model output, or tool payload cannot round-trip through
9
+ * these contracts. Raw payloads travel only through an {@link ArtifactPort} the caller owns.
10
+ */
11
+ /** Orchestration contract version. Additive to the session `AGENT_PROTOCOL_VERSION`. */
12
+ export const RUN_PLAN_VERSION = 1;
13
+ /** Hard cap on a single serialized evidence record. A content-free record never approaches this. */
14
+ export const EVIDENCE_MAX_BYTES = 4096;
15
+ /**
16
+ * Keys that would carry payload content. They are never valid on evidence or artifact records and
17
+ * are rejected by the strict parsers even if they would otherwise fit the size cap.
18
+ */
19
+ export const FORBIDDEN_CONTENT_KEYS = Object.freeze([
20
+ "prompt",
21
+ "text",
22
+ "input",
23
+ "output",
24
+ "report",
25
+ "message",
26
+ "payload",
27
+ "body",
28
+ "args",
29
+ "content",
30
+ "response",
31
+ "completion",
32
+ ]);
33
+ // ── Strict parsers ──────────────────────────────────────────────────────────────────────────────
34
+ /** Thrown by every parser in this module on malformed or content-bearing input. Fails closed. */
35
+ export class RunContractError extends Error {
36
+ reason;
37
+ constructor(reason) {
38
+ super(`orchestration contract: ${reason}`);
39
+ this.reason = reason;
40
+ this.name = "RunContractError";
41
+ }
42
+ }
43
+ function isRecord(value) {
44
+ return typeof value === "object" && value !== null && !Array.isArray(value);
45
+ }
46
+ function assertNoForbiddenKeys(record, where) {
47
+ for (const key of FORBIDDEN_CONTENT_KEYS) {
48
+ if (key in record)
49
+ throw new RunContractError(`${where} carries forbidden content key '${key}'`);
50
+ }
51
+ }
52
+ function assertOnlyKeys(record, allowed, where) {
53
+ for (const key of Object.keys(record)) {
54
+ if (!allowed.includes(key))
55
+ throw new RunContractError(`${where} has unknown key '${key}'`);
56
+ }
57
+ }
58
+ const HEX64 = /^[0-9a-f]{64}$/;
59
+ function str(record, key, where) {
60
+ const value = record[key];
61
+ if (typeof value !== "string" || value.length === 0)
62
+ throw new RunContractError(`${where}.${key} must be a non-empty string`);
63
+ return value;
64
+ }
65
+ function int(record, key, where) {
66
+ const value = record[key];
67
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)
68
+ throw new RunContractError(`${where}.${key} must be a non-negative integer`);
69
+ return value;
70
+ }
71
+ /** Parse a content-free artifact reference. Rejects any non-schema or content key. */
72
+ export function parseArtifactRef(value) {
73
+ if (!isRecord(value))
74
+ throw new RunContractError("artifact ref must be an object");
75
+ assertOnlyKeys(value, ["id", "digest", "bytes", "mediaType", "locator"], "artifact ref");
76
+ assertNoForbiddenKeys(value, "artifact ref");
77
+ const digest = str(value, "digest", "artifact ref");
78
+ if (!HEX64.test(digest))
79
+ throw new RunContractError("artifact ref.digest must be sha256 hex");
80
+ const ref = {
81
+ id: str(value, "id", "artifact ref"),
82
+ digest,
83
+ bytes: int(value, "bytes", "artifact ref"),
84
+ mediaType: str(value, "mediaType", "artifact ref"),
85
+ };
86
+ if (value.locator !== undefined) {
87
+ if (typeof value.locator !== "string")
88
+ throw new RunContractError("artifact ref.locator must be a string");
89
+ return { ...ref, locator: value.locator };
90
+ }
91
+ return ref;
92
+ }
93
+ const LEAF_KINDS = [
94
+ "task",
95
+ "verify",
96
+ "approve",
97
+ "checkpoint",
98
+ "handoff",
99
+ "subagent",
100
+ ];
101
+ const STRUCTURAL_KINDS = ["sequence", "parallel", "retry", "branch"];
102
+ function posInt(record, key, where) {
103
+ const value = record[key];
104
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1)
105
+ throw new RunContractError(`${where}.${key} must be a positive integer`);
106
+ return value;
107
+ }
108
+ function parseDependsOn(raw, where, allowDepends) {
109
+ if (raw.dependsOn === undefined)
110
+ return undefined;
111
+ if (!allowDepends)
112
+ throw new RunContractError(`${where} is nested and may not declare dependsOn`);
113
+ if (!Array.isArray(raw.dependsOn) || raw.dependsOn.some((d) => typeof d !== "string"))
114
+ throw new RunContractError(`${where}.dependsOn must be a string array`);
115
+ return [...raw.dependsOn];
116
+ }
117
+ function parseRetryPolicy(value, where) {
118
+ if (!isRecord(value))
119
+ throw new RunContractError(`${where}.retry must be an object`);
120
+ assertOnlyKeys(value, ["attempts", "backoffMs"], `${where}.retry`);
121
+ const attempts = posInt(value, "attempts", `${where}.retry`);
122
+ if (attempts > 16)
123
+ throw new RunContractError(`${where}.retry.attempts must be 1..16`);
124
+ if (value.backoffMs === undefined)
125
+ return { attempts };
126
+ return { attempts, backoffMs: int(value, "backoffMs", `${where}.retry`) };
127
+ }
128
+ /** Parse one node (recursively). `allowDepends` is true only for top-level nodes. */
129
+ function parseNode(raw, where, allowDepends, ids) {
130
+ if (!isRecord(raw))
131
+ throw new RunContractError(`${where} must be an object`);
132
+ const kind = raw.kind;
133
+ if (typeof kind !== "string")
134
+ throw new RunContractError(`${where}.kind must be a string`);
135
+ const isLeaf = LEAF_KINDS.includes(kind);
136
+ if (!isLeaf && !STRUCTURAL_KINDS.includes(kind))
137
+ throw new RunContractError(`${where}.kind '${kind}' is invalid`);
138
+ const allowed = kind === "sequence"
139
+ ? ["id", "kind", "children", "dependsOn"]
140
+ : kind === "parallel"
141
+ ? ["id", "kind", "children", "maxConcurrency", "dependsOn"]
142
+ : kind === "retry"
143
+ ? ["id", "kind", "child", "attempts", "backoffMs", "dependsOn"]
144
+ : kind === "branch"
145
+ ? ["id", "kind", "step", "then", "otherwise", "dependsOn"]
146
+ : ["id", "kind", "step", "dependsOn", "reason", "stepVersion", "retry"];
147
+ assertOnlyKeys(raw, allowed, where);
148
+ assertNoForbiddenKeys(raw, where);
149
+ const id = str(raw, "id", where);
150
+ if (ids.has(id))
151
+ throw new RunContractError(`duplicate node id '${id}'`);
152
+ ids.add(id);
153
+ const dependsOn = parseDependsOn(raw, where, allowDepends);
154
+ const withDeps = (node) => dependsOn === undefined ? node : { ...node, dependsOn };
155
+ if (isLeaf) {
156
+ const leaf = { id, kind: kind, step: str(raw, "step", where) };
157
+ let out = leaf;
158
+ if (raw.reason !== undefined) {
159
+ if (typeof raw.reason !== "string")
160
+ throw new RunContractError(`${where}.reason must be a string`);
161
+ out = { ...out, reason: raw.reason };
162
+ }
163
+ if (kind === "approve" && out.reason === undefined)
164
+ throw new RunContractError(`${where} of kind 'approve' requires a reason`);
165
+ if (raw.stepVersion !== undefined)
166
+ out = { ...out, stepVersion: posInt(raw, "stepVersion", where) };
167
+ if (raw.retry !== undefined)
168
+ out = { ...out, retry: parseRetryPolicy(raw.retry, where) };
169
+ return withDeps(out);
170
+ }
171
+ if (kind === "sequence" || kind === "parallel") {
172
+ if (!Array.isArray(raw.children) || raw.children.length === 0)
173
+ throw new RunContractError(`${where}.children must be a non-empty array`);
174
+ const children = raw.children.map((child, i) => parseNode(child, `${where}.children[${i}]`, false, ids));
175
+ if (kind === "sequence")
176
+ return withDeps({ id, kind, children });
177
+ const node = { id, kind, children };
178
+ return withDeps(raw.maxConcurrency === undefined
179
+ ? node
180
+ : { ...node, maxConcurrency: posInt(raw, "maxConcurrency", where) });
181
+ }
182
+ if (kind === "retry") {
183
+ const attempts = posInt(raw, "attempts", where);
184
+ if (attempts > 16)
185
+ throw new RunContractError(`${where}.attempts must be 1..16`);
186
+ const child = parseNode(raw.child, `${where}.child`, false, ids);
187
+ const node = { id, kind, child, attempts };
188
+ return withDeps(raw.backoffMs === undefined ? node : { ...node, backoffMs: int(raw, "backoffMs", where) });
189
+ }
190
+ // branch
191
+ const then = parseNode(raw.then, `${where}.then`, false, ids);
192
+ const node = { id, kind: "branch", step: str(raw, "step", where), then };
193
+ return withDeps(raw.otherwise === undefined
194
+ ? node
195
+ : { ...node, otherwise: parseNode(raw.otherwise, `${where}.otherwise`, false, ids) });
196
+ }
197
+ /** Parse a declarative run plan. Rejects closures, unknown keys, and structural errors. */
198
+ export function parseRunPlan(value) {
199
+ if (!isRecord(value))
200
+ throw new RunContractError("run plan must be an object");
201
+ assertOnlyKeys(value, ["version", "id", "nodes"], "run plan");
202
+ if (value.version !== RUN_PLAN_VERSION)
203
+ throw new RunContractError(`run plan.version must be ${RUN_PLAN_VERSION}`);
204
+ if (!Array.isArray(value.nodes) || value.nodes.length === 0)
205
+ throw new RunContractError("run plan.nodes must be a non-empty array");
206
+ const ids = new Set();
207
+ const nodes = value.nodes.map((raw, index) => parseNode(raw, `node[${index}]`, true, ids));
208
+ const topLevel = new Set(nodes.map((node) => node.id));
209
+ for (const node of nodes) {
210
+ for (const dep of node.dependsOn ?? []) {
211
+ if (dep === node.id)
212
+ throw new RunContractError(`node '${node.id}' depends on itself`);
213
+ if (!topLevel.has(dep))
214
+ throw new RunContractError(`node '${node.id}' depends on unknown '${dep}'`);
215
+ }
216
+ }
217
+ return { version: RUN_PLAN_VERSION, id: str(value, "id", "run plan"), nodes };
218
+ }
219
+ /** Parse a content-free evidence record. Rejects content keys and any record over the size cap. */
220
+ export function parseRunEvidence(value) {
221
+ if (!isRecord(value))
222
+ throw new RunContractError("evidence must be an object");
223
+ assertOnlyKeys(value, [
224
+ "version",
225
+ "runId",
226
+ "planDigest",
227
+ "nodeId",
228
+ "status",
229
+ "seq",
230
+ "effectKey",
231
+ "idempotent",
232
+ "artifacts",
233
+ "errorCode",
234
+ "durationMs",
235
+ ], "evidence");
236
+ assertNoForbiddenKeys(value, "evidence");
237
+ if (value.version !== RUN_PLAN_VERSION)
238
+ throw new RunContractError(`evidence.version must be ${RUN_PLAN_VERSION}`);
239
+ const status = value.status;
240
+ if (status !== "started" && status !== "completed" && status !== "failed")
241
+ throw new RunContractError("evidence.status is invalid");
242
+ if (typeof value.idempotent !== "boolean")
243
+ throw new RunContractError("evidence.idempotent must be a boolean");
244
+ const evidence = {
245
+ version: RUN_PLAN_VERSION,
246
+ runId: str(value, "runId", "evidence"),
247
+ planDigest: str(value, "planDigest", "evidence"),
248
+ nodeId: str(value, "nodeId", "evidence"),
249
+ status,
250
+ seq: int(value, "seq", "evidence"),
251
+ idempotent: value.idempotent,
252
+ ...(value.effectKey !== undefined
253
+ ? { effectKey: parseDigest(value.effectKey, "effectKey") }
254
+ : {}),
255
+ ...(value.errorCode !== undefined ? { errorCode: str(value, "errorCode", "evidence") } : {}),
256
+ ...(value.durationMs !== undefined ? { durationMs: int(value, "durationMs", "evidence") } : {}),
257
+ ...(value.artifacts !== undefined ? { artifacts: parseArtifacts(value.artifacts) } : {}),
258
+ };
259
+ assertEvidenceSize(evidence);
260
+ return evidence;
261
+ }
262
+ function parseDigest(value, field) {
263
+ if (typeof value !== "string" || !HEX64.test(value))
264
+ throw new RunContractError(`evidence.${field} must be sha256 hex`);
265
+ return value;
266
+ }
267
+ function parseArtifacts(value) {
268
+ if (!Array.isArray(value))
269
+ throw new RunContractError("evidence.artifacts must be an array");
270
+ return value.map(parseArtifactRef);
271
+ }
272
+ /** Assert a record serializes within the hard cap. Public reference records are content-free. */
273
+ export function assertEvidenceSize(evidence) {
274
+ const bytes = new TextEncoder().encode(JSON.stringify(evidence)).length;
275
+ if (bytes > EVIDENCE_MAX_BYTES)
276
+ throw new RunContractError(`evidence record ${bytes}B exceeds ${EVIDENCE_MAX_BYTES}B cap`);
277
+ }
278
+ //# sourceMappingURL=orchestration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestration.js","sourceRoot":"","sources":["../src/orchestration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Additive run-lifecycle contracts: content-free run snapshots, evidence-event envelopes, handoff
3
+ * snapshots, feature negotiation, and cursor resume. These layer on top of the orchestration value
4
+ * contracts without changing `AGENT_PROTOCOL_VERSION`, and - like the evidence contract - carry no
5
+ * payload content.
6
+ *
7
+ * Two decoder disciplines live here on purpose:
8
+ * - Transport decoders ({@link parseRunSnapshot}, {@link parseHandoffSnapshot},
9
+ * {@link parseRunPlanRef}, and the envelope of {@link parseRunEvidenceEvent}) are lenient about
10
+ * unknown additive fields so a newer host can add optional metadata without breaking an older
11
+ * client. They still reject any {@link FORBIDDEN_CONTENT_KEYS} so a payload can never ride along.
12
+ * - The evidence sink stays strict: the inner record of a {@link RunEvidenceEvent} is validated by
13
+ * {@link parseRunEvidence}, which accepts only the declared content-free keys.
14
+ */
15
+ import { type RunEvidence } from "./orchestration.js";
16
+ /** Run-lifecycle contract version. Additive to the session `AGENT_PROTOCOL_VERSION`. */
17
+ export declare const RUN_LIFECYCLE_VERSION: 1;
18
+ /** Terminal-or-transient state of a run as observed through evidence. */
19
+ export type RunLifecycleState = "submitted" | "running" | "paused" | "succeeded" | "failed" | "cancelled";
20
+ /** Handoff resolution state, surfaced content-free. */
21
+ export type HandoffStatus = "pending" | "accepted" | "declined";
22
+ /** A content-free pointer to the plan a run is executing. */
23
+ export interface RunPlanRef {
24
+ readonly id: string;
25
+ /** SHA-256 hex of the canonical plan. Content-free. */
26
+ readonly digest: string;
27
+ readonly nodeCount: number;
28
+ }
29
+ /** Running tallies over a run's evidence stream. */
30
+ export interface RunCounters {
31
+ readonly total: number;
32
+ readonly completed: number;
33
+ readonly failed: number;
34
+ }
35
+ /**
36
+ * The bounded current view of a run: its plan pointer, lifecycle state, resume cursor, and counters.
37
+ * `cursor` is the highest evidence `seq` reflected here; a client resumes with everything after it.
38
+ */
39
+ export interface RunSnapshot {
40
+ readonly version: typeof RUN_LIFECYCLE_VERSION;
41
+ readonly runId: string;
42
+ readonly plan: RunPlanRef;
43
+ readonly state: RunLifecycleState;
44
+ /** Highest evidence seq reflected in this snapshot, or -1 before any evidence. */
45
+ readonly cursor: number;
46
+ readonly counters: RunCounters;
47
+ readonly updatedAt: number;
48
+ readonly failureCode?: string;
49
+ }
50
+ /** A content-free pointer to one evidence record, with the stable dedupe identity. */
51
+ export interface EvidenceRef {
52
+ readonly runId: string;
53
+ readonly seq: number;
54
+ /** Stable per-record identity: `${runId}:${seq}`. */
55
+ readonly eventId: string;
56
+ }
57
+ /** A transport envelope wrapping one strict evidence record with its stable dedupe identity. */
58
+ export interface RunEvidenceEvent {
59
+ readonly version: typeof RUN_LIFECYCLE_VERSION;
60
+ /** Stable per-record identity: `${runId}:${seq}` of the inner evidence. */
61
+ readonly eventId: string;
62
+ readonly evidence: RunEvidence;
63
+ }
64
+ /** A content-free snapshot of one handoff between roles/agents within a run. */
65
+ export interface HandoffSnapshot {
66
+ readonly version: typeof RUN_LIFECYCLE_VERSION;
67
+ readonly runId: string;
68
+ readonly nodeId: string;
69
+ readonly seq: number;
70
+ /** Caller-opaque role identifiers. Non-secret structural coordinates. */
71
+ readonly from: string;
72
+ readonly to: string;
73
+ readonly status: HandoffStatus;
74
+ readonly reason?: string;
75
+ }
76
+ /** The stable dedupe identity for an evidence record. */
77
+ export declare function evidenceEventId(runId: string, seq: number): string;
78
+ /** The result of reconciling a client's requested features against a host's offered set. */
79
+ export interface FeatureNegotiation {
80
+ /** Requested features the host offers, sorted and de-duplicated. */
81
+ readonly granted: readonly string[];
82
+ /** Requested features the host does not offer, sorted and de-duplicated. */
83
+ readonly unsupported: readonly string[];
84
+ }
85
+ /**
86
+ * Reconcile requested features against the offered set. A requested feature the host does not offer
87
+ * is reported as unsupported rather than silently dropped, so a client can degrade deliberately.
88
+ */
89
+ export declare function negotiateFeatures(offered: readonly string[], requested: readonly string[]): FeatureNegotiation;
90
+ export type CursorResyncReason = "stale_cursor";
91
+ /** Events after the cursor were retained; deliver them and advance. */
92
+ export interface CursorResumeOk<T> {
93
+ readonly status: "ok";
94
+ readonly events: readonly T[];
95
+ /** Highest seq now delivered, or the input cursor when nothing followed it. */
96
+ readonly nextCursor: number;
97
+ }
98
+ /** The bounded window no longer contains the record after the cursor; a full resync is required. */
99
+ export interface CursorResyncRequired {
100
+ readonly status: "resync_required";
101
+ readonly reason: CursorResyncReason;
102
+ readonly earliest: number;
103
+ readonly latest: number;
104
+ }
105
+ export type CursorResume<T> = CursorResumeOk<T> | CursorResyncRequired;
106
+ /** Sentinel cursor meaning "before any record". A fresh subscription passes this or `undefined`. */
107
+ export declare const CURSOR_BEFORE_ALL = -1;
108
+ /**
109
+ * Resume an ordered, seq-keyed window from a cursor.
110
+ *
111
+ * The window must be sorted by ascending, strictly increasing `seq`. `cursor` is the last seq the
112
+ * client already holds; `undefined` (or {@link CURSOR_BEFORE_ALL}) means the client holds nothing.
113
+ * If the record immediately after the cursor was already evicted from the bounded window, a gap
114
+ * exists and this returns `resync_required` with reason `stale_cursor` rather than silently skipping.
115
+ */
116
+ export declare function resumeFromCursor<T extends {
117
+ readonly seq: number;
118
+ }>(window: readonly T[], cursor?: number): CursorResume<T>;
119
+ /** Decode a content-free plan reference. Lenient about unknown additive keys, never content. */
120
+ export declare function parseRunPlanRef(value: unknown): RunPlanRef;
121
+ /**
122
+ * Decode a bounded run snapshot. Forward-compatible: unknown additive fields are ignored so an
123
+ * older client tolerates a newer host. Forbidden content keys are still rejected.
124
+ */
125
+ export declare function parseRunSnapshot(value: unknown): RunSnapshot;
126
+ /**
127
+ * Decode an evidence-event envelope. The envelope is forward-compatible, but the inner record is
128
+ * validated strictly by {@link parseRunEvidence}, and its identity must match `${runId}:${seq}`.
129
+ */
130
+ export declare function parseRunEvidenceEvent(value: unknown): RunEvidenceEvent;
131
+ /**
132
+ * Decode a handoff snapshot. Forward-compatible about unknown additive fields; forbidden content
133
+ * keys are rejected.
134
+ */
135
+ export declare function parseHandoffSnapshot(value: unknown): HandoffSnapshot;
136
+ /** The two boundary families a host pauses on. */
137
+ export type BoundaryKind = "approval" | "handoff";
138
+ /** Approval lifecycle. Terminal states accept no further transition. */
139
+ export type ApprovalLifecycleState = "pending" | "approved" | "denied" | "expired" | "cancelled";
140
+ /** Handoff lifecycle. `assigned` is the only non-pending live state; the rest are terminal. */
141
+ export type HandoffLifecycleState = "pending" | "assigned" | "accepted" | "declined" | "resolved" | "expired" | "cancelled";
142
+ /** The operations that drive a boundary. Not every op is legal from every state. */
143
+ export type BoundaryOp = "approve" | "deny" | "assign" | "accept" | "decline" | "resolve" | "expire" | "cancel";
144
+ /**
145
+ * The negotiated command surface for the inbox: a superset of {@link BoundaryOp} plus the read verbs
146
+ * `list` and `inspect`. A host advertises the subset it supports; a client drives only the granted
147
+ * commands. Order here is the canonical advertisement order.
148
+ */
149
+ export declare const BOUNDARY_COMMANDS: readonly ["list", "inspect", "approve", "deny", "assign", "resolve", "expire", "cancel"];
150
+ export type BoundaryCommand = (typeof BOUNDARY_COMMANDS)[number];
151
+ /** Stable, content-free reasons a boundary decision is refused. */
152
+ export type BoundaryRejection = "unknown_boundary" | "identity_mismatch" | "stale_vector" | "expired" | "illegal_transition";
153
+ /**
154
+ * The content-free identity of one decision boundary. `vector` is the run's monotonic child index at
155
+ * which the boundary opened; a decision must carry the boundary's exact vector, so a replayed or
156
+ * superseded decision (a lower or mismatched vector) is refused. `expiresAt` is an absolute epoch-ms
157
+ * deadline. No field carries a prompt, a reason-as-free-text, or a payload.
158
+ */
159
+ export interface DecisionCoordinate {
160
+ readonly runId: string;
161
+ readonly nodeId: string;
162
+ readonly capability: string;
163
+ readonly requestId: string;
164
+ readonly vector: number;
165
+ readonly expiresAt: number;
166
+ }
167
+ /** True when both coordinates address the same boundary at the same child vector. */
168
+ export declare function coordinatesMatch(a: DecisionCoordinate, b: DecisionCoordinate): boolean;
169
+ /** True while `now` is strictly before the coordinate's expiry. At or past expiry fails closed. */
170
+ export declare function coordinateIsFresh(coordinate: DecisionCoordinate, now: number): boolean;
171
+ /**
172
+ * Monotonic child-vector check: a newly opened boundary must advance strictly past the run's last
173
+ * allocated vector. A non-advancing vector is a replay and is refused. `last` is `-1` before any
174
+ * boundary has opened for the run.
175
+ */
176
+ export declare function vectorAdvances(last: number, next: number): boolean;
177
+ /** The next approval state for an op, or `undefined` when the transition is illegal. */
178
+ export declare function nextApprovalState(from: ApprovalLifecycleState, op: BoundaryOp): ApprovalLifecycleState | undefined;
179
+ /** The next handoff state for an op, or `undefined` when the transition is illegal. */
180
+ export declare function nextHandoffState(from: HandoffLifecycleState, op: BoundaryOp): HandoffLifecycleState | undefined;
181
+ /** True once a boundary state accepts no further op. */
182
+ export declare function isTerminalApprovalState(state: ApprovalLifecycleState): boolean;
183
+ /** True once a handoff state accepts no further op. */
184
+ export declare function isTerminalHandoffState(state: HandoffLifecycleState): boolean;
185
+ /**
186
+ * Decode a decision coordinate. Content-free: forbidden payload keys are rejected, and only the
187
+ * declared structural fields are read. `vector` and `expiresAt` must be non-negative safe integers.
188
+ */
189
+ export declare function parseDecisionCoordinate(value: unknown): DecisionCoordinate;
190
+ //# sourceMappingURL=run-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-lifecycle.d.ts","sourceRoot":"","sources":["../src/run-lifecycle.ts"],"names":[],"mappings":"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"}