@tangle-network/agent-interface 1.2.0 → 1.4.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/README.md CHANGED
@@ -33,9 +33,15 @@ The public `AgentInstanceRecord` contains a credential-free profile identity, no
33
33
 
34
34
  `AgentRunControlRef` identifies a retained run without depending on a live JavaScript object and may carry the provider's admission digest so reconstruction can reject changed-input reuse.
35
35
  `RuntimeEventEnvelope` adds stable run, event, sequence, cursor, and timestamp fields around the existing `StreamEvent` union, and its runtime schema validates every canonical event variant.
36
+ The `child-task` event reports one update of a provider-native child task (a subagent, worker, or delegated task) with a stable `childId`, an optional `parentChildId`, a lifecycle status, start and update times, and the runner, model, usage, and terminal reason when the provider reports them.
37
+ Its `sourceEventId` identifies the exact update, so a consumer applies the first event with a given `sourceEventId` and ignores later copies during replay or reconnect.
38
+ Identity never depends on the bounded `raw` payload, and a provider that cannot report a stable `childId` emits no `child-task` event.
36
39
  The canonical `cancelled` status identifies caller cancellation and remains distinct from `failed`.
37
40
  Providers advertise `retainedControl` only when exact run, result, event, cancellation, replay, detach, turn, and session identity are all implemented together.
38
41
  `AgentEnvironment.metadata` is the detached snapshot returned by create or get, so recovery can check persisted annotations without listing environments.
42
+ `AgentEnvironment.creation` reports what the create call that returned the object did: `created` when the call provisioned the environment, `replayed` when an existing environment matched the idempotency key.
43
+ It is a per-call fact, so a same-key replay returns a view of the same environment with `creation: "replayed"`, and the value is absent when the provider cannot prove either outcome.
44
+ A consumer never destroys an environment whose creation it cannot prove, because another caller can hold it.
39
45
  Metadata can include caller-authored values and does not prove authorization or authorship.
40
46
  `AgentSession.cancelRun()` accepts a canonical request digest bound to one operation and `AgentExactRunControlRef`, so a caller can safely repeat the same cancellation after losing the first acknowledgement.
41
47
  Its acknowledgement repeats the operation, digest, and run coordinates and distinguishes a known cancellation effect from conflict or unknown state.
@@ -0,0 +1,308 @@
1
+ import { z } from "zod";
2
+ import type { Sha256Digest } from "./agent-candidate.js";
3
+ import { type ReasoningEffort } from "./agent-profile.js";
4
+ import { type AgentProfileMaterializationAxis } from "./agent-profile-materialization.js";
5
+ import { type HarnessType } from "./harness.js";
6
+ import { type AgentWorkspaceSourceSnapshotPolicy } from "./agent-workspace-source-snapshot.js";
7
+ export type AgentExecutionPreparationDisposition = "behavior" | "control" | "overridden" | "unsupported";
8
+ export type AgentExecutionPreparationOwner = "runtime" | "executor";
9
+ /** One exact profile path and how the prepared execution will handle it. */
10
+ export interface AgentExecutionPreparationAxisResult {
11
+ axis: AgentProfileMaterializationAxis;
12
+ disposition: AgentExecutionPreparationDisposition;
13
+ owner: AgentExecutionPreparationOwner;
14
+ /** Public mechanism identifier; launch arguments are structurally refused. */
15
+ mechanism: string;
16
+ evidenceDigest?: Sha256Digest;
17
+ /** RFC 6901 JSON Pointer. Required when one axis has multiple requested paths. */
18
+ path?: string;
19
+ /**
20
+ * Sanitized public diagnostic prose for an override or unsupported path.
21
+ * The schema refuses recognized credential formats, but cannot identify
22
+ * arbitrary secret strings; producers remain responsible for redaction.
23
+ */
24
+ reason?: string;
25
+ }
26
+ export interface AgentExecutionPreparationReasoningEffort {
27
+ requested: ReasoningEffort;
28
+ resolved?: ReasoningEffort;
29
+ fidelity: "exact" | "clamped" | "unsupported";
30
+ }
31
+ export interface AgentExecutionPreparationResolvedModel {
32
+ /** Exact effective profile request; an explicit empty hint remains empty. */
33
+ requested: string;
34
+ /** Concrete non-empty model selected for execution. */
35
+ resolved: string;
36
+ /** Exact effective provider hint when present, including an explicit empty hint. */
37
+ provider?: string;
38
+ reasoningEffort?: AgentExecutionPreparationReasoningEffort;
39
+ }
40
+ export interface AgentExecutionPreparationWorkspace {
41
+ /** Public, non-secret lifecycle identity for the workspace lease. */
42
+ leaseId: string;
43
+ /** Provider that owns the private prepared workspace capability. */
44
+ provider: string;
45
+ /**
46
+ * Digest of the immutable allocation tuple (provider, lease/allocation id,
47
+ * and canonical root). This binds `leaseId` to its allocation; it is not a
48
+ * filesystem-content digest.
49
+ */
50
+ identityDigest: Sha256Digest;
51
+ isolation: "per-run" | "shared";
52
+ /** Canonical source snapshot before the isolated copy is prepared. */
53
+ sourceSnapshotDigest: Sha256Digest;
54
+ /** Public identity of the provider's exact snapshot/canonicalization policy. */
55
+ sourceSnapshotPolicy: AgentWorkspaceSourceSnapshotPolicy;
56
+ /** Canonical actual workspace after profile activation and before compute. */
57
+ preparedWorkspaceDigest: Sha256Digest;
58
+ profileActivationDigest: Sha256Digest;
59
+ }
60
+ export interface AgentExecutionPreparationMaterializer {
61
+ name: string;
62
+ version: string;
63
+ }
64
+ /**
65
+ * Executor acknowledgement emitted after all launch decisions are fixed and
66
+ * before any agent compute begins.
67
+ *
68
+ * `executionPlanDigest` is required to hash only public launch decisions plus
69
+ * caller-declared public secret-slot/reference identities. Secret values belong
70
+ * solely in the private prepared-executor closure/capability; hashing them here
71
+ * would leak equality and permit guessing low-entropy credentials. This receipt
72
+ * proves public plan identity, not possession of that private capability.
73
+ * Secret-capable MCP/hook slots structurally accept only tagged public values or
74
+ * opaque references. Other authored profile text and reference keys remain
75
+ * caller-declared public data; recognizable-pattern refusal is defense in depth,
76
+ * not proof that arbitrary text is non-secret.
77
+ */
78
+ export interface AgentExecutionPreparationReceipt {
79
+ kind: "agent-execution-preparation";
80
+ schemaVersion: 1;
81
+ preparationId: string;
82
+ requestDigest: Sha256Digest;
83
+ /** Canonical identity before executor overrides. */
84
+ authoredProfileDigest: Sha256Digest;
85
+ /** Canonical identity after executor overrides. */
86
+ effectiveProfileDigest: Sha256Digest;
87
+ backend: string;
88
+ harness: HarnessType;
89
+ harnessVersion: string;
90
+ resolvedModel: AgentExecutionPreparationResolvedModel;
91
+ workspace: AgentExecutionPreparationWorkspace;
92
+ axisResults: AgentExecutionPreparationAxisResult[];
93
+ /** Caller-supplied digest of public decisions and secret-reference identities. */
94
+ executionPlanDigest: Sha256Digest;
95
+ materializer: AgentExecutionPreparationMaterializer;
96
+ expiresAtMs: number;
97
+ digest: Sha256Digest;
98
+ }
99
+ export declare const agentExecutionPreparationAxisResultSchema: z.ZodObject<{
100
+ axis: z.ZodEnum<{
101
+ name: "name";
102
+ systemPrompt: "systemPrompt";
103
+ appendSystemPrompt: "appendSystemPrompt";
104
+ instructions: "instructions";
105
+ files: "files";
106
+ tools: "tools";
107
+ skills: "skills";
108
+ commands: "commands";
109
+ description: "description";
110
+ version: "version";
111
+ tags: "tags";
112
+ harness: "harness";
113
+ permissions: "permissions";
114
+ mcp: "mcp";
115
+ connections: "connections";
116
+ subagents: "subagents";
117
+ hooks: "hooks";
118
+ modes: "modes";
119
+ confidential: "confidential";
120
+ metadata: "metadata";
121
+ extensions: "extensions";
122
+ modelDefault: "modelDefault";
123
+ modelSmall: "modelSmall";
124
+ modelProvider: "modelProvider";
125
+ modelReasoningEffort: "modelReasoningEffort";
126
+ modelMetadata: "modelMetadata";
127
+ resourceTools: "resourceTools";
128
+ resourceAgents: "resourceAgents";
129
+ resourceInstructions: "resourceInstructions";
130
+ resourceFailOnError: "resourceFailOnError";
131
+ }>;
132
+ disposition: z.ZodEnum<{
133
+ unsupported: "unsupported";
134
+ behavior: "behavior";
135
+ control: "control";
136
+ overridden: "overridden";
137
+ }>;
138
+ owner: z.ZodEnum<{
139
+ runtime: "runtime";
140
+ executor: "executor";
141
+ }>;
142
+ mechanism: z.ZodString;
143
+ evidenceDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
144
+ path: z.ZodOptional<z.ZodString>;
145
+ reason: z.ZodOptional<z.ZodString>;
146
+ }, z.core.$strict>;
147
+ export declare const agentExecutionPreparationReasoningEffortSchema: z.ZodObject<{
148
+ requested: z.ZodEnum<{
149
+ none: "none";
150
+ minimal: "minimal";
151
+ low: "low";
152
+ medium: "medium";
153
+ high: "high";
154
+ xhigh: "xhigh";
155
+ ultracode: "ultracode";
156
+ }>;
157
+ resolved: z.ZodOptional<z.ZodEnum<{
158
+ none: "none";
159
+ minimal: "minimal";
160
+ low: "low";
161
+ medium: "medium";
162
+ high: "high";
163
+ xhigh: "xhigh";
164
+ ultracode: "ultracode";
165
+ }>>;
166
+ fidelity: z.ZodEnum<{
167
+ exact: "exact";
168
+ unsupported: "unsupported";
169
+ clamped: "clamped";
170
+ }>;
171
+ }, z.core.$strict>;
172
+ export declare const agentExecutionPreparationReceiptSchema: z.ZodObject<{
173
+ kind: z.ZodLiteral<"agent-execution-preparation">;
174
+ schemaVersion: z.ZodLiteral<1>;
175
+ preparationId: z.ZodString;
176
+ requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
177
+ authoredProfileDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
178
+ effectiveProfileDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
179
+ backend: z.ZodString;
180
+ harness: z.ZodEnum<{
181
+ "claude-code": "claude-code";
182
+ nanoclaw: "nanoclaw";
183
+ codex: "codex";
184
+ opencode: "opencode";
185
+ "kimi-code": "kimi-code";
186
+ pi: "pi";
187
+ prime: "prime";
188
+ gemini: "gemini";
189
+ hermes: "hermes";
190
+ openclaw: "openclaw";
191
+ amp: "amp";
192
+ "factory-droids": "factory-droids";
193
+ forge: "forge";
194
+ cursor: "cursor";
195
+ acp: "acp";
196
+ "cli-base": "cli-base";
197
+ }>;
198
+ harnessVersion: z.ZodString;
199
+ resolvedModel: z.ZodObject<{
200
+ requested: z.ZodString;
201
+ resolved: z.ZodString;
202
+ provider: z.ZodOptional<z.ZodString>;
203
+ reasoningEffort: z.ZodOptional<z.ZodObject<{
204
+ requested: z.ZodEnum<{
205
+ none: "none";
206
+ minimal: "minimal";
207
+ low: "low";
208
+ medium: "medium";
209
+ high: "high";
210
+ xhigh: "xhigh";
211
+ ultracode: "ultracode";
212
+ }>;
213
+ resolved: z.ZodOptional<z.ZodEnum<{
214
+ none: "none";
215
+ minimal: "minimal";
216
+ low: "low";
217
+ medium: "medium";
218
+ high: "high";
219
+ xhigh: "xhigh";
220
+ ultracode: "ultracode";
221
+ }>>;
222
+ fidelity: z.ZodEnum<{
223
+ exact: "exact";
224
+ unsupported: "unsupported";
225
+ clamped: "clamped";
226
+ }>;
227
+ }, z.core.$strict>>;
228
+ }, z.core.$strict>;
229
+ workspace: z.ZodObject<{
230
+ leaseId: z.ZodString;
231
+ provider: z.ZodString;
232
+ identityDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
233
+ isolation: z.ZodEnum<{
234
+ "per-run": "per-run";
235
+ shared: "shared";
236
+ }>;
237
+ sourceSnapshotDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
238
+ sourceSnapshotPolicy: z.ZodObject<{
239
+ kind: z.ZodLiteral<"provider-declared">;
240
+ name: z.ZodString;
241
+ version: z.ZodNumber;
242
+ digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
243
+ }, z.core.$strict>;
244
+ preparedWorkspaceDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
245
+ profileActivationDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
246
+ }, z.core.$strict>;
247
+ axisResults: z.ZodArray<z.ZodObject<{
248
+ axis: z.ZodEnum<{
249
+ name: "name";
250
+ systemPrompt: "systemPrompt";
251
+ appendSystemPrompt: "appendSystemPrompt";
252
+ instructions: "instructions";
253
+ files: "files";
254
+ tools: "tools";
255
+ skills: "skills";
256
+ commands: "commands";
257
+ description: "description";
258
+ version: "version";
259
+ tags: "tags";
260
+ harness: "harness";
261
+ permissions: "permissions";
262
+ mcp: "mcp";
263
+ connections: "connections";
264
+ subagents: "subagents";
265
+ hooks: "hooks";
266
+ modes: "modes";
267
+ confidential: "confidential";
268
+ metadata: "metadata";
269
+ extensions: "extensions";
270
+ modelDefault: "modelDefault";
271
+ modelSmall: "modelSmall";
272
+ modelProvider: "modelProvider";
273
+ modelReasoningEffort: "modelReasoningEffort";
274
+ modelMetadata: "modelMetadata";
275
+ resourceTools: "resourceTools";
276
+ resourceAgents: "resourceAgents";
277
+ resourceInstructions: "resourceInstructions";
278
+ resourceFailOnError: "resourceFailOnError";
279
+ }>;
280
+ disposition: z.ZodEnum<{
281
+ unsupported: "unsupported";
282
+ behavior: "behavior";
283
+ control: "control";
284
+ overridden: "overridden";
285
+ }>;
286
+ owner: z.ZodEnum<{
287
+ runtime: "runtime";
288
+ executor: "executor";
289
+ }>;
290
+ mechanism: z.ZodString;
291
+ evidenceDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
292
+ path: z.ZodOptional<z.ZodString>;
293
+ reason: z.ZodOptional<z.ZodString>;
294
+ }, z.core.$strict>>;
295
+ executionPlanDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
296
+ materializer: z.ZodObject<{
297
+ name: z.ZodString;
298
+ version: z.ZodString;
299
+ }, z.core.$strict>;
300
+ expiresAtMs: z.ZodNumber;
301
+ digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
302
+ }, z.core.$strict>;
303
+ /** @internal Canonical identity for one preparation axis and path. */
304
+ export declare function agentExecutionPreparationAxisResultKey(axis: AgentProfileMaterializationAxis, path: string | undefined): string;
305
+ /** @internal Exact public equality for preparation axis rows. */
306
+ export declare function agentExecutionPreparationAxisResultsEqual(left: AgentExecutionPreparationAxisResult, right: AgentExecutionPreparationAxisResult): boolean;
307
+ /** @internal Canonical order for preparation axis rows. */
308
+ export declare function compareAgentExecutionPreparationAxisResults(left: AgentExecutionPreparationAxisResult, right: AgentExecutionPreparationAxisResult): number;
@@ -0,0 +1,217 @@
1
+ import { z } from "zod";
2
+ import { canonicalCandidateDigest, canonicalCandidateJson, isCanonicalJsonValue, isWellFormedUnicode, looksLikeCredential, omitTopLevelDigest, sha256DigestSchema, } from "./agent-candidate-schema-common.js";
3
+ import { REASONING_EFFORTS } from "./agent-profile.js";
4
+ import { AGENT_PROFILE_MATERIALIZATION_AXES, } from "./agent-profile-materialization.js";
5
+ import { harnessTypeSchema } from "./harness.js";
6
+ import { agentWorkspaceSourceSnapshotPolicySchema, } from "./agent-workspace-source-snapshot.js";
7
+ const nonBlankStringSchema = z
8
+ .string()
9
+ .refine((value) => value.trim().length > 0, "value cannot be blank");
10
+ const publicMechanismIdentifierSchema = z
11
+ .string()
12
+ .regex(/^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$/, "mechanism must be a public identifier, not launch arguments")
13
+ .refine((value) => !looksLikeCredential(value), "mechanism cannot carry credential-like material");
14
+ const publicLifecycleIdentifierSchema = z
15
+ .string()
16
+ .regex(/^[A-Za-z0-9][A-Za-z0-9._~:/+-]{0,499}$/, "lifecycle identity must be a public identifier")
17
+ .refine((value) => !looksLikeCredential(value), "lifecycle identity cannot carry credential-like material");
18
+ const publicReasonSchema = nonBlankStringSchema
19
+ .max(4_000)
20
+ .refine((value) => !looksLikeCredential(value), "reason cannot carry credential-like material");
21
+ const jsonPointerSchema = z
22
+ .string()
23
+ .refine(isCanonicalJsonPointer, "path must be a canonical RFC 6901 JSON Pointer");
24
+ export const agentExecutionPreparationAxisResultSchema = z
25
+ .strictObject({
26
+ axis: z.enum(AGENT_PROFILE_MATERIALIZATION_AXES),
27
+ disposition: z.enum(["behavior", "control", "overridden", "unsupported"]),
28
+ owner: z.enum(["runtime", "executor"]),
29
+ mechanism: publicMechanismIdentifierSchema,
30
+ evidenceDigest: sha256DigestSchema.optional(),
31
+ path: jsonPointerSchema.optional(),
32
+ reason: publicReasonSchema.optional(),
33
+ })
34
+ .superRefine((result, context) => {
35
+ const requiresReason = result.disposition === "overridden" ||
36
+ result.disposition === "unsupported";
37
+ if (requiresReason && result.reason === undefined) {
38
+ context.addIssue({
39
+ code: "custom",
40
+ path: ["reason"],
41
+ message: `${result.disposition} profile coverage requires a reason`,
42
+ });
43
+ }
44
+ if (!requiresReason && result.reason !== undefined) {
45
+ context.addIssue({
46
+ code: "custom",
47
+ path: ["reason"],
48
+ message: `${result.disposition} profile coverage cannot carry an override reason`,
49
+ });
50
+ }
51
+ });
52
+ const reasoningEffortSchema = z.enum(REASONING_EFFORTS);
53
+ export const agentExecutionPreparationReasoningEffortSchema = z
54
+ .strictObject({
55
+ requested: reasoningEffortSchema,
56
+ resolved: reasoningEffortSchema.optional(),
57
+ fidelity: z.enum(["exact", "clamped", "unsupported"]),
58
+ })
59
+ .superRefine((effort, context) => {
60
+ if (effort.fidelity === "unsupported") {
61
+ if (effort.resolved !== undefined) {
62
+ context.addIssue({
63
+ code: "custom",
64
+ path: ["resolved"],
65
+ message: "unsupported reasoning effort cannot claim a resolved value",
66
+ });
67
+ }
68
+ return;
69
+ }
70
+ if (effort.resolved === undefined) {
71
+ context.addIssue({
72
+ code: "custom",
73
+ path: ["resolved"],
74
+ message: `${effort.fidelity} reasoning fidelity requires a resolved value`,
75
+ });
76
+ return;
77
+ }
78
+ if (effort.fidelity === "exact" && effort.resolved !== effort.requested) {
79
+ context.addIssue({
80
+ code: "custom",
81
+ path: ["resolved"],
82
+ message: "exact reasoning fidelity must preserve the requested effort",
83
+ });
84
+ }
85
+ if (effort.fidelity === "clamped") {
86
+ if (effort.resolved === effort.requested) {
87
+ context.addIssue({
88
+ code: "custom",
89
+ path: ["resolved"],
90
+ message: "clamped reasoning fidelity must change the requested effort",
91
+ });
92
+ }
93
+ else if (!isDownwardReasoningClamp(effort.requested, effort.resolved)) {
94
+ context.addIssue({
95
+ code: "custom",
96
+ path: ["resolved"],
97
+ message: "reasoning effort may clamp down but must never increase",
98
+ });
99
+ }
100
+ }
101
+ });
102
+ export const agentExecutionPreparationReceiptSchema = z
103
+ .strictObject({
104
+ kind: z.literal("agent-execution-preparation"),
105
+ schemaVersion: z.literal(1),
106
+ preparationId: nonBlankStringSchema.max(500),
107
+ requestDigest: sha256DigestSchema,
108
+ authoredProfileDigest: sha256DigestSchema,
109
+ effectiveProfileDigest: sha256DigestSchema,
110
+ backend: nonBlankStringSchema.max(200),
111
+ harness: harnessTypeSchema,
112
+ harnessVersion: nonBlankStringSchema.max(200),
113
+ resolvedModel: z.strictObject({
114
+ requested: z.string().max(500),
115
+ resolved: nonBlankStringSchema.max(500),
116
+ provider: z.string().max(200).optional(),
117
+ reasoningEffort: agentExecutionPreparationReasoningEffortSchema.optional(),
118
+ }),
119
+ workspace: z.strictObject({
120
+ leaseId: publicLifecycleIdentifierSchema,
121
+ provider: publicLifecycleIdentifierSchema,
122
+ identityDigest: sha256DigestSchema,
123
+ isolation: z.enum(["per-run", "shared"]),
124
+ sourceSnapshotDigest: sha256DigestSchema,
125
+ sourceSnapshotPolicy: agentWorkspaceSourceSnapshotPolicySchema,
126
+ preparedWorkspaceDigest: sha256DigestSchema,
127
+ profileActivationDigest: sha256DigestSchema,
128
+ }),
129
+ axisResults: z.array(agentExecutionPreparationAxisResultSchema),
130
+ executionPlanDigest: sha256DigestSchema,
131
+ materializer: z.strictObject({
132
+ name: nonBlankStringSchema.max(200),
133
+ version: nonBlankStringSchema.max(200),
134
+ }),
135
+ expiresAtMs: z.number().int().positive().safe(),
136
+ digest: sha256DigestSchema,
137
+ })
138
+ .superRefine((receipt, context) => {
139
+ const seen = new Map();
140
+ for (const [index, result] of receipt.axisResults.entries()) {
141
+ const key = agentExecutionPreparationAxisResultKey(result.axis, result.path);
142
+ const previous = seen.get(key);
143
+ if (previous !== undefined) {
144
+ context.addIssue({
145
+ code: "custom",
146
+ path: ["axisResults", index],
147
+ message: agentExecutionPreparationAxisResultsEqual(previous, result)
148
+ ? "duplicate profile axis/path result"
149
+ : "conflicting profile axis/path results",
150
+ });
151
+ }
152
+ else {
153
+ seen.set(key, result);
154
+ }
155
+ if (index > 0 &&
156
+ compareAgentExecutionPreparationAxisResults(receipt.axisResults[index - 1], result) >= 0) {
157
+ context.addIssue({
158
+ code: "custom",
159
+ path: ["axisResults", index],
160
+ message: "profile axis/path results must be canonically sorted",
161
+ });
162
+ }
163
+ }
164
+ if (!isCanonicalJsonValue(receipt)) {
165
+ context.addIssue({
166
+ code: "custom",
167
+ message: "execution preparation receipt must contain only RFC 8785 JSON values",
168
+ });
169
+ }
170
+ else if (canonicalCandidateDigest(omitTopLevelDigest(receipt)) !== receipt.digest) {
171
+ context.addIssue({
172
+ code: "custom",
173
+ path: ["digest"],
174
+ message: "execution preparation receipt digest is invalid",
175
+ });
176
+ }
177
+ });
178
+ /** @internal Canonical identity for one preparation axis and path. */
179
+ export function agentExecutionPreparationAxisResultKey(axis, path) {
180
+ return `${axis}\u0000${path ?? ""}`;
181
+ }
182
+ /** @internal Exact public equality for preparation axis rows. */
183
+ export function agentExecutionPreparationAxisResultsEqual(left, right) {
184
+ try {
185
+ return canonicalCandidateJson(left) === canonicalCandidateJson(right);
186
+ }
187
+ catch {
188
+ return false;
189
+ }
190
+ }
191
+ const AXIS_ORDER = new Map(AGENT_PROFILE_MATERIALIZATION_AXES.map((axis, index) => [axis, index]));
192
+ /** @internal Canonical order for preparation axis rows. */
193
+ export function compareAgentExecutionPreparationAxisResults(left, right) {
194
+ const axisDifference = (AXIS_ORDER.get(left.axis) ?? Number.MAX_SAFE_INTEGER) -
195
+ (AXIS_ORDER.get(right.axis) ?? Number.MAX_SAFE_INTEGER);
196
+ if (axisDifference !== 0)
197
+ return axisDifference;
198
+ const leftPath = left.path ?? "";
199
+ const rightPath = right.path ?? "";
200
+ return leftPath < rightPath ? -1 : leftPath > rightPath ? 1 : 0;
201
+ }
202
+ function isCanonicalJsonPointer(value) {
203
+ if (!value.startsWith("/") || !isWellFormedUnicode(value))
204
+ return false;
205
+ for (let index = 0; index < value.length; index += 1) {
206
+ if (value[index] !== "~")
207
+ continue;
208
+ const escape = value[index + 1];
209
+ if (escape !== "0" && escape !== "1")
210
+ return false;
211
+ index += 1;
212
+ }
213
+ return true;
214
+ }
215
+ function isDownwardReasoningClamp(requested, resolved) {
216
+ return (REASONING_EFFORTS.indexOf(resolved) < REASONING_EFFORTS.indexOf(requested));
217
+ }