@openpond/evals 0.10.1 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/LEARNING.md +70 -0
  2. package/dist/learning/batch-service.js +44 -0
  3. package/dist/learning/contracts.js +1 -1
  4. package/dist/learning/index.js +3 -0
  5. package/dist/learning/iteration-dispatch-commands.js +31 -0
  6. package/dist/learning/iteration-dispatch-contracts.js +73 -0
  7. package/dist/learning/iteration-dispatch-worker.js +178 -0
  8. package/dist/learning/iteration-eligibility.js +76 -0
  9. package/dist/learning/iteration-reservation-cancellation.js +31 -0
  10. package/dist/learning/iteration-reservation-contracts.js +57 -0
  11. package/dist/learning/iteration-reservation-service.js +106 -0
  12. package/dist/learning/operations.js +6 -1
  13. package/dist/learning/repository.js +4 -0
  14. package/dist/learning/service.js +19 -43
  15. package/dist/types/learning/batch-service.d.ts +8 -0
  16. package/dist/types/learning/batch-service.d.ts.map +1 -0
  17. package/dist/types/learning/contracts.d.ts +6 -0
  18. package/dist/types/learning/contracts.d.ts.map +1 -1
  19. package/dist/types/learning/index.d.ts +3 -0
  20. package/dist/types/learning/index.d.ts.map +1 -1
  21. package/dist/types/learning/iteration-dispatch-commands.d.ts +8 -0
  22. package/dist/types/learning/iteration-dispatch-commands.d.ts.map +1 -0
  23. package/dist/types/learning/iteration-dispatch-contracts.d.ts +93 -0
  24. package/dist/types/learning/iteration-dispatch-contracts.d.ts.map +1 -0
  25. package/dist/types/learning/iteration-dispatch-worker.d.ts +35 -0
  26. package/dist/types/learning/iteration-dispatch-worker.d.ts.map +1 -0
  27. package/dist/types/learning/iteration-eligibility.d.ts +18 -0
  28. package/dist/types/learning/iteration-eligibility.d.ts.map +1 -0
  29. package/dist/types/learning/iteration-reservation-cancellation.d.ts +8 -0
  30. package/dist/types/learning/iteration-reservation-cancellation.d.ts.map +1 -0
  31. package/dist/types/learning/iteration-reservation-contracts.d.ts +90 -0
  32. package/dist/types/learning/iteration-reservation-contracts.d.ts.map +1 -0
  33. package/dist/types/learning/iteration-reservation-service.d.ts +9 -0
  34. package/dist/types/learning/iteration-reservation-service.d.ts.map +1 -0
  35. package/dist/types/learning/operations.d.ts +64 -0
  36. package/dist/types/learning/operations.d.ts.map +1 -1
  37. package/dist/types/learning/repository.d.ts +121 -0
  38. package/dist/types/learning/repository.d.ts.map +1 -1
  39. package/dist/types/learning/service.d.ts.map +1 -1
  40. package/dist/types/learning/transport.d.ts +151 -0
  41. package/dist/types/learning/transport.d.ts.map +1 -1
  42. package/package.json +1 -1
  43. package/schemas/learning/v1/chain.schema.json +72 -0
  44. package/schemas/learning/v1/command-request.schema.json +374 -233
  45. package/schemas/learning/v1/consumption.schema.json +77 -0
  46. package/schemas/learning/v1/dispatch.schema.json +338 -0
  47. package/schemas/learning/v1/iteration.schema.json +3 -1
  48. package/schemas/learning/v1/read-request.schema.json +4 -0
  49. package/schemas/learning/v1/reservation.schema.json +201 -0
@@ -0,0 +1,106 @@
1
+ import { contentHash } from "@openpond/harness";
2
+ import { sealLearningBatch } from "./batch-service.js";
3
+ import { LearningIterationSchema, learningRef, sameLearningRef } from "./contracts.js";
4
+ import { LearningDomainError } from "./errors.js";
5
+ import { inspectIterationEligibility, learningChainId, learningConsumptionId } from "./iteration-eligibility.js";
6
+ import { LearningChainSchema, LearningConsumptionSchema, LearningIterationReservationSchema } from "./iteration-reservation-contracts.js";
7
+ import { requireLearningRelease, requireLearningResource } from "./repository.js";
8
+ /** The caller owns one scope-serialized transaction. This never submits a Job. */
9
+ export async function reserveLearningIteration(transaction, input, actorId, now) {
10
+ const policy = await requireLearningRelease(transaction, "policy", input.policy);
11
+ const chainId = learningChainId(policy.modelProjectId);
12
+ const trigger = input.trigger.kind === "schedule" ? { ...input.trigger, scheduledAt: new Date(input.trigger.scheduledAt).toISOString() } : input.trigger;
13
+ const triggerIdentity = contentHash([input.policy.id, trigger]);
14
+ const id = `iteration-${contentHash([chainId, triggerIdentity])}`;
15
+ const requestHash = contentHash({ policy: input.policy, trigger });
16
+ const previous = await transaction.get("reservation", id);
17
+ if (previous) {
18
+ if (previous.requestHash !== requestHash)
19
+ throw new LearningDomainError("learning_trigger_identity_conflict", 409);
20
+ // Fire identity is independent of actor and transport operation identity.
21
+ return [{ kind: "iteration", id, revision: (await requireLearningResource(transaction, "iteration", id)).revision }, { kind: "reservation", id, revision: previous.revision }];
22
+ }
23
+ const current = await requireLearningResource(transaction, "policy", policy.id);
24
+ if (!sameLearningRef(learningRef(current), input.policy))
25
+ throw new LearningDomainError("learning_policy_revision_stale", 409);
26
+ if (!policy.enabled)
27
+ throw new LearningDomainError("learning_policy_paused", 409);
28
+ if (policy.automation.accept || policy.automation.serve)
29
+ throw new LearningDomainError("learning_automatic_acceptance_not_available", 422);
30
+ if (input.trigger.kind === "schedule") {
31
+ if (policy.trigger.kind !== "schedule" || !policy.automation.train)
32
+ throw new LearningDomainError("learning_schedule_not_enabled", 409);
33
+ if (Date.parse(input.trigger.scheduledAt) > Date.parse(now))
34
+ throw new LearningDomainError("learning_schedule_not_due", 409);
35
+ }
36
+ const chain = await transaction.get("chain", chainId);
37
+ if (chain?.activeIterationId)
38
+ throw new LearningDomainError("learning_iteration_active", 409, chain.activeIterationId);
39
+ if (chain?.lastReservedAt && Date.parse(now) - Date.parse(chain.lastReservedAt) < policy.limits.cooldownSeconds * 1_000) {
40
+ throw new LearningDomainError("learning_iteration_cooldown", 409);
41
+ }
42
+ const eligibility = await inspectIterationEligibility(transaction, policy);
43
+ const ready = eligibility.counts.eligible >= policy.admission.minimumApprovedExamples;
44
+ const status = ready ? "ready" : eligibility.counts.awaitingReview > 0 ? "waiting_for_review" : "waiting_for_data";
45
+ const pointers = [];
46
+ let batch = null;
47
+ if (ready) {
48
+ await assertAvailableBudget(transaction, chainId, now, policy.limits.maxIterationSpendUsd, policy.limits.maxDailySpendUsd);
49
+ const sealed = await sealLearningBatch(transaction, {
50
+ action: "seal_batch", operationId: input.operationId, batchId: `batch-${contentHash(id)}`,
51
+ taskDefinition: policy.taskDefinition, purpose: eligibility.purpose,
52
+ evidence: eligibility.selected.map((item) => learningRef(item.evidence)),
53
+ decisions: eligibility.selected.map((item) => learningRef(item.decision)),
54
+ }, actorId, now);
55
+ pointers.push(...sealed);
56
+ batch = learningRef(await requireLearningResource(transaction, "batch", sealed[0].id));
57
+ for (const item of eligibility.selected) {
58
+ const consumption = LearningConsumptionSchema.parse({
59
+ schemaVersion: "openpond.learningConsumption.v1", id: learningConsumptionId(chainId, item.evidence), revision: 1,
60
+ chainId, iterationId: id, evidence: learningRef(item.evidence), decision: learningRef(item.decision), reservedAt: now,
61
+ });
62
+ await transaction.put("consumption", consumption, 0, { parentId: chainId });
63
+ }
64
+ }
65
+ const iteration = LearningIterationSchema.parse({
66
+ schemaVersion: "openpond.learningIteration.v1", id, revision: 1, policy: input.policy, status,
67
+ triggerIdentity, batch,
68
+ // Existing evidence has no ordered ingress sequence. Consumption records,
69
+ // not a count or lexicographic ID cursor, decide whether an example is new.
70
+ sourceWatermarks: {}, trainingParent: policy.trainingParent, teacher: policy.teacher, upstreamEvent: null,
71
+ trainingJob: null, evaluationJob: null, candidateVersion: null, dispatchId: `dispatch-${contentHash(id)}`,
72
+ retryCount: 0, spendUsd: 0, failure: null, createdAt: now, updatedAt: now,
73
+ });
74
+ const reservation = LearningIterationReservationSchema.parse({
75
+ schemaVersion: "openpond.learningIterationReservation.v1", id, revision: 1, chainId, iterationId: id,
76
+ policy: input.policy, trigger, requestHash, outcome: ready ? "reserved" : status,
77
+ counts: eligibility.counts,
78
+ budget: { maximumSpendUsd: ready ? policy.limits.maxIterationSpendUsd : 0, reservedSpendUsd: ready ? policy.limits.maxIterationSpendUsd : 0, settledSpendUsd: 0, settledAt: ready ? null : now },
79
+ createdAt: now, updatedAt: now,
80
+ });
81
+ const updatedChain = LearningChainSchema.parse({
82
+ schemaVersion: "openpond.learningChain.v1", id: chainId, revision: (chain?.revision ?? 0) + 1,
83
+ modelProjectId: policy.modelProjectId, activeIterationId: ready ? id : null, latestIterationId: id,
84
+ lastReservedAt: ready ? now : chain?.lastReservedAt ?? null, updatedAt: now,
85
+ });
86
+ await transaction.put("iteration", iteration, 0, { parentId: chainId, status });
87
+ await transaction.put("reservation", reservation, 0, { parentId: chainId, status: reservation.outcome });
88
+ await transaction.put("chain", updatedChain, chain?.revision ?? 0, { parentId: policy.modelProjectId });
89
+ return [{ kind: "iteration", id, revision: 1 }, { kind: "reservation", id, revision: 1 }, ...pointers];
90
+ }
91
+ async function assertAvailableBudget(transaction, chainId, now, requested, maximum) {
92
+ let committed = 0;
93
+ let afterId;
94
+ do {
95
+ const page = await transaction.list("reservation", { parentId: chainId, limit: 100, ...(afterId ? { afterId } : {}) });
96
+ for (const { budget } of page.items) {
97
+ // Unsettled reservations carry across midnight and worker restarts.
98
+ committed += budget.reservedSpendUsd;
99
+ if (budget.settledAt && new Date(budget.settledAt).toISOString().slice(0, 10) === new Date(now).toISOString().slice(0, 10))
100
+ committed += budget.settledSpendUsd;
101
+ }
102
+ afterId = page.nextCursor ?? undefined;
103
+ } while (afterId);
104
+ if (committed + requested > maximum)
105
+ throw new LearningDomainError("learning_daily_budget_exhausted", 409);
106
+ }
@@ -1,3 +1,4 @@
1
+ import { LearningIterationTriggerSchema } from "./iteration-reservation-contracts.js";
1
2
  import { z } from "zod";
2
3
  import { ReleaseIdSchema } from "@openpond/harness";
3
4
  import { LearningJsonObjectSchema, LearningRevisionRefSchema, LearningSourceContentSchema, TaskDefinitionContentSchema, TaskExampleSubmissionSchema, TaskFeedbackSubmissionSchema, LearningPolicyContentSchema } from "./contracts.js";
@@ -36,4 +37,8 @@ export const SaveAuthoringDraftCommandSchema = command.extend({ action: z.litera
36
37
  export const ArchiveAuthoringDraftCommandSchema = command.extend({ action: z.literal("archive_draft"), draft: LearningRevisionRefSchema }).strict();
37
38
  export const QueueRewardCheckCommandSchema = command.extend({ action: z.literal("queue_reward_check"), draft: LearningRevisionRefSchema, timeoutMs: z.number().int().min(100).max(300_000).default(30_000), maximumSpendUsd: z.number().nonnegative().max(1_000).default(0) }).strict();
38
39
  export const CancelRewardCheckCommandSchema = command.extend({ action: z.literal("cancel_reward_check"), checkId: ReleaseIdSchema, expectedRevision: z.number().int().positive() }).strict();
39
- export const LearningCommandSchema = z.union([QueueRewardCheckCommandSchema, CancelRewardCheckCommandSchema, SaveAuthoringDraftCommandSchema, ArchiveAuthoringDraftCommandSchema, PublishLearningResourceCommandSchema, PublishLearningResourcesCommandSchema, SubmitTaskExampleCommandSchema, SubmitTaskFeedbackCommandSchema, ApplyTaskCorrectionCommandSchema, ResolveTaskFeedbackCommandSchema, QueueTaskGradeCommandSchema, ReviewTaskEvidenceCommandSchema, SealTaskBatchCommandSchema, CancelTaskGradeCommandSchema]);
40
+ export const ReserveLearningIterationCommandSchema = command.extend({ action: z.literal("reserve_iteration"), policy: LearningRevisionRefSchema, trigger: LearningIterationTriggerSchema }).strict();
41
+ export const CancelLearningIterationReservationCommandSchema = command.extend({ action: z.literal("cancel_iteration_reservation"), iterationId: ReleaseIdSchema, expectedRevision: z.number().int().positive() }).strict();
42
+ export const CancelLearningIterationCommandSchema = command.extend({ action: z.literal("cancel_iteration"), iterationId: ReleaseIdSchema, expectedRevision: z.number().int().positive() }).strict();
43
+ export const RetryLearningIterationDispatchCommandSchema = command.extend({ action: z.literal("retry_iteration_dispatch"), iterationId: ReleaseIdSchema, expectedRevision: z.number().int().positive() }).strict();
44
+ export const LearningCommandSchema = z.union([CancelLearningIterationCommandSchema, RetryLearningIterationDispatchCommandSchema, CancelLearningIterationReservationCommandSchema, ReserveLearningIterationCommandSchema, QueueRewardCheckCommandSchema, CancelRewardCheckCommandSchema, SaveAuthoringDraftCommandSchema, ArchiveAuthoringDraftCommandSchema, PublishLearningResourceCommandSchema, PublishLearningResourcesCommandSchema, SubmitTaskExampleCommandSchema, SubmitTaskFeedbackCommandSchema, ApplyTaskCorrectionCommandSchema, ResolveTaskFeedbackCommandSchema, QueueTaskGradeCommandSchema, ReviewTaskEvidenceCommandSchema, SealTaskBatchCommandSchema, CancelTaskGradeCommandSchema]);
@@ -1,3 +1,5 @@
1
+ import { LearningChainSchema, LearningConsumptionSchema, LearningIterationReservationSchema } from "./iteration-reservation-contracts.js";
2
+ import { LearningIterationDispatchSchema } from "./iteration-dispatch-contracts.js";
1
3
  import { z } from "zod";
2
4
  import { contentHash } from "@openpond/harness";
3
5
  import { assertLearningContentHash, LearningSourceSchema, TaskAdmissionDecisionSchema, TaskBatchSchema, TaskDefinitionSchema, TaskEvidenceSchema, TaskFeedbackSchema, TaskGradeRunSchema, LearningPolicySchema, LearningIterationSchema } from "./contracts.js";
@@ -14,6 +16,8 @@ export const learningResourceSchemas = {
14
16
  definition: TaskDefinitionSchema, reward: RewardReleaseSchema, binding: RewardBindingSchema,
15
17
  source: LearningSourceSchema, evidence: TaskEvidenceSchema, feedback: TaskFeedbackSchema,
16
18
  decision: TaskAdmissionDecisionSchema, batch: TaskBatchSchema, policy: LearningPolicySchema,
19
+ chain: LearningChainSchema, consumption: LearningConsumptionSchema, reservation: LearningIterationReservationSchema,
20
+ dispatch: LearningIterationDispatchSchema,
17
21
  iteration: LearningIterationSchema, grade: TaskGradeRunSchema, package: TasksetReleaseSchema,
18
22
  };
19
23
  export const LearningResourceKindSchema = z.enum(Object.keys(learningResourceSchemas));
@@ -1,10 +1,14 @@
1
+ import { cancelLearningIterationReservation } from "./iteration-reservation-cancellation.js";
2
+ import { commandLearningIterationDispatch } from "./iteration-dispatch-commands.js";
3
+ import { reserveLearningIteration } from "./iteration-reservation-service.js";
4
+ import { requireCurrentLearningEvidence as currentEvidence, sealLearningBatch } from "./batch-service.js";
1
5
  import { saveAuthoringDraft, archiveAuthoringDraft, finalizeAuthoringDraft } from "./authoring-service.js";
2
6
  import { queueRewardCheck, cancelRewardCheck } from "./reward-check-service.js";
3
7
  import { LearningDomainError } from "./errors.js";
4
8
  import { contentHash } from "@openpond/harness";
5
- import { createRewardBinding, createRewardRelease, resolveBoundRewards } from "../rewards.js";
9
+ import { createRewardBinding, createRewardRelease } from "../rewards.js";
6
10
  import { assertBoundedTaskJson, validateTaskValue } from "../task-schema.js";
7
- import { assertAdmissionDecision, assertGradeIdentity, compileTaskBatch, inspectTaskEvidence, sealTaskBatch, taskFamilyReservations } from "./admission.js";
11
+ import { assertAdmissionDecision, assertGradeIdentity, inspectTaskEvidence } from "./admission.js";
8
12
  import { learningRef, LearningSourceSchema, LearningPolicySchema, sameLearningRef, sealLearningContent, TaskAdmissionDecisionContentSchema, TaskAdmissionDecisionSchema, TaskDefinitionSchema, TaskEvidenceContentSchema, TaskEvidenceSchema, TaskFeedbackSchema, TaskGradeRunSchema } from "./contracts.js";
9
13
  import { LearningCommandSchema } from "./operations.js";
10
14
  import { LearningConflictError, learningEvidenceId, learningOperationId, requireLearningRelease, requireLearningResource } from "./repository.js";
@@ -29,6 +33,16 @@ export function createLearningService(repository, options = {}) {
29
33
  }
30
34
  let pointers;
31
35
  switch (input.action) {
36
+ case "cancel_iteration":
37
+ case "retry_iteration_dispatch":
38
+ pointers = await commandLearningIterationDispatch(transaction, input, now());
39
+ break;
40
+ case "cancel_iteration_reservation":
41
+ pointers = await cancelLearningIterationReservation(transaction, input, now());
42
+ break;
43
+ case "reserve_iteration":
44
+ pointers = await reserveLearningIteration(transaction, input, context.actor.id, now());
45
+ break;
32
46
  case "queue_reward_check":
33
47
  pointers = [await queueRewardCheck(transaction, input, operationId, now())];
34
48
  break;
@@ -72,7 +86,7 @@ export function createLearningService(repository, options = {}) {
72
86
  pointers = [await review(transaction, input, context.actor.id)];
73
87
  break;
74
88
  case "seal_batch":
75
- pointers = await seal(transaction, input, context.actor.id);
89
+ pointers = await sealLearningBatch(transaction, input, context.actor.id, now());
76
90
  break;
77
91
  }
78
92
  if (input.action === "publish" || input.action === "publish_resources") {
@@ -143,7 +157,7 @@ export function createLearningService(repository, options = {}) {
143
157
  break;
144
158
  }
145
159
  }
146
- await transaction.put(input.kind, resource, input.expectedRevision);
160
+ await transaction.put(input.kind, resource, input.expectedRevision, input.kind === "policy" ? { parentId: input.content.modelProjectId } : undefined);
147
161
  return pointer(input.kind, resource);
148
162
  }
149
163
  async function submit(transaction, input) {
@@ -308,37 +322,6 @@ export function createLearningService(repository, options = {}) {
308
322
  await transaction.put("decision", decision, input.expectedRevision, { parentId: evidence.id, status: decision.taskAdmissibility });
309
323
  return pointer("decision", decision);
310
324
  }
311
- async function seal(transaction, input, actorId) {
312
- const definition = await requireLearningRelease(transaction, "definition", input.taskDefinition);
313
- const binding = await requireLearningRelease(transaction, "binding", definition.rewardBinding);
314
- const rewards = await Promise.all(binding.sources.map((source) => requireLearningRelease(transaction, "reward", source.reward)));
315
- resolveBoundRewards(binding, rewards);
316
- const evidence = await Promise.all(input.evidence.map((ref) => currentEvidence(transaction, ref)));
317
- const decisions = await Promise.all(input.decisions.map(async (ref) => {
318
- const decision = await requireLearningRelease(transaction, "decision", ref);
319
- const current = await requireLearningResource(transaction, "decision", ref.id);
320
- if (!sameLearningRef(learningRef(current), ref))
321
- throw new LearningDomainError("task_admission_revision_stale", 409);
322
- return decision;
323
- }));
324
- const priorSplits = [];
325
- for (const item of evidence) {
326
- for (const reservation of taskFamilyReservations(item, definition)) {
327
- const split = await transaction.familySplit(reservation.namespace, reservation.kind, reservation.key);
328
- if (split !== null)
329
- priorSplits.push({ ...reservation, split: split });
330
- }
331
- }
332
- const batch = sealTaskBatch({ id: input.batchId, definition, binding, rewards, purpose: input.purpose, evidence, decisions, priorSplits, actorId, now: now() });
333
- const release = compileTaskBatch({ batch, definition, binding, rewards, evidence, decisions });
334
- for (const item of evidence) {
335
- for (const reservation of taskFamilyReservations(item, definition))
336
- await transaction.reserveFamilySplit(reservation.namespace, reservation.kind, reservation.key, reservation.split);
337
- }
338
- await transaction.put("batch", batch, 0, { parentId: definition.id });
339
- await transaction.put("package", release, 0, { parentId: batch.id });
340
- return [pointer("batch", batch), pointer("package", release)];
341
- }
342
325
  return {
343
326
  command,
344
327
  async inspectEvidence(context, reference) {
@@ -361,13 +344,6 @@ export function createLearningService(repository, options = {}) {
361
344
  },
362
345
  };
363
346
  }
364
- async function currentEvidence(transaction, ref) {
365
- const evidence = await requireLearningRelease(transaction, "evidence", ref);
366
- const current = await requireLearningResource(transaction, "evidence", ref.id);
367
- if (!sameLearningRef(learningRef(current), ref))
368
- throw new LearningDomainError("task_evidence_revision_stale", 409);
369
- return evidence;
370
- }
371
347
  async function gradeResult(transaction, id, evidence, target) {
372
348
  if (id === null)
373
349
  return null;
@@ -391,6 +367,6 @@ function authorize(context, input) {
391
367
  if (!sourceId || sourceId !== context.actor.sourceId)
392
368
  throw new LearningDomainError("learning_source_not_authorized", 403);
393
369
  }
394
- if (["review", "apply_correction", "resolve_feedback", "seal_batch"].includes(input.action) && context.actor.role !== "reviewer")
370
+ if (["review", "apply_correction", "resolve_feedback", "seal_batch", "reserve_iteration", "cancel_iteration_reservation", "cancel_iteration", "retry_iteration_dispatch"].includes(input.action) && context.actor.role !== "reviewer")
395
371
  throw new LearningDomainError("learning_review_not_authorized", 403);
396
372
  }
@@ -0,0 +1,8 @@
1
+ import { type LearningRevisionRef, type TaskEvidence } from "./contracts.js";
2
+ import type { LearningCommand } from "./operations.js";
3
+ import { type LearningResourcePointer, type LearningTransaction } from "./repository.js";
4
+ export declare function sealLearningBatch(transaction: LearningTransaction, input: Extract<LearningCommand, {
5
+ action: "seal_batch";
6
+ }>, actorId: string, timestamp: string): Promise<LearningResourcePointer[]>;
7
+ export declare function requireCurrentLearningEvidence(transaction: LearningTransaction, ref: LearningRevisionRef): Promise<TaskEvidence>;
8
+ //# sourceMappingURL=batch-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-service.d.ts","sourceRoot":"","sources":["../../../../../src/learning/batch-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgC,KAAK,mBAAmB,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE3G,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAA8E,KAAK,uBAAuB,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAErK,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,mBAAmB,EAAE,KAAK,EAAE,OAAO,CAAC,eAAe,EAAE;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CA2B3M;AAED,wBAAsB,8BAA8B,CAAC,WAAW,EAAE,mBAAmB,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAKtI"}
@@ -1183,10 +1183,12 @@ export declare const LearningIterationStatusSchema: z.ZodEnum<{
1183
1183
  waiting_for_data: "waiting_for_data";
1184
1184
  waiting_for_review: "waiting_for_review";
1185
1185
  ready: "ready";
1186
+ dispatching: "dispatching";
1186
1187
  evaluating: "evaluating";
1187
1188
  candidate_ready: "candidate_ready";
1188
1189
  paused: "paused";
1189
1190
  cancelling: "cancelling";
1191
+ completed_without_candidate: "completed_without_candidate";
1190
1192
  }>;
1191
1193
  export declare const LearningIterationSchema: z.ZodObject<{
1192
1194
  schemaVersion: z.ZodLiteral<"openpond.learningIteration.v1">;
@@ -1206,10 +1208,12 @@ export declare const LearningIterationSchema: z.ZodObject<{
1206
1208
  waiting_for_data: "waiting_for_data";
1207
1209
  waiting_for_review: "waiting_for_review";
1208
1210
  ready: "ready";
1211
+ dispatching: "dispatching";
1209
1212
  evaluating: "evaluating";
1210
1213
  candidate_ready: "candidate_ready";
1211
1214
  paused: "paused";
1212
1215
  cancelling: "cancelling";
1216
+ completed_without_candidate: "completed_without_candidate";
1213
1217
  }>;
1214
1218
  triggerIdentity: z.ZodString;
1215
1219
  batch: z.ZodNullable<z.ZodObject<{
@@ -2078,10 +2082,12 @@ export declare const LearningResourceSchema: z.ZodUnion<readonly [z.ZodObject<{
2078
2082
  waiting_for_data: "waiting_for_data";
2079
2083
  waiting_for_review: "waiting_for_review";
2080
2084
  ready: "ready";
2085
+ dispatching: "dispatching";
2081
2086
  evaluating: "evaluating";
2082
2087
  candidate_ready: "candidate_ready";
2083
2088
  paused: "paused";
2084
2089
  cancelling: "cancelling";
2090
+ completed_without_candidate: "completed_without_candidate";
2085
2091
  }>;
2086
2092
  triggerIdentity: z.ZodString;
2087
2093
  batch: z.ZodNullable<z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../../../src/learning/contracts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../../../src/learning/contracts.ts"],"names":[],"mappings":"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"}
@@ -12,4 +12,7 @@ export * from "./reward-authoring.js";
12
12
  export * from "./reward-checks.js";
13
13
  export * from "./reward-check-worker.js";
14
14
  export * from "./reward-fixture-executor.js";
15
+ export * from "./iteration-reservation-contracts.js";
16
+ export * from "./iteration-dispatch-contracts.js";
17
+ export * from "./iteration-dispatch-worker.js";
15
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/learning/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/learning/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { LearningCommand } from "./operations.js";
2
+ import { type LearningResourcePointer, type LearningTransaction } from "./repository.js";
3
+ type DispatchCommand = Extract<LearningCommand, {
4
+ action: "cancel_iteration" | "retry_iteration_dispatch";
5
+ }>;
6
+ export declare function commandLearningIterationDispatch(tx: LearningTransaction, input: DispatchCommand, now: string): Promise<LearningResourcePointer[]>;
7
+ export {};
8
+ //# sourceMappingURL=iteration-dispatch-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iteration-dispatch-commands.d.ts","sourceRoot":"","sources":["../../../../../src/learning/iteration-dispatch-commands.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAkD,KAAK,uBAAuB,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEzI,KAAK,eAAe,GAAG,OAAO,CAAC,eAAe,EAAE;IAAE,MAAM,EAAE,kBAAkB,GAAG,0BAA0B,CAAA;CAAE,CAAC,CAAC;AAE7G,wBAAsB,gCAAgC,CAAC,EAAE,EAAE,mBAAmB,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAoBvJ"}
@@ -0,0 +1,93 @@
1
+ import { z } from "zod";
2
+ /** The executor validates its protocol payload before returning this snapshot.
3
+ * Credentials and expiring transport URLs belong to the executor, not payload. */
4
+ export declare const LearningIterationSubmissionSchema: z.ZodObject<{
5
+ provider: z.ZodString;
6
+ protocol: z.ZodString;
7
+ payload: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
8
+ }, z.core.$strict>;
9
+ export declare const LearningIterationDispatchSchema: z.ZodObject<{
10
+ schemaVersion: z.ZodLiteral<"openpond.learningIterationDispatch.v1">;
11
+ id: z.ZodString;
12
+ revision: z.ZodNumber;
13
+ iterationId: z.ZodString;
14
+ chainId: z.ZodString;
15
+ policy: z.ZodObject<{
16
+ id: z.ZodString;
17
+ contentHash: z.ZodString;
18
+ revision: z.ZodNumber;
19
+ }, z.core.$strict>;
20
+ batch: z.ZodObject<{
21
+ id: z.ZodString;
22
+ contentHash: z.ZodString;
23
+ revision: z.ZodNumber;
24
+ }, z.core.$strict>;
25
+ state: z.ZodEnum<{
26
+ blocked: "blocked";
27
+ preparing: "preparing";
28
+ prepared: "prepared";
29
+ submitted: "submitted";
30
+ settled: "settled";
31
+ }>;
32
+ submission: z.ZodNullable<z.ZodObject<{
33
+ provider: z.ZodString;
34
+ protocol: z.ZodString;
35
+ payload: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
36
+ }, z.core.$strict>>;
37
+ submissionHash: z.ZodNullable<z.ZodString>;
38
+ submissionStartedAt: z.ZodNullable<z.ZodString>;
39
+ execution: z.ZodNullable<z.ZodObject<{
40
+ id: z.ZodString;
41
+ contentHash: z.ZodString;
42
+ }, z.core.$strict>>;
43
+ terminalReceipt: z.ZodNullable<z.ZodObject<{
44
+ id: z.ZodString;
45
+ contentHash: z.ZodString;
46
+ }, z.core.$strict>>;
47
+ cancelRequestedAt: z.ZodNullable<z.ZodString>;
48
+ leaseOwner: z.ZodNullable<z.ZodString>;
49
+ leaseGeneration: z.ZodNumber;
50
+ leaseExpiresAt: z.ZodNullable<z.ZodString>;
51
+ consecutiveFailures: z.ZodNumber;
52
+ nextAttemptAt: z.ZodNullable<z.ZodString>;
53
+ lastError: z.ZodNullable<z.ZodString>;
54
+ createdAt: z.ZodString;
55
+ updatedAt: z.ZodString;
56
+ }, z.core.$strict>;
57
+ /** Terminal cleanup includes fencing future submission under this dispatch ID.
58
+ * The execution adapter verifies its authoritative provider receipt. */
59
+ export declare const LearningIterationObservationSchema: z.ZodObject<{
60
+ scope: z.ZodString;
61
+ dispatchId: z.ZodString;
62
+ submissionHash: z.ZodString;
63
+ execution: z.ZodNullable<z.ZodObject<{
64
+ id: z.ZodString;
65
+ contentHash: z.ZodString;
66
+ }, z.core.$strict>>;
67
+ status: z.ZodEnum<{
68
+ failed: "failed";
69
+ cancelled: "cancelled";
70
+ running: "running";
71
+ evaluating: "evaluating";
72
+ succeeded: "succeeded";
73
+ }>;
74
+ spendUsd: z.ZodNumber;
75
+ cleanupComplete: z.ZodBoolean;
76
+ receipt: z.ZodNullable<z.ZodObject<{
77
+ id: z.ZodString;
78
+ contentHash: z.ZodString;
79
+ }, z.core.$strict>>;
80
+ evaluation: z.ZodNullable<z.ZodObject<{
81
+ id: z.ZodString;
82
+ contentHash: z.ZodString;
83
+ }, z.core.$strict>>;
84
+ candidate: z.ZodNullable<z.ZodObject<{
85
+ id: z.ZodString;
86
+ contentHash: z.ZodString;
87
+ }, z.core.$strict>>;
88
+ failure: z.ZodNullable<z.ZodString>;
89
+ }, z.core.$strict>;
90
+ export type LearningIterationSubmission = z.infer<typeof LearningIterationSubmissionSchema>;
91
+ export type LearningIterationDispatch = z.infer<typeof LearningIterationDispatchSchema>;
92
+ export type LearningIterationObservation = z.infer<typeof LearningIterationObservationSchema>;
93
+ //# sourceMappingURL=iteration-dispatch-contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iteration-dispatch-contracts.d.ts","sourceRoot":"","sources":["../../../../../src/learning/iteration-dispatch-contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;kFACkF;AAClF,eAAO,MAAM,iCAAiC;;;;kBAInC,CAAC;AAEZ,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiC1C,CAAC;AAEH;wEACwE;AACxE,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAkB7C,CAAC;AAEH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAC5F,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AACxF,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { type LearningIteration, type LearningPolicy, type TaskBatch } from "./contracts.js";
2
+ import { type LearningIterationDispatch, type LearningIterationObservation, type LearningIterationSubmission } from "./iteration-dispatch-contracts.js";
3
+ import { type LearningRepository } from "./repository.js";
4
+ export type LearningIterationExecutionContext = {
5
+ scope: string;
6
+ dispatch: LearningIterationDispatch;
7
+ iteration: LearningIteration;
8
+ policy: LearningPolicy;
9
+ batch: TaskBatch;
10
+ signal: AbortSignal;
11
+ };
12
+ export interface LearningIterationExecutor {
13
+ /** Resolve immutable inputs and validate compatibility. Must not launch compute. */
14
+ prepare(input: LearningIterationExecutionContext): Promise<LearningIterationSubmission>;
15
+ /** Return the existing execution under dispatch.id; null means not found.
16
+ * An unavailable owner must throw, never report absence. */
17
+ reconcile(input: LearningIterationExecutionContext): Promise<LearningIterationObservation | null>;
18
+ /** Idempotently submit exactly dispatch.submission under dispatch.id, across
19
+ * crashes, lease owners and retries. Never create a different Job on retry. */
20
+ submit(input: LearningIterationExecutionContext): Promise<LearningIterationObservation>;
21
+ /** Cancel by dispatch identity, including an ambiguous initial submission.
22
+ * Terminal confirmation MUST fence late submits under that identity, including
23
+ * when no Job was created. A network abort alone is not cleanup confirmation. */
24
+ cancel(input: LearningIterationExecutionContext): Promise<LearningIterationObservation>;
25
+ }
26
+ export declare function createLearningIterationWorker(repository: LearningRepository, executor: LearningIterationExecutor, options: {
27
+ workerId: string;
28
+ executionOwner: LearningPolicy["executionOwner"];
29
+ now?: () => string;
30
+ leaseMs?: number;
31
+ requestTimeoutMs?: number;
32
+ }): {
33
+ run: (scope: string, iterationId: string) => Promise<LearningIteration>;
34
+ };
35
+ //# sourceMappingURL=iteration-dispatch-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iteration-dispatch-worker.d.ts","sourceRoot":"","sources":["../../../../../src/learning/iteration-dispatch-worker.ts"],"names":[],"mappings":"AACA,OAAO,EAA2B,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGtH,OAAO,EAEL,KAAK,yBAAyB,EAAE,KAAK,4BAA4B,EAAE,KAAK,2BAA2B,EACpG,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAmD,KAAK,kBAAkB,EAA4B,MAAM,iBAAiB,CAAC;AAErI,MAAM,MAAM,iCAAiC,GAAG;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,yBAAyB,CAAC;IACpC,SAAS,EAAE,iBAAiB,CAAC;IAC7B,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;CACrB,CAAC;AACF,MAAM,WAAW,yBAAyB;IACxC,oFAAoF;IACpF,OAAO,CAAC,KAAK,EAAE,iCAAiC,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACxF;gEAC4D;IAC5D,SAAS,CAAC,KAAK,EAAE,iCAAiC,GAAG,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAAC;IAClG;mFAC+E;IAC/E,MAAM,CAAC,KAAK,EAAE,iCAAiC,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAC;IACxF;;qFAEiF;IACjF,MAAM,CAAC,KAAK,EAAE,iCAAiC,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAC;CACzF;AAID,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,yBAAyB,EAAE,OAAO,EAAE;IAC1H,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,cAAc,CAAC,gBAAgB,CAAC,CAAC;IACjD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;iBAsF2B,MAAM,eAAe,MAAM,KAAG,OAAO,CAAC,iBAAiB,CAAC;EA8DnF"}
@@ -0,0 +1,18 @@
1
+ import { type LearningPolicy, type TaskAdmissionDecision, type TaskEvidence } from "./contracts.js";
2
+ import { type LearningTransaction } from "./repository.js";
3
+ export declare function learningChainId(modelProjectId: string): string;
4
+ export declare function learningConsumptionId(chainId: string, evidence: TaskEvidence): string;
5
+ export declare function inspectIterationEligibility(transaction: LearningTransaction, policy: LearningPolicy): Promise<{
6
+ counts: {
7
+ eligible: number;
8
+ awaitingReview: number;
9
+ excluded: number;
10
+ consumed: number;
11
+ };
12
+ selected: {
13
+ evidence: TaskEvidence;
14
+ decision: TaskAdmissionDecision;
15
+ }[];
16
+ purpose: "supervised_training" | "reward_training";
17
+ }>;
18
+ //# sourceMappingURL=iteration-eligibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iteration-eligibility.d.ts","sourceRoot":"","sources":["../../../../../src/learning/iteration-eligibility.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgC,KAAK,cAAc,EAAE,KAAK,qBAAqB,EAAkB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGlJ,OAAO,EAAmD,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE5G,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,MAAM,CAErF;AAED,wBAAsB,2BAA2B,CAAC,WAAW,EAAE,mBAAmB,EAAE,MAAM,EAAE,cAAc;;;;;;;;kBAY5E,YAAY;kBAAY,qBAAqB;;;GA2C1E"}
@@ -0,0 +1,8 @@
1
+ import type { LearningCommand } from "./operations.js";
2
+ import { type LearningResourcePointer, type LearningTransaction } from "./repository.js";
3
+ /** Only a reservation that has never been dispatched can release spend locally.
4
+ * Submitted executions require authoritative cancellation and settlement. */
5
+ export declare function cancelLearningIterationReservation(transaction: LearningTransaction, input: Extract<LearningCommand, {
6
+ action: "cancel_iteration_reservation";
7
+ }>, now: string): Promise<LearningResourcePointer[]>;
8
+ //# sourceMappingURL=iteration-reservation-cancellation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iteration-reservation-cancellation.d.ts","sourceRoot":"","sources":["../../../../../src/learning/iteration-reservation-cancellation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAkD,KAAK,uBAAuB,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEzI;6EAC6E;AAC7E,wBAAsB,kCAAkC,CACtD,WAAW,EAAE,mBAAmB,EAChC,KAAK,EAAE,OAAO,CAAC,eAAe,EAAE;IAAE,MAAM,EAAE,8BAA8B,CAAA;CAAE,CAAC,EAC3E,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAsBpC"}
@@ -0,0 +1,90 @@
1
+ import { z } from "zod";
2
+ export declare const LearningIterationTriggerSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
3
+ kind: z.ZodLiteral<"manual">;
4
+ identity: z.ZodString;
5
+ }, z.core.$strict>, z.ZodObject<{
6
+ kind: z.ZodLiteral<"schedule">;
7
+ scheduledAt: z.ZodString;
8
+ }, z.core.$strict>], "kind">;
9
+ /** Stable across policy edits: a Model owns one learning chain in its scope. */
10
+ export declare const LearningChainSchema: z.ZodObject<{
11
+ schemaVersion: z.ZodLiteral<"openpond.learningChain.v1">;
12
+ id: z.ZodString;
13
+ revision: z.ZodNumber;
14
+ modelProjectId: z.ZodString;
15
+ activeIterationId: z.ZodNullable<z.ZodString>;
16
+ latestIterationId: z.ZodString;
17
+ lastReservedAt: z.ZodNullable<z.ZodString>;
18
+ updatedAt: z.ZodString;
19
+ }, z.core.$strict>;
20
+ export declare const LearningEligibilityCountsSchema: z.ZodObject<{
21
+ eligible: z.ZodNumber;
22
+ awaitingReview: z.ZodNumber;
23
+ excluded: z.ZodNumber;
24
+ consumed: z.ZodNumber;
25
+ }, z.core.$strict>;
26
+ /** Immutable evidence consumption survives rejection and policy revision changes.
27
+ * A corrected evidence revision is new data; reapproving the same revision isn't. */
28
+ export declare const LearningConsumptionSchema: z.ZodObject<{
29
+ schemaVersion: z.ZodLiteral<"openpond.learningConsumption.v1">;
30
+ id: z.ZodString;
31
+ revision: z.ZodLiteral<1>;
32
+ chainId: z.ZodString;
33
+ iterationId: z.ZodString;
34
+ evidence: z.ZodObject<{
35
+ id: z.ZodString;
36
+ contentHash: z.ZodString;
37
+ revision: z.ZodNumber;
38
+ }, z.core.$strict>;
39
+ decision: z.ZodObject<{
40
+ id: z.ZodString;
41
+ contentHash: z.ZodString;
42
+ revision: z.ZodNumber;
43
+ }, z.core.$strict>;
44
+ reservedAt: z.ZodString;
45
+ }, z.core.$strict>;
46
+ /** Dispatch must reconcile this reservation, never reserve a second batch on retry. */
47
+ export declare const LearningIterationReservationSchema: z.ZodObject<{
48
+ schemaVersion: z.ZodLiteral<"openpond.learningIterationReservation.v1">;
49
+ id: z.ZodString;
50
+ revision: z.ZodNumber;
51
+ chainId: z.ZodString;
52
+ iterationId: z.ZodString;
53
+ policy: z.ZodObject<{
54
+ id: z.ZodString;
55
+ contentHash: z.ZodString;
56
+ revision: z.ZodNumber;
57
+ }, z.core.$strict>;
58
+ trigger: z.ZodDiscriminatedUnion<[z.ZodObject<{
59
+ kind: z.ZodLiteral<"manual">;
60
+ identity: z.ZodString;
61
+ }, z.core.$strict>, z.ZodObject<{
62
+ kind: z.ZodLiteral<"schedule">;
63
+ scheduledAt: z.ZodString;
64
+ }, z.core.$strict>], "kind">;
65
+ requestHash: z.ZodString;
66
+ outcome: z.ZodEnum<{
67
+ waiting_for_data: "waiting_for_data";
68
+ waiting_for_review: "waiting_for_review";
69
+ reserved: "reserved";
70
+ }>;
71
+ counts: z.ZodObject<{
72
+ eligible: z.ZodNumber;
73
+ awaitingReview: z.ZodNumber;
74
+ excluded: z.ZodNumber;
75
+ consumed: z.ZodNumber;
76
+ }, z.core.$strict>;
77
+ budget: z.ZodObject<{
78
+ maximumSpendUsd: z.ZodNumber;
79
+ reservedSpendUsd: z.ZodNumber;
80
+ settledSpendUsd: z.ZodNumber;
81
+ settledAt: z.ZodNullable<z.ZodString>;
82
+ }, z.core.$strict>;
83
+ createdAt: z.ZodString;
84
+ updatedAt: z.ZodString;
85
+ }, z.core.$strict>;
86
+ export type LearningChain = z.infer<typeof LearningChainSchema>;
87
+ export type LearningConsumption = z.infer<typeof LearningConsumptionSchema>;
88
+ export type LearningIterationReservation = z.infer<typeof LearningIterationReservationSchema>;
89
+ export type LearningIterationTrigger = z.infer<typeof LearningIterationTriggerSchema>;
90
+ //# sourceMappingURL=iteration-reservation-contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iteration-reservation-contracts.d.ts","sourceRoot":"","sources":["../../../../../src/learning/iteration-reservation-contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,8BAA8B;;;;;;4BAGzC,CAAC;AAEH,gFAAgF;AAChF,eAAO,MAAM,mBAAmB;;;;;;;;;kBASrB,CAAC;AAEZ,eAAO,MAAM,+BAA+B;;;;;kBAKjC,CAAC;AAEZ;qFACqF;AACrF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;kBAS3B,CAAC;AAEZ,uFAAuF;AACvF,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmBpC,CAAC;AAEZ,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAC5E,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAC9F,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC"}