@openpond/evals 0.2.0 → 0.3.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/CONTRACT.md CHANGED
@@ -6,13 +6,13 @@ authorization, model streaming, artifact bytes, and runtime processes.
6
6
 
7
7
  | Existing object | Portable object | Migration rule |
8
8
  | --- | --- | --- |
9
- | `Taskset` | `TasksetRelease` | Project only the released tasks, policy, environment, tools, capabilities, graders, and immutable Harness binding. Authoring state and UI readiness remain host state. |
9
+ | `Taskset` | `TasksetRelease` | Project only the released tasks, policy, environment, tools, capabilities, and graders. A Taskset is deliberately independent of any Harness so the same workload can run against local or hosted execution. Authoring state and UI readiness remain host state. |
10
10
  | `HarnessRunManifest` (`openpond.harnessRunManifest.v1`) | `RunManifest` (`openpond.runManifest.v1`) | Treat the old object as a legacy training projection. Normalize its release/model/runtime identities into one new manifest; recipe, compute, engine, secret leases, and approval records remain host bindings referenced by hashes. |
11
11
  | `HarnessRunTrace` | `HarnessTrace` | Preserve ordered actions, observations, lifecycle events, terminal state, failure class, and trace hash. Learning-signal envelopes remain a training projection of the trace and receipt. |
12
12
  | `TaskAttemptResult` | `AttemptReceipt` | Preserve the old record for application persistence while adding a lossless receipt reference. Output becomes `outputHash`; trace and artifacts are separately hash-bound. |
13
13
  | `GradeResult` | `GraderEvidence[]` | Preserve component score, pass, reward eligibility, failure class, feedback, and visible/private evidence references. Aggregate UI results remain host projections. |
14
14
  | managed-RL local receipt | `AttemptReceipt` | Submit canonical manifest/task/trace/artifact/grader identities; policy token responses and provider request IDs remain host-private trace data. |
15
- | resolved training bundle | `HarnessRelease` + host training binding | Environment, tools, program, policy, files, and grader interface belong to the Harness. Dataset/evidence, recipe, compute, engine, approval, and opaque leases remain explicit host-side bindings. |
15
+ | resolved training bundle | `HarnessRelease` + host training binding | Agent snapshot, program, lifecycle, tool declarations, files, and grader interface belong to the Harness. Taskset environment/policy/graders and dataset/evidence, recipe, compute, engine, approval, and opaque leases remain explicit host-side bindings. |
16
16
  | completed Work or Development turn | `WorkEvidenceReceipt` | Project the authoritative terminal turn, immutable Agent snapshot when available, model/runtime identity, sanitized trace reference, exact output revisions, validation evidence, interventions, timing, usage, and explicit consent provenance. Keep the raw source and trace host-private. |
17
17
  | Agent plus environment runtime events | `WorkProcessTrace` | Emit one ordered trace with `agent` and `environment` layers. Bind every environment step to its outer Agent tool call or stable Agent-turn receipt hash. Hash inputs/outputs and expose only enumerated, bounded attributes. |
18
18
  | user feedback on Work output | `WorkFeedbackReceipt` | Append a new receipt bound to the evidence receipt and, when selected, the exact content-addressed output-revision descriptor. Corrections are separate artifacts and never mutate prior receipts. |
@@ -26,6 +26,17 @@ authorization, model streaming, artifact bytes, and runtime processes.
26
26
  - Compatible package releases may add optional helpers and exports. Changing a
27
27
  required field, identity hash, or privacy boundary requires a new schema
28
28
  literal and an explicit normalizer.
29
+ - `openpond.agentSnapshot.v2`, `openpond.harnessRelease.v2`, and
30
+ `openpond.tasksetRelease.v2` define the Harness-first boundary. The v2
31
+ contracts remove the Profile reference from the Agent snapshot and keep the
32
+ Taskset independent of a concrete Harness, environment, or policy binding.
33
+ - Runs with different Harness releases require an explicit
34
+ `HarnessCompatibilityReceipt` binding both Harnesses to the same Taskset and
35
+ recording environment, tool, policy, and grader-interface contract hashes.
36
+ Callers with materialized releases should use
37
+ `createVerifiedHarnessCompatibilityReceipt`; it derives those hashes from the
38
+ immutable objects and rejects lifecycle, tool, grader-interface, or required
39
+ Environment-tool drift before issuing the receipt.
29
40
  - The initial support target is Node.js ESM on Node 22.14 through Node 24.
30
41
  - Portable paths are relative and at most 2,000 characters. Individual assets
31
42
  are at most 250 MB. Tasksets, traces, and evidence arrays have schema-level
package/RELEASING.md CHANGED
@@ -1,19 +1,20 @@
1
1
  # Releasing `@openpond/evals`
2
2
 
3
3
  The package version is independent from OpenPond application and schema
4
- versions. Version `0.1.1` is the current provenance-backed baseline and supports
4
+ versions. Version `0.3.0` is the next Harness-first release and supports
5
5
  these initial schema literals:
6
6
 
7
- - `openpond.agentSnapshot.v1`
8
- - `openpond.harnessRelease.v1`
9
- - `openpond.tasksetRelease.v1`
7
+ - `openpond.agentSnapshot.v2`
8
+ - `openpond.harnessRelease.v2`
9
+ - `openpond.tasksetRelease.v2`
10
10
  - `openpond.runManifest.v1`
11
11
  - `openpond.attemptReceipt.v1`
12
12
  - `openpond.harnessTrace.v1`
13
+ - `openpond.harnessCompatibility.v1`
13
14
  - `openpond.graderEvidence.v1`
14
15
  - `openpond.evaluationResult.v1`
15
16
 
16
- This branch prepares the additive Work evidence schemas for `0.2.0`:
17
+ The package also carries the Work evidence schemas introduced in `0.2.0`:
17
18
 
18
19
  - `openpond.workEvidenceReceipt.v1`
19
20
  - `openpond.workProcessTrace.v1`
@@ -0,0 +1,45 @@
1
+ import { assertContentHash, contentHash } from "./common.js";
2
+ import { HarnessReleaseSchema, } from "./harness.js";
3
+ import { createHarnessCompatibilityReceipt, } from "./runs.js";
4
+ import { TasksetReleaseSchema, } from "./tasksets.js";
5
+ export function createVerifiedHarnessCompatibilityReceipt(input) {
6
+ const base = HarnessReleaseSchema.parse(input.baseHarnessRelease);
7
+ const candidate = HarnessReleaseSchema.parse(input.candidateHarnessRelease);
8
+ const taskset = TasksetReleaseSchema.parse(input.tasksetRelease);
9
+ assertContentHash(base, "Base Harness release");
10
+ assertContentHash(candidate, "Candidate Harness release");
11
+ assertContentHash(taskset, "Taskset release");
12
+ requireSameContract("lifecycle", base.lifecycle, candidate.lifecycle);
13
+ requireSameContract("tool", base.tools, candidate.tools);
14
+ requireSameContract("grader interface", base.graderInterface, candidate.graderInterface);
15
+ const environmentTools = new Set(taskset.tools.map((tool) => tool.name));
16
+ const unsupportedTools = base.tools
17
+ .map((tool) => tool.name)
18
+ .filter((name) => !environmentTools.has(name));
19
+ if (unsupportedTools.length) {
20
+ throw new Error(`Harness compatibility failed: Taskset Environment does not provide ${unsupportedTools.join(", ")}.`);
21
+ }
22
+ return createHarnessCompatibilityReceipt({
23
+ schemaVersion: "openpond.harnessCompatibility.v1",
24
+ id: input.id,
25
+ baseHarnessRelease: { id: base.id, contentHash: base.contentHash },
26
+ candidateHarnessRelease: {
27
+ id: candidate.id,
28
+ contentHash: candidate.contentHash,
29
+ },
30
+ tasksetRelease: { id: taskset.id, contentHash: taskset.contentHash },
31
+ environmentHash: contentHash(taskset.environment),
32
+ toolContractHash: contentHash(taskset.tools),
33
+ policyHash: contentHash(taskset.policy),
34
+ graderInterfaceHash: contentHash({
35
+ harness: base.graderInterface,
36
+ taskset: taskset.graders,
37
+ }),
38
+ metadata: input.metadata ?? {},
39
+ });
40
+ }
41
+ function requireSameContract(label, base, candidate) {
42
+ if (contentHash(base) !== contentHash(candidate)) {
43
+ throw new Error(`Harness compatibility failed: ${label} contract changed.`);
44
+ }
45
+ }
@@ -14,32 +14,29 @@ export const marketingPortfolioConformance = fixture("marketing-portfolio-v1", [
14
14
  ]);
15
15
  function fixture(id, tools) {
16
16
  const snapshot = createAgentSnapshot({
17
- schemaVersion: "openpond.agentSnapshot.v1",
17
+ schemaVersion: "openpond.agentSnapshot.v2",
18
18
  id: `${id}-agent`,
19
- profileRelease: null,
19
+ sourceRelease: null,
20
20
  instructions: [], skills: [], agents: [], toolDeclarations: tools,
21
21
  capabilityRequirements: [], dependencyLock,
22
22
  portability: { portable: true, blockers: [], localOnlyAssetRefs: [], hostPrivateAssetRefs: [] },
23
23
  metadata: { conformanceFixture: id },
24
24
  });
25
25
  const harness = createHarnessRelease({
26
- schemaVersion: "openpond.harnessRelease.v1",
26
+ schemaVersion: "openpond.harnessRelease.v2",
27
27
  id: `${id}-harness`,
28
28
  agentSnapshot: { id: snapshot.id, contentHash: snapshot.contentHash },
29
29
  program,
30
- environment: { protocolVersion: "openpond.environment.v1", kind: "agent", entrypoint: id, stateful: true, deterministicSeeds: true, lifecycle: ["create", "reset", "step", "collect", "destroy"], networkPolicy: "none", defaultTimeoutMs: 5_000 },
31
30
  tools,
32
31
  lifecycle: { create: true, reset: true, step: true, collect: true, destroy: true, resetScope: "attempt" },
33
32
  graderInterface: { visibleEvidence: ["output"], privilegedEvidence: ["expected"], privateVerifierIsolation: true },
34
- policy: { policyVisibleFields: ["input"], privilegedFields: ["expectedOutput"], hiddenGraderRefs: [], connectedAppScopes: [] },
35
33
  files: [], metadata: { conformanceFixture: id },
36
34
  });
37
35
  const tasksetContent = {
38
- schemaVersion: "openpond.tasksetRelease.v1",
36
+ schemaVersion: "openpond.tasksetRelease.v2",
39
37
  id: `${id}-taskset`, revision: 1,
40
- harnessRelease: { id: harness.id, contentHash: harness.contentHash },
41
- policy: harness.policy,
42
- environment: harness.environment,
38
+ policy: { policyVisibleFields: ["input"], privilegedFields: ["expectedOutput"], hiddenGraderRefs: [], connectedAppScopes: [] },
39
+ environment: { protocolVersion: "openpond.environment.v1", kind: "agent", entrypoint: id, stateful: true, deterministicSeeds: true, lifecycle: ["create", "reset", "step", "collect", "destroy"], networkPolicy: "none", defaultTimeoutMs: 5_000 },
43
40
  tools,
44
41
  capabilities: [],
45
42
  tasks: [
@@ -0,0 +1,329 @@
1
+ import { z } from "zod";
2
+ import { HarnessImprovementRouteSchema, HarnessOverlaySnapshotRefSchema, } from "./harness-workspaces.js";
3
+ import { contentHash, ImmutableReleaseRefSchema, ReleaseHashSchema, ReleaseIdSchema, ReleaseTimestampSchema, } from "./common.js";
4
+ const BoundedTextSchema = z.string().trim().min(1).max(100_000);
5
+ const MetadataSchema = z.record(z.string(), z.unknown()).default({});
6
+ export const ImprovementSafeBoundaryKindSchema = z.enum([
7
+ "completed_tool_batch",
8
+ "before_model_step",
9
+ "turn_completed",
10
+ "turn_paused",
11
+ ]);
12
+ export const ImprovementSafeBoundarySchema = z
13
+ .object({
14
+ kind: ImprovementSafeBoundaryKindSchema,
15
+ eventSequence: z.number().int().nonnegative(),
16
+ occurredAt: ReleaseTimestampSchema,
17
+ })
18
+ .strict();
19
+ export const ImprovementEventRefSchema = z
20
+ .object({
21
+ id: ReleaseIdSchema,
22
+ sequence: z.number().int().nonnegative().nullable(),
23
+ contentHash: ReleaseHashSchema,
24
+ })
25
+ .strict();
26
+ export const ImprovementObservationKindSchema = z.enum([
27
+ "tool_failure",
28
+ "retry",
29
+ "recovery",
30
+ "validation",
31
+ "user_correction",
32
+ "reusable_success",
33
+ "completion_detour",
34
+ ]);
35
+ export const ImprovementObservationStateSchema = z.enum([
36
+ "open",
37
+ "recovered",
38
+ "terminal",
39
+ ]);
40
+ export const ImprovementToolIdentitySchema = z
41
+ .object({
42
+ name: z.string().trim().min(1).max(500),
43
+ invocationKey: ReleaseHashSchema,
44
+ })
45
+ .strict();
46
+ export const ImprovementObservationContentSchema = z
47
+ .object({
48
+ schemaVersion: z.literal("openpond.improvementObservation.v1"),
49
+ id: ReleaseIdSchema,
50
+ runRef: ReleaseIdSchema,
51
+ turnId: ReleaseIdSchema,
52
+ harnessRelease: ImmutableReleaseRefSchema,
53
+ overlay: HarnessOverlaySnapshotRefSchema.nullable(),
54
+ eventRefs: z.array(ImprovementEventRefSchema).min(1).max(100),
55
+ kind: ImprovementObservationKindSchema,
56
+ state: ImprovementObservationStateSchema,
57
+ tool: ImprovementToolIdentitySchema.nullable(),
58
+ deterministicClass: z.string().trim().min(1).max(500).nullable(),
59
+ summary: BoundedTextSchema,
60
+ createdAt: ReleaseTimestampSchema,
61
+ metadata: MetadataSchema,
62
+ })
63
+ .strict()
64
+ .superRefine((observation, context) => {
65
+ if (new Set(observation.eventRefs.map((reference) => reference.id)).size !==
66
+ observation.eventRefs.length) {
67
+ context.addIssue({
68
+ code: "custom",
69
+ message: "observation event refs must be unique",
70
+ path: ["eventRefs"],
71
+ });
72
+ }
73
+ if (["tool_failure", "retry", "recovery", "completion_detour"].includes(observation.kind) &&
74
+ observation.tool === null) {
75
+ context.addIssue({
76
+ code: "custom",
77
+ message: `${observation.kind} observations require a tool identity`,
78
+ path: ["tool"],
79
+ });
80
+ }
81
+ });
82
+ export const ImprovementObservationSchema = ImprovementObservationContentSchema.extend({
83
+ contentHash: ReleaseHashSchema,
84
+ }).strict();
85
+ export const RefinementTriggerPolicySchema = z
86
+ .object({
87
+ schemaVersion: z.literal("openpond.refinementTriggerPolicy.v1"),
88
+ maxEstimatedCostUsd: z.number().finite().nonnegative(),
89
+ cooldownMs: z.number().int().nonnegative(),
90
+ maxPendingPlans: z.number().int().min(1).max(100),
91
+ maxEvidenceEvents: z.number().int().min(1).max(1_000),
92
+ maxProposalEdits: z.number().int().min(1).max(1_000),
93
+ maxProposalBytes: z.number().int().min(1).max(10_000_000),
94
+ })
95
+ .strict();
96
+ export const RefinementTriggerDecisionKindSchema = z.enum([
97
+ "no_action",
98
+ "route_deterministically",
99
+ "queue_refiner",
100
+ ]);
101
+ export const RefinementTriggerDecisionContentSchema = z
102
+ .object({
103
+ schemaVersion: z.literal("openpond.refinementTriggerDecision.v1"),
104
+ id: ReleaseIdSchema,
105
+ runRef: ReleaseIdSchema,
106
+ turnId: ReleaseIdSchema,
107
+ harnessRelease: ImmutableReleaseRefSchema,
108
+ overlay: HarnessOverlaySnapshotRefSchema.nullable(),
109
+ observations: z.array(ImmutableReleaseRefSchema).max(100),
110
+ decision: RefinementTriggerDecisionKindSchema,
111
+ deterministicRoute: HarnessImprovementRouteSchema.nullable(),
112
+ suggestedRoutes: z.array(HarnessImprovementRouteSchema).max(8),
113
+ reason: BoundedTextSchema,
114
+ deduplicationKey: ReleaseHashSchema,
115
+ policy: RefinementTriggerPolicySchema,
116
+ estimatedMaxCostUsd: z.number().finite().nonnegative(),
117
+ pendingPlanCount: z.number().int().nonnegative(),
118
+ boundary: ImprovementSafeBoundarySchema,
119
+ cooldownUntil: ReleaseTimestampSchema.nullable(),
120
+ createdAt: ReleaseTimestampSchema,
121
+ metadata: MetadataSchema,
122
+ })
123
+ .strict()
124
+ .superRefine((trigger, context) => {
125
+ if (trigger.estimatedMaxCostUsd > trigger.policy.maxEstimatedCostUsd) {
126
+ context.addIssue({
127
+ code: "custom",
128
+ message: "estimated Refiner cost exceeds the trigger policy budget",
129
+ path: ["estimatedMaxCostUsd"],
130
+ });
131
+ }
132
+ if (trigger.pendingPlanCount > trigger.policy.maxPendingPlans) {
133
+ context.addIssue({
134
+ code: "custom",
135
+ message: "pending plan count exceeds the trigger policy limit",
136
+ path: ["pendingPlanCount"],
137
+ });
138
+ }
139
+ if (trigger.observations.length > trigger.policy.maxEvidenceEvents) {
140
+ context.addIssue({
141
+ code: "custom",
142
+ message: "trigger observations exceed the evidence budget",
143
+ path: ["observations"],
144
+ });
145
+ }
146
+ if (trigger.decision === "route_deterministically" &&
147
+ trigger.deterministicRoute === null) {
148
+ context.addIssue({
149
+ code: "custom",
150
+ message: "deterministic decisions require a route",
151
+ path: ["deterministicRoute"],
152
+ });
153
+ }
154
+ if (trigger.decision !== "route_deterministically" &&
155
+ trigger.deterministicRoute !== null) {
156
+ context.addIssue({
157
+ code: "custom",
158
+ message: "only deterministic decisions may declare a deterministic route",
159
+ path: ["deterministicRoute"],
160
+ });
161
+ }
162
+ if (trigger.decision === "no_action" && trigger.suggestedRoutes.length > 0) {
163
+ context.addIssue({
164
+ code: "custom",
165
+ message: "no-action decisions cannot suggest routes",
166
+ path: ["suggestedRoutes"],
167
+ });
168
+ }
169
+ if (trigger.decision !== "no_action" && trigger.observations.length === 0) {
170
+ context.addIssue({
171
+ code: "custom",
172
+ message: "actionable trigger decisions require observations",
173
+ path: ["observations"],
174
+ });
175
+ }
176
+ });
177
+ export const RefinementTriggerDecisionSchema = RefinementTriggerDecisionContentSchema.extend({
178
+ contentHash: ReleaseHashSchema,
179
+ }).strict();
180
+ export const ImprovementRouteAuthoritySchema = z.enum([
181
+ "runtime_service",
182
+ "refiner_model",
183
+ "human_review",
184
+ "evaluation_system",
185
+ "training_system",
186
+ ]);
187
+ export const ImprovementRouteDecisionContentSchema = z
188
+ .object({
189
+ schemaVersion: z.literal("openpond.improvementRouteDecision.v1"),
190
+ id: ReleaseIdSchema,
191
+ trigger: ImmutableReleaseRefSchema,
192
+ route: HarnessImprovementRouteSchema,
193
+ authority: ImprovementRouteAuthoritySchema,
194
+ automatic: z.boolean(),
195
+ reason: BoundedTextSchema,
196
+ createdAt: ReleaseTimestampSchema,
197
+ metadata: MetadataSchema,
198
+ })
199
+ .strict()
200
+ .superRefine((decision, context) => {
201
+ if (decision.automatic &&
202
+ ["human_review", "evaluation_system", "training_system"].includes(decision.authority)) {
203
+ context.addIssue({
204
+ code: "custom",
205
+ message: `${decision.authority} routes cannot be marked automatic`,
206
+ path: ["automatic"],
207
+ });
208
+ }
209
+ if (decision.route === "training" && decision.authority !== "training_system") {
210
+ context.addIssue({
211
+ code: "custom",
212
+ message: "training routes require training-system authority",
213
+ path: ["authority"],
214
+ });
215
+ }
216
+ });
217
+ export const ImprovementRouteDecisionSchema = ImprovementRouteDecisionContentSchema.extend({
218
+ contentHash: ReleaseHashSchema,
219
+ }).strict();
220
+ export const HarnessRefinerOutcomeContentSchema = z
221
+ .object({
222
+ schemaVersion: z.literal("openpond.harnessRefinerOutcome.v1"),
223
+ id: ReleaseIdSchema,
224
+ trigger: ImmutableReleaseRefSchema,
225
+ decision: z.enum(["no_action", "proposed"]),
226
+ proposal: ImmutableReleaseRefSchema.nullable(),
227
+ reason: BoundedTextSchema,
228
+ evidenceRefs: z.array(ImmutableReleaseRefSchema).max(100),
229
+ estimatedCostUsd: z.number().finite().nonnegative(),
230
+ createdAt: ReleaseTimestampSchema,
231
+ metadata: MetadataSchema,
232
+ })
233
+ .strict()
234
+ .superRefine((outcome, context) => {
235
+ if ((outcome.decision === "proposed") !== (outcome.proposal !== null)) {
236
+ context.addIssue({
237
+ code: "custom",
238
+ message: "proposed Refiner outcomes require a proposal; no-action outcomes cannot include one",
239
+ path: ["proposal"],
240
+ });
241
+ }
242
+ });
243
+ export const HarnessRefinerOutcomeSchema = HarnessRefinerOutcomeContentSchema.extend({
244
+ contentHash: ReleaseHashSchema,
245
+ }).strict();
246
+ export const ImprovementApplyDecisionSchema = z.enum([
247
+ "applied",
248
+ "retained",
249
+ "declined",
250
+ "conflict",
251
+ "rolled_back",
252
+ ]);
253
+ export const ImprovementApplyReceiptContentSchema = z
254
+ .object({
255
+ schemaVersion: z.literal("openpond.improvementApplyReceipt.v1"),
256
+ id: ReleaseIdSchema,
257
+ proposal: ImmutableReleaseRefSchema,
258
+ beforeOverlay: HarnessOverlaySnapshotRefSchema,
259
+ afterOverlay: HarnessOverlaySnapshotRefSchema.nullable(),
260
+ decision: ImprovementApplyDecisionSchema,
261
+ boundary: ImprovementSafeBoundarySchema,
262
+ validationRefs: z.array(ImmutableReleaseRefSchema).max(100),
263
+ outcomeEvidenceRefs: z.array(ImprovementEventRefSchema).max(1_000),
264
+ rollbackOf: ImmutableReleaseRefSchema.nullable(),
265
+ createdAt: ReleaseTimestampSchema,
266
+ metadata: MetadataSchema,
267
+ })
268
+ .strict()
269
+ .superRefine((receipt, context) => {
270
+ if ((receipt.decision === "applied") !== (receipt.afterOverlay !== null)) {
271
+ context.addIssue({
272
+ code: "custom",
273
+ message: "applied receipts require an after-overlay; other decisions cannot include one",
274
+ path: ["afterOverlay"],
275
+ });
276
+ }
277
+ if ((receipt.decision === "rolled_back") !== (receipt.rollbackOf !== null)) {
278
+ context.addIssue({
279
+ code: "custom",
280
+ message: "only rollback receipts require rollbackOf",
281
+ path: ["rollbackOf"],
282
+ });
283
+ }
284
+ });
285
+ export const ImprovementApplyReceiptSchema = ImprovementApplyReceiptContentSchema.extend({
286
+ contentHash: ReleaseHashSchema,
287
+ }).strict();
288
+ function createHashedContract(input) {
289
+ const parsed = input.contentSchema.parse(input.content);
290
+ return input.resultSchema.parse({
291
+ ...parsed,
292
+ contentHash: contentHash(parsed),
293
+ });
294
+ }
295
+ export function createImprovementObservation(content) {
296
+ return createHashedContract({
297
+ content,
298
+ contentSchema: ImprovementObservationContentSchema,
299
+ resultSchema: ImprovementObservationSchema,
300
+ });
301
+ }
302
+ export function createRefinementTriggerDecision(content) {
303
+ return createHashedContract({
304
+ content,
305
+ contentSchema: RefinementTriggerDecisionContentSchema,
306
+ resultSchema: RefinementTriggerDecisionSchema,
307
+ });
308
+ }
309
+ export function createImprovementRouteDecision(content) {
310
+ return createHashedContract({
311
+ content,
312
+ contentSchema: ImprovementRouteDecisionContentSchema,
313
+ resultSchema: ImprovementRouteDecisionSchema,
314
+ });
315
+ }
316
+ export function createHarnessRefinerOutcome(content) {
317
+ return createHashedContract({
318
+ content,
319
+ contentSchema: HarnessRefinerOutcomeContentSchema,
320
+ resultSchema: HarnessRefinerOutcomeSchema,
321
+ });
322
+ }
323
+ export function createImprovementApplyReceipt(content) {
324
+ return createHashedContract({
325
+ content,
326
+ contentSchema: ImprovementApplyReceiptContentSchema,
327
+ resultSchema: ImprovementApplyReceiptSchema,
328
+ });
329
+ }