openpond-sdk 0.3.3 → 0.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.
Files changed (124) hide show
  1. package/TASKSETS.md +55 -0
  2. package/dist/actions-local.js +67 -118
  3. package/dist/actions-local.js.map +4 -4
  4. package/dist/actions.js +4 -92
  5. package/dist/actions.js.map +4 -4
  6. package/dist/chunk-27ETSPHQ.js +83 -0
  7. package/dist/chunk-27ETSPHQ.js.map +7 -0
  8. package/dist/chunk-5PRP457R.js +477 -0
  9. package/dist/chunk-5PRP457R.js.map +7 -0
  10. package/dist/chunk-65D4C7HP.js +273 -0
  11. package/dist/chunk-65D4C7HP.js.map +7 -0
  12. package/dist/chunk-747CMU2Y.js +222 -0
  13. package/dist/chunk-747CMU2Y.js.map +7 -0
  14. package/dist/chunk-7O5X7DBU.js +80 -0
  15. package/dist/chunk-7O5X7DBU.js.map +7 -0
  16. package/dist/chunk-A4ZDOZKP.js +115 -0
  17. package/dist/chunk-A4ZDOZKP.js.map +7 -0
  18. package/dist/chunk-APHPXQEA.js +155 -0
  19. package/dist/chunk-APHPXQEA.js.map +7 -0
  20. package/dist/chunk-AVW35YOH.js +574 -0
  21. package/dist/chunk-AVW35YOH.js.map +7 -0
  22. package/dist/chunk-AZUCY3E5.js +2395 -0
  23. package/dist/chunk-AZUCY3E5.js.map +7 -0
  24. package/dist/chunk-IVEXCIHO.js +1373 -0
  25. package/dist/chunk-IVEXCIHO.js.map +7 -0
  26. package/dist/chunk-K5ZCYOZO.js +49 -0
  27. package/dist/chunk-K5ZCYOZO.js.map +7 -0
  28. package/dist/chunk-LLHE4BOD.js +220 -0
  29. package/dist/chunk-LLHE4BOD.js.map +7 -0
  30. package/dist/chunk-LXXQVGQY.js +1 -0
  31. package/dist/chunk-LXXQVGQY.js.map +7 -0
  32. package/dist/chunk-P27DQ65Z.js +138 -0
  33. package/dist/chunk-P27DQ65Z.js.map +7 -0
  34. package/dist/chunk-QLEJOCQX.js +72 -0
  35. package/dist/chunk-QLEJOCQX.js.map +7 -0
  36. package/dist/chunk-S7I45WJQ.js +57 -0
  37. package/dist/chunk-S7I45WJQ.js.map +7 -0
  38. package/dist/chunk-ZPCK222K.js +586 -0
  39. package/dist/chunk-ZPCK222K.js.map +7 -0
  40. package/dist/index.js +33 -2488
  41. package/dist/index.js.map +4 -4
  42. package/dist/learning.js +16 -2042
  43. package/dist/learning.js.map +4 -4
  44. package/dist/model-batch-review.js +5 -42
  45. package/dist/model-batch-review.js.map +3 -3
  46. package/dist/model-projects.js +29 -430
  47. package/dist/model-projects.js.map +3 -3
  48. package/dist/model-starter-attempts.js +53 -310
  49. package/dist/model-starter-attempts.js.map +4 -4
  50. package/dist/model-starter-catalog.js +17 -460
  51. package/dist/model-starter-catalog.js.map +4 -4
  52. package/dist/model-starters.js +32 -709
  53. package/dist/model-starters.js.map +4 -4
  54. package/dist/model-taskset-authoring.js +11 -44
  55. package/dist/model-taskset-authoring.js.map +3 -3
  56. package/dist/profile-actions.js +4 -211
  57. package/dist/profile-actions.js.map +3 -3
  58. package/dist/project-actions.js +4 -224
  59. package/dist/project-actions.js.map +3 -3
  60. package/dist/refiner.js +14 -554
  61. package/dist/refiner.js.map +4 -4
  62. package/dist/taskset-catalog.js +9 -104
  63. package/dist/taskset-catalog.js.map +3 -3
  64. package/dist/taskset-drafts.js +465 -0
  65. package/dist/taskset-drafts.js.map +7 -0
  66. package/dist/taskset-packages.js +946 -3089
  67. package/dist/taskset-packages.js.map +4 -4
  68. package/dist/training.js +43 -822
  69. package/dist/training.js.map +4 -4
  70. package/dist/types/packages/sdk/src/index.d.ts +3 -3
  71. package/dist/types/packages/sdk/src/index.d.ts.map +1 -1
  72. package/dist/types/packages/sdk/src/learning-client.d.ts +130 -0
  73. package/dist/types/packages/sdk/src/learning-client.d.ts.map +1 -0
  74. package/dist/types/packages/sdk/src/learning.d.ts +1 -129
  75. package/dist/types/packages/sdk/src/learning.d.ts.map +1 -1
  76. package/dist/types/packages/sdk/src/taskset-authored-contracts.d.ts +1170 -0
  77. package/dist/types/packages/sdk/src/taskset-authored-contracts.d.ts.map +1 -0
  78. package/dist/types/packages/sdk/src/taskset-authored-files.d.ts +560 -0
  79. package/dist/types/packages/sdk/src/taskset-authored-files.d.ts.map +1 -0
  80. package/dist/types/packages/sdk/src/taskset-authored-portable-release.d.ts +92 -0
  81. package/dist/types/packages/sdk/src/taskset-authored-portable-release.d.ts.map +1 -0
  82. package/dist/types/packages/sdk/src/taskset-authored-tool-environment.d.ts +15 -0
  83. package/dist/types/packages/sdk/src/taskset-authored-tool-environment.d.ts.map +1 -0
  84. package/dist/types/packages/sdk/src/taskset-authored-validation.d.ts +18 -0
  85. package/dist/types/packages/sdk/src/taskset-authored-validation.d.ts.map +1 -0
  86. package/dist/types/packages/sdk/src/taskset-draft-api-contracts.d.ts +1681 -0
  87. package/dist/types/packages/sdk/src/taskset-draft-api-contracts.d.ts.map +1 -0
  88. package/dist/types/packages/sdk/src/taskset-draft-authoring.d.ts +19 -0
  89. package/dist/types/packages/sdk/src/taskset-draft-authoring.d.ts.map +1 -0
  90. package/dist/types/packages/sdk/src/taskset-draft-client.d.ts +2713 -0
  91. package/dist/types/packages/sdk/src/taskset-draft-client.d.ts.map +1 -0
  92. package/dist/types/packages/sdk/src/taskset-draft-core.d.ts +1000 -0
  93. package/dist/types/packages/sdk/src/taskset-draft-core.d.ts.map +1 -0
  94. package/dist/types/packages/sdk/src/taskset-draft-dataset-artifacts.d.ts +429 -0
  95. package/dist/types/packages/sdk/src/taskset-draft-dataset-artifacts.d.ts.map +1 -0
  96. package/dist/types/packages/sdk/src/taskset-draft-dataset-sources.d.ts +284 -0
  97. package/dist/types/packages/sdk/src/taskset-draft-dataset-sources.d.ts.map +1 -0
  98. package/dist/types/packages/sdk/src/taskset-draft-document.d.ts +846 -0
  99. package/dist/types/packages/sdk/src/taskset-draft-document.d.ts.map +1 -0
  100. package/dist/types/packages/sdk/src/taskset-draft-files.d.ts +8 -0
  101. package/dist/types/packages/sdk/src/taskset-draft-files.d.ts.map +1 -0
  102. package/dist/types/packages/sdk/src/taskset-draft-harness-actions.d.ts +28 -0
  103. package/dist/types/packages/sdk/src/taskset-draft-harness-actions.d.ts.map +1 -0
  104. package/dist/types/packages/sdk/src/taskset-draft-manifests.d.ts +8 -0
  105. package/dist/types/packages/sdk/src/taskset-draft-manifests.d.ts.map +1 -0
  106. package/dist/types/packages/sdk/src/taskset-draft-package-compiler.d.ts +967 -0
  107. package/dist/types/packages/sdk/src/taskset-draft-package-compiler.d.ts.map +1 -0
  108. package/dist/types/packages/sdk/src/taskset-draft-publication.d.ts +10 -0
  109. package/dist/types/packages/sdk/src/taskset-draft-publication.d.ts.map +1 -0
  110. package/dist/types/packages/sdk/src/taskset-draft-source.d.ts +1297 -0
  111. package/dist/types/packages/sdk/src/taskset-draft-source.d.ts.map +1 -0
  112. package/dist/types/packages/sdk/src/taskset-draft-workspace.d.ts +1597 -0
  113. package/dist/types/packages/sdk/src/taskset-draft-workspace.d.ts.map +1 -0
  114. package/dist/types/packages/sdk/src/taskset-drafts.d.ts +16 -0
  115. package/dist/types/packages/sdk/src/taskset-drafts.d.ts.map +1 -0
  116. package/dist/types/packages/sdk/src/taskset-package-grader-projection.d.ts +64 -0
  117. package/dist/types/packages/sdk/src/taskset-package-grader-projection.d.ts.map +1 -0
  118. package/dist/types/packages/sdk/src/taskset-package-projection.d.ts +1514 -0
  119. package/dist/types/packages/sdk/src/taskset-package-projection.d.ts.map +1 -0
  120. package/dist/types/packages/sdk/src/taskset-packages.d.ts +6 -0
  121. package/dist/types/packages/sdk/src/taskset-packages.d.ts.map +1 -1
  122. package/dist/workflows.js +4 -221
  123. package/dist/workflows.js.map +3 -3
  124. package/package.json +5 -1
@@ -0,0 +1,2395 @@
1
+ import {
2
+ ModelTasksetAuthoringSchema,
3
+ ModelTasksetDraftPreparationSchema,
4
+ TasksetDraftFileContentSchema,
5
+ TasksetDraftFileMutationSchema,
6
+ TasksetDraftFilePathSchema
7
+ } from "./chunk-S7I45WJQ.js";
8
+ import {
9
+ TasksetCatalogReleaseRefSchema
10
+ } from "./chunk-A4ZDOZKP.js";
11
+ import {
12
+ ModelStarterExecutionSchema,
13
+ ModelTasksetPackageSchema,
14
+ createModelStarterExecutionAsset,
15
+ modelStarterExecutionAssetId,
16
+ validateModelStarterExecution,
17
+ validateModelTasksetPackage
18
+ } from "./chunk-65D4C7HP.js";
19
+ import {
20
+ ChatModelRefSchema
21
+ } from "./chunk-IVEXCIHO.js";
22
+ import {
23
+ ImmutableAssetRefSchema,
24
+ ImmutableReleaseRefSchema,
25
+ ReleaseHashSchema,
26
+ ReleaseIdSchema,
27
+ VersionedReleaseRefSchema,
28
+ canonicalJson,
29
+ contentHash,
30
+ sha256
31
+ } from "./chunk-ZPCK222K.js";
32
+ import {
33
+ HostedModelProjectSummarySchema,
34
+ HostedModelProjectSyncSchema,
35
+ HostedModelProjectTrainingSetupSchema,
36
+ canonicalJson as canonicalJson2
37
+ } from "./chunk-5PRP457R.js";
38
+
39
+ // src/taskset-package-learning.ts
40
+ import { z } from "zod";
41
+ import {
42
+ TaskBatchSchema,
43
+ TaskEvidenceSchema,
44
+ TaskAdmissionDecisionSchema,
45
+ LearningSourceSchema,
46
+ LearningTextAssetSchema,
47
+ assertLearningContentHash,
48
+ compileTaskBatch,
49
+ learningRef,
50
+ sameLearningRef,
51
+ taskBatchPackageMetadata,
52
+ verifyLearningTextAsset
53
+ } from "@openpond/evals/learning";
54
+ var TasksetPackageLearningResourcesSchema = z.object({
55
+ batch: TaskBatchSchema,
56
+ evidence: z.array(TaskEvidenceSchema).min(1).max(1e4),
57
+ decisions: z.array(TaskAdmissionDecisionSchema).min(1).max(1e4),
58
+ sources: z.array(LearningSourceSchema).min(1).max(1e4),
59
+ assets: z.array(LearningTextAssetSchema).max(1e3)
60
+ }).strict();
61
+ function learningPackageContextFiles(resources) {
62
+ return resources.evidence.filter((evidence) => evidence.submission.evaluatorContext !== null).map((evidence) => {
63
+ const text = canonicalJson2(evidence.submission.evaluatorContext);
64
+ const bytes = new TextEncoder().encode(text);
65
+ return {
66
+ asset: {
67
+ id: `task-evidence:${evidence.contentHash}`,
68
+ path: `learning/context/${evidence.contentHash}.json`,
69
+ contentHash: sha256(bytes),
70
+ sizeBytes: bytes.byteLength,
71
+ mediaType: "application/json",
72
+ visibility: "host_private"
73
+ },
74
+ base64: btoa(Array.from(bytes, (byte) => String.fromCharCode(byte)).join(""))
75
+ };
76
+ });
77
+ }
78
+ function validateTasksetLearningResources(taskset, input) {
79
+ const resources = TasksetPackageLearningResourcesSchema.parse(input);
80
+ const metadata = taskBatchPackageMetadata(taskset);
81
+ if (!sameLearningRef(learningRef(resources.batch), metadata.batch)) throw new Error("Taskset learning batch differs from its admission metadata.");
82
+ for (const collection of [resources.evidence, resources.decisions, resources.sources, resources.assets]) {
83
+ const identities = /* @__PURE__ */ new Set();
84
+ for (const resource of collection) {
85
+ assertLearningContentHash(resource);
86
+ const key = `${resource.id}:${resource.revision}`;
87
+ if (identities.has(key)) throw new Error("Taskset learning resource identities must be unique.");
88
+ identities.add(key);
89
+ }
90
+ }
91
+ if (resources.evidence.length !== resources.batch.examples.length || resources.decisions.length !== resources.batch.examples.length) throw new Error("Taskset learning snapshots must match the admitted batch inventory.");
92
+ for (const evidence of resources.evidence) {
93
+ const source = resources.sources.find((source2) => sameLearningRef(learningRef(source2), evidence.source));
94
+ if (!source || !sameLearningRef(source.taskDefinition, learningRef(metadata.definition))) throw new Error("Taskset evidence source differs from its task definition.");
95
+ }
96
+ if (resources.sources.some((source) => !resources.evidence.some((evidence) => sameLearningRef(evidence.source, learningRef(source))))) throw new Error("Taskset package includes an unrelated learning source.");
97
+ const rewardAssets = metadata.rewards.flatMap((reward) => [
98
+ ...reward.assets,
99
+ ...reward.implementation.kind === "custom_verifier" ? [reward.implementation.verifierRef] : reward.implementation.kind === "model_judge" || reward.implementation.kind === "human" ? [reward.implementation.rubricRef] : [],
100
+ ..."inputContract" in reward.implementation ? [reward.implementation.inputContract] : []
101
+ ]);
102
+ for (const ref of rewardAssets) {
103
+ const asset = resources.assets.find((asset2) => asset2.id === ref.id);
104
+ if (!asset) throw new Error("Taskset learning Reward asset is missing.");
105
+ verifyLearningTextAsset(asset, ref);
106
+ }
107
+ if (resources.assets.some((asset) => !rewardAssets.some((ref) => ref.id === asset.id))) throw new Error("Taskset package includes an unrelated learning asset.");
108
+ const compiled = compileTaskBatch({
109
+ batch: resources.batch,
110
+ definition: metadata.definition,
111
+ binding: metadata.binding,
112
+ rewards: metadata.rewards,
113
+ evidence: resources.evidence,
114
+ decisions: resources.decisions
115
+ });
116
+ const compiledMetadata = taskBatchPackageMetadata(compiled);
117
+ if (contentHash(compiledMetadata) !== contentHash(metadata)) throw new Error("Taskset admission metadata differs from its reviewed snapshots.");
118
+ const execution = (release) => ({ policy: release.policy, environment: release.environment, tools: release.tools });
119
+ if (contentHash(execution(compiled)) !== contentHash(execution(taskset))) throw new Error("Taskset execution differs from its reviewed task definition.");
120
+ const taskContent = (task) => ({
121
+ id: task.id,
122
+ clusterKey: task.clusterKey,
123
+ split: task.split,
124
+ input: task.input,
125
+ expectedOutput: task.expectedOutput,
126
+ policyVisibleContext: task.policyVisibleContext,
127
+ privilegedContextRef: task.privilegedContextRef,
128
+ artifactRefs: task.artifactRefs,
129
+ requiredOutputs: task.requiredOutputs ?? [],
130
+ tags: task.tags
131
+ });
132
+ if (contentHash(compiled.tasks.map(taskContent)) !== contentHash(taskset.tasks.map(taskContent))) throw new Error("Taskset rows differ from their reviewed evidence.");
133
+ return resources;
134
+ }
135
+
136
+ // src/taskset-package-files.ts
137
+ import { z as z2 } from "zod";
138
+ var MAX_TASKSET_PACKAGE_BYTES = 64 * 1024 * 1024;
139
+ var TasksetPackageFileSchema = z2.object({
140
+ asset: ImmutableAssetRefSchema,
141
+ base64: z2.string().max(Math.ceil(MAX_TASKSET_PACKAGE_BYTES / 3) * 4)
142
+ }).strict();
143
+ function decodeTasksetPackageFile(value) {
144
+ const file = TasksetPackageFileSchema.parse(value);
145
+ const raw = atob(file.base64);
146
+ if (btoa(raw) !== file.base64) throw new Error(`Taskset asset ${file.asset.id} has noncanonical base64.`);
147
+ const bytes = Uint8Array.from(raw, (character) => character.charCodeAt(0));
148
+ if (bytes.byteLength !== file.asset.sizeBytes || sha256(bytes) !== file.asset.contentHash) throw new Error(`Taskset asset ${file.asset.id} differs from its immutable bytes.`);
149
+ return bytes;
150
+ }
151
+
152
+ // src/taskset-package-execution.ts
153
+ import { LearningTextAssetSchema as LearningTextAssetSchema2, sealLearningContent } from "@openpond/evals/learning";
154
+ function resolveTasksetPackageExecution(input) {
155
+ if (input.taskset.environment.entrypoint !== "openpond.javascript-environment.v1") return null;
156
+ const byId = new Map(input.files.map((file) => [file.asset.id, file]));
157
+ const read = (id) => {
158
+ const file = byId.get(id);
159
+ if (!file) throw new Error(`Taskset environment asset is missing: ${id}.`);
160
+ if (file.asset.sizeBytes > 524288) throw new Error("Taskset environment source exceeds the authored asset limit.");
161
+ const text = new TextDecoder("utf-8", { fatal: true }).decode(decodeTasksetPackageFile(file));
162
+ return LearningTextAssetSchema2.parse(sealLearningContent({ schemaVersion: "openpond.learningTextAsset.v1", id, revision: 1, asset: file.asset, text }));
163
+ };
164
+ let execution;
165
+ if (input.modelResources) {
166
+ if (!input.modelResources.execution) throw new Error("Bound Taskset JavaScript execution resources are missing.");
167
+ execution = ModelStarterExecutionSchema.parse(input.modelResources.execution);
168
+ } else {
169
+ const declaration = read(modelStarterExecutionAssetId(input.taskset));
170
+ if (declaration.asset.visibility !== "host_private" || declaration.asset.mediaType !== "application/json" || declaration.asset.path !== "environment/execution.json") throw new Error("Taskset execution declaration must be private JSON at environment/execution.json.");
171
+ execution = ModelStarterExecutionSchema.parse(JSON.parse(declaration.text));
172
+ }
173
+ const ids = /* @__PURE__ */ new Set([
174
+ execution.javascript.module.id,
175
+ ...[execution.environment.actionSchemaRef, execution.environment.observationSchemaRef, execution.environment.stateSchemaRef].flatMap((ref) => ref ? [ref.id] : []),
176
+ ...input.taskset.tasks.flatMap((task) => task.privilegedContextRef ? [task.privilegedContextRef] : [])
177
+ ]);
178
+ const assets = [...ids].map(read);
179
+ validateModelStarterExecution(execution, input.taskset, assets);
180
+ return { execution, assets };
181
+ }
182
+ function createTasksetPackageExecutionFile(execution) {
183
+ const asset = createModelStarterExecutionAsset(execution);
184
+ const bytes = new TextEncoder().encode(asset.text);
185
+ let raw = "";
186
+ for (const byte of bytes) raw += String.fromCharCode(byte);
187
+ return { asset: asset.asset, base64: btoa(raw) };
188
+ }
189
+
190
+ // src/taskset-package-contracts.ts
191
+ import { z as z3 } from "zod";
192
+ import { EnvironmentReleaseSchema, VerifierSetReleaseSchema, verifyEnvironmentRelease, verifyVerifierSetRelease } from "@openpond/evals";
193
+ import { assertTasksetRelease, TasksetReleaseSchema } from "@openpond/evals/tasksets";
194
+ import { assertBoundedTaskJson } from "@openpond/evals/task-schema";
195
+ import { taskBatchPackageMetadata as taskBatchPackageMetadata2 } from "@openpond/evals/learning";
196
+
197
+ // src/model-taskset-authoring-lineage.ts
198
+ import { sameLearningRef as sameLearningRef2 } from "@openpond/evals/learning";
199
+ function modelAuthoredTasksetId(lineage) {
200
+ return `model-authored-taskset-${contentHash({ owner: lineage.owner, root: lineage.root })}`;
201
+ }
202
+ function assertModelTasksetAuthoring(taskset) {
203
+ if (taskset.metadata.modelTasksetAuthoring === void 0) return null;
204
+ const lineage = ModelTasksetAuthoringSchema.parse(taskset.metadata.modelTasksetAuthoring);
205
+ if (taskset.id !== modelAuthoredTasksetId(lineage) || (taskset.revision === 1 ? !sameLearningRef2(lineage.parent, lineage.root) : lineage.parent.id !== taskset.id || lineage.parent.revision !== taskset.revision - 1)) {
206
+ throw new Error("Authored Taskset revision differs from its ownership lineage.");
207
+ }
208
+ return lineage;
209
+ }
210
+
211
+ // src/taskset-package-contracts.ts
212
+ var BoundModelResourcesSchema = ModelTasksetPackageSchema.omit({ taskset: true, executionResources: true });
213
+ var TasksetPackageContentSchema = z3.object({
214
+ schemaVersion: z3.literal("openpond.tasksetPackage.v1"),
215
+ taskset: TasksetReleaseSchema,
216
+ environment: EnvironmentReleaseSchema,
217
+ verifierSet: VerifierSetReleaseSchema,
218
+ files: z3.array(TasksetPackageFileSchema).max(1e4),
219
+ modelResources: BoundModelResourcesSchema.optional(),
220
+ learningResources: TasksetPackageLearningResourcesSchema.optional()
221
+ }).strict();
222
+ var TasksetPackageSchema = TasksetPackageContentSchema.extend({ contentHash: z3.string().regex(/^[a-f0-9]{64}$/) }).strict();
223
+ function tasksetPackageRewardBinding(value) {
224
+ return value.learningResources ? taskBatchPackageMetadata2(value.taskset).binding : value.modelResources?.rewardBinding ?? null;
225
+ }
226
+ function resolveTasksetPackageInstructions(value) {
227
+ if (value.learningResources) return taskBatchPackageMetadata2(value.taskset).definition.instructions;
228
+ if (value.modelResources) return value.modelResources.taskDefinition.instructions;
229
+ const authoring = z3.object({ instructions: z3.string().max(2e4).optional() }).passthrough().parse(value.taskset.metadata.ordinaryAuthoring ?? {});
230
+ return authoring.instructions ?? "";
231
+ }
232
+ function validateTasksetPackage(value) {
233
+ assertBoundedTaskJson(value, MAX_TASKSET_PACKAGE_BYTES);
234
+ const result = TasksetPackageSchema.parse(value);
235
+ const { contentHash: hash, ...content } = result;
236
+ if (contentHash(content) !== hash) throw new Error("Taskset package content hash differs from its bytes.");
237
+ const { taskset, environment, verifierSet } = result;
238
+ assertTasksetRelease(taskset);
239
+ const authoring = assertModelTasksetAuthoring(taskset);
240
+ if (authoring && (result.modelResources || result.learningResources)) throw new Error("Taskset package cannot declare competing authoring graphs.");
241
+ if (!verifyEnvironmentRelease(environment) || !verifyVerifierSetRelease(verifierSet) || !same(taskset.environmentRelease, { id: environment.id, contentHash: environment.contentHash }) || !same(taskset.verifierSetRelease, { id: verifierSet.id, contentHash: verifierSet.contentHash }) || !same(taskset.environment, environment.contract) || !same(taskset.graders, verifierSet.graders)) {
242
+ throw new Error("Taskset package execution releases do not match its Taskset.");
243
+ }
244
+ const files = /* @__PURE__ */ new Map();
245
+ for (const file of result.files) {
246
+ if (files.has(file.asset.id)) throw new Error(`Duplicate Taskset asset identity: ${file.asset.id}.`);
247
+ decodeTasksetPackageFile(file);
248
+ files.set(file.asset.id, file);
249
+ }
250
+ function requireAsset(ref) {
251
+ const file = files.get(ref.id);
252
+ if (!file || !same(file.asset, ref)) throw new Error(`Taskset package asset is missing or mismatched: ${ref.id}.`);
253
+ }
254
+ for (const task of taskset.tasks) {
255
+ for (const asset of task.artifactRefs) requireAsset(asset);
256
+ for (const output of task.requiredOutputs ?? []) if (output.schemaRef) requireAsset(output.schemaRef);
257
+ if (task.privilegedContextRef && files.get(task.privilegedContextRef)?.asset.visibility !== "host_private") {
258
+ throw new Error(`Taskset package private context is missing: ${task.id}.`);
259
+ }
260
+ }
261
+ for (const ref of [environment.actionSchemaRef, environment.observationSchemaRef, environment.stateSchemaRef]) if (ref) requireAsset(ref);
262
+ for (const grader of taskset.graders) {
263
+ const ref = "verifierRef" in grader ? grader.verifierRef : "rubricRef" in grader ? grader.rubricRef : null;
264
+ if (ref) {
265
+ requireAsset(ref);
266
+ if (ref.visibility === "policy") throw new Error(`Taskset grader asset must be private: ${ref.id}.`);
267
+ }
268
+ }
269
+ if (taskset.metrics?.customAggregator) {
270
+ const aggregator = taskset.metrics.customAggregator;
271
+ const modules = result.files.filter((file) => file.asset.path === aggregator.module);
272
+ if (modules.length !== 1 || modules[0].asset.contentHash !== aggregator.contentHash || modules[0].asset.sizeBytes > 524288 || modules[0].asset.visibility === "policy") {
273
+ throw new Error("Taskset metric module is missing or mismatched, public, or exceeds the source limit.");
274
+ }
275
+ }
276
+ for (const declarations of [taskset.metadata.environmentResources, environment.metadata.resources]) {
277
+ if (declarations === void 0) continue;
278
+ for (const resource of z3.array(z3.object({ path: z3.string().min(1) }).passthrough()).parse(declarations)) {
279
+ if (!result.files.some((file) => file.asset.path === resource.path)) throw new Error(`Taskset environment resource is missing: ${resource.path}.`);
280
+ }
281
+ }
282
+ if (result.learningResources) {
283
+ if (result.modelResources) throw new Error("Taskset package cannot declare competing authoring graphs.");
284
+ const learning = validateTasksetLearningResources(taskset, result.learningResources);
285
+ for (const expected of learningPackageContextFiles(learning)) {
286
+ if (!same(files.get(expected.asset.id), expected)) throw new Error("Taskset private context differs from its reviewed evidence.");
287
+ }
288
+ for (const asset of learning.assets) requireAsset(asset.asset);
289
+ } else if (result.modelResources) {
290
+ const model = validateModelTasksetPackage({ ...result.modelResources, taskset, executionResources: { environment, verifierSet } });
291
+ for (const asset of model.assets) requireAsset(asset.asset);
292
+ } else if (["starter", "rewardBinding", "rewardExecution", "modelTasksetDerivation", "learning"].some((key) => taskset.metadata[key] !== void 0)) {
293
+ throw new Error("Bound Taskset publication requires its complete model resources.");
294
+ }
295
+ resolveTasksetPackageExecution(result);
296
+ resolveTasksetPackageInstructions(result);
297
+ return result;
298
+ }
299
+ function createTasksetPackage(value) {
300
+ assertBoundedTaskJson(value, MAX_TASKSET_PACKAGE_BYTES);
301
+ const content = TasksetPackageContentSchema.parse(value);
302
+ return validateTasksetPackage({ ...content, contentHash: contentHash(content) });
303
+ }
304
+ function same(left, right) {
305
+ return contentHash({ value: left }) === contentHash({ value: right });
306
+ }
307
+
308
+ // src/taskset-package-client.ts
309
+ import { z as z4 } from "zod";
310
+ import { learningRef as learningRef2 } from "@openpond/evals/learning";
311
+ var IdSchema = z4.string().trim().min(1).max(500);
312
+ var HashSchema = z4.string().regex(/^[a-f0-9]{64}$/);
313
+ var TasksetPackageModelConfigurationSchema = HostedModelProjectSyncSchema.pick({
314
+ portableProjectId: true,
315
+ name: true,
316
+ objective: true,
317
+ defaultBaseModel: true,
318
+ defaultDestinationId: true,
319
+ sourceRevision: true,
320
+ sourceUpdatedAt: true
321
+ }).extend({ trainingSetup: HostedModelProjectTrainingSetupSchema.omit({ tasksetRef: true, rewardBindingRef: true, tasksetRelease: true, recipe: true }) }).strict();
322
+ var TasksetPackagePublicationSchema = z4.object({
323
+ schemaVersion: z4.literal("openpond.tasksetPackagePublication.v1"),
324
+ operationId: IdSchema,
325
+ modelProjectId: IdSchema,
326
+ expectedProjectEtag: HashSchema.nullable(),
327
+ name: z4.string().trim().min(1).max(200),
328
+ description: z4.string().max(5e3),
329
+ buildIntent: z4.enum(["demonstrations", "preferences", "verifiable_reward", "rubric", "discovery"]),
330
+ methodHint: z4.enum(["sft", "dpo", "grpo", "ppo"]).nullable(),
331
+ package: TasksetPackageSchema,
332
+ modelConfiguration: TasksetPackageModelConfigurationSchema.optional(),
333
+ selection: z4.enum(["select", "attach"]).optional()
334
+ }).strict().refine((value) => value.selection !== "attach" || value.modelConfiguration === void 0, "Attachment-only publication cannot replace Model configuration.");
335
+ var TasksetPackageReceiptSchema = z4.object({
336
+ schemaVersion: z4.literal("openpond.tasksetPackageReceipt.v1"),
337
+ teamId: IdSchema,
338
+ modelProjectId: IdSchema,
339
+ operationId: IdSchema,
340
+ taskset: TasksetCatalogReleaseRefSchema,
341
+ packageHash: HashSchema,
342
+ hostedTasksetId: IdSchema,
343
+ projectEtag: HashSchema,
344
+ project: HostedModelProjectSummarySchema.optional(),
345
+ selection: z4.enum(["select", "attach"]).optional()
346
+ }).strict();
347
+ var TasksetPackageReadbackSchema = z4.object({
348
+ schemaVersion: z4.literal("openpond.tasksetPackageReadback.v1"),
349
+ teamId: IdSchema,
350
+ modelProjectId: IdSchema,
351
+ package: TasksetPackageSchema
352
+ }).strict();
353
+ var OpenPondTasksetPackageError = class extends Error {
354
+ constructor(status, code, message) {
355
+ super(message);
356
+ this.status = status;
357
+ this.code = code;
358
+ this.name = "OpenPondTasksetPackageError";
359
+ }
360
+ status;
361
+ code;
362
+ };
363
+ var OpenPondTasksetPackageClient = class {
364
+ #options;
365
+ constructor(options) {
366
+ const url = new URL(options.baseUrl);
367
+ if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.search || url.hash || !options.apiKey.trim() || !options.teamId.trim()) throw new Error("Taskset package client requires a clean HTTP(S) endpoint and workspace credentials.");
368
+ this.#options = { ...options, baseUrl: url.toString().replace(/\/+$/, "") };
369
+ }
370
+ async publish(input, options = {}) {
371
+ const request = TasksetPackagePublicationSchema.parse(input);
372
+ validateTasksetPackage(request.package);
373
+ const receipt = TasksetPackageReceiptSchema.parse(await this.#request("", "POST", request, options.signal));
374
+ const release = request.package.taskset;
375
+ if (receipt.teamId !== this.#options.teamId || receipt.modelProjectId !== request.modelProjectId || receipt.operationId !== request.operationId || receipt.packageHash !== request.package.contentHash || receipt.taskset.id !== release.id || receipt.taskset.revision !== release.revision || receipt.taskset.contentHash !== release.contentHash) {
376
+ throw new OpenPondTasksetPackageError(502, "package_receipt_mismatch", "Taskset publication receipt did not match the requested package and owner.");
377
+ }
378
+ if (request.selection !== void 0 && receipt.selection !== request.selection) throw new OpenPondTasksetPackageError(502, "package_receipt_mismatch", "Taskset publication did not retain its selection mode.");
379
+ if (request.selection === "attach" && receipt.projectEtag !== request.expectedProjectEtag) throw new OpenPondTasksetPackageError(502, "package_receipt_mismatch", "Attaching a historical Taskset changed the Model configuration.");
380
+ if (request.modelConfiguration) {
381
+ const expected = request.modelConfiguration;
382
+ const project = receipt.project;
383
+ const binding = tasksetPackageRewardBinding(request.package);
384
+ const setup = HostedModelProjectTrainingSetupSchema.parse({
385
+ ...expected.trainingSetup,
386
+ tasksetRef: learningRef2(release),
387
+ rewardBindingRef: binding ? learningRef2(binding) : null,
388
+ tasksetRelease: null,
389
+ recipe: null
390
+ });
391
+ if (!project || project.teamId !== this.#options.teamId || project.etag !== receipt.projectEtag || ![project.id, project.portableProjectId].includes(request.modelProjectId) || project.portableProjectId !== expected.portableProjectId || project.name !== expected.name || project.objective !== expected.objective || project.sourceRevision !== expected.sourceRevision || Date.parse(project.sourceUpdatedAt) !== Date.parse(expected.sourceUpdatedAt) || contentHash(project.defaultBaseModel) !== contentHash(expected.defaultBaseModel) || project.defaultDestinationId !== expected.defaultDestinationId || contentHash(project.trainingSetup) !== contentHash(setup)) {
392
+ throw new OpenPondTasksetPackageError(502, "package_receipt_mismatch", "Taskset publication did not retain the requested Model configuration.");
393
+ }
394
+ }
395
+ return receipt;
396
+ }
397
+ async get(modelProjectId, reference, options = {}) {
398
+ const project = IdSchema.parse(modelProjectId);
399
+ const ref = TasksetCatalogReleaseRefSchema.parse(reference);
400
+ const expectedPackageHash = options.expectedPackageHash === void 0 ? void 0 : HashSchema.parse(options.expectedPackageHash);
401
+ const response = TasksetPackageReadbackSchema.parse(await this.#request(`/${encodeURIComponent(project)}/${encodeURIComponent(ref.id)}/${ref.revision}/${ref.contentHash}`, "GET", void 0, options.signal));
402
+ const taskset = response.package.taskset;
403
+ if (response.teamId !== this.#options.teamId || response.modelProjectId !== project || taskset.id !== ref.id || taskset.revision !== ref.revision || taskset.contentHash !== ref.contentHash) throw new OpenPondTasksetPackageError(502, "package_readback_mismatch", "Taskset package did not match the requested release and owner.");
404
+ if (expectedPackageHash !== void 0 && response.package.contentHash !== expectedPackageHash) throw new OpenPondTasksetPackageError(502, "package_readback_mismatch", "Taskset package did not match the saved publication receipt.");
405
+ return validateTasksetPackage(response.package);
406
+ }
407
+ async #request(path, method, body, signal) {
408
+ const serialized = body === void 0 ? void 0 : JSON.stringify(body);
409
+ if (serialized && new TextEncoder().encode(serialized).byteLength > MAX_TASKSET_PACKAGE_BYTES) throw new OpenPondTasksetPackageError(413, "package_too_large", "Taskset publication exceeds the 64 MiB envelope.");
410
+ const response = await (this.#options.fetch ?? globalThis.fetch)(`${this.#options.baseUrl}/v1/taskset-packages${path}`, {
411
+ method,
412
+ headers: { Authorization: `Bearer ${this.#options.apiKey}`, "X-OpenPond-Team-Id": this.#options.teamId, Accept: "application/json", ...serialized ? { "Content-Type": "application/json" } : {} },
413
+ body: serialized,
414
+ signal,
415
+ redirect: "error"
416
+ });
417
+ const reader = response.body?.getReader();
418
+ if (!reader) throw new OpenPondTasksetPackageError(response.status, "empty_response", "Taskset package response was empty.");
419
+ const decoder = new TextDecoder("utf-8", { fatal: true });
420
+ let bytes = 0;
421
+ let text = "";
422
+ try {
423
+ while (true) {
424
+ const chunk = await reader.read();
425
+ if (chunk.done) break;
426
+ bytes += chunk.value.byteLength;
427
+ if (bytes > MAX_TASKSET_PACKAGE_BYTES) throw new OpenPondTasksetPackageError(413, "package_too_large", "Taskset response exceeds the 64 MiB envelope.");
428
+ text += decoder.decode(chunk.value, { stream: true });
429
+ }
430
+ text += decoder.decode();
431
+ } finally {
432
+ await reader.cancel();
433
+ reader.releaseLock();
434
+ }
435
+ const payload = JSON.parse(text);
436
+ if (!response.ok) {
437
+ const error = z4.object({ code: z4.string(), message: z4.string() }).safeParse(payload);
438
+ throw new OpenPondTasksetPackageError(response.status, error.success ? error.data.code : "package_request_failed", error.success ? error.data.message : `Taskset package request failed (${response.status}).`);
439
+ }
440
+ return payload;
441
+ }
442
+ };
443
+
444
+ // src/taskset-draft-dataset-artifacts.ts
445
+ import { z as z5 } from "zod";
446
+ var IdSchema2 = z5.string().trim().min(1).max(240);
447
+ var TimestampSchema = z5.string().trim().min(1);
448
+ var HashSchema2 = z5.string().trim().min(8).max(256);
449
+ var RelativePathSchema = z5.string().trim().min(1).max(1e3).refine(
450
+ (value) => !value.startsWith("/") && !value.startsWith("\\") && !value.split(/[\\/]/).includes(".."),
451
+ "Artifact paths must be relative and stay inside the Dataset."
452
+ );
453
+ var DatasetSplitSchema = z5.enum([
454
+ "train",
455
+ "validation",
456
+ "test",
457
+ "frozen_eval"
458
+ ]);
459
+ var DatasetSemanticFieldSchema = z5.object({
460
+ name: z5.string().trim().min(1).max(500),
461
+ semanticRole: z5.enum([
462
+ "row_id",
463
+ "cluster_id",
464
+ "prompt",
465
+ "messages",
466
+ "demonstration",
467
+ "chosen",
468
+ "rejected",
469
+ "expected_output",
470
+ "privileged_context",
471
+ "reward",
472
+ "feedback",
473
+ "tag",
474
+ "metadata"
475
+ ]),
476
+ logicalType: z5.enum([
477
+ "string",
478
+ "integer",
479
+ "float",
480
+ "boolean",
481
+ "json",
482
+ "messages"
483
+ ]),
484
+ nullable: z5.boolean(),
485
+ policy: z5.enum(["visible", "privileged", "metadata"])
486
+ });
487
+ var DatasetSemanticSchemaSchema = z5.object({
488
+ schemaVersion: z5.literal("openpond.datasetSemanticSchema.v1"),
489
+ fields: z5.array(DatasetSemanticFieldSchema).min(1).max(1e4),
490
+ schemaHash: HashSchema2
491
+ });
492
+ var DatasetShardRefSchema = z5.object({
493
+ id: IdSchema2,
494
+ split: DatasetSplitSchema,
495
+ path: RelativePathSchema,
496
+ contentHash: HashSchema2,
497
+ schemaHash: HashSchema2,
498
+ sizeBytes: z5.number().int().nonnegative(),
499
+ rowCount: z5.number().int().positive(),
500
+ rowGroupCount: z5.number().int().positive()
501
+ });
502
+ var DatasetArtifactManifestSchema = z5.object({
503
+ schemaVersion: z5.literal("openpond.datasetArtifact.v1"),
504
+ id: IdSchema2,
505
+ tasksetId: IdSchema2,
506
+ tasksetRevision: z5.number().int().positive(),
507
+ contentHash: HashSchema2,
508
+ format: z5.literal("parquet"),
509
+ schema: DatasetSemanticSchemaSchema,
510
+ shards: z5.array(DatasetShardRefSchema).min(1).max(1e5),
511
+ rowCount: z5.number().int().positive(),
512
+ splitCounts: z5.record(DatasetSplitSchema, z5.number().int().nonnegative()),
513
+ sourceReceiptRefs: z5.array(IdSchema2).min(1).max(1e5),
514
+ mappingHash: HashSchema2,
515
+ qualityReportHash: HashSchema2,
516
+ createdAt: TimestampSchema
517
+ });
518
+ var DatasetArtifactSummarySchema = z5.object({
519
+ schemaVersion: z5.literal("openpond.datasetArtifactSummary.v1"),
520
+ artifactId: IdSchema2,
521
+ tasksetId: IdSchema2,
522
+ tasksetRevision: z5.number().int().positive(),
523
+ format: z5.literal("parquet"),
524
+ rowCount: z5.number().int().positive(),
525
+ splitCounts: z5.record(DatasetSplitSchema, z5.number().int().nonnegative()),
526
+ sizeBytes: z5.number().int().nonnegative(),
527
+ contentHash: HashSchema2,
528
+ available: z5.boolean(),
529
+ unavailableReason: z5.string().trim().min(1).max(2e3).nullable(),
530
+ createdAt: TimestampSchema
531
+ });
532
+ var DatasetCatalogItemSchema = z5.object({
533
+ schemaVersion: z5.literal("openpond.datasetCatalogItem.v1"),
534
+ tasksetId: IdSchema2,
535
+ tasksetRevision: z5.number().int().positive(),
536
+ artifactId: IdSchema2.nullable(),
537
+ name: z5.string().trim().min(1).max(500),
538
+ status: z5.enum([
539
+ "draft",
540
+ "awaiting_disclosure_approval",
541
+ "awaiting_materialization_approval",
542
+ "materializing",
543
+ "validating",
544
+ "needs_review",
545
+ "baselining",
546
+ "ready",
547
+ "blocked",
548
+ "failed",
549
+ "archived"
550
+ ]),
551
+ storageKind: z5.enum(["inline", "parquet"]),
552
+ rowCount: z5.number().int().nonnegative(),
553
+ splitCounts: z5.record(DatasetSplitSchema, z5.number().int().nonnegative()),
554
+ sizeBytes: z5.number().int().nonnegative().nullable(),
555
+ available: z5.boolean(),
556
+ unavailableReason: z5.string().trim().min(1).max(2e3).nullable(),
557
+ createdAt: TimestampSchema,
558
+ updatedAt: TimestampSchema
559
+ });
560
+ var DatasetCatalogResponseSchema = z5.object({
561
+ schemaVersion: z5.literal("openpond.datasetCatalog.v1"),
562
+ profileId: IdSchema2,
563
+ datasets: z5.array(DatasetCatalogItemSchema),
564
+ generatedAt: TimestampSchema
565
+ });
566
+ var DatasetArtifactRegistryEntrySchema = z5.object({
567
+ schemaVersion: z5.literal("openpond.datasetArtifactRegistry.v1"),
568
+ manifest: DatasetArtifactManifestSchema,
569
+ profileId: IdSchema2,
570
+ storageRoot: z5.string().trim().min(1).max(4e3),
571
+ relativeManifestPath: RelativePathSchema,
572
+ available: z5.boolean(),
573
+ unavailableReason: z5.string().trim().min(1).max(2e3).nullable(),
574
+ verifiedAt: TimestampSchema.nullable(),
575
+ createdAt: TimestampSchema,
576
+ updatedAt: TimestampSchema
577
+ });
578
+ var DatasetRowPageRequestSchema = z5.object({
579
+ split: DatasetSplitSchema.nullable().default(null),
580
+ cursor: z5.string().trim().min(1).max(2e3).nullable().default(null),
581
+ limit: z5.number().int().min(1).max(100).default(25),
582
+ columns: z5.array(z5.string().trim().min(1).max(500)).max(100).default([])
583
+ });
584
+ var DatasetRowPageSchema = z5.object({
585
+ schemaVersion: z5.literal("openpond.datasetRowPage.v1"),
586
+ tasksetId: IdSchema2,
587
+ tasksetRevision: z5.number().int().positive(),
588
+ artifactHash: HashSchema2,
589
+ split: DatasetSplitSchema.nullable(),
590
+ rows: z5.array(z5.record(z5.string(), z5.unknown())).max(100),
591
+ nextCursor: z5.string().max(2e3).nullable(),
592
+ totalRows: z5.number().int().nonnegative(),
593
+ returnedRows: z5.number().int().nonnegative()
594
+ });
595
+ var DatasetStorageSettingsSchema = z5.object({
596
+ schemaVersion: z5.literal("openpond.datasetStorageSettings.v1"),
597
+ datasetStorePath: z5.string().trim().min(1).max(4e3),
598
+ updatedAt: TimestampSchema
599
+ });
600
+ var DatasetStorageRootSchema = z5.object({
601
+ id: IdSchema2,
602
+ label: z5.string().trim().min(1).max(500),
603
+ path: z5.string().trim().min(1).max(4e3),
604
+ datasetStorePath: z5.string().trim().min(1).max(4e3),
605
+ kind: z5.enum(["local", "network", "removable", "cache"]),
606
+ configured: z5.boolean(),
607
+ mounted: z5.boolean(),
608
+ writable: z5.boolean(),
609
+ totalBytes: z5.number().int().nonnegative().nullable(),
610
+ freeBytes: z5.number().int().nonnegative().nullable()
611
+ });
612
+ var DatasetStorageStateSchema = z5.object({
613
+ schemaVersion: z5.literal("openpond.datasetStorageState.v1"),
614
+ settings: DatasetStorageSettingsSchema,
615
+ storageRoots: z5.array(DatasetStorageRootSchema)
616
+ });
617
+ var UpdateDatasetStorageSettingsRequestSchema = z5.object({
618
+ datasetStorePath: z5.string().trim().min(1).max(4e3)
619
+ });
620
+
621
+ // src/taskset-draft-dataset-sources.ts
622
+ import { z as z6 } from "zod";
623
+ var IdSchema3 = z6.string().trim().min(1).max(240);
624
+ var TimestampSchema2 = z6.string().trim().min(1);
625
+ var HashSchema3 = z6.string().trim().min(8).max(256);
626
+ var MetadataSchema = z6.record(z6.string(), z6.unknown()).default({});
627
+ var RevisionSchema = z6.string().trim().min(7).max(256);
628
+ var DatasetSourceReviewStatusSchema = z6.enum([
629
+ "pending",
630
+ "approved",
631
+ "review",
632
+ "blocked"
633
+ ]);
634
+ var ExternalDatasetSourceBaseSchema = z6.object({
635
+ id: IdSchema3,
636
+ profileId: IdSchema3,
637
+ title: z6.string().trim().min(1).max(500),
638
+ sourceHash: HashSchema3,
639
+ occurredAt: TimestampSchema2,
640
+ licensingStatus: DatasetSourceReviewStatusSchema,
641
+ secretScanStatus: z6.enum(["pending", "passed", "blocked"]),
642
+ piiScanStatus: z6.enum(["pending", "passed", "review", "blocked"]),
643
+ metadata: MetadataSchema
644
+ });
645
+ var HuggingFaceDatasetSourceRefSchema = ExternalDatasetSourceBaseSchema.extend({
646
+ schemaVersion: z6.literal("openpond.huggingFaceDatasetSource.v1"),
647
+ kind: z6.literal("huggingface"),
648
+ repositoryId: z6.string().trim().regex(/^[^/\s]+\/[^/\s]+$/).max(500),
649
+ repositoryUrl: z6.string().url().max(2e3),
650
+ revision: RevisionSchema,
651
+ configuration: z6.string().trim().min(1).max(500),
652
+ upstreamSplits: z6.array(z6.string().trim().min(1).max(500)).min(1).max(1e3),
653
+ gated: z6.boolean(),
654
+ private: z6.boolean(),
655
+ declaredLicense: z6.string().trim().min(1).max(500).nullable(),
656
+ sourceFileHashes: z6.array(HashSchema3).min(1).max(1e5)
657
+ });
658
+ var UploadedFileDatasetSourceRefSchema = ExternalDatasetSourceBaseSchema.extend({
659
+ schemaVersion: z6.literal("openpond.uploadedFileDatasetSource.v1"),
660
+ kind: z6.literal("uploaded_file"),
661
+ originalFileNames: z6.array(z6.string().trim().min(1).max(500)).min(1).max(1e3),
662
+ mediaTypes: z6.array(z6.string().trim().min(1).max(200)).min(1).max(1e3),
663
+ sourceFileHashes: z6.array(HashSchema3).min(1).max(1e3),
664
+ totalBytes: z6.number().int().nonnegative(),
665
+ parserVersion: z6.string().trim().min(1).max(200)
666
+ });
667
+ var GeneratedDatasetSourceRefSchema = ExternalDatasetSourceBaseSchema.extend({
668
+ schemaVersion: z6.literal("openpond.generatedDatasetSource.v1"),
669
+ kind: z6.literal("generated"),
670
+ generatorId: IdSchema3,
671
+ generatorVersion: z6.string().trim().min(1).max(200),
672
+ seed: z6.number().int(),
673
+ generatorHash: HashSchema3
674
+ });
675
+ var LearningBatchDatasetSourceRefSchema = ExternalDatasetSourceBaseSchema.extend({
676
+ schemaVersion: z6.literal("openpond.learningBatchDatasetSource.v1"),
677
+ kind: z6.literal("learning_batch"),
678
+ batch: z6.object({ id: IdSchema3, revision: z6.number().int().positive(), contentHash: HashSchema3 }).strict(),
679
+ taskDefinition: z6.object({ id: IdSchema3, revision: z6.number().int().positive(), contentHash: HashSchema3 }).strict(),
680
+ admittedBy: IdSchema3
681
+ });
682
+ var ExternalDatasetSourceRefSchema = z6.discriminatedUnion("kind", [
683
+ HuggingFaceDatasetSourceRefSchema,
684
+ UploadedFileDatasetSourceRefSchema,
685
+ GeneratedDatasetSourceRefSchema,
686
+ LearningBatchDatasetSourceRefSchema
687
+ ]);
688
+
689
+ // src/taskset-draft-harness-actions.ts
690
+ import { z as z7 } from "zod";
691
+ var HarnessActionBindingSchema = z7.object({
692
+ schemaVersion: z7.literal("openpond.harnessActionBinding.v1"),
693
+ actionId: ReleaseIdSchema,
694
+ modelToolName: z7.string().trim().min(1).max(64).regex(/^[a-zA-Z][a-zA-Z0-9_-]*$/),
695
+ description: z7.string().trim().min(1).max(1e3),
696
+ inputSchema: z7.record(z7.string(), z7.unknown()),
697
+ actionSchemaHash: ReleaseHashSchema,
698
+ agentRelease: ImmutableReleaseRefSchema,
699
+ implementationHash: ReleaseHashSchema,
700
+ runtimeBindingId: ReleaseIdSchema,
701
+ capabilityReceiptHash: ReleaseHashSchema,
702
+ sideEffect: z7.enum(["read", "write"]),
703
+ studentVisible: z7.boolean(),
704
+ timeoutMs: z7.number().int().positive().max(36e5),
705
+ episodeArgumentBindings: z7.array(
706
+ z7.object({
707
+ argument: ReleaseIdSchema,
708
+ source: z7.literal("case_id")
709
+ }).strict()
710
+ ).max(20).default([])
711
+ }).strict();
712
+
713
+ // src/taskset-draft-core.ts
714
+ import { z as z8 } from "zod";
715
+ var IdSchema4 = z8.string().trim().min(1).max(240);
716
+ var TimestampSchema3 = z8.string().trim().min(1);
717
+ var HashSchema4 = z8.string().trim().min(8).max(256);
718
+ var Sha256Schema = z8.string().trim().regex(/^[a-f0-9]{64}$/);
719
+ var CodeIdentifierSchema = z8.string().trim().regex(/^[A-Za-z_$][A-Za-z0-9_$]*$/);
720
+ var MetadataSchema2 = z8.record(z8.string(), z8.unknown()).default({});
721
+ var NullableIdSchema = IdSchema4.nullable();
722
+ function safeRelativeFilePath(value) {
723
+ const normalized = value.trim().replaceAll("\\", "/");
724
+ if (!normalized || normalized.startsWith("/") || normalized === "." || normalized === "..") {
725
+ return false;
726
+ }
727
+ return !normalized.split("/").some(
728
+ (segment) => !segment || segment === "." || segment === ".."
729
+ );
730
+ }
731
+ function safeFileName(value) {
732
+ const normalized = value.trim();
733
+ return normalized.length > 0 && normalized !== "." && normalized !== ".." && !normalized.includes("/") && !normalized.includes("\\") && !normalized.includes("\0");
734
+ }
735
+ var TasksetSplitSchema = DatasetSplitSchema;
736
+ var TasksetPurposeSchema = z8.enum(["general", "benchmark"]);
737
+ var TasksetBenchmarkBindingSchema = z8.object({
738
+ schemaVersion: z8.literal("openpond.tasksetBenchmark.v1"),
739
+ definitionId: IdSchema4,
740
+ releaseId: IdSchema4,
741
+ releaseHash: Sha256Schema,
742
+ managedReleasePath: z8.string().trim().min(1).max(1e3).refine(safeRelativeFilePath, "Benchmark release paths must remain relative."),
743
+ adaptationSplit: TasksetSplitSchema,
744
+ evaluationSplit: TasksetSplitSchema,
745
+ primaryMetric: z8.enum([
746
+ "foreground_tokens",
747
+ "success_rate",
748
+ "latency_ms",
749
+ "cost_usd"
750
+ ]),
751
+ qualityGate: z8.enum(["none", "non_regression", "all_pass"]),
752
+ source: z8.enum(["builtin", "imported"]),
753
+ metadata: MetadataSchema2
754
+ });
755
+ var TasksetPreferenceComparisonBindingSchema = z8.object({
756
+ schemaVersion: z8.literal("openpond.tasksetPreferenceComparisonBinding.v1"),
757
+ releaseId: IdSchema4,
758
+ releaseHash: Sha256Schema,
759
+ publishedAt: TimestampSchema3,
760
+ metadata: MetadataSchema2
761
+ });
762
+ var TrainingSourceConsentSchema = z8.object({
763
+ status: z8.enum(["pending", "granted", "denied", "revoked"]),
764
+ scope: z8.enum(["metadata_only", "selected_turns", "full_session"]),
765
+ grantedBy: NullableIdSchema,
766
+ grantedAt: TimestampSchema3.nullable(),
767
+ purpose: z8.literal("task_authoring_and_evaluation")
768
+ });
769
+ var TrainingSourceRefSchema = z8.object({
770
+ schemaVersion: z8.literal("openpond.trainingSource.v1"),
771
+ id: IdSchema4,
772
+ profileId: IdSchema4,
773
+ sessionId: IdSchema4,
774
+ turnIds: z8.array(IdSchema4).max(1e3).default([]),
775
+ workspaceId: NullableIdSchema,
776
+ sourceHash: HashSchema4,
777
+ clusterKey: IdSchema4,
778
+ title: z8.string().trim().min(1).max(500),
779
+ occurredAt: TimestampSchema3,
780
+ consent: TrainingSourceConsentSchema,
781
+ connectedAppIds: z8.array(IdSchema4).max(100).default([]),
782
+ secretScanStatus: z8.enum(["pending", "passed", "blocked"]),
783
+ piiScanStatus: z8.enum(["pending", "passed", "review", "blocked"]),
784
+ licensingStatus: z8.enum(["pending", "approved", "review", "blocked"]),
785
+ metadata: MetadataSchema2
786
+ });
787
+ var TasksetSourceRefSchema = z8.union([
788
+ TrainingSourceRefSchema,
789
+ ExternalDatasetSourceRefSchema
790
+ ]);
791
+ var TaskPolicyBoundarySchema = z8.object({
792
+ policyVisibleFields: z8.array(IdSchema4).max(1e3).default([]),
793
+ privilegedFields: z8.array(IdSchema4).max(1e3).default([]),
794
+ hiddenGraderRefs: z8.array(IdSchema4).max(100).default([]),
795
+ connectedAppScopes: z8.array(IdSchema4).max(100).default([])
796
+ });
797
+ var TaskAssetRefSchema = z8.object({
798
+ id: IdSchema4,
799
+ sourceRefId: IdSchema4,
800
+ artifactRef: z8.string().trim().min(1).max(4e3).refine(safeRelativeFilePath, "Task asset references must be safe relative paths."),
801
+ fileName: z8.string().trim().min(1).max(500).refine(safeFileName, "Task asset file names must not contain path separators."),
802
+ mediaType: z8.string().trim().min(1).max(200),
803
+ sha256: Sha256Schema,
804
+ sizeBytes: z8.number().int().nonnegative().max(25e7),
805
+ split: TasksetSplitSchema,
806
+ metadata: MetadataSchema2
807
+ });
808
+ var TaskRequiredOutputSchema = z8.object({
809
+ path: z8.string().trim().min(1).max(1e3).refine(safeRelativeFilePath, "Required output paths must stay inside the Work output directory."),
810
+ mediaType: z8.string().trim().min(1).max(200),
811
+ schemaRef: IdSchema4.nullable().optional(),
812
+ maxBytes: z8.number().int().positive().max(1e7).optional(),
813
+ metadata: MetadataSchema2
814
+ });
815
+ var TaskDataRecordSchema = z8.object({
816
+ schemaVersion: z8.literal("openpond.taskData.v1"),
817
+ id: IdSchema4,
818
+ clusterKey: IdSchema4,
819
+ split: TasksetSplitSchema,
820
+ input: z8.record(z8.string(), z8.unknown()),
821
+ expectedOutput: z8.record(z8.string(), z8.unknown()).nullable(),
822
+ policyVisibleContext: z8.record(z8.string(), z8.unknown()).default({}),
823
+ privilegedContextRef: NullableIdSchema,
824
+ sourceRefs: z8.array(IdSchema4).min(1).max(100),
825
+ assets: z8.array(TaskAssetRefSchema).max(1e3).optional(),
826
+ resourceRefs: z8.array(IdSchema4).max(1e3).optional(),
827
+ requiredOutputs: z8.array(TaskRequiredOutputSchema).max(100).optional(),
828
+ tags: z8.array(IdSchema4).max(100).default([]),
829
+ metadata: MetadataSchema2
830
+ });
831
+ var TasksetEnvironmentResourceSchema = z8.object({
832
+ id: IdSchema4,
833
+ kind: z8.enum(["file", "catalog", "configuration", "code_module"]),
834
+ path: z8.string().trim().min(1).max(1e3).refine(safeRelativeFilePath, "Environment resource paths must remain relative."),
835
+ mediaType: z8.string().trim().min(1).max(200).nullable().optional(),
836
+ visibility: z8.enum(["policy_visible", "policy_hidden", "privileged"]),
837
+ required: z8.boolean(),
838
+ metadata: MetadataSchema2
839
+ });
840
+ var LearningSignalBaseSchema = z8.object({
841
+ id: IdSchema4,
842
+ taskId: NullableIdSchema,
843
+ sourceRefs: z8.array(IdSchema4).min(1).max(100),
844
+ artifactRef: IdSchema4,
845
+ approved: z8.boolean(),
846
+ confidence: z8.number().min(0).max(1),
847
+ metadata: MetadataSchema2
848
+ });
849
+ var DemonstrationSignalSchema = LearningSignalBaseSchema.extend({
850
+ kind: z8.literal("demonstration"),
851
+ prompt: z8.string().max(1e5).nullable().default(null),
852
+ response: z8.string().max(2e5).nullable().default(null)
853
+ });
854
+ var PreferenceSignalSchema = LearningSignalBaseSchema.extend({
855
+ kind: z8.literal("preference"),
856
+ prompt: z8.string().max(1e5),
857
+ chosen: z8.string().max(2e5),
858
+ rejected: z8.string().max(2e5),
859
+ rationale: z8.string().max(1e5).nullable().default(null)
860
+ });
861
+ var CorrectionSignalSchema = LearningSignalBaseSchema.extend({
862
+ kind: z8.literal("correction"),
863
+ original: z8.string().max(2e5),
864
+ corrected: z8.string().max(2e5),
865
+ rationale: z8.string().max(1e5).nullable().default(null)
866
+ });
867
+ var FeedbackSignalSchema = LearningSignalBaseSchema.extend({
868
+ kind: z8.literal("feedback"),
869
+ feedback: z8.string().max(1e5),
870
+ polarity: z8.enum(["positive", "negative", "mixed", "neutral"])
871
+ });
872
+ var RewardSignalSchema = LearningSignalBaseSchema.extend({
873
+ kind: z8.literal("reward"),
874
+ task: z8.string().max(1e5),
875
+ rules: z8.array(z8.object({
876
+ id: IdSchema4,
877
+ points: z8.number().finite(),
878
+ condition: z8.string().trim().min(1).max(1e5)
879
+ })).min(1).max(1e3),
880
+ otherwisePoints: z8.number().finite(),
881
+ executable: z8.boolean()
882
+ });
883
+ var LabelSignalSchema = LearningSignalBaseSchema.extend({
884
+ kind: z8.literal("label"),
885
+ labelKind: z8.literal("rubric"),
886
+ task: z8.string().max(1e5),
887
+ criteria: z8.array(z8.object({
888
+ id: IdSchema4,
889
+ label: z8.string().trim().min(1).max(500),
890
+ description: z8.string().trim().min(1).max(1e5)
891
+ })).min(1).max(1e3),
892
+ calibrationExamples: z8.object({
893
+ positive: z8.string().trim().min(1).max(2e5),
894
+ negative: z8.string().trim().min(1).max(2e5),
895
+ boundary: z8.string().trim().min(1).max(2e5)
896
+ })
897
+ });
898
+ var LearningSignalRefSchema = z8.discriminatedUnion("kind", [
899
+ DemonstrationSignalSchema,
900
+ PreferenceSignalSchema,
901
+ CorrectionSignalSchema,
902
+ FeedbackSignalSchema,
903
+ RewardSignalSchema,
904
+ LabelSignalSchema
905
+ ]);
906
+ var LearningSignalInventorySchema = z8.object({
907
+ demonstrations: z8.array(DemonstrationSignalSchema).max(1e5).default([]),
908
+ preferences: z8.array(PreferenceSignalSchema).max(1e5).default([]),
909
+ corrections: z8.array(CorrectionSignalSchema).max(1e5).default([]),
910
+ feedback: z8.array(FeedbackSignalSchema).max(1e5).default([]),
911
+ rewards: z8.array(RewardSignalSchema).max(1e5).default([]),
912
+ labels: z8.array(LabelSignalSchema).max(1e5).default([])
913
+ });
914
+ var TasksetEnvironmentContractSchema = z8.object({
915
+ protocolVersion: z8.literal("openpond.taskEnvironment.v1"),
916
+ kind: z8.enum(["chat", "agent", "program", "stateful_harness", "work"]),
917
+ entrypoint: z8.string().trim().min(1).max(1e3),
918
+ stateful: z8.boolean(),
919
+ deterministicSeeds: z8.boolean(),
920
+ toolNames: z8.array(IdSchema4).max(200).default([]),
921
+ actionBindings: z8.array(HarnessActionBindingSchema).max(200).optional(),
922
+ lifecycle: z8.array(z8.enum(["create", "reset", "step", "grade", "cleanup"])).min(1),
923
+ defaultTimeoutMs: z8.number().int().positive().max(36e5),
924
+ networkPolicy: z8.enum(["none", "declared_read_only", "declared_scoped"]),
925
+ resources: z8.array(TasksetEnvironmentResourceSchema).max(1e4).optional(),
926
+ metadata: MetadataSchema2
927
+ });
928
+ var TasksetCapabilityManifestSchema = z8.object({
929
+ schemaVersion: z8.literal("openpond.tasksetCapabilities.v1"),
930
+ taskKind: z8.enum(["chat", "single_agent", "multi_agent", "custom_program"]),
931
+ supportedSignals: z8.array(z8.enum(["demonstration", "preference", "correction", "feedback", "reward", "label"])),
932
+ compatibleMethods: z8.array(z8.enum(["none", "retrieval", "sft", "dpo", "grpo", "ppo", "sdft", "opd", "opsd", "sdpo"])),
933
+ rewardKinds: z8.array(z8.enum(["none", "exact", "deterministic", "model_judge", "human"])),
934
+ requiresTools: z8.boolean(),
935
+ requiresState: z8.boolean(),
936
+ requiresPrivilegedGrading: z8.boolean(),
937
+ environmentPlacements: z8.array(z8.enum(["local", "remote", "colocated", "provider_native"])),
938
+ exportable: z8.boolean(),
939
+ portabilityBlockers: z8.array(z8.string().trim().min(1).max(2e3)).default([])
940
+ });
941
+ var GraderBaseSchema = z8.object({
942
+ id: IdSchema4,
943
+ version: z8.string().trim().min(1).max(100),
944
+ label: z8.string().trim().min(1).max(500),
945
+ weight: z8.number().min(0).max(1e3).default(1),
946
+ hardGate: z8.boolean().default(false),
947
+ rewardEligible: z8.boolean().default(false),
948
+ privileged: z8.boolean().default(false),
949
+ metadata: MetadataSchema2
950
+ });
951
+ var DeterministicGraderSpecSchema = GraderBaseSchema.extend({
952
+ kind: z8.enum(["content", "schema", "file", "diff", "test", "runtime_event", "state"]),
953
+ config: z8.record(z8.string(), z8.unknown())
954
+ });
955
+ var RubricGraderSpecSchema = GraderBaseSchema.extend({
956
+ kind: z8.literal("model_judge"),
957
+ rubric: z8.string().trim().min(1).max(5e4),
958
+ judge: ChatModelRefSchema,
959
+ calibrationFixtureRefs: z8.array(IdSchema4).min(1).max(500),
960
+ calibrationStatus: z8.enum(["pending", "passed", "failed"]),
961
+ temperature: z8.number().min(0).max(2).default(0)
962
+ });
963
+ var HumanGraderSpecSchema = GraderBaseSchema.extend({
964
+ kind: z8.literal("human"),
965
+ rubric: z8.string().trim().min(1).max(5e4),
966
+ reviewerRole: z8.string().trim().min(1).max(500)
967
+ });
968
+ var CustomVerifierGraderSpecSchema = GraderBaseSchema.extend({
969
+ kind: z8.literal("custom_verifier"),
970
+ module: z8.string().trim().min(1).max(1e3).refine(safeRelativeFilePath, "Custom verifier modules must use a safe relative path."),
971
+ exportName: CodeIdentifierSchema,
972
+ timeoutMs: z8.number().int().positive().max(3e5),
973
+ networkPolicy: z8.literal("none")
974
+ });
975
+ var GraderSpecSchema = z8.union([
976
+ DeterministicGraderSpecSchema,
977
+ RubricGraderSpecSchema,
978
+ HumanGraderSpecSchema,
979
+ CustomVerifierGraderSpecSchema
980
+ ]);
981
+ var GraderFixtureLabelSchema = z8.enum([
982
+ "positive",
983
+ "negative",
984
+ "boundary",
985
+ "adversarial",
986
+ "prompt_injection",
987
+ "infrastructure_failure"
988
+ ]);
989
+ var GraderFixtureSchema = z8.object({
990
+ id: IdSchema4,
991
+ taskId: IdSchema4,
992
+ label: GraderFixtureLabelSchema,
993
+ output: z8.record(z8.string(), z8.unknown()),
994
+ infrastructureError: z8.string().trim().min(1).max(1e4).nullable(),
995
+ expectedPassed: z8.boolean(),
996
+ expectedRewardEligible: z8.boolean(),
997
+ metadata: MetadataSchema2
998
+ });
999
+
1000
+ // src/taskset-authored-contracts.ts
1001
+ import { z as z9 } from "zod";
1002
+ import { TasksetMetricPolicySchema } from "@openpond/evals/metrics";
1003
+ var IdSchema5 = z9.string().trim().min(1).max(240);
1004
+ var TimestampSchema4 = z9.string().trim().min(1);
1005
+ var HashSchema5 = z9.string().trim().min(8).max(256);
1006
+ var MetadataSchema3 = z9.record(z9.string(), z9.unknown()).default({});
1007
+ var NullableIdSchema2 = IdSchema5.nullable();
1008
+ var TASKSET_WORK_TOOL_NAMES = [
1009
+ "work_capabilities",
1010
+ "work_environment",
1011
+ "work_list_files",
1012
+ "work_read_file",
1013
+ "work_read_document",
1014
+ "work_write_file",
1015
+ "work_write_docx",
1016
+ "work_edit_file",
1017
+ "work_delete_file",
1018
+ "work_exec",
1019
+ "work_save_output",
1020
+ "work_stop"
1021
+ ];
1022
+ var TasksetStatusSchema = z9.enum([
1023
+ "draft",
1024
+ "awaiting_disclosure_approval",
1025
+ "awaiting_materialization_approval",
1026
+ "materializing",
1027
+ "validating",
1028
+ "needs_review",
1029
+ "baselining",
1030
+ "ready",
1031
+ "blocked",
1032
+ "failed",
1033
+ "archived"
1034
+ ]);
1035
+ var DatasetBuildIntentSchema = z9.enum([
1036
+ "demonstrations",
1037
+ "preferences",
1038
+ "verifiable_reward",
1039
+ "rubric",
1040
+ "discovery"
1041
+ ]);
1042
+ var DatasetEvidenceTextSchema = z9.string().trim().max(1e5);
1043
+ var DatasetBuildSpecificationSchema = z9.discriminatedUnion("kind", [
1044
+ z9.object({
1045
+ kind: z9.literal("demonstrations"),
1046
+ behavior: DatasetEvidenceTextSchema,
1047
+ examples: z9.array(z9.object({
1048
+ id: IdSchema5,
1049
+ prompt: DatasetEvidenceTextSchema,
1050
+ response: DatasetEvidenceTextSchema
1051
+ })).max(1e3).default([])
1052
+ }),
1053
+ z9.object({
1054
+ kind: z9.literal("preferences"),
1055
+ preference: DatasetEvidenceTextSchema,
1056
+ pairs: z9.array(z9.object({
1057
+ id: IdSchema5,
1058
+ prompt: DatasetEvidenceTextSchema,
1059
+ chosen: DatasetEvidenceTextSchema,
1060
+ rejected: DatasetEvidenceTextSchema,
1061
+ rationale: DatasetEvidenceTextSchema
1062
+ })).max(1e3).default([])
1063
+ }),
1064
+ z9.object({
1065
+ kind: z9.literal("verifiable_reward"),
1066
+ task: DatasetEvidenceTextSchema,
1067
+ rules: z9.array(z9.object({
1068
+ id: IdSchema5,
1069
+ points: z9.number().finite(),
1070
+ condition: DatasetEvidenceTextSchema
1071
+ })).max(1e3).default([]),
1072
+ otherwisePoints: z9.number().finite().default(0)
1073
+ }),
1074
+ z9.object({
1075
+ kind: z9.literal("rubric"),
1076
+ task: DatasetEvidenceTextSchema,
1077
+ criteria: z9.array(z9.object({
1078
+ id: IdSchema5,
1079
+ label: z9.string().trim().max(500),
1080
+ description: DatasetEvidenceTextSchema
1081
+ })).max(1e3).default([]),
1082
+ positiveExample: DatasetEvidenceTextSchema,
1083
+ negativeExample: DatasetEvidenceTextSchema,
1084
+ boundaryExample: DatasetEvidenceTextSchema
1085
+ })
1086
+ ]);
1087
+ var GeneratedTaskFileSchema = z9.object({
1088
+ path: z9.string().trim().min(1).max(1e3),
1089
+ role: z9.enum(["environment", "verifier", "fixture"]),
1090
+ content: z9.string().max(25e4)
1091
+ });
1092
+ var TrainingPathRecommendationSchema = z9.object({
1093
+ primaryMethod: z9.enum(["sft", "dpo", "grpo", "ppo", "sdft", "opsd", "sdpo"]),
1094
+ bootstrap: z9.object({
1095
+ method: z9.literal("sft"),
1096
+ purpose: z9.literal("trajectory_bootstrap"),
1097
+ demonstrationRefs: z9.array(IdSchema5).min(1).max(1e5),
1098
+ limitations: z9.array(z9.string().trim().min(1).max(5e3)).min(1).max(100)
1099
+ }).nullable()
1100
+ });
1101
+ var TrainingMethodReadinessReasonCodeSchema = z9.enum([
1102
+ "taskset_not_ready",
1103
+ "demonstrations_missing",
1104
+ "preference_pairs_missing",
1105
+ "preference_pairs_invalid",
1106
+ "executable_reward_missing",
1107
+ "reward_not_calibrated",
1108
+ "reward_model_missing",
1109
+ "value_model_required",
1110
+ "frozen_eval_missing"
1111
+ ]);
1112
+ var TrainingMethodReadinessSchema = z9.object({
1113
+ method: z9.enum(["sft", "dpo", "grpo", "ppo"]),
1114
+ status: z9.enum(["recommended", "compatible", "needs_dataset_work"]),
1115
+ reasonCodes: z9.array(TrainingMethodReadinessReasonCodeSchema).default([]),
1116
+ reasons: z9.array(z9.string().trim().min(1).max(5e3)).default([])
1117
+ });
1118
+ var TasksetReadinessFindingSchema = z9.object({
1119
+ code: IdSchema5,
1120
+ message: z9.string().trim().min(1).max(5e3),
1121
+ path: z9.string().trim().max(2e3).nullable()
1122
+ });
1123
+ var TasksetReadinessReportSchema = z9.object({
1124
+ schemaVersion: z9.literal("openpond.tasksetReadiness.v1"),
1125
+ tasksetId: IdSchema5,
1126
+ tasksetHash: HashSchema5,
1127
+ ready: z9.boolean(),
1128
+ recommendedMethod: z9.enum(["none", "retrieval", "sft", "dpo", "grpo", "ppo", "sdft", "opd", "opsd", "sdpo"]),
1129
+ trainingPath: TrainingPathRecommendationSchema.nullable().default(null),
1130
+ methodReadiness: z9.array(TrainingMethodReadinessSchema).default([]),
1131
+ compatibleDestinationClasses: z9.array(
1132
+ z9.enum(["export", "custom", "hosted_managed"])
1133
+ ),
1134
+ blockers: z9.array(TasksetReadinessFindingSchema).default([]),
1135
+ advisories: z9.array(TasksetReadinessFindingSchema).default([]),
1136
+ warnings: z9.array(z9.string().trim().min(1).max(5e3)).default([]),
1137
+ generatedAt: TimestampSchema4
1138
+ });
1139
+ var AuthoringRepairSchema = z9.object({ attempt: z9.number().int().positive(), summary: z9.string().trim().min(1).max(5e3), createdAt: TimestampSchema4 });
1140
+ var AuthoringProvenanceSchema = z9.object({
1141
+ schemaVersion: z9.literal("openpond.taskAuthoringProvenance.v1"),
1142
+ model: ChatModelRefSchema.nullable(),
1143
+ modelConfig: MetadataSchema3,
1144
+ skillHash: HashSchema5,
1145
+ promptTemplateVersion: z9.string().trim().min(1).max(200),
1146
+ buildIntent: DatasetBuildIntentSchema.default("demonstrations"),
1147
+ buildSpecification: DatasetBuildSpecificationSchema.nullable().default(null),
1148
+ evidenceHashes: z9.array(HashSchema5).max(1e5),
1149
+ tasksetSdkVersion: z9.string().trim().min(1).max(100),
1150
+ sourceCommit: z9.string().trim().min(1).max(256).nullable(),
1151
+ repairHistory: z9.array(AuthoringRepairSchema).max(1e3),
1152
+ createdAt: TimestampSchema4
1153
+ });
1154
+ var TasksetSchema = z9.object({
1155
+ schemaVersion: z9.literal("openpond.taskset.v1"),
1156
+ id: IdSchema5,
1157
+ revision: z9.number().int().positive().default(1),
1158
+ profileId: IdSchema5,
1159
+ profileRelease: VersionedReleaseRefSchema.nullable().optional(),
1160
+ createImproveRunId: NullableIdSchema2.default(null),
1161
+ name: z9.string().trim().min(1).max(500),
1162
+ // Portable tasks may carry all instructions in their individual inputs.
1163
+ // Preserve an absent package prompt; draft publication validates its objective.
1164
+ objective: z9.string().trim().max(2e4),
1165
+ purpose: TasksetPurposeSchema.default("general"),
1166
+ benchmark: TasksetBenchmarkBindingSchema.nullable().default(null),
1167
+ preferenceComparison: TasksetPreferenceComparisonBindingSchema.nullable().default(null),
1168
+ status: TasksetStatusSchema,
1169
+ sourceRefs: z9.array(TasksetSourceRefSchema).min(1).max(1e5),
1170
+ datasetArtifact: DatasetArtifactManifestSchema.nullable().optional(),
1171
+ policy: TaskPolicyBoundarySchema,
1172
+ environment: TasksetEnvironmentContractSchema,
1173
+ capabilities: TasksetCapabilityManifestSchema,
1174
+ metrics: TasksetMetricPolicySchema.optional(),
1175
+ tasks: z9.array(TaskDataRecordSchema).max(1e6),
1176
+ graders: z9.array(GraderSpecSchema).min(1).max(1e3),
1177
+ // Imported releases are inspectable before local calibration. Admission
1178
+ // requires real fixtures separately in validateTaskset.
1179
+ graderFixtures: z9.array(GraderFixtureSchema).max(1e5),
1180
+ learningSignals: LearningSignalInventorySchema,
1181
+ authoringProvenance: AuthoringProvenanceSchema,
1182
+ readiness: TasksetReadinessReportSchema.nullable(),
1183
+ contentHash: HashSchema5,
1184
+ createdAt: TimestampSchema4,
1185
+ updatedAt: TimestampSchema4,
1186
+ metadata: MetadataSchema3
1187
+ }).superRefine((taskset, context) => {
1188
+ if (taskset.purpose === "benchmark" && !taskset.benchmark) {
1189
+ context.addIssue({
1190
+ code: "custom",
1191
+ message: "Benchmark Tasksets require an immutable benchmark binding.",
1192
+ path: ["benchmark"]
1193
+ });
1194
+ }
1195
+ if (taskset.purpose !== "benchmark" && taskset.benchmark) {
1196
+ context.addIssue({
1197
+ code: "custom",
1198
+ message: "Only benchmark Tasksets may carry a benchmark binding.",
1199
+ path: ["benchmark"]
1200
+ });
1201
+ }
1202
+ if (taskset.datasetArtifact && taskset.tasks.length > 0) {
1203
+ context.addIssue({
1204
+ code: "custom",
1205
+ message: "Artifact-backed Tasksets may not duplicate canonical rows inline.",
1206
+ path: ["tasks"]
1207
+ });
1208
+ }
1209
+ if (!taskset.datasetArtifact && taskset.tasks.length === 0) {
1210
+ context.addIssue({
1211
+ code: "custom",
1212
+ message: "A Taskset requires inline tasks or a Dataset artifact manifest.",
1213
+ path: ["tasks"]
1214
+ });
1215
+ }
1216
+ });
1217
+ function isTrainingSourceRef(source) {
1218
+ return source.schemaVersion === "openpond.trainingSource.v1";
1219
+ }
1220
+
1221
+ // src/taskset-authored-validation.ts
1222
+ function validateTaskset(input) {
1223
+ const parsed = TasksetSchema.safeParse(input);
1224
+ if (!parsed.success) {
1225
+ return {
1226
+ valid: false,
1227
+ taskset: null,
1228
+ computedHash: null,
1229
+ issues: parsed.error.issues.map((issue) => ({
1230
+ code: "schema_invalid",
1231
+ severity: "error",
1232
+ message: issue.message,
1233
+ path: issue.path.join(".")
1234
+ }))
1235
+ };
1236
+ }
1237
+ const taskset = parsed.data;
1238
+ const issues = [];
1239
+ validateSourceConsent(taskset, issues);
1240
+ validateDatasetArtifact(taskset, issues);
1241
+ validateSplitIsolation(taskset, issues);
1242
+ validatePolicyBoundary(taskset, issues);
1243
+ validateGraders(taskset, issues);
1244
+ validateGraderFixtures(taskset, issues);
1245
+ validateLearningSignals(taskset, issues);
1246
+ validateCapabilities(taskset.capabilities, issues, taskset);
1247
+ validateWorkExecution(taskset, issues);
1248
+ const computedHash = tasksetContentHash(taskset);
1249
+ if (taskset.contentHash !== computedHash) {
1250
+ issues.push({
1251
+ code: "content_hash_mismatch",
1252
+ severity: "error",
1253
+ message: `Taskset contentHash is ${taskset.contentHash}, expected ${computedHash}.`,
1254
+ path: "contentHash"
1255
+ });
1256
+ }
1257
+ return {
1258
+ valid: !issues.some((issue) => issue.severity === "error"),
1259
+ taskset,
1260
+ computedHash,
1261
+ issues
1262
+ };
1263
+ }
1264
+ function validateGraderFixtures(taskset, issues) {
1265
+ if (!taskset.graderFixtures.length) issues.push({ code: "grader_fixtures_required", severity: "error", message: "Taskset admission requires authored grader fixtures.", path: "graderFixtures" });
1266
+ const taskIds = new Set(taskset.tasks.map((task) => task.id));
1267
+ const required = /* @__PURE__ */ new Set(["positive", "negative", "boundary", "adversarial", "prompt_injection", "infrastructure_failure"]);
1268
+ for (const fixture of taskset.graderFixtures) {
1269
+ if (!taskset.datasetArtifact && !taskIds.has(fixture.taskId)) issues.push({ code: "grader_fixture_task_missing", severity: "warning", message: `Fixture ${fixture.id} references a task outside this Taskset revision (${fixture.taskId}).`, path: `graderFixtures.${fixture.id}.taskId` });
1270
+ required.delete(fixture.label);
1271
+ if (fixture.label === "infrastructure_failure" && !fixture.infrastructureError) issues.push({ code: "infrastructure_fixture_error_missing", severity: "error", message: `Infrastructure fixture ${fixture.id} must declare an infrastructure error.`, path: `graderFixtures.${fixture.id}.infrastructureError` });
1272
+ }
1273
+ for (const label of required) issues.push({ code: "grader_fixture_missing", severity: "warning", message: `Taskset does not include the optional ${label} grader calibration fixture.`, path: "graderFixtures" });
1274
+ }
1275
+ function validateDatasetArtifact(taskset, issues) {
1276
+ const artifact = taskset.datasetArtifact;
1277
+ if (!artifact) return;
1278
+ if (artifact.tasksetId !== taskset.id || artifact.tasksetRevision !== taskset.revision) {
1279
+ issues.push({
1280
+ code: "dataset_artifact_taskset_mismatch",
1281
+ severity: "error",
1282
+ message: "Dataset artifact identity does not match its Taskset revision.",
1283
+ path: "datasetArtifact"
1284
+ });
1285
+ }
1286
+ const splitTotal = Object.values(artifact.splitCounts).reduce((total, count) => total + count, 0);
1287
+ const shardTotal = artifact.shards.reduce((total, shard) => total + shard.rowCount, 0);
1288
+ if (splitTotal !== artifact.rowCount || shardTotal !== artifact.rowCount) {
1289
+ issues.push({
1290
+ code: "dataset_artifact_row_count_mismatch",
1291
+ severity: "error",
1292
+ message: "Dataset artifact row, split, and shard counts do not agree.",
1293
+ path: "datasetArtifact.rowCount"
1294
+ });
1295
+ }
1296
+ const shardSplitCounts = /* @__PURE__ */ new Map();
1297
+ for (const shard of artifact.shards) {
1298
+ shardSplitCounts.set(
1299
+ shard.split,
1300
+ (shardSplitCounts.get(shard.split) ?? 0) + shard.rowCount
1301
+ );
1302
+ }
1303
+ for (const [split, count] of Object.entries(artifact.splitCounts)) {
1304
+ if ((shardSplitCounts.get(split) ?? 0) !== count) {
1305
+ issues.push({
1306
+ code: "dataset_artifact_split_count_mismatch",
1307
+ severity: "error",
1308
+ message: `Dataset artifact ${split} shard counts do not match its manifest.`,
1309
+ path: `datasetArtifact.splitCounts.${split}`
1310
+ });
1311
+ }
1312
+ }
1313
+ const { contentHash: _contentHash, ...hashable } = artifact;
1314
+ if (contentHash(hashable) !== artifact.contentHash) {
1315
+ issues.push({
1316
+ code: "dataset_artifact_hash_mismatch",
1317
+ severity: "error",
1318
+ message: "Dataset artifact manifest content hash is invalid.",
1319
+ path: "datasetArtifact.contentHash"
1320
+ });
1321
+ }
1322
+ }
1323
+ function computeTasksetHash(taskset) {
1324
+ return tasksetContentHash(taskset);
1325
+ }
1326
+ function tasksetContentHash(taskset) {
1327
+ const { contentHash: _contentHash, status: _status, readiness: _readiness, updatedAt: _updatedAt, ...source } = taskset;
1328
+ return contentHash(source);
1329
+ }
1330
+ function validatePortability(capabilities) {
1331
+ const issues = [];
1332
+ validateCapabilities(capabilities, issues, null);
1333
+ return issues;
1334
+ }
1335
+ function validateSourceConsent(taskset, issues) {
1336
+ for (const [index, source] of taskset.sourceRefs.entries()) {
1337
+ if (isTrainingSourceRef(source) && source.consent.status !== "granted") {
1338
+ issues.push({ code: "source_consent_missing", severity: "error", message: `Source ${source.id} is not consented.`, path: `sourceRefs.${index}.consent.status` });
1339
+ }
1340
+ if (source.secretScanStatus !== "passed") {
1341
+ issues.push({ code: "source_secret_scan", severity: "error", message: `Source ${source.id} did not pass secret scanning.`, path: `sourceRefs.${index}.secretScanStatus` });
1342
+ }
1343
+ if (source.piiScanStatus !== "passed") {
1344
+ issues.push({ code: "source_pii_scan", severity: "error", message: `Source ${source.id} has unresolved PII policy.`, path: `sourceRefs.${index}.piiScanStatus` });
1345
+ }
1346
+ if (source.licensingStatus !== "approved") {
1347
+ issues.push({ code: "source_license", severity: "error", message: `Source ${source.id} has unresolved licensing policy.`, path: `sourceRefs.${index}.licensingStatus` });
1348
+ }
1349
+ }
1350
+ }
1351
+ function validateSplitIsolation(taskset, issues) {
1352
+ const clusterSplits = /* @__PURE__ */ new Map();
1353
+ for (const task of taskset.tasks) {
1354
+ const splits = clusterSplits.get(task.clusterKey) ?? /* @__PURE__ */ new Set();
1355
+ splits.add(task.split);
1356
+ clusterSplits.set(task.clusterKey, splits);
1357
+ }
1358
+ for (const [cluster, splits] of clusterSplits) {
1359
+ if (splits.size > 1) {
1360
+ issues.push({ code: "split_cluster_contamination", severity: "error", message: `Source cluster ${cluster} appears in multiple splits: ${[...splits].join(", ")}.`, path: "tasks" });
1361
+ }
1362
+ }
1363
+ const frozenCount = taskset.datasetArtifact ? taskset.datasetArtifact.splitCounts.frozen_eval ?? 0 : taskset.tasks.filter((task) => task.split === "frozen_eval").length;
1364
+ if (frozenCount === 0) issues.push({ code: "frozen_eval_missing", severity: "warning", message: "Add an independent test example before training.", path: "tasks" });
1365
+ }
1366
+ function validateWorkExecution(taskset, issues) {
1367
+ if (taskset.environment.kind !== "work") return;
1368
+ if (taskset.environment.entrypoint !== "openpond-work-v1") {
1369
+ issues.push({
1370
+ code: "work_entrypoint_invalid",
1371
+ severity: "error",
1372
+ message: "Work Tasksets must use the openpond-work-v1 entrypoint.",
1373
+ path: "environment.entrypoint"
1374
+ });
1375
+ }
1376
+ if (taskset.environment.stateful) {
1377
+ issues.push({
1378
+ code: "work_stateful_invalid",
1379
+ severity: "error",
1380
+ message: "Automated Work attempts must start from clean state.",
1381
+ path: "environment.stateful"
1382
+ });
1383
+ }
1384
+ const allowedTools = new Set(TASKSET_WORK_TOOL_NAMES);
1385
+ const unknownTools = taskset.environment.toolNames.filter(
1386
+ (name) => !allowedTools.has(name)
1387
+ );
1388
+ if (unknownTools.length) {
1389
+ issues.push({
1390
+ code: "work_tool_unknown",
1391
+ severity: "error",
1392
+ message: `Work Taskset declares unknown tools: ${unknownTools.join(", ")}.`,
1393
+ path: "environment.toolNames"
1394
+ });
1395
+ }
1396
+ if (!taskset.environment.toolNames.includes("work_save_output")) {
1397
+ issues.push({
1398
+ code: "work_output_tool_missing",
1399
+ severity: "error",
1400
+ message: "Work Tasksets must declare work_save_output.",
1401
+ path: "environment.toolNames"
1402
+ });
1403
+ }
1404
+ for (const lifecycle of ["create", "reset", "step", "grade", "cleanup"]) {
1405
+ if (!taskset.environment.lifecycle.includes(lifecycle)) {
1406
+ issues.push({
1407
+ code: "work_lifecycle_incomplete",
1408
+ severity: "error",
1409
+ message: `Work Tasksets require the ${lifecycle} lifecycle stage.`,
1410
+ path: "environment.lifecycle"
1411
+ });
1412
+ }
1413
+ }
1414
+ const sourceById = new Map(
1415
+ taskset.sourceRefs.map((source) => [source.id, source])
1416
+ );
1417
+ for (const [taskIndex, task] of taskset.tasks.entries()) {
1418
+ const assetIds = /* @__PURE__ */ new Set();
1419
+ const fileNames = /* @__PURE__ */ new Set();
1420
+ for (const [assetIndex, asset] of (task.assets ?? []).entries()) {
1421
+ const path = `tasks.${taskIndex}.assets.${assetIndex}`;
1422
+ if (assetIds.has(asset.id)) {
1423
+ issues.push({
1424
+ code: "work_asset_duplicate_id",
1425
+ severity: "error",
1426
+ message: `Task ${task.id} repeats asset id ${asset.id}.`,
1427
+ path: `${path}.id`
1428
+ });
1429
+ }
1430
+ if (fileNames.has(asset.fileName)) {
1431
+ issues.push({
1432
+ code: "work_asset_duplicate_name",
1433
+ severity: "error",
1434
+ message: `Task ${task.id} repeats staged file name ${asset.fileName}.`,
1435
+ path: `${path}.fileName`
1436
+ });
1437
+ }
1438
+ assetIds.add(asset.id);
1439
+ fileNames.add(asset.fileName);
1440
+ if (!task.sourceRefs.includes(asset.sourceRefId)) {
1441
+ issues.push({
1442
+ code: "work_asset_task_source_missing",
1443
+ severity: "error",
1444
+ message: `Asset ${asset.id} references source ${asset.sourceRefId} outside task ${task.id}.`,
1445
+ path: `${path}.sourceRefId`
1446
+ });
1447
+ }
1448
+ const source = sourceById.get(asset.sourceRefId);
1449
+ if (!source) {
1450
+ issues.push({
1451
+ code: "work_asset_source_missing",
1452
+ severity: "error",
1453
+ message: `Asset ${asset.id} references missing source ${asset.sourceRefId}.`,
1454
+ path: `${path}.sourceRefId`
1455
+ });
1456
+ } else if ("sourceFileHashes" in source && !source.sourceFileHashes.includes(asset.sha256)) {
1457
+ issues.push({
1458
+ code: "work_asset_hash_unregistered",
1459
+ severity: "error",
1460
+ message: `Asset ${asset.id} hash is not registered by source ${asset.sourceRefId}.`,
1461
+ path: `${path}.sha256`
1462
+ });
1463
+ }
1464
+ if (source && "kind" in source && source.kind === "uploaded_file" && !source.originalFileNames.includes(asset.fileName)) {
1465
+ issues.push({
1466
+ code: "work_asset_name_unregistered",
1467
+ severity: "error",
1468
+ message: `Asset ${asset.id} file name is not registered by source ${asset.sourceRefId}.`,
1469
+ path: `${path}.fileName`
1470
+ });
1471
+ }
1472
+ if (source && "kind" in source && source.kind === "uploaded_file" && !source.mediaTypes.includes(asset.mediaType)) {
1473
+ issues.push({
1474
+ code: "work_asset_media_type_unregistered",
1475
+ severity: "error",
1476
+ message: `Asset ${asset.id} media type is not registered by source ${asset.sourceRefId}.`,
1477
+ path: `${path}.mediaType`
1478
+ });
1479
+ }
1480
+ if (asset.split !== task.split) {
1481
+ issues.push({
1482
+ code: "work_asset_split_mismatch",
1483
+ severity: "error",
1484
+ message: `Asset ${asset.id} is assigned to ${asset.split}, not task split ${task.split}.`,
1485
+ path: `${path}.split`
1486
+ });
1487
+ }
1488
+ }
1489
+ const outputPaths = /* @__PURE__ */ new Set();
1490
+ for (const [outputIndex, output] of (task.requiredOutputs ?? []).entries()) {
1491
+ const normalized = output.path.replaceAll("\\", "/");
1492
+ const path = `tasks.${taskIndex}.requiredOutputs.${outputIndex}.path`;
1493
+ if (outputPaths.has(normalized)) {
1494
+ issues.push({
1495
+ code: "work_output_duplicate_path",
1496
+ severity: "error",
1497
+ message: `Task ${task.id} repeats required output path ${normalized}.`,
1498
+ path
1499
+ });
1500
+ }
1501
+ outputPaths.add(normalized);
1502
+ }
1503
+ if ((task.requiredOutputs ?? []).length === 0) {
1504
+ issues.push({
1505
+ code: "work_output_missing",
1506
+ severity: "error",
1507
+ message: `Work task ${task.id} must declare at least one required output.`,
1508
+ path: `tasks.${taskIndex}.requiredOutputs`
1509
+ });
1510
+ }
1511
+ }
1512
+ }
1513
+ function validatePolicyBoundary(taskset, issues) {
1514
+ const visible = new Set(taskset.policy.policyVisibleFields);
1515
+ for (const field of taskset.policy.privilegedFields) {
1516
+ if (visible.has(field)) issues.push({ code: "privileged_field_visible", severity: "error", message: `Field ${field} is both policy-visible and privileged.`, path: "policy" });
1517
+ }
1518
+ for (const task of taskset.tasks) {
1519
+ if (task.privilegedContextRef && Object.keys(task.policyVisibleContext).includes(task.privilegedContextRef)) {
1520
+ issues.push({ code: "privileged_context_leak", severity: "error", message: `Task ${task.id} exposes its privileged context reference.`, path: `tasks.${task.id}.policyVisibleContext` });
1521
+ }
1522
+ }
1523
+ }
1524
+ function validateGraders(taskset, issues) {
1525
+ const ids = /* @__PURE__ */ new Set();
1526
+ for (const grader of taskset.graders) {
1527
+ if (ids.has(grader.id)) issues.push({ code: "grader_duplicate", severity: "error", message: `Duplicate grader id ${grader.id}.`, path: "graders" });
1528
+ ids.add(grader.id);
1529
+ if (grader.kind === "model_judge" && grader.rewardEligible && grader.calibrationStatus !== "passed") {
1530
+ issues.push({ code: "judge_calibration_pending", severity: "warning", message: `Model judge ${grader.id} is selected for reward without a passing advisory calibration report.`, path: `graders.${grader.id}` });
1531
+ }
1532
+ if (grader.kind === "model_judge" && grader.calibrationStatus === "passed" && typeof grader.metadata.calibrationEvidenceHash !== "string") {
1533
+ issues.push({ code: "judge_calibration_evidence_missing", severity: "warning", message: `Model judge ${grader.id} declares calibration without an OpenPond fixture evidence hash.`, path: `graders.${grader.id}.metadata.calibrationEvidenceHash` });
1534
+ }
1535
+ if (grader.kind === "human" && grader.rewardEligible) {
1536
+ issues.push({ code: "human_online_reward", severity: "error", message: `Human grader ${grader.id} cannot be an online optimizer reward.`, path: `graders.${grader.id}` });
1537
+ }
1538
+ }
1539
+ }
1540
+ function validateLearningSignals(taskset, issues) {
1541
+ const taskIds = new Set(taskset.tasks.map((task) => task.id));
1542
+ const sourceIds = new Set(taskset.sourceRefs.map((source) => source.id));
1543
+ for (const signal of [
1544
+ ...taskset.learningSignals.demonstrations,
1545
+ ...taskset.learningSignals.preferences,
1546
+ ...taskset.learningSignals.corrections,
1547
+ ...taskset.learningSignals.feedback,
1548
+ ...taskset.learningSignals.rewards,
1549
+ ...taskset.learningSignals.labels
1550
+ ]) {
1551
+ if (signal.taskId && !taskset.datasetArtifact && !taskIds.has(signal.taskId)) {
1552
+ issues.push({ code: "learning_signal_task_missing", severity: "error", message: `Signal ${signal.id} references missing task ${signal.taskId}.`, path: `learningSignals.${signal.kind}.${signal.id}.taskId` });
1553
+ }
1554
+ if (signal.sourceRefs.some((sourceId) => !sourceIds.has(sourceId))) {
1555
+ issues.push({ code: "learning_signal_source_missing", severity: "error", message: `Signal ${signal.id} references a source outside the Dataset.`, path: `learningSignals.${signal.kind}.${signal.id}.sourceRefs` });
1556
+ }
1557
+ }
1558
+ for (const preference of taskset.learningSignals.preferences) {
1559
+ if (preference.chosen.trim() === preference.rejected.trim()) {
1560
+ issues.push({ code: "preference_pair_identical", severity: "error", message: `Preference ${preference.id} has identical chosen and rejected responses.`, path: `learningSignals.preferences.${preference.id}` });
1561
+ }
1562
+ }
1563
+ for (const reward of taskset.learningSignals.rewards) {
1564
+ if (!reward.executable) {
1565
+ issues.push({ code: "reward_not_executable", severity: "warning", message: `Reward ${reward.id} is a reviewed specification but has no executable verifier yet.`, path: `learningSignals.rewards.${reward.id}.executable` });
1566
+ }
1567
+ }
1568
+ }
1569
+ function validateCapabilities(capabilities, issues, taskset) {
1570
+ if (!capabilities.exportable && capabilities.portabilityBlockers.length === 0) {
1571
+ issues.push({ code: "portability_reason_missing", severity: "error", message: "Non-exportable Tasksets must declare a portability blocker.", path: "capabilities.portabilityBlockers" });
1572
+ }
1573
+ if (capabilities.compatibleMethods.includes("grpo") && !capabilities.rewardKinds.some((kind) => kind === "exact" || kind === "deterministic" || kind === "model_judge")) {
1574
+ issues.push({ code: "grpo_reward_missing", severity: "error", message: "GRPO compatibility requires a scalar reward kind.", path: "capabilities.rewardKinds" });
1575
+ }
1576
+ if (taskset?.capabilities.compatibleMethods.includes("sft") && taskset.learningSignals.demonstrations.length === 0) {
1577
+ issues.push({ code: "sft_demonstrations_missing", severity: "error", message: "SFT compatibility requires approved demonstrations.", path: "learningSignals.demonstrations" });
1578
+ }
1579
+ if (taskset?.capabilities.compatibleMethods.includes("dpo") && taskset.learningSignals.preferences.length === 0) {
1580
+ issues.push({ code: "dpo_preferences_missing", severity: "error", message: "DPO compatibility requires chosen and rejected response pairs.", path: "learningSignals.preferences" });
1581
+ }
1582
+ if (taskset && (taskset.capabilities.compatibleMethods.includes("grpo") || taskset.capabilities.compatibleMethods.includes("ppo")) && !taskset.learningSignals.rewards.some((reward) => reward.executable)) {
1583
+ issues.push({ code: "online_reward_not_executable", severity: "error", message: "GRPO/PPO compatibility requires an executable scalar reward.", path: "learningSignals.rewards" });
1584
+ }
1585
+ }
1586
+
1587
+ // src/taskset-draft-document.ts
1588
+ import { z as z10 } from "zod";
1589
+ import { TasksetMetricPolicySchema as TasksetMetricPolicySchema2 } from "@openpond/evals/metrics";
1590
+ var IdSchema6 = z10.string().trim().min(1).max(240);
1591
+ var TimestampSchema5 = z10.string().trim().min(1);
1592
+ var HashSchema6 = z10.string().trim().min(8).max(256);
1593
+ var CodeIdentifierSchema2 = z10.string().trim().regex(/^[A-Za-z_$][A-Za-z0-9_$]*$/);
1594
+ var MetadataSchema4 = z10.record(z10.string(), z10.unknown()).default({});
1595
+ function safeRelativeFilePath2(value) {
1596
+ const normalized = value.trim().replaceAll("\\", "/");
1597
+ if (!normalized || normalized.startsWith("/") || normalized === "." || normalized === "..") {
1598
+ return false;
1599
+ }
1600
+ return !normalized.split("/").some(
1601
+ (segment) => !segment || segment === "." || segment === ".."
1602
+ );
1603
+ }
1604
+ var TaskDataDraftSchema = TaskDataRecordSchema.extend({
1605
+ sourceRefs: z10.array(IdSchema6).max(100).default([])
1606
+ });
1607
+ var TasksetDraftStatusSchema = z10.enum([
1608
+ "draft",
1609
+ "validating",
1610
+ "needs_review",
1611
+ "published"
1612
+ ]);
1613
+ var TasksetDraftReviewPolicySchema = z10.object({
1614
+ enabled: z10.boolean(),
1615
+ candidateCount: z10.number().int().min(2).max(4),
1616
+ minimumSamples: z10.number().int().min(1).max(1e4).default(100),
1617
+ allowTies: z10.boolean(),
1618
+ allowRejectAll: z10.boolean(),
1619
+ rubric: z10.string().trim().max(5e4),
1620
+ criteria: z10.array(z10.object({
1621
+ id: IdSchema6,
1622
+ label: z10.string().trim().min(1).max(500),
1623
+ description: z10.string().trim().max(1e4),
1624
+ weight: z10.number().nonnegative().max(1e3)
1625
+ })).max(100)
1626
+ });
1627
+ var TasksetDraftOutputContractSchema = z10.object({
1628
+ mode: z10.enum(["text", "structured_json", "artifacts"]),
1629
+ jsonSchema: z10.record(z10.string(), z10.unknown()).nullable(),
1630
+ renderer: z10.object({
1631
+ module: z10.string().trim().min(1).max(1e3).refine(safeRelativeFilePath2, "Renderer modules must use a safe relative path."),
1632
+ exportName: CodeIdentifierSchema2,
1633
+ configRef: z10.string().trim().min(1).max(1e3).refine(safeRelativeFilePath2, "Renderer configuration must use a safe relative path.").nullable().default(null)
1634
+ }).nullable()
1635
+ }).superRefine((output, context) => {
1636
+ if (output.mode === "structured_json" && !output.jsonSchema) {
1637
+ context.addIssue({
1638
+ code: "custom",
1639
+ message: "Structured JSON output requires a JSON Schema.",
1640
+ path: ["jsonSchema"]
1641
+ });
1642
+ }
1643
+ if (output.mode === "text" && output.renderer) {
1644
+ context.addIssue({
1645
+ code: "custom",
1646
+ message: "Text output cannot configure an artifact renderer.",
1647
+ path: ["renderer"]
1648
+ });
1649
+ }
1650
+ });
1651
+ var TasksetDraftSchema = z10.object({
1652
+ schemaVersion: z10.literal("openpond.tasksetDraft.v1"),
1653
+ id: IdSchema6,
1654
+ revision: z10.number().int().positive(),
1655
+ profileId: IdSchema6,
1656
+ modelScope: z10.object({
1657
+ modelId: IdSchema6,
1658
+ expectedModelRevision: z10.number().int().positive(),
1659
+ source: ModelTasksetDraftPreparationSchema.optional()
1660
+ }).strict().nullable().default(null),
1661
+ name: z10.string().trim().max(500),
1662
+ objective: z10.string().trim().max(2e4),
1663
+ purpose: TasksetPurposeSchema.default("general"),
1664
+ benchmark: TasksetBenchmarkBindingSchema.nullable().default(null),
1665
+ preferenceComparison: TasksetPreferenceComparisonBindingSchema.nullable().default(null),
1666
+ status: TasksetDraftStatusSchema,
1667
+ sourceRefs: z10.array(TasksetSourceRefSchema).max(1e5).default([]),
1668
+ datasetArtifact: DatasetArtifactManifestSchema.nullable().optional(),
1669
+ policy: TaskPolicyBoundarySchema,
1670
+ environment: TasksetEnvironmentContractSchema,
1671
+ output: TasksetDraftOutputContractSchema.default({
1672
+ mode: "text",
1673
+ jsonSchema: null,
1674
+ renderer: null
1675
+ }),
1676
+ capabilities: TasksetCapabilityManifestSchema,
1677
+ metrics: TasksetMetricPolicySchema2,
1678
+ review: TasksetDraftReviewPolicySchema,
1679
+ tasks: z10.array(TaskDataDraftSchema).max(1e6).default([]),
1680
+ graders: z10.array(GraderSpecSchema).max(1e3).default([]),
1681
+ graderFixtures: z10.array(GraderFixtureSchema).max(1e5).default([]),
1682
+ learningSignals: LearningSignalInventorySchema,
1683
+ publishedTasksetRef: z10.object({
1684
+ id: IdSchema6,
1685
+ revision: z10.number().int().positive(),
1686
+ contentHash: HashSchema6
1687
+ }).nullable(),
1688
+ createdAt: TimestampSchema5,
1689
+ updatedAt: TimestampSchema5,
1690
+ metadata: MetadataSchema4
1691
+ }).superRefine((draft, context) => {
1692
+ if (draft.purpose === "benchmark" && !draft.benchmark) {
1693
+ context.addIssue({
1694
+ code: "custom",
1695
+ message: "Benchmark drafts require an immutable benchmark binding.",
1696
+ path: ["benchmark"]
1697
+ });
1698
+ }
1699
+ if (draft.purpose !== "benchmark" && draft.benchmark) {
1700
+ context.addIssue({
1701
+ code: "custom",
1702
+ message: "Only benchmark drafts may carry a benchmark binding.",
1703
+ path: ["benchmark"]
1704
+ });
1705
+ }
1706
+ if (draft.datasetArtifact && draft.tasks.length > 0) {
1707
+ context.addIssue({
1708
+ code: "custom",
1709
+ message: "Artifact-backed drafts may not duplicate canonical rows inline.",
1710
+ path: ["tasks"]
1711
+ });
1712
+ }
1713
+ if (draft.status === "published" && !draft.publishedTasksetRef) {
1714
+ context.addIssue({
1715
+ code: "custom",
1716
+ message: "Published drafts require an immutable Taskset reference.",
1717
+ path: ["publishedTasksetRef"]
1718
+ });
1719
+ }
1720
+ });
1721
+
1722
+ // src/taskset-draft-authoring.ts
1723
+ var TasksetDraftPublishError = class extends Error {
1724
+ issues;
1725
+ constructor(issues) {
1726
+ super(issues.map((issue) => issue.message).join("\n"));
1727
+ this.name = "TasksetDraftPublishError";
1728
+ this.issues = issues;
1729
+ }
1730
+ };
1731
+ function createTasksetDraft(input) {
1732
+ const timestamp = input.now ?? (/* @__PURE__ */ new Date()).toISOString();
1733
+ const id = input.id?.trim() || `taskset-draft-${globalThis.crypto.randomUUID()}`;
1734
+ return TasksetDraftSchema.parse({
1735
+ schemaVersion: "openpond.tasksetDraft.v1",
1736
+ id,
1737
+ revision: 1,
1738
+ profileId: input.profileId,
1739
+ modelScope: input.modelScope ?? null,
1740
+ name: input.name?.trim() ?? "",
1741
+ objective: "",
1742
+ purpose: "general",
1743
+ benchmark: null,
1744
+ preferenceComparison: null,
1745
+ status: "draft",
1746
+ sourceRefs: [],
1747
+ datasetArtifact: null,
1748
+ policy: {
1749
+ policyVisibleFields: ["input"],
1750
+ privilegedFields: ["expectedOutput"],
1751
+ hiddenGraderRefs: [],
1752
+ connectedAppScopes: []
1753
+ },
1754
+ environment: {
1755
+ protocolVersion: "openpond.taskEnvironment.v1",
1756
+ kind: "chat",
1757
+ entrypoint: "openpond-chat-v1",
1758
+ stateful: false,
1759
+ deterministicSeeds: true,
1760
+ toolNames: [],
1761
+ lifecycle: ["create", "reset", "step", "grade", "cleanup"],
1762
+ defaultTimeoutMs: 12e4,
1763
+ networkPolicy: "none",
1764
+ resources: [],
1765
+ metadata: {}
1766
+ },
1767
+ output: {
1768
+ mode: "text",
1769
+ jsonSchema: null,
1770
+ renderer: null
1771
+ },
1772
+ capabilities: {
1773
+ schemaVersion: "openpond.tasksetCapabilities.v1",
1774
+ taskKind: "chat",
1775
+ supportedSignals: [
1776
+ "demonstration",
1777
+ "preference",
1778
+ "correction",
1779
+ "feedback",
1780
+ "reward",
1781
+ "label"
1782
+ ],
1783
+ compatibleMethods: ["none"],
1784
+ rewardKinds: ["none"],
1785
+ requiresTools: false,
1786
+ requiresState: false,
1787
+ requiresPrivilegedGrading: true,
1788
+ environmentPlacements: ["local", "remote", "colocated"],
1789
+ exportable: true,
1790
+ portabilityBlockers: []
1791
+ },
1792
+ metrics: {
1793
+ schemaVersion: "openpond.tasksetMetricPolicy.v1",
1794
+ primaryMetric: "score",
1795
+ aggregation: "mean_score",
1796
+ missingReward: "zero",
1797
+ customAggregator: null
1798
+ },
1799
+ review: {
1800
+ enabled: false,
1801
+ candidateCount: 2,
1802
+ minimumSamples: 100,
1803
+ allowTies: true,
1804
+ allowRejectAll: true,
1805
+ rubric: "",
1806
+ criteria: []
1807
+ },
1808
+ tasks: [],
1809
+ graders: [],
1810
+ graderFixtures: [],
1811
+ learningSignals: {
1812
+ demonstrations: [],
1813
+ preferences: [],
1814
+ corrections: [],
1815
+ feedback: [],
1816
+ rewards: [],
1817
+ labels: []
1818
+ },
1819
+ publishedTasksetRef: null,
1820
+ createdAt: timestamp,
1821
+ updatedAt: timestamp,
1822
+ metadata: {}
1823
+ });
1824
+ }
1825
+ function draftPublishIssues(draft) {
1826
+ const issues = [];
1827
+ if (!draft.name.trim()) issues.push({ code: "name_missing", message: "Name is required.", path: "name" });
1828
+ if (!draft.objective.trim()) issues.push({ code: "objective_missing", message: "Objective is required.", path: "objective" });
1829
+ if (!draft.datasetArtifact && draft.tasks.length === 0) issues.push({ code: "tasks_missing", message: "Add at least one task or Dataset artifact.", path: "tasks" });
1830
+ if (draft.graders.length === 0) issues.push({ code: "graders_missing", message: "Add at least one grader.", path: "graders" });
1831
+ if (draft.graderFixtures.length === 0) issues.push({ code: "grader_fixtures_missing", message: "Add grader fixtures before publishing.", path: "graderFixtures" });
1832
+ const sourceIds = new Set(draft.sourceRefs.map((source) => source.id));
1833
+ for (const task of draft.tasks) {
1834
+ for (const sourceId of task.sourceRefs) {
1835
+ if (!sourceIds.has(sourceId)) issues.push({ code: "task_source_missing", message: `Task ${task.id} references missing source ${sourceId}.`, path: `tasks.${task.id}.sourceRefs` });
1836
+ }
1837
+ }
1838
+ return issues;
1839
+ }
1840
+
1841
+ // src/taskset-draft-publication.ts
1842
+ function tasksetDraftFromTaskset(tasksetInput, now = (/* @__PURE__ */ new Date()).toISOString()) {
1843
+ const taskset = TasksetSchema.parse(tasksetInput);
1844
+ return TasksetDraftSchema.parse({
1845
+ schemaVersion: "openpond.tasksetDraft.v1",
1846
+ id: `${taskset.id}-draft`,
1847
+ revision: 1,
1848
+ profileId: taskset.profileId,
1849
+ name: taskset.name,
1850
+ objective: taskset.objective,
1851
+ purpose: taskset.purpose,
1852
+ benchmark: taskset.benchmark,
1853
+ preferenceComparison: taskset.preferenceComparison,
1854
+ status: "draft",
1855
+ sourceRefs: taskset.sourceRefs,
1856
+ datasetArtifact: taskset.datasetArtifact ?? null,
1857
+ policy: taskset.policy,
1858
+ environment: taskset.environment,
1859
+ output: tasksetOutputContract(taskset.metadata),
1860
+ capabilities: taskset.capabilities,
1861
+ metrics: taskset.metrics ?? {
1862
+ schemaVersion: "openpond.tasksetMetricPolicy.v1",
1863
+ primaryMetric: "score",
1864
+ aggregation: "mean_score",
1865
+ missingReward: "zero",
1866
+ customAggregator: null
1867
+ },
1868
+ review: {
1869
+ enabled: Boolean(taskset.preferenceComparison),
1870
+ candidateCount: 2,
1871
+ minimumSamples: 100,
1872
+ allowTies: true,
1873
+ allowRejectAll: true,
1874
+ rubric: "",
1875
+ criteria: []
1876
+ },
1877
+ tasks: taskset.tasks,
1878
+ graders: taskset.graders,
1879
+ graderFixtures: taskset.graderFixtures,
1880
+ learningSignals: taskset.learningSignals,
1881
+ publishedTasksetRef: {
1882
+ id: taskset.id,
1883
+ revision: taskset.revision,
1884
+ contentHash: taskset.contentHash
1885
+ },
1886
+ createdAt: now,
1887
+ updatedAt: now,
1888
+ metadata: {
1889
+ ...taskset.metadata,
1890
+ importedFromTaskset: {
1891
+ id: taskset.id,
1892
+ revision: taskset.revision,
1893
+ contentHash: taskset.contentHash
1894
+ }
1895
+ }
1896
+ });
1897
+ }
1898
+ function publishTasksetDraft(input) {
1899
+ const draft = TasksetDraftSchema.parse(input.draft);
1900
+ const timestamp = input.now ?? (/* @__PURE__ */ new Date()).toISOString();
1901
+ const issues = draftPublishIssues(draft);
1902
+ if (issues.length) throw new TasksetDraftPublishError(issues);
1903
+ const preparedSource = draft.modelScope?.source;
1904
+ if (preparedSource && input.tasksetId && input.tasksetId !== preparedSource.tasksetId) throw new Error("Taskset draft publication differs from its prepared identity.");
1905
+ const tasksetId = preparedSource?.tasksetId || input.tasksetId?.trim() || draft.publishedTasksetRef?.id || draft.id.replace(/-draft$/, "");
1906
+ const revision = preparedSource?.tasksetRevision ?? (draft.publishedTasksetRef?.id === tasksetId ? draft.publishedTasksetRef.revision + 1 : 1);
1907
+ const sourceRefs = draft.sourceRefs.length ? draft.sourceRefs : [generatedDraftSource(draft, tasksetId, timestamp)];
1908
+ const defaultSourceId = sourceRefs[0].id;
1909
+ const tasks = draft.tasks.map((task) => TaskDataRecordSchema.parse({
1910
+ ...task,
1911
+ sourceRefs: task.sourceRefs.length ? task.sourceRefs : [defaultSourceId],
1912
+ metadata: {
1913
+ exampleOrigin: "expert_authored",
1914
+ ...task.metadata
1915
+ }
1916
+ }));
1917
+ const authoredMethod = draft.capabilities.compatibleMethods.find(
1918
+ (method) => method !== "none" && method !== "retrieval"
1919
+ ) ?? null;
1920
+ const buildIntent = buildIntentForDraft(draft);
1921
+ const taskset = TasksetSchema.parse({
1922
+ schemaVersion: "openpond.taskset.v1",
1923
+ id: tasksetId,
1924
+ revision,
1925
+ profileId: draft.profileId,
1926
+ profileRelease: null,
1927
+ createImproveRunId: null,
1928
+ name: draft.name,
1929
+ objective: draft.objective,
1930
+ purpose: draft.purpose,
1931
+ benchmark: draft.benchmark,
1932
+ preferenceComparison: draft.preferenceComparison,
1933
+ status: "needs_review",
1934
+ sourceRefs,
1935
+ datasetArtifact: draft.datasetArtifact ?? null,
1936
+ policy: draft.policy,
1937
+ environment: draft.environment,
1938
+ capabilities: draft.capabilities,
1939
+ metrics: draft.metrics,
1940
+ tasks,
1941
+ graders: draft.graders,
1942
+ graderFixtures: draft.graderFixtures,
1943
+ learningSignals: draft.learningSignals,
1944
+ authoringProvenance: {
1945
+ schemaVersion: "openpond.taskAuthoringProvenance.v1",
1946
+ model: null,
1947
+ modelConfig: {},
1948
+ skillHash: contentHash("openpond-taskset-draft-authoring-v1"),
1949
+ promptTemplateVersion: "taskset-draft-v1",
1950
+ buildIntent,
1951
+ buildSpecification: null,
1952
+ evidenceHashes: sourceRefs.map((source) => source.sourceHash),
1953
+ tasksetSdkVersion: "draft-v1",
1954
+ sourceCommit: null,
1955
+ repairHistory: [],
1956
+ createdAt: timestamp
1957
+ },
1958
+ readiness: null,
1959
+ contentHash: "00000000",
1960
+ createdAt: revision === 1 ? draft.createdAt : timestamp,
1961
+ updatedAt: timestamp,
1962
+ metadata: {
1963
+ ...draft.metadata,
1964
+ ...preparedSource ? { modelTasksetAuthoring: preparedSource.lineage } : {},
1965
+ tasksetReviewPolicy: draft.review,
1966
+ tasksetOutputContract: draft.output,
1967
+ ...input.sourcePackageHash ? { sourcePackageHash: input.sourcePackageHash } : {},
1968
+ ...authoredMethod ? { trainingMethod: authoredMethod } : {},
1969
+ diagnosis: {
1970
+ schemaVersion: "openpond.capabilityDiagnosis.v1",
1971
+ summary: draft.objective,
1972
+ stableBehavior: [draft.objective],
1973
+ changingKnowledge: [],
1974
+ requiredContext: [],
1975
+ requiredTools: draft.environment.toolNames,
1976
+ intervention: authoredMethod === "dpo" ? "preference" : authoredMethod === "grpo" || authoredMethod === "ppo" ? "grpo_rft" : authoredMethod === "sft" ? "sft" : "no_training",
1977
+ trainingEligible: authoredMethod !== null,
1978
+ rationale: authoredMethod ? [`The author selected ${authoredMethod.toUpperCase()} compatibility.`] : ["The Taskset is currently configured for evaluation only."],
1979
+ confidence: 1
1980
+ }
1981
+ }
1982
+ });
1983
+ const hashed = TasksetSchema.parse({
1984
+ ...taskset,
1985
+ contentHash: computeTasksetHash(taskset)
1986
+ });
1987
+ const report = validateTaskset(hashed);
1988
+ const validationErrors = report.issues.filter((issue) => issue.severity === "error");
1989
+ if (validationErrors.length) {
1990
+ throw new TasksetDraftPublishError(validationErrors.map((issue) => ({
1991
+ code: issue.code,
1992
+ message: issue.message,
1993
+ path: issue.path
1994
+ })));
1995
+ }
1996
+ return hashed;
1997
+ }
1998
+ function generatedDraftSource(draft, tasksetId, timestamp) {
1999
+ const generatorHash = contentHash({
2000
+ draftId: draft.id,
2001
+ draftRevision: draft.revision,
2002
+ tasks: draft.tasks
2003
+ });
2004
+ return {
2005
+ schemaVersion: "openpond.generatedDatasetSource.v1",
2006
+ kind: "generated",
2007
+ id: `source-${tasksetId}`,
2008
+ profileId: draft.profileId,
2009
+ title: `${draft.name} manual authoring`,
2010
+ sourceHash: generatorHash,
2011
+ occurredAt: timestamp,
2012
+ licensingStatus: "approved",
2013
+ secretScanStatus: "passed",
2014
+ piiScanStatus: "passed",
2015
+ generatorId: "openpond-taskset-draft",
2016
+ generatorVersion: "1",
2017
+ seed: 0,
2018
+ generatorHash,
2019
+ metadata: { draftId: draft.id, draftRevision: draft.revision }
2020
+ };
2021
+ }
2022
+ function buildIntentForDraft(draft) {
2023
+ if (draft.learningSignals.preferences.length) return "preferences";
2024
+ if (draft.learningSignals.rewards.length) return "verifiable_reward";
2025
+ if (draft.learningSignals.labels.length) return "rubric";
2026
+ return "demonstrations";
2027
+ }
2028
+ function tasksetOutputContract(metadata) {
2029
+ const value = metadata.tasksetOutputContract;
2030
+ if (value && typeof value === "object" && !Array.isArray(value)) {
2031
+ return value;
2032
+ }
2033
+ return { mode: "text", jsonSchema: null, renderer: null };
2034
+ }
2035
+
2036
+ // src/taskset-draft-files.ts
2037
+ var MAX_TASKSET_DRAFT_EDIT_FILE_BYTES = 6e6;
2038
+ var MANAGED_FILES = /* @__PURE__ */ new Set(["taskset.json", "capabilities.json", "data/tasks.jsonl", "tasks/tasks.jsonl", "graders/graders.json", "fixtures/grader-fixtures.json", "metrics/policy.json", "assets/manifest.json", "environment/contract.json", "environment/taskset.ts", "rubrics/preference-review.md", "comparisons/policy.json"]);
2039
+ function isWritableTasksetDraftFilePath(value) {
2040
+ const path = TasksetDraftFilePathSchema.parse(value);
2041
+ return !MANAGED_FILES.has(path) && !path.startsWith("source-artifacts/");
2042
+ }
2043
+ function isManagedTasksetDraftFilePath(value) {
2044
+ return MANAGED_FILES.has(TasksetDraftFilePathSchema.parse(value));
2045
+ }
2046
+ function createTasksetDraftFile(path, bytes) {
2047
+ const writable = isWritableTasksetDraftFilePath(path);
2048
+ if (bytes.byteLength > MAX_TASKSET_DRAFT_EDIT_FILE_BYTES) throw new Error("Taskset draft file content is invalid or exceeds 6 MB.");
2049
+ let content;
2050
+ try {
2051
+ const text = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
2052
+ content = /[\u0000-\u0008\u000e-\u001f]/.test(text) ? base64Content(bytes) : { encoding: "utf8", data: text };
2053
+ } catch {
2054
+ content = base64Content(bytes);
2055
+ }
2056
+ return { path, writable, content, sizeBytes: bytes.byteLength, contentHash: sha256(bytes) };
2057
+ }
2058
+ function decodeTasksetDraftFileContent(input) {
2059
+ const content = TasksetDraftFileContentSchema.parse(input);
2060
+ let bytes;
2061
+ try {
2062
+ if (content.encoding === "utf8") bytes = new TextEncoder().encode(content.data);
2063
+ else {
2064
+ const raw = atob(content.data);
2065
+ if (btoa(raw) !== content.data) throw new Error("Noncanonical base64");
2066
+ bytes = Uint8Array.from(raw, (character) => character.charCodeAt(0));
2067
+ }
2068
+ } catch {
2069
+ throw new Error("Taskset draft file content is invalid or exceeds 6 MB.");
2070
+ }
2071
+ if (bytes.byteLength > MAX_TASKSET_DRAFT_EDIT_FILE_BYTES) throw new Error("Taskset draft file content is invalid or exceeds 6 MB.");
2072
+ return bytes;
2073
+ }
2074
+ function base64Content(bytes) {
2075
+ let raw = "";
2076
+ for (let offset = 0; offset < bytes.length; offset += 8192) raw += String.fromCharCode(...bytes.subarray(offset, offset + 8192));
2077
+ return { encoding: "base64", data: btoa(raw) };
2078
+ }
2079
+
2080
+ // src/taskset-draft-manifests.ts
2081
+ function configuredTasksetDraftFiles(draft) {
2082
+ const configured = [];
2083
+ if (draft.output.renderer) {
2084
+ configured.push({
2085
+ relativePath: draft.output.renderer.module,
2086
+ source: `export async function ${draft.output.renderer.exportName}(output: unknown) {
2087
+ // Return artifact paths or bytes derived from the model's structured output.
2088
+ return output;
2089
+ }
2090
+ `
2091
+ });
2092
+ }
2093
+ for (const grader of draft.graders) {
2094
+ if (grader.kind !== "custom_verifier") continue;
2095
+ configured.push({
2096
+ relativePath: grader.module,
2097
+ source: `export async function ${grader.exportName}(input: { output: unknown; task: unknown }) {
2098
+ return { passed: false, score: 0, feedback: "Implement this verifier." };
2099
+ }
2100
+ `
2101
+ });
2102
+ }
2103
+ if (draft.metrics.customAggregator) {
2104
+ configured.push({
2105
+ relativePath: draft.metrics.customAggregator.module,
2106
+ source: `export function ${draft.metrics.customAggregator.exportName}(scores: number[]) {
2107
+ return scores.length ? scores.reduce((sum, score) => sum + score, 0) / scores.length : 0;
2108
+ }
2109
+ `
2110
+ });
2111
+ }
2112
+ for (const file of configured) TasksetDraftFilePathSchema.parse(file.relativePath);
2113
+ return configured;
2114
+ }
2115
+ function renderTasksetDraftManifests(input) {
2116
+ const draft = TasksetDraftSchema.parse(input);
2117
+ return /* @__PURE__ */ new Map([
2118
+ ["taskset.json", canonicalJson(draft)],
2119
+ ["tasks/tasks.jsonl", jsonLines(draft.tasks)],
2120
+ ["graders/graders.json", canonicalJson(draft.graders)],
2121
+ ["fixtures/grader-fixtures.json", canonicalJson(draft.graderFixtures)],
2122
+ ["metrics/policy.json", canonicalJson(draft.metrics)],
2123
+ ["assets/manifest.json", canonicalJson(draft.tasks.flatMap((task) => task.assets ?? []))],
2124
+ ["environment/contract.json", canonicalJson(draft.environment)],
2125
+ ["rubrics/preference-review.md", rubricMarkdown(draft)],
2126
+ ["comparisons/policy.json", canonicalJson(draft.review)]
2127
+ ]);
2128
+ }
2129
+ function rubricMarkdown(draft) {
2130
+ const criteria = draft.review.criteria.length ? `
2131
+
2132
+ ## Criteria
2133
+
2134
+ ${draft.review.criteria.map(
2135
+ (criterion) => `- **${criterion.label}** (${criterion.weight}): ${criterion.description}`
2136
+ ).join("\n")}` : "";
2137
+ return `# Preference review rubric
2138
+
2139
+ ${draft.review.rubric}${criteria}
2140
+ `;
2141
+ }
2142
+ function jsonLines(values) {
2143
+ return values.length ? `${values.map((value) => JSON.stringify(value)).join("\n")}
2144
+ ` : "";
2145
+ }
2146
+
2147
+ // src/taskset-draft-workspace.ts
2148
+ import { z as z11 } from "zod";
2149
+ import { assertBoundedTaskJson as assertBoundedTaskJson2 } from "@openpond/evals/task-schema";
2150
+ var MAX_TASKSET_DRAFT_WORKSPACE_BYTES = 64 * 1024 * 1024;
2151
+ var HashSchema7 = z11.string().regex(/^[a-f0-9]{64}$/);
2152
+ var TasksetDraftWorkspaceFileSchema = z11.object({
2153
+ path: TasksetDraftFilePathSchema,
2154
+ contentHash: HashSchema7,
2155
+ sizeBytes: z11.number().int().nonnegative().max(MAX_TASKSET_DRAFT_WORKSPACE_BYTES),
2156
+ base64: z11.string().max(MAX_TASKSET_DRAFT_WORKSPACE_BYTES)
2157
+ }).strict();
2158
+ var WorkspaceContentSchema = z11.object({
2159
+ schemaVersion: z11.literal("openpond.tasksetDraftWorkspace.v1"),
2160
+ draft: TasksetDraftSchema,
2161
+ files: z11.array(TasksetDraftWorkspaceFileSchema).max(1e4)
2162
+ }).strict();
2163
+ var TasksetDraftWorkspaceSchema = WorkspaceContentSchema.extend({ contentHash: HashSchema7 }).strict();
2164
+ function createTasksetDraftWorkspace(input) {
2165
+ assertBoundedTaskJson2(input, MAX_TASKSET_DRAFT_WORKSPACE_BYTES);
2166
+ const content = WorkspaceContentSchema.parse(input);
2167
+ content.files.sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0);
2168
+ return validateTasksetDraftWorkspace({ ...content, contentHash: contentHash(content) });
2169
+ }
2170
+ function validateTasksetDraftWorkspace(input) {
2171
+ assertBoundedTaskJson2(input, MAX_TASKSET_DRAFT_WORKSPACE_BYTES);
2172
+ const workspace = TasksetDraftWorkspaceSchema.parse(input);
2173
+ const { contentHash: expectedHash, ...content } = workspace;
2174
+ if (contentHash(content) !== expectedHash) throw new Error("Taskset draft workspace differs from its retained bytes.");
2175
+ let previousPath = null;
2176
+ const paths = /* @__PURE__ */ new Set();
2177
+ for (const file of workspace.files) {
2178
+ if (isManagedTasksetDraftFilePath(file.path)) throw new Error("Managed Taskset files are represented by the draft document.");
2179
+ if (previousPath !== null && previousPath >= file.path) throw new Error("Taskset draft file paths must be unique and sorted.");
2180
+ const segments = file.path.split("/");
2181
+ for (let end = 1; end < segments.length; end++) if (paths.has(segments.slice(0, end).join("/"))) throw new Error("A Taskset draft file occupies another file's directory.");
2182
+ decodeTasksetDraftWorkspaceFile(file);
2183
+ paths.add(file.path);
2184
+ previousPath = file.path;
2185
+ }
2186
+ return workspace;
2187
+ }
2188
+ function readTasksetDraftWorkspaceFile(input, path) {
2189
+ const workspace = validateTasksetDraftWorkspace(input);
2190
+ TasksetDraftFilePathSchema.parse(path);
2191
+ const file = workspace.files.find((candidate) => candidate.path === path);
2192
+ const manifest = isManagedTasksetDraftFilePath(path) ? renderTasksetDraftManifests(workspace.draft).get(path) : void 0;
2193
+ if (!file && manifest === void 0) throw new Error("Taskset draft file does not exist.");
2194
+ const result = createTasksetDraftFile(path, file ? decodeTasksetDraftWorkspaceFile(file) : new TextEncoder().encode(manifest));
2195
+ return { draftRevision: workspace.draft.revision, file: { ...result, writable: result.writable && workspace.draft.status !== "published" } };
2196
+ }
2197
+ function listTasksetDraftWorkspaceFiles(input) {
2198
+ const workspace = validateTasksetDraftWorkspace(input);
2199
+ const files = workspace.files.map((file) => ({
2200
+ path: file.path,
2201
+ sizeBytes: file.sizeBytes,
2202
+ writable: workspace.draft.status !== "published" && isWritableTasksetDraftFilePath(file.path)
2203
+ }));
2204
+ for (const [path, content] of renderTasksetDraftManifests(workspace.draft)) files.push({ path, sizeBytes: new TextEncoder().encode(content).byteLength, writable: false });
2205
+ return { draftRevision: workspace.draft.revision, files: files.sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0) };
2206
+ }
2207
+ function saveTasksetDraftWorkspaceDocument(input) {
2208
+ const workspace = editableWorkspace(input.workspace, input.expectedDraftRevision);
2209
+ const draft = TasksetDraftSchema.parse(input.draft);
2210
+ const current = workspace.draft;
2211
+ if (draft.id !== current.id || draft.profileId !== current.profileId || contentHash(draft.modelScope) !== contentHash(current.modelScope)) throw new Error("Taskset draft Model ownership cannot change.");
2212
+ if (draft.revision !== current.revision || draft.status !== current.status || draft.createdAt !== current.createdAt || contentHash(draft.publishedTasksetRef) !== contentHash(current.publishedTasksetRef)) throw new Error("Taskset draft lifecycle fields cannot change through form edits.");
2213
+ const files = [...workspace.files];
2214
+ for (const configured of configuredTasksetDraftFiles(draft)) if (!files.some((file) => file.path === configured.relativePath)) {
2215
+ const bytes = new TextEncoder().encode(configured.source);
2216
+ files.push({ path: configured.relativePath, contentHash: sha256(bytes), sizeBytes: bytes.byteLength, base64: base64(bytes) });
2217
+ }
2218
+ const aggregator = draft.metrics.customAggregator;
2219
+ const module = aggregator ? files.find((file) => file.path === aggregator.module) : void 0;
2220
+ return createTasksetDraftWorkspace({
2221
+ schemaVersion: workspace.schemaVersion,
2222
+ files,
2223
+ draft: {
2224
+ ...draft,
2225
+ revision: current.revision + 1,
2226
+ status: "draft",
2227
+ updatedAt: input.now,
2228
+ ...aggregator && module ? { metrics: { ...draft.metrics, customAggregator: { ...aggregator, contentHash: module.contentHash } } } : {}
2229
+ }
2230
+ });
2231
+ }
2232
+ function saveTasksetDraftWorkspaceFile(input) {
2233
+ const mutation = TasksetDraftFileMutationSchema.parse(input.mutation);
2234
+ const workspace = editableWorkspace(input.workspace, mutation.expectedDraftRevision);
2235
+ if (workspace.draft.id !== mutation.draftId) throw new Error("Taskset draft file belongs to another draft.");
2236
+ if (!isWritableTasksetDraftFilePath(mutation.path)) throw new Error("This file is managed by the Taskset forms or retained source history.");
2237
+ const previous = workspace.files.find((file) => file.path === mutation.path);
2238
+ if ((previous?.contentHash ?? null) !== mutation.expectedFileHash) throw new Error("Taskset draft file changed. Reload it before saving.");
2239
+ if (!previous && mutation.content === null) throw new Error("Taskset draft file does not exist.");
2240
+ const files = workspace.files.filter((file) => file.path !== mutation.path);
2241
+ if (mutation.content !== null) {
2242
+ const bytes = decodeTasksetDraftFileContent(mutation.content);
2243
+ files.push({ path: mutation.path, contentHash: sha256(bytes), sizeBytes: bytes.byteLength, base64: base64(bytes) });
2244
+ }
2245
+ return createTasksetDraftWorkspace({
2246
+ schemaVersion: workspace.schemaVersion,
2247
+ files,
2248
+ draft: { ...workspace.draft, revision: workspace.draft.revision + 1, status: "draft", updatedAt: input.now }
2249
+ });
2250
+ }
2251
+ function editableWorkspace(input, expectedRevision) {
2252
+ const workspace = validateTasksetDraftWorkspace(input);
2253
+ if (workspace.draft.status === "published") throw new Error("Published Taskset drafts are immutable.");
2254
+ if (workspace.draft.revision !== expectedRevision) throw new Error("Taskset draft changed. Reload before saving.");
2255
+ return workspace;
2256
+ }
2257
+ function decodeTasksetDraftWorkspaceFile(input) {
2258
+ const file = TasksetDraftWorkspaceFileSchema.parse(input);
2259
+ let raw;
2260
+ try {
2261
+ raw = atob(file.base64);
2262
+ } catch {
2263
+ throw new Error("Taskset draft file contains invalid base64.");
2264
+ }
2265
+ if (btoa(raw) !== file.base64) throw new Error("Taskset draft file contains noncanonical base64.");
2266
+ const bytes = Uint8Array.from(raw, (character) => character.charCodeAt(0));
2267
+ if (bytes.byteLength !== file.sizeBytes || sha256(bytes) !== file.contentHash) throw new Error("Taskset draft file differs from its retained bytes.");
2268
+ return bytes;
2269
+ }
2270
+ function base64(bytes) {
2271
+ let raw = "";
2272
+ for (let offset = 0; offset < bytes.length; offset += 8192) raw += String.fromCharCode(...bytes.subarray(offset, offset + 8192));
2273
+ return btoa(raw);
2274
+ }
2275
+
2276
+ export {
2277
+ TasksetPackageLearningResourcesSchema,
2278
+ learningPackageContextFiles,
2279
+ validateTasksetLearningResources,
2280
+ modelAuthoredTasksetId,
2281
+ assertModelTasksetAuthoring,
2282
+ MAX_TASKSET_PACKAGE_BYTES,
2283
+ TasksetPackageFileSchema,
2284
+ decodeTasksetPackageFile,
2285
+ resolveTasksetPackageExecution,
2286
+ createTasksetPackageExecutionFile,
2287
+ TasksetPackageContentSchema,
2288
+ TasksetPackageSchema,
2289
+ tasksetPackageRewardBinding,
2290
+ resolveTasksetPackageInstructions,
2291
+ validateTasksetPackage,
2292
+ createTasksetPackage,
2293
+ TasksetPackageModelConfigurationSchema,
2294
+ TasksetPackagePublicationSchema,
2295
+ TasksetPackageReceiptSchema,
2296
+ TasksetPackageReadbackSchema,
2297
+ OpenPondTasksetPackageError,
2298
+ OpenPondTasksetPackageClient,
2299
+ DatasetSplitSchema,
2300
+ DatasetSemanticFieldSchema,
2301
+ DatasetSemanticSchemaSchema,
2302
+ DatasetShardRefSchema,
2303
+ DatasetArtifactManifestSchema,
2304
+ DatasetArtifactSummarySchema,
2305
+ DatasetCatalogItemSchema,
2306
+ DatasetCatalogResponseSchema,
2307
+ DatasetArtifactRegistryEntrySchema,
2308
+ DatasetRowPageRequestSchema,
2309
+ DatasetRowPageSchema,
2310
+ DatasetStorageSettingsSchema,
2311
+ DatasetStorageRootSchema,
2312
+ DatasetStorageStateSchema,
2313
+ UpdateDatasetStorageSettingsRequestSchema,
2314
+ DatasetSourceReviewStatusSchema,
2315
+ HuggingFaceDatasetSourceRefSchema,
2316
+ UploadedFileDatasetSourceRefSchema,
2317
+ GeneratedDatasetSourceRefSchema,
2318
+ LearningBatchDatasetSourceRefSchema,
2319
+ ExternalDatasetSourceRefSchema,
2320
+ HarnessActionBindingSchema,
2321
+ TasksetSplitSchema,
2322
+ TasksetPurposeSchema,
2323
+ TasksetBenchmarkBindingSchema,
2324
+ TasksetPreferenceComparisonBindingSchema,
2325
+ TrainingSourceConsentSchema,
2326
+ TrainingSourceRefSchema,
2327
+ TasksetSourceRefSchema,
2328
+ TaskPolicyBoundarySchema,
2329
+ TaskAssetRefSchema,
2330
+ TaskRequiredOutputSchema,
2331
+ TaskDataRecordSchema,
2332
+ TasksetEnvironmentResourceSchema,
2333
+ DemonstrationSignalSchema,
2334
+ PreferenceSignalSchema,
2335
+ CorrectionSignalSchema,
2336
+ FeedbackSignalSchema,
2337
+ RewardSignalSchema,
2338
+ LabelSignalSchema,
2339
+ LearningSignalRefSchema,
2340
+ LearningSignalInventorySchema,
2341
+ TasksetEnvironmentContractSchema,
2342
+ TasksetCapabilityManifestSchema,
2343
+ DeterministicGraderSpecSchema,
2344
+ RubricGraderSpecSchema,
2345
+ HumanGraderSpecSchema,
2346
+ CustomVerifierGraderSpecSchema,
2347
+ GraderSpecSchema,
2348
+ GraderFixtureLabelSchema,
2349
+ GraderFixtureSchema,
2350
+ TASKSET_WORK_TOOL_NAMES,
2351
+ TasksetStatusSchema,
2352
+ DatasetBuildIntentSchema,
2353
+ DatasetBuildSpecificationSchema,
2354
+ GeneratedTaskFileSchema,
2355
+ TrainingPathRecommendationSchema,
2356
+ TrainingMethodReadinessReasonCodeSchema,
2357
+ TrainingMethodReadinessSchema,
2358
+ TasksetReadinessFindingSchema,
2359
+ TasksetReadinessReportSchema,
2360
+ AuthoringRepairSchema,
2361
+ AuthoringProvenanceSchema,
2362
+ TasksetSchema,
2363
+ isTrainingSourceRef,
2364
+ validateTaskset,
2365
+ computeTasksetHash,
2366
+ validatePortability,
2367
+ TaskDataDraftSchema,
2368
+ TasksetDraftStatusSchema,
2369
+ TasksetDraftReviewPolicySchema,
2370
+ TasksetDraftOutputContractSchema,
2371
+ TasksetDraftSchema,
2372
+ TasksetDraftPublishError,
2373
+ createTasksetDraft,
2374
+ draftPublishIssues,
2375
+ tasksetDraftFromTaskset,
2376
+ publishTasksetDraft,
2377
+ MAX_TASKSET_DRAFT_EDIT_FILE_BYTES,
2378
+ isWritableTasksetDraftFilePath,
2379
+ isManagedTasksetDraftFilePath,
2380
+ createTasksetDraftFile,
2381
+ decodeTasksetDraftFileContent,
2382
+ configuredTasksetDraftFiles,
2383
+ renderTasksetDraftManifests,
2384
+ MAX_TASKSET_DRAFT_WORKSPACE_BYTES,
2385
+ TasksetDraftWorkspaceFileSchema,
2386
+ TasksetDraftWorkspaceSchema,
2387
+ createTasksetDraftWorkspace,
2388
+ validateTasksetDraftWorkspace,
2389
+ readTasksetDraftWorkspaceFile,
2390
+ listTasksetDraftWorkspaceFiles,
2391
+ saveTasksetDraftWorkspaceDocument,
2392
+ saveTasksetDraftWorkspaceFile,
2393
+ decodeTasksetDraftWorkspaceFile
2394
+ };
2395
+ //# sourceMappingURL=chunk-AZUCY3E5.js.map