@openpond/evals 0.12.0 → 0.12.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 (290) hide show
  1. package/dist/artifact-verification.js +2 -0
  2. package/dist/connected-evidence/sources/claude-branches.js +34 -1
  3. package/dist/connected-evidence/sources/claude-code.js +1 -1
  4. package/dist/learning/continuation-mode.js +9 -0
  5. package/dist/learning/contracts.js +2 -0
  6. package/dist/learning/correction-metrics.js +61 -0
  7. package/dist/learning/index.js +2 -0
  8. package/dist/native-conversations/collector-acquisition.js +17 -6
  9. package/dist/native-conversations/collector-source-cache.js +1 -1
  10. package/dist/native-conversations/collector-store.js +27 -2
  11. package/dist/native-conversations/collector.js +4 -3
  12. package/dist/native-conversations/history.js +28 -8
  13. package/dist/native-conversations/index.js +1 -0
  14. package/dist/native-conversations/selection.js +57 -0
  15. package/dist/native-conversations/supervisor.js +2 -0
  16. package/dist/native-conversations/titles.js +2 -2
  17. package/dist/tasksets.js +1 -0
  18. package/dist/types/artifact-verification.d.ts.map +1 -1
  19. package/dist/types/benchmarks.d.ts +22 -22
  20. package/dist/types/benchmarks.d.ts.map +1 -1
  21. package/dist/types/builtin-benchmarks/harness-refiner.d.ts +40 -39
  22. package/dist/types/builtin-benchmarks/harness-refiner.d.ts.map +1 -1
  23. package/dist/types/compatibility.d.ts.map +1 -1
  24. package/dist/types/conformance.d.ts +98 -96
  25. package/dist/types/conformance.d.ts.map +1 -1
  26. package/dist/types/connected-evidence/codex-command-observations.d.ts.map +1 -1
  27. package/dist/types/connected-evidence/collector-coverage-contracts.d.ts +6 -6
  28. package/dist/types/connected-evidence/collector-coverage-contracts.d.ts.map +1 -1
  29. package/dist/types/connected-evidence/contracts.d.ts +58 -58
  30. package/dist/types/connected-evidence/contracts.d.ts.map +1 -1
  31. package/dist/types/connected-evidence/git-file-contracts.d.ts.map +1 -1
  32. package/dist/types/connected-evidence/git-file-proof.d.ts.map +1 -1
  33. package/dist/types/connected-evidence/git-starting-state.d.ts.map +1 -1
  34. package/dist/types/connected-evidence/git.d.ts.map +1 -1
  35. package/dist/types/connected-evidence/imports.d.ts.map +1 -1
  36. package/dist/types/connected-evidence/index.d.ts.map +1 -1
  37. package/dist/types/connected-evidence/normalize.d.ts.map +1 -1
  38. package/dist/types/connected-evidence/python-correctness.d.ts +38 -38
  39. package/dist/types/connected-evidence/python-correctness.d.ts.map +1 -1
  40. package/dist/types/connected-evidence/sources/claude-branches.d.ts +1 -0
  41. package/dist/types/connected-evidence/sources/claude-branches.d.ts.map +1 -1
  42. package/dist/types/connected-evidence/sources/claude-code.d.ts +25 -25
  43. package/dist/types/connected-evidence/sources/claude-code.d.ts.map +1 -1
  44. package/dist/types/connected-evidence/sources/codex-authorization.d.ts.map +1 -1
  45. package/dist/types/connected-evidence/sources/codex-metadata.d.ts.map +1 -1
  46. package/dist/types/connected-evidence/sources/codex.d.ts +25 -25
  47. package/dist/types/connected-evidence/sources/codex.d.ts.map +1 -1
  48. package/dist/types/connected-evidence/sources/grok-build.d.ts +25 -25
  49. package/dist/types/connected-evidence/sources/grok-build.d.ts.map +1 -1
  50. package/dist/types/connected-evidence/sources/history.d.ts +44 -44
  51. package/dist/types/connected-evidence/sources/history.d.ts.map +1 -1
  52. package/dist/types/connected-evidence/sources/opencode.d.ts +25 -25
  53. package/dist/types/connected-evidence/sources/opencode.d.ts.map +1 -1
  54. package/dist/types/connected-evidence/sources/pi.d.ts +25 -25
  55. package/dist/types/connected-evidence/sources/pi.d.ts.map +1 -1
  56. package/dist/types/connected-evidence/sources/usage.d.ts.map +1 -1
  57. package/dist/types/connected-evidence/usage-summary.d.ts.map +1 -1
  58. package/dist/types/deterministic-graders.d.ts.map +1 -1
  59. package/dist/types/environment-execution-services-contract.d.ts +19 -19
  60. package/dist/types/environment-execution-services-contract.d.ts.map +1 -1
  61. package/dist/types/environment-execution-services.d.ts.map +1 -1
  62. package/dist/types/evidence/authoring.d.ts.map +1 -1
  63. package/dist/types/evidence/conformance.d.ts +98 -98
  64. package/dist/types/evidence/conformance.d.ts.map +1 -1
  65. package/dist/types/evidence/contracts.d.ts +183 -183
  66. package/dist/types/evidence/contracts.d.ts.map +1 -1
  67. package/dist/types/evidence/eligibility.d.ts +160 -160
  68. package/dist/types/evidence/eligibility.d.ts.map +1 -1
  69. package/dist/types/evidence/index.d.ts.map +1 -1
  70. package/dist/types/execution-contracts.d.ts +110 -110
  71. package/dist/types/execution-contracts.d.ts.map +1 -1
  72. package/dist/types/execution-receipts.d.ts.map +1 -1
  73. package/dist/types/experiments.d.ts +96 -96
  74. package/dist/types/experiments.d.ts.map +1 -1
  75. package/dist/types/graders.d.ts +35 -35
  76. package/dist/types/graders.d.ts.map +1 -1
  77. package/dist/types/harness-experiment-source.d.ts.map +1 -1
  78. package/dist/types/harness.d.ts.map +1 -1
  79. package/dist/types/human-review/comparison.d.ts +189 -189
  80. package/dist/types/human-review/comparison.d.ts.map +1 -1
  81. package/dist/types/human-review/contracts.d.ts +178 -178
  82. package/dist/types/human-review/contracts.d.ts.map +1 -1
  83. package/dist/types/human-review/execution.d.ts +53 -53
  84. package/dist/types/human-review/execution.d.ts.map +1 -1
  85. package/dist/types/human-review/handoff.d.ts +43 -43
  86. package/dist/types/human-review/handoff.d.ts.map +1 -1
  87. package/dist/types/human-review/index.d.ts.map +1 -1
  88. package/dist/types/human-review/local-publication.d.ts +4 -4
  89. package/dist/types/human-review/local-publication.d.ts.map +1 -1
  90. package/dist/types/human-review/repository.d.ts.map +1 -1
  91. package/dist/types/human-review/results.d.ts +8 -8
  92. package/dist/types/human-review/results.d.ts.map +1 -1
  93. package/dist/types/human-review/service.d.ts +292 -292
  94. package/dist/types/human-review/service.d.ts.map +1 -1
  95. package/dist/types/human-review/task-proposals.d.ts +2 -2
  96. package/dist/types/human-review/task-proposals.d.ts.map +1 -1
  97. package/dist/types/index.d.ts.map +1 -1
  98. package/dist/types/javascript-environment-attempt.d.ts.map +1 -1
  99. package/dist/types/javascript-environment-contract.d.ts +39 -39
  100. package/dist/types/javascript-environment-contract.d.ts.map +1 -1
  101. package/dist/types/javascript-environment-node.d.ts.map +1 -1
  102. package/dist/types/javascript-environment.d.ts +14 -14
  103. package/dist/types/javascript-environment.d.ts.map +1 -1
  104. package/dist/types/javascript-isolate-node.d.ts.map +1 -1
  105. package/dist/types/javascript-isolate-process-entry.d.ts.map +1 -1
  106. package/dist/types/javascript-isolate-process.d.ts.map +1 -1
  107. package/dist/types/javascript-isolate.d.ts.map +1 -1
  108. package/dist/types/javascript-verifier-contract.d.ts.map +1 -1
  109. package/dist/types/javascript-verifier-node.d.ts.map +1 -1
  110. package/dist/types/javascript-verifier-worker.d.ts.map +1 -1
  111. package/dist/types/javascript-verifier.d.ts.map +1 -1
  112. package/dist/types/learned-preference.d.ts +10 -10
  113. package/dist/types/learned-preference.d.ts.map +1 -1
  114. package/dist/types/learning/acceptance-group.d.ts +44 -44
  115. package/dist/types/learning/acceptance-group.d.ts.map +1 -1
  116. package/dist/types/learning/acceptance-plan.d.ts +8 -8
  117. package/dist/types/learning/acceptance-plan.d.ts.map +1 -1
  118. package/dist/types/learning/admission.d.ts +37 -36
  119. package/dist/types/learning/admission.d.ts.map +1 -1
  120. package/dist/types/learning/assets.d.ts +2 -2
  121. package/dist/types/learning/assets.d.ts.map +1 -1
  122. package/dist/types/learning/authoring-service.d.ts +11 -11
  123. package/dist/types/learning/authoring-service.d.ts.map +1 -1
  124. package/dist/types/learning/authoring.d.ts +38 -38
  125. package/dist/types/learning/authoring.d.ts.map +1 -1
  126. package/dist/types/learning/batch-service.d.ts +75 -72
  127. package/dist/types/learning/batch-service.d.ts.map +1 -1
  128. package/dist/types/learning/budgeted-reward-fixtures.d.ts.map +1 -1
  129. package/dist/types/learning/continuation-mode.d.ts +18 -0
  130. package/dist/types/learning/continuation-mode.d.ts.map +1 -0
  131. package/dist/types/learning/contracts.d.ts +341 -298
  132. package/dist/types/learning/contracts.d.ts.map +1 -1
  133. package/dist/types/learning/correction-metrics.d.ts +274 -0
  134. package/dist/types/learning/correction-metrics.d.ts.map +1 -0
  135. package/dist/types/learning/errors.d.ts.map +1 -1
  136. package/dist/types/learning/grade-judge-budget.d.ts.map +1 -1
  137. package/dist/types/learning/grade-worker.d.ts.map +1 -1
  138. package/dist/types/learning/index.d.ts +2 -0
  139. package/dist/types/learning/index.d.ts.map +1 -1
  140. package/dist/types/learning/intake-contracts.d.ts +10 -10
  141. package/dist/types/learning/intake-contracts.d.ts.map +1 -1
  142. package/dist/types/learning/intake-csv.d.ts.map +1 -1
  143. package/dist/types/learning/intake-history.d.ts.map +1 -1
  144. package/dist/types/learning/intake-service.d.ts.map +1 -1
  145. package/dist/types/learning/intake-text.d.ts.map +1 -1
  146. package/dist/types/learning/intake.d.ts.map +1 -1
  147. package/dist/types/learning/iteration-budget.d.ts.map +1 -1
  148. package/dist/types/learning/iteration-candidate-decision.d.ts +16 -16
  149. package/dist/types/learning/iteration-candidate-decision.d.ts.map +1 -1
  150. package/dist/types/learning/iteration-dispatch-commands.d.ts.map +1 -1
  151. package/dist/types/learning/iteration-dispatch-contracts.d.ts +4 -4
  152. package/dist/types/learning/iteration-dispatch-contracts.d.ts.map +1 -1
  153. package/dist/types/learning/iteration-dispatch-worker.d.ts.map +1 -1
  154. package/dist/types/learning/iteration-eligibility.d.ts +1 -1
  155. package/dist/types/learning/iteration-eligibility.d.ts.map +1 -1
  156. package/dist/types/learning/iteration-reservation-cancellation.d.ts.map +1 -1
  157. package/dist/types/learning/iteration-reservation-contracts.d.ts.map +1 -1
  158. package/dist/types/learning/iteration-reservation-service.d.ts.map +1 -1
  159. package/dist/types/learning/iteration-training-parent.d.ts.map +1 -1
  160. package/dist/types/learning/judge-budget.d.ts +1 -1
  161. package/dist/types/learning/judge-budget.d.ts.map +1 -1
  162. package/dist/types/learning/model-judge.d.ts.map +1 -1
  163. package/dist/types/learning/nightly-schedule.d.ts.map +1 -1
  164. package/dist/types/learning/operations.d.ts +352 -298
  165. package/dist/types/learning/operations.d.ts.map +1 -1
  166. package/dist/types/learning/policy-inspection.d.ts.map +1 -1
  167. package/dist/types/learning/rating-reward-fixture.d.ts.map +1 -1
  168. package/dist/types/learning/repository.d.ts +199 -184
  169. package/dist/types/learning/repository.d.ts.map +1 -1
  170. package/dist/types/learning/reward-authoring.d.ts.map +1 -1
  171. package/dist/types/learning/reward-calibration-closure.d.ts +248 -248
  172. package/dist/types/learning/reward-calibration-closure.d.ts.map +1 -1
  173. package/dist/types/learning/reward-calibration.d.ts +62 -62
  174. package/dist/types/learning/reward-calibration.d.ts.map +1 -1
  175. package/dist/types/learning/reward-check-budget.d.ts.map +1 -1
  176. package/dist/types/learning/reward-check-service.d.ts.map +1 -1
  177. package/dist/types/learning/reward-check-worker.d.ts.map +1 -1
  178. package/dist/types/learning/reward-checks.d.ts +30 -30
  179. package/dist/types/learning/reward-checks.d.ts.map +1 -1
  180. package/dist/types/learning/reward-fixture-executor.d.ts.map +1 -1
  181. package/dist/types/learning/schedule-contracts.d.ts +3 -3
  182. package/dist/types/learning/schedule-contracts.d.ts.map +1 -1
  183. package/dist/types/learning/schedule-service.d.ts +2 -2
  184. package/dist/types/learning/schedule-service.d.ts.map +1 -1
  185. package/dist/types/learning/schedule-worker.d.ts.map +1 -1
  186. package/dist/types/learning/service.d.ts +3 -3
  187. package/dist/types/learning/service.d.ts.map +1 -1
  188. package/dist/types/learning/task-queue-inspection.d.ts.map +1 -1
  189. package/dist/types/learning/training-handoff.d.ts +9 -9
  190. package/dist/types/learning/training-handoff.d.ts.map +1 -1
  191. package/dist/types/learning/transport.d.ts +2270 -2228
  192. package/dist/types/learning/transport.d.ts.map +1 -1
  193. package/dist/types/metric-policy.d.ts +6 -6
  194. package/dist/types/metric-policy.d.ts.map +1 -1
  195. package/dist/types/metrics-node.d.ts.map +1 -1
  196. package/dist/types/metrics.d.ts.map +1 -1
  197. package/dist/types/model-improvement-qualification.d.ts +17 -17
  198. package/dist/types/model-improvement-qualification.d.ts.map +1 -1
  199. package/dist/types/native-conversations/appimage-runtime.d.ts.map +1 -1
  200. package/dist/types/native-conversations/codex-window-inventory.d.ts.map +1 -1
  201. package/dist/types/native-conversations/collector-acquisition.d.ts.map +1 -1
  202. package/dist/types/native-conversations/collector-branches.d.ts.map +1 -1
  203. package/dist/types/native-conversations/collector-calendar-gate.d.ts.map +1 -1
  204. package/dist/types/native-conversations/collector-contracts.d.ts +3 -0
  205. package/dist/types/native-conversations/collector-contracts.d.ts.map +1 -1
  206. package/dist/types/native-conversations/collector-coverage.d.ts +2 -2
  207. package/dist/types/native-conversations/collector-coverage.d.ts.map +1 -1
  208. package/dist/types/native-conversations/collector-cron.d.ts.map +1 -1
  209. package/dist/types/native-conversations/collector-destinations.d.ts.map +1 -1
  210. package/dist/types/native-conversations/collector-errors.d.ts.map +1 -1
  211. package/dist/types/native-conversations/collector-progress.d.ts.map +1 -1
  212. package/dist/types/native-conversations/collector-schedule.d.ts.map +1 -1
  213. package/dist/types/native-conversations/collector-service-files.d.ts.map +1 -1
  214. package/dist/types/native-conversations/collector-snapshots.d.ts.map +1 -1
  215. package/dist/types/native-conversations/collector-source-cache.d.ts +2 -2
  216. package/dist/types/native-conversations/collector-source-cache.d.ts.map +1 -1
  217. package/dist/types/native-conversations/collector-store.d.ts.map +1 -1
  218. package/dist/types/native-conversations/collector-sync-requests.d.ts.map +1 -1
  219. package/dist/types/native-conversations/collector.d.ts.map +1 -1
  220. package/dist/types/native-conversations/contracts.d.ts +2 -0
  221. package/dist/types/native-conversations/contracts.d.ts.map +1 -1
  222. package/dist/types/native-conversations/database.d.ts.map +1 -1
  223. package/dist/types/native-conversations/discovery.d.ts.map +1 -1
  224. package/dist/types/native-conversations/git-assets.d.ts.map +1 -1
  225. package/dist/types/native-conversations/history.d.ts +2 -0
  226. package/dist/types/native-conversations/history.d.ts.map +1 -1
  227. package/dist/types/native-conversations/index.d.ts +1 -0
  228. package/dist/types/native-conversations/index.d.ts.map +1 -1
  229. package/dist/types/native-conversations/location.d.ts.map +1 -1
  230. package/dist/types/native-conversations/openclaw-cold-archive.d.ts.map +1 -1
  231. package/dist/types/native-conversations/openclaw-database.d.ts.map +1 -1
  232. package/dist/types/native-conversations/readiness.d.ts.map +1 -1
  233. package/dist/types/native-conversations/selection.d.ts +32 -0
  234. package/dist/types/native-conversations/selection.d.ts.map +1 -0
  235. package/dist/types/native-conversations/source-locations.d.ts.map +1 -1
  236. package/dist/types/native-conversations/supervisor.d.ts.map +1 -1
  237. package/dist/types/native-conversations/titles.d.ts +1 -1
  238. package/dist/types/native-conversations/titles.d.ts.map +1 -1
  239. package/dist/types/native-harness-experiment-attempt.d.ts.map +1 -1
  240. package/dist/types/preferences.d.ts +22 -22
  241. package/dist/types/preferences.d.ts.map +1 -1
  242. package/dist/types/prepared-process-isolation.d.ts.map +1 -1
  243. package/dist/types/profile-evaluation-comparisons.d.ts +18 -18
  244. package/dist/types/profile-evaluation-comparisons.d.ts.map +1 -1
  245. package/dist/types/profile-evaluation-execution.d.ts.map +1 -1
  246. package/dist/types/profile-evaluation-reports.d.ts +2 -2
  247. package/dist/types/profile-evaluation-reports.d.ts.map +1 -1
  248. package/dist/types/profile-evaluation-suites.d.ts.map +1 -1
  249. package/dist/types/profile-evaluation-target.d.ts.map +1 -1
  250. package/dist/types/profile-evaluations.d.ts +15 -15
  251. package/dist/types/profile-evaluations.d.ts.map +1 -1
  252. package/dist/types/profile-external-evaluation.d.ts +84 -84
  253. package/dist/types/profile-external-evaluation.d.ts.map +1 -1
  254. package/dist/types/profile-source-candidate.d.ts.map +1 -1
  255. package/dist/types/review-conformance.d.ts +53 -53
  256. package/dist/types/review-conformance.d.ts.map +1 -1
  257. package/dist/types/rewards.d.ts +104 -104
  258. package/dist/types/rewards.d.ts.map +1 -1
  259. package/dist/types/rollouts.d.ts +16 -16
  260. package/dist/types/rollouts.d.ts.map +1 -1
  261. package/dist/types/runs.d.ts +22 -22
  262. package/dist/types/runs.d.ts.map +1 -1
  263. package/dist/types/sql-execution-contract.d.ts +3 -3
  264. package/dist/types/sql-execution-contract.d.ts.map +1 -1
  265. package/dist/types/sql-execution-engine.d.ts.map +1 -1
  266. package/dist/types/sql-execution-node.d.ts.map +1 -1
  267. package/dist/types/sql-execution-process-entry.d.ts.map +1 -1
  268. package/dist/types/task-schema-validation.d.ts.map +1 -1
  269. package/dist/types/task-schema.d.ts.map +1 -1
  270. package/dist/types/task-value-validator.d.ts.map +1 -1
  271. package/dist/types/taskset-run-contract.d.ts +26 -26
  272. package/dist/types/taskset-run-contract.d.ts.map +1 -1
  273. package/dist/types/tasksets.d.ts +73 -69
  274. package/dist/types/tasksets.d.ts.map +1 -1
  275. package/dist/types/telemetry/index.d.ts.map +1 -1
  276. package/dist/types/telemetry-analysis.d.ts +6 -6
  277. package/dist/types/telemetry-analysis.d.ts.map +1 -1
  278. package/dist/types/telemetry-bundle.d.ts +42 -42
  279. package/dist/types/telemetry-bundle.d.ts.map +1 -1
  280. package/dist/types/telemetry-catalog.d.ts +67 -67
  281. package/dist/types/telemetry-catalog.d.ts.map +1 -1
  282. package/dist/types/telemetry.d.ts +44 -44
  283. package/dist/types/telemetry.d.ts.map +1 -1
  284. package/package.json +1 -1
  285. package/schemas/learning/v1/command-request.schema.json +44 -0
  286. package/schemas/learning/v1/definition.schema.json +4 -0
  287. package/schemas/learning/v1/evidence.schema.json +4 -0
  288. package/schemas/learning/v1/example-submission.schema.json +4 -0
  289. package/schemas/learning/v1/package.schema.json +4 -0
  290. package/schemas/learning/v1/policy.schema.json +40 -0
@@ -143,6 +143,8 @@ function structuralFailures(required, entry) {
143
143
  }
144
144
  if (entry.parseStatus === "failed")
145
145
  failures.push(`Required output ${required.path} could not be parsed.`);
146
+ if (required.submissionMode === "structured_json" && (entry.schemaStatus !== "passed" || entry.parseStatus !== "passed" || entry.metadata.structuredSchemaHash !== required.schemaRef?.contentHash || entry.metadata.structuredArtifactHash !== entry.artifact?.contentHash))
147
+ failures.push(`Required output ${required.path} lacks bound structured validation evidence.`);
146
148
  if (entry.schemaStatus === "failed")
147
149
  failures.push(`Required output ${required.path} failed schema validation.`);
148
150
  return failures;
@@ -48,5 +48,38 @@ export function claudeGraph(rows) {
48
48
  return { leafId: leaf.uuid, chainHash: selected.chainHash, title: title.slice(0, 180), updatedAt: connectedTimestamp(last?.timestamp), messages: messages.length };
49
49
  });
50
50
  }
51
- return { sessionId, leaves, select, branches };
51
+ function latestLeafId() {
52
+ // Match Claude's session browser: walk terminal bookkeeping back to a
53
+ // message, then prefer the last main-chain message in file order. Wall
54
+ // clock timestamps and later sidechain/meta records do not choose the chat.
55
+ const candidates = new Set();
56
+ for (const leaf of leaves) {
57
+ let current = leaf;
58
+ const seen = new Set();
59
+ while (current) {
60
+ const id = current.uuid;
61
+ if (seen.has(id))
62
+ throw new Error("Claude Code branch contains a parent cycle.");
63
+ seen.add(id);
64
+ if (current.type === "user" || current.type === "assistant") {
65
+ candidates.add(id);
66
+ break;
67
+ }
68
+ current = typeof current.parentUuid === "string" ? byId.get(current.parentUuid) : undefined;
69
+ }
70
+ }
71
+ let latest, fallback;
72
+ for (const row of nodes) {
73
+ const id = row.uuid;
74
+ if (!candidates.has(id))
75
+ continue;
76
+ fallback = id;
77
+ if (!row.isSidechain && !row.teamName && !row.isMeta)
78
+ latest = id;
79
+ }
80
+ if (!latest && !fallback)
81
+ throw new Error("Claude Code transcript has no conversation message.");
82
+ return (latest ?? fallback);
83
+ }
84
+ return { sessionId, leaves, select, branches, latestLeafId };
52
85
  }
@@ -30,7 +30,7 @@ export function parseClaudeSession(file, rows, leafId) {
30
30
  if (block.type === "tool_use")
31
31
  events.push(event({ ...base, id, kind: "tool_call", callId: typeof block.id === "string" ? block.id : null, content: json(block) }));
32
32
  else if (block.type === "tool_result")
33
- events.push(event({ ...base, id, kind: "tool_result", role: "tool", callId: typeof block.tool_use_id === "string" ? block.tool_use_id : null, content: json(block) }));
33
+ events.push(event({ ...base, id, kind: "tool_result", role: "tool", callId: typeof block.tool_use_id === "string" ? block.tool_use_id : null, content: json({ ...block, ...(row.tool_use_result !== undefined ? { nativeToolResult: row.tool_use_result } : {}) }) }));
34
34
  else
35
35
  events.push(event({ ...base, id, kind: "unknown", content: json(block) }));
36
36
  }
@@ -0,0 +1,9 @@
1
+ import { z } from "zod";
2
+ import { ReleaseHashSchema, ReleaseIdSchema } from "@openpond/harness";
3
+ /** A deliberate future-stage choice, independent of the original pinned
4
+ * optimizer/data configuration. Its Model source reference remains truthful;
5
+ * already reserved iterations retain their earlier immutable policy revision. */
6
+ export const LearningContinuationModeOverrideSchema = z.object({
7
+ adapterMode: z.enum(["residual_append", "shared", "sequential_merge"]),
8
+ sourceConfiguration: z.object({ id: ReleaseIdSchema, revision: z.number().int().positive(), etag: ReleaseHashSchema }).strict(),
9
+ }).strict();
@@ -1,3 +1,4 @@
1
+ import { LearningContinuationModeOverrideSchema } from "./continuation-mode.js";
1
2
  import { TrainingHandoffOriginSchema } from "./training-handoff.js";
2
3
  import { LearningDomainError } from "./errors.js";
3
4
  import { z } from "zod";
@@ -421,6 +422,7 @@ export const LearningPolicyContentSchema = z
421
422
  recipe: ImmutableReleaseRefSchema,
422
423
  retentionEvaluation: ImmutableReleaseRefSchema,
423
424
  replayBatches: z.array(ImmutableReleaseRefSchema).max(100),
425
+ continuationMode: LearningContinuationModeOverrideSchema.optional(),
424
426
  })
425
427
  .strict(),
426
428
  limits: z
@@ -0,0 +1,61 @@
1
+ import { z } from "zod";
2
+ import { ReleaseIdSchema, ReleaseHashSchema, ReleaseTimestampSchema, ImmutableReleaseRefSchema } from "@openpond/harness";
3
+ import { LearningRevisionRefSchema } from "./contracts.js";
4
+ /** Reviewed behavior identity and verifier membership are frozen before either
5
+ * declared evaluation starts. A failed unrelated grader is never a repeat. */
6
+ export const CorrectionVerificationCheckSchema = z.object({
7
+ id: ReleaseIdSchema,
8
+ role: z.enum(["replay", "transfer"]),
9
+ taskId: ReleaseIdSchema,
10
+ seeds: z.array(z.string().min(1).max(500)).min(1).max(100),
11
+ grader: z.object({ id: ReleaseIdSchema, revision: z.string().min(1).max(200), contentHash: ReleaseHashSchema, reward: LearningRevisionRefSchema.nullable().default(null) }).strict(),
12
+ failureMeaning: z.literal("corrected_mistake_repeated"),
13
+ }).strict();
14
+ export const CorrectionVerificationPlanContentSchema = z.object({
15
+ schemaVersion: z.literal("openpond.correctionVerificationPlan.v1"),
16
+ id: ReleaseIdSchema, revision: z.literal(1), teamId: ReleaseIdSchema, ownerUserId: ReleaseIdSchema, modelId: ReleaseIdSchema,
17
+ classification: z.literal("reviewed_model_behavior"),
18
+ feedback: LearningRevisionRefSchema, evidence: LearningRevisionRefSchema,
19
+ trainingJobId: ReleaseIdSchema, checkpoint: ImmutableReleaseRefSchema, artifact: ImmutableReleaseRefSchema,
20
+ taskset: LearningRevisionRefSchema,
21
+ checks: z.array(CorrectionVerificationCheckSchema).min(1).max(1000),
22
+ baselineOperationId: ReleaseIdSchema, candidateOperationId: ReleaseIdSchema,
23
+ criterion: z.literal("all_declared_checks_pass_after_failed_parent"),
24
+ receivedAt: ReleaseTimestampSchema, eligibleAt: ReleaseTimestampSchema, frozenAt: ReleaseTimestampSchema,
25
+ }).strict().superRefine((plan, context) => {
26
+ if (plan.baselineOperationId === plan.candidateOperationId)
27
+ context.addIssue({ code: "custom", path: ["candidateOperationId"], message: "Parent and candidate must have distinct evaluation operations." });
28
+ if (new Set(plan.checks.map(check => check.id)).size !== plan.checks.length)
29
+ context.addIssue({ code: "custom", path: ["checks"], message: "Correction check identities must be unique." });
30
+ for (const [index, check] of plan.checks.entries())
31
+ if (new Set(check.seeds).size !== check.seeds.length)
32
+ context.addIssue({ code: "custom", path: ["checks", index, "seeds"], message: "Seeds must be unique per correction check." });
33
+ });
34
+ export const CorrectionVerificationPlanSchema = CorrectionVerificationPlanContentSchema.safeExtend({ contentHash: ReleaseHashSchema });
35
+ export const CorrectionOpportunitySchema = z.object({
36
+ schemaVersion: z.literal("openpond.correctionOpportunity.v1"),
37
+ id: ReleaseIdSchema, correction: ImmutableReleaseRefSchema, source: z.enum(["evaluation", "live"]),
38
+ modelId: ReleaseIdSchema, trainingJobId: ReleaseIdSchema, artifactId: ReleaseIdSchema, checkpointId: ReleaseIdSchema,
39
+ observedAt: ReleaseTimestampSchema, occurredAt: ReleaseTimestampSchema,
40
+ attempt: ImmutableReleaseRefSchema,
41
+ classification: z.enum(["confirmed_repeat", "passed", "unscored"]),
42
+ checkIds: z.array(ReleaseIdSchema).min(1).max(1000),
43
+ }).strict();
44
+ export const CorrectionMetricObservationSchema = z.object({
45
+ schemaVersion: z.literal("openpond.correctionMetricObservation.v1"),
46
+ correction: ImmutableReleaseRefSchema, modelId: ReleaseIdSchema, trainingJobId: ReleaseIdSchema,
47
+ checkpointId: ReleaseIdSchema, artifactId: ReleaseIdSchema, receivedAt: ReleaseTimestampSchema, eligibleAt: ReleaseTimestampSchema,
48
+ firstBatchConsumptionAt: ReleaseTimestampSchema.nullable(), firstTrainingUseAt: ReleaseTimestampSchema.nullable(),
49
+ verifiedAt: ReleaseTimestampSchema.nullable(), servedAt: ReleaseTimestampSchema.nullable(),
50
+ baselineEvaluation: ImmutableReleaseRefSchema.nullable(), candidateEvaluation: ImmutableReleaseRefSchema.nullable(),
51
+ status: z.enum(["pending_exposure", "pending_verification", "baseline_not_failed", "verified", "regressed", "withdrawn"]),
52
+ opportunities: z.array(CorrectionOpportunitySchema).max(100_000), blockers: z.array(z.string().max(500)).max(20).default([]), observedAt: ReleaseTimestampSchema,
53
+ }).strict();
54
+ const repeat = z.object({ confirmedRepeats: z.number().int().nonnegative(), scoredRelevantOpportunities: z.number().int().nonnegative(), unscoredOpportunities: z.number().int().nonnegative(), rate: z.number().min(0).max(1).nullable() }).strict();
55
+ export const CorrectionMetricSummarySchema = z.object({
56
+ schemaVersion: z.literal("openpond.correctionMetricSummary.v1"), observedAt: ReleaseTimestampSchema,
57
+ scope: z.object({ teamId: ReleaseIdSchema, modelId: ReleaseIdSchema, runId: ReleaseIdSchema.nullable(), checkpointId: ReleaseIdSchema.nullable(), artifactId: ReleaseIdSchema.nullable() }).strict(),
58
+ window: z.object({ from: ReleaseTimestampSchema, to: ReleaseTimestampSchema }).strict(), correctionCount: z.number().int().nonnegative(),
59
+ adaptation: z.object({ medianSeconds: z.number().nonnegative().nullable(), resolvedCount: z.number().int().nonnegative(), pendingCount: z.number().int().nonnegative(), oldestPendingSeconds: z.number().nonnegative().nullable() }).strict(),
60
+ evaluation: repeat.safeExtend({ source: z.literal("evaluation") }), live: repeat.safeExtend({ source: z.literal("live") }),
61
+ }).strict();
@@ -36,3 +36,5 @@ export * from "./task-queue-inspection.js";
36
36
  export * from "./acceptance-plan.js";
37
37
  export * from "./acceptance-group.js";
38
38
  export { TrainingHandoffOriginSchema } from "./training-handoff.js";
39
+ export * from "./correction-metrics.js";
40
+ export * from "./continuation-mode.js";
@@ -7,6 +7,7 @@ import { CollectorQueueFullError } from "./collector-snapshots.js";
7
7
  import { COLLECTOR_DEFAULTS } from "./collector-contracts.js";
8
8
  import { CollectorCoverage } from "./collector-coverage.js";
9
9
  import { CollectorSourceCache } from "./collector-source-cache.js";
10
+ import { nativeSessionSelectionKey } from "./selection.js";
10
11
  /** One pass over a frozen listing per page. Unchanged revisions are cheap; a
11
12
  * failed source is tried again only in a later explicitly launched job. */
12
13
  export async function acquireCollectorSource(input) {
@@ -14,23 +15,30 @@ export async function acquireCollectorSource(input) {
14
15
  const cache = new CollectorSourceCache(store);
15
16
  let cursor, processed = 0, discovered = 0;
16
17
  const failures = [];
18
+ const selection = connection.selectedSessionKeys ? new Set(connection.selectedSessionKeys) : null;
19
+ const found = new Set();
20
+ let enumerated = 0;
17
21
  do {
18
22
  await check();
19
23
  progress({ phase: "discovering" });
20
24
  // File mtimes and native activity summaries are not event-time authority.
21
25
  // Enumerate the source, then apply the consented window to native events.
22
26
  const page = await listSessions(connection.source, { cursor, limit: 50 });
23
- discovered += page.items.length;
24
- if (discovered > 10_000)
25
- throw new Error("Source inventory exceeds 10,000 sessions. Select a narrower import window.");
26
- for (const native of page.items) {
27
+ enumerated += page.items.length;
28
+ if (enumerated > 10_000)
29
+ throw new Error("Source inventory exceeds 10,000 sessions. Select a narrower source directory.");
30
+ const items = page.items.filter(native => !selection || selection.has(nativeSessionSelectionKey(native)));
31
+ for (const native of items)
32
+ found.add(nativeSessionSelectionKey(native));
33
+ discovered += items.length;
34
+ for (const native of items) {
27
35
  const scanKey = JSON.stringify([native.path, native.nativeSessionId]);
28
36
  store.coverage.record(connection.id, { sourceKeyHash: CollectorCoverage.sourceKey(scanKey),
29
37
  nativeRevisionHash: native.storageRevision ? contentHash([native.storageRevision, agentImportNormalizerRevision(connection.source.source)]) : null,
30
38
  state: "reading", reason: null, unknownTimeBoundaries: 0, normalized: [] });
31
39
  }
32
40
  progress({ discovered });
33
- for (const native of page.items) {
41
+ for (const native of items) {
34
42
  await check();
35
43
  // Do not parse another transcript while any retained admission is blocked.
36
44
  await drain();
@@ -139,7 +147,10 @@ export async function acquireCollectorSource(input) {
139
147
  cursor = page.nextCursor ?? undefined;
140
148
  } while (cursor);
141
149
  store.progress.discovered(connection.id);
142
- store.coverage.finish(connection.id, true);
150
+ // A chosen subset cannot certify coverage of the entire source window.
151
+ store.coverage.finish(connection.id, selection === null);
152
+ if (selection && [...selection].some(key => !found.has(key)))
153
+ throw new Error("A selected conversation is no longer available. Review the upload selection.");
143
154
  if (failures.length)
144
155
  throw new Error(`${failures.length} session(s) need attention. ${failures[0]}`);
145
156
  }
@@ -12,7 +12,7 @@ export class CollectorSourceCache {
12
12
  }
13
13
  selection(connection, until, revision) {
14
14
  return contentHash([connection.source, connection.projectId, connection.teamId,
15
- connection.apiBaseUrl, connection.account ?? null, connection.since, until, revision]);
15
+ connection.apiBaseUrl, connection.account ?? null, connection.since, connection.selectedSessionKeys ?? null, until, revision]);
16
16
  }
17
17
  read(connection, until, sessionKey, revision) {
18
18
  const row = this.store.database.prepare("SELECT value FROM source_read_cache WHERE connection_id=? AND session_key=? AND selection_hash=?").get(connection.id, sessionKey, this.selection(connection, until, revision));
@@ -61,6 +61,20 @@ export class CollectorStore {
61
61
  this.database.exec("COMMIT");
62
62
  return;
63
63
  }
64
+ if (prior && JSON.stringify(prior.selectedSessionKeys) !== JSON.stringify(connection.selectedSessionKeys)) {
65
+ const owner = JSON.parse(this.setting("owner") || "{}");
66
+ if (owner.pid) {
67
+ let alive = true;
68
+ try {
69
+ process.kill(owner.pid, 0);
70
+ }
71
+ catch (error) {
72
+ alive = error.code !== "ESRCH";
73
+ }
74
+ if (alive)
75
+ throw new Error("Cancel or finish the running import before changing its conversation selection.");
76
+ }
77
+ }
64
78
  const identityChanged = !!prior &&
65
79
  (prior.source.instanceId !== connection.source.instanceId ||
66
80
  prior.projectId !== connection.projectId ||
@@ -69,7 +83,8 @@ export class CollectorStore {
69
83
  prior.account !== connection.account);
70
84
  if (identityChanged)
71
85
  connection = { ...connection, destinations: undefined };
72
- if (prior && (identityChanged || prior.since !== connection.since)) {
86
+ if (prior && (identityChanged || prior.since !== connection.since ||
87
+ JSON.stringify(prior.selectedSessionKeys) !== JSON.stringify(connection.selectedSessionKeys))) {
73
88
  this.database.prepare("DELETE FROM settings WHERE key=?").run(`coverage:${connection.id}`);
74
89
  this.database.prepare("DELETE FROM coverage_sessions WHERE connection_id=?").run(connection.id);
75
90
  // Scope changes fence queued evidence too: do not upload a wider old
@@ -81,7 +96,16 @@ export class CollectorStore {
81
96
  this.database.prepare("DELETE FROM settings WHERE key=?").run(`syncAcknowledged:${connection.id}`);
82
97
  connection = { ...connection, completedSyncRevision: 0 };
83
98
  this.error(connection.id, null);
84
- for (const table of ["source_scans", "checkpoints", "pending"])
99
+ if (!identityChanged && prior.since === connection.since) {
100
+ // Preserve acknowledged boundaries when adding conversations, but
101
+ // reacquire every queued boundary whose snapshot is being discarded.
102
+ this.database.prepare(`DELETE FROM checkpoints WHERE connection_id=? AND EXISTS (
103
+ SELECT 1 FROM pending p, json_each(p.payload,'$.boundaryIds') b
104
+ WHERE p.connection_id=checkpoints.connection_id
105
+ AND json_extract(p.payload,'$.sessionKey')=checkpoints.session_key
106
+ AND b.value=checkpoints.boundary_id)`).run(connection.id);
107
+ }
108
+ for (const table of identityChanged || prior.since !== connection.since ? ["source_scans", "checkpoints", "pending"] : ["source_scans", "pending"])
85
109
  this.database
86
110
  .prepare(`DELETE FROM ${table} WHERE connection_id=?`)
87
111
  .run(connection.id);
@@ -270,6 +294,7 @@ export class CollectorStore {
270
294
  .get(String(row.id))?.bytes ?? 0),
271
295
  lastAdmissionAt: this.setting(`lastAdmission:${row.id}`),
272
296
  since: config.since,
297
+ selectedConversations: config.selectedSessionKeys?.length ?? null,
273
298
  schedule,
274
299
  nextRunAt: schedule && config.state === "active" ? nextScheduledSync(schedule) : null,
275
300
  lastSuccessfulSyncAt: this.setting(`lastSuccess:${row.id}`),
@@ -36,7 +36,7 @@ export async function runCollector(input) {
36
36
  }
37
37
  }
38
38
  const now = new Date();
39
- selected = store.connections().filter(connection => connection.state !== "disconnected" &&
39
+ selected = store.connections().filter(connection => connection.state !== "disconnected" && connection.selectedSessionKeys?.length !== 0 &&
40
40
  (!input.connectionIds || input.connectionIds.includes(connection.id)) &&
41
41
  (input.trigger !== "scheduled" || (connection.state === "active" && scheduledSyncDue(store.schedule(connection.id), store.setting(`scheduledMinute:${connection.id}`), now))));
42
42
  if (input.trigger === "scheduled")
@@ -173,13 +173,14 @@ export async function runCollector(input) {
173
173
  for (let pass = 0; pass < 3; pass++) {
174
174
  await check();
175
175
  const revision = connection.revision, requested = connection.requestedSyncRevision ?? 0;
176
+ const selection = JSON.stringify(connection.selectedSessionKeys);
176
177
  phase = "source";
177
178
  new CollectorSourceCache(store).seed(connection, until, store.coverage.manifest(connection.id));
178
179
  store.coverage.begin(connection, `${nonce}-${pass}`, run.startedAt, until);
179
180
  const checkAcquisition = async () => {
180
181
  await check();
181
182
  phase = "source";
182
- if (connection.revision !== revision)
183
+ if (connection.revision !== revision || JSON.stringify(connection.selectedSessionKeys) !== selection)
183
184
  throw new CollectorScopeChangedError("Source settings changed during acquisition.");
184
185
  };
185
186
  try {
@@ -193,7 +194,7 @@ export async function runCollector(input) {
193
194
  }
194
195
  errors.set(connection.id, "source", null);
195
196
  await drain();
196
- await input.transport.publishCoverage(connection, store.coverage.finish(connection.id, true), signal);
197
+ await input.transport.publishCoverage(connection, store.coverage.finish(connection.id, connection.selectedSessionKeys === undefined), signal);
197
198
  connection = retained(connection);
198
199
  if (connection.revision !== revision) {
199
200
  if (pass === 2)
@@ -114,6 +114,8 @@ export async function listSessions(source, input = {}) {
114
114
  return listDatabaseSessions(source, { ...input, limit });
115
115
  const paths = await pathsBelow(source), candidates = [];
116
116
  for (const path of paths) {
117
+ if (input.parentNativeSessionId && source.source === "claude_code" && !path.replaceAll("\\", "/").includes(`/${input.parentNativeSessionId}/subagents/`))
118
+ continue;
117
119
  if (input.cursor && path <= input.cursor)
118
120
  continue;
119
121
  try {
@@ -193,12 +195,14 @@ export async function listSessions(source, input = {}) {
193
195
  // Claude writes queue/history bookkeeping before its first message. The
194
196
  // native session's message metadata owns cwd; encoded project-directory
195
197
  // names are ambiguous and must never be decoded into a guessed path.
198
+ const claudeWorker = source.source === "claude_code" && /(?:^|[\/])subagents[\/]agent-[^\/]+\.jsonl$/u.test(path)
199
+ ? rows.find(row => row.isSidechain === true && typeof row.agentId === "string" && `agent-${row.agentId}` === id && typeof row.sessionId === "string" && basename(dirname(dirname(path))) === row.sessionId) : undefined;
196
200
  const claudeMessage = source.source === "claude_code"
197
- ? rows.find((row) => row.sessionId === id && row.type === "user" && typeof row.cwd === "string" && isAbsolute(row.cwd))
201
+ ? rows.find((row) => row.sessionId === (claudeWorker?.sessionId ?? id) && row.type === "user" && typeof row.cwd === "string" && isAbsolute(row.cwd))
198
202
  : undefined;
199
203
  let cwd = claudeMessage?.cwd ?? payload.cwd;
200
204
  let title = source.source === "claude_code"
201
- ? claudeConversationTitle(rows, id)
205
+ ? claudeConversationTitle(rows, claudeWorker ? String(claudeWorker.sessionId) : id, Boolean(claudeWorker))
202
206
  : retainedConversationTitle(payload.title, id);
203
207
  if (source.source === "grok_build" && path.endsWith("updates.jsonl")) {
204
208
  try {
@@ -214,6 +218,7 @@ export async function listSessions(source, input = {}) {
214
218
  }
215
219
  candidates.push({
216
220
  nativeSessionId: id,
221
+ ...(claudeWorker ? { parentNativeSessionId: String(claudeWorker.sessionId) } : {}),
217
222
  sourceInstanceId: source.instanceId,
218
223
  path,
219
224
  title,
@@ -251,6 +256,18 @@ export async function listSessions(source, input = {}) {
251
256
  nextCursor: candidates.length > limit ? candidates[limit - 1].path : null,
252
257
  };
253
258
  }
259
+ /** Revalidate worker identity after acquisition; parent sessionId is shared by siblings. */
260
+ function assertClaudeIdentity(session, rows) {
261
+ const graph = claudeGraph(rows);
262
+ if (graph.sessionId !== (session.parentNativeSessionId ?? session.nativeSessionId))
263
+ throw new Error("Native session changed identity.");
264
+ if (session.parentNativeSessionId) {
265
+ const messages = rows.filter(row => row.type === "user" || row.type === "assistant");
266
+ if (messages.some(row => row.isSidechain !== true || `agent-${String(row.agentId)}` !== session.nativeSessionId))
267
+ throw new Error("Native worker changed identity.");
268
+ }
269
+ return graph;
270
+ }
254
271
  export async function inspectSessionBranches(source, session) {
255
272
  if (source.source !== "claude_code")
256
273
  return { revision: "", branches: [] };
@@ -259,9 +276,7 @@ export async function inspectSessionBranches(source, session) {
259
276
  if (session.sourceInstanceId !== source.instanceId)
260
277
  throw new Error("Native session belongs to another selected source.");
261
278
  const text = await readSelectedFile(source, session.path);
262
- const graph = claudeGraph(connectedJsonLines({ path: basename(session.path), text }));
263
- if (graph.sessionId !== session.nativeSessionId)
264
- throw new Error("Native session changed identity.");
279
+ const graph = assertClaudeIdentity(session, connectedJsonLines({ path: basename(session.path), text }));
265
280
  return { revision: contentHash(text), branches: graph.branches() };
266
281
  }
267
282
  export async function readSession(source, session, input = {}) {
@@ -290,9 +305,14 @@ export async function readSession(source, session, input = {}) {
290
305
  throw new Error("Choose a branch before supplying its revision.");
291
306
  if (source.source === "claude_code") {
292
307
  const file = files[0];
293
- const graph = claudeGraph(connectedJsonLines(file));
294
- if (graph.sessionId !== session.nativeSessionId)
295
- throw new Error("Native session changed identity.");
308
+ const graph = assertClaudeIdentity(session, connectedJsonLines(file));
309
+ if (input.latestBranch) {
310
+ if (input.branchLeafId || input.expectedBranchRevision || input.branchAnchor)
311
+ throw new Error("Choose either the latest conversation or an explicit branch.");
312
+ // Desktop inspection follows the native conversation. Imports keep their
313
+ // existing explicit branch authority and never enable this option.
314
+ files = [{ ...file, text: graph.select(graph.latestLeafId()).chain.map(row => JSON.stringify(row)).join("\n") + "\n" }];
315
+ }
296
316
  if (input.branchAnchor) {
297
317
  if (input.branchLeafId || input.expectedBranchRevision)
298
318
  throw new Error("Choose either a frozen branch snapshot or a followed branch anchor.");
@@ -2,6 +2,7 @@
2
2
  export * from "./contracts.js";
3
3
  export * from "./discovery.js";
4
4
  export * from "./history.js";
5
+ export * from "./selection.js";
5
6
  export * from "./collector-contracts.js";
6
7
  export * from "./collector-store.js";
7
8
  export * from "./collector.js";
@@ -0,0 +1,57 @@
1
+ import { contentHash } from "@openpond/harness";
2
+ import { z } from "zod";
3
+ import { listSessions } from "./history.js";
4
+ export const NativeUploadSelectionSchema = z.object({
5
+ sourceInstanceId: z.string().min(1).max(500),
6
+ sessionKeys: z.array(z.string().regex(/^[a-f0-9]{64}$/)).min(1).max(10_000),
7
+ }).strict().refine(value => new Set(value.sessionKeys).size === value.sessionKeys.length, "Conversation selection contains duplicates.");
8
+ /** Includes the source path so duplicate native IDs cannot select a sibling file. */
9
+ export function nativeSessionSelectionKey(session) {
10
+ return contentHash(JSON.stringify([session.path, session.nativeSessionId]));
11
+ }
12
+ export async function nativeUploadInventory(source) {
13
+ if (!source.available || !source.capabilities.history)
14
+ throw new Error("The selected conversation source is unavailable.");
15
+ const items = [];
16
+ let cursor;
17
+ const seen = new Set();
18
+ do {
19
+ const page = await listSessions(source, { cursor, limit: 100 });
20
+ items.push(...page.items);
21
+ if (items.length > 10_000)
22
+ throw new Error("Choose a source with no more than 10,000 conversations.");
23
+ cursor = page.nextCursor ?? undefined;
24
+ if (cursor && seen.has(cursor))
25
+ throw new Error("Conversation listing did not advance. Refresh the source.");
26
+ if (cursor)
27
+ seen.add(cursor);
28
+ } while (cursor);
29
+ return items;
30
+ }
31
+ export async function validateNativeUploadSelection(source, raw) {
32
+ const selection = NativeUploadSelectionSchema.parse(raw);
33
+ if (selection.sourceInstanceId !== source.instanceId)
34
+ throw new Error("Conversation selection belongs to another source installation.");
35
+ const available = new Set((await nativeUploadInventory(source)).map(nativeSessionSelectionKey));
36
+ if (selection.sessionKeys.some(key => !available.has(key)))
37
+ throw new Error("A selected conversation is no longer available. Refresh and select it again.");
38
+ return selection;
39
+ }
40
+ export function nativeUploadConversationPage(connection, inventory, input) {
41
+ const query = (input.query ?? "").trim().toLocaleLowerCase(), range = input.range ?? "all", offset = input.offset ?? 0;
42
+ if (query.length > 500 || !["day", "week", "all"].includes(range) || !Number.isInteger(offset) || offset < 0 || offset > 10_000)
43
+ throw new Error("Invalid conversation search or page.");
44
+ const since = range === "all" ? 0 : Date.now() - (range === "day" ? 1 : 7) * 86400000;
45
+ const items = inventory.filter(item => Date.parse(item.updatedAt) >= since &&
46
+ (!query || [item.title, item.cwd, item.nativeSessionId].some(text => text?.toLocaleLowerCase().includes(query))))
47
+ .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
48
+ const approved = connection.selectedSessionKeys ? new Set(connection.selectedSessionKeys) : null;
49
+ return {
50
+ total: items.length, nextOffset: offset + 50 < items.length ? offset + 50 : null,
51
+ items: items.slice(offset, offset + 50).map(item => ({
52
+ key: nativeSessionSelectionKey(item), title: item.title, cwd: item.cwd,
53
+ nativeSessionId: item.nativeSessionId, updatedAt: item.updatedAt, issue: item.issue ?? null,
54
+ approved: approved === null || approved.has(nativeSessionSelectionKey(item)),
55
+ })),
56
+ };
57
+ }
@@ -164,6 +164,8 @@ export async function setCollectorSchedule(input, connectionId, schedule) {
164
164
  const connection = store.connections().find(item => item.id === connectionId);
165
165
  if (!connection || (schedule && connection.state === "disconnected"))
166
166
  throw new Error("Select a connected source before scheduling imports.");
167
+ if (schedule && connection.selectedSessionKeys?.length === 0)
168
+ throw new Error("Choose conversations to upload before enabling continual imports.");
167
169
  const owner = store.setting("scheduleOwner");
168
170
  if (owner) {
169
171
  const { pid } = JSON.parse(owner);
@@ -5,7 +5,7 @@ function titleText(value) {
5
5
  return value.replace(/\s+/gu, " ").trim().slice(0, 160) || null;
6
6
  }
7
7
  /** Retained provider titles take precedence over a preview of the first real user prompt. */
8
- export function claudeConversationTitle(rows, sessionId) {
8
+ export function claudeConversationTitle(rows, sessionId, allowSidechain = false) {
9
9
  const owned = rows.filter((row) => row.sessionId === undefined || row.sessionId === sessionId);
10
10
  for (const row of [...owned].reverse()) {
11
11
  if (row.type === "custom-title") {
@@ -22,7 +22,7 @@ export function claudeConversationTitle(rows, sessionId) {
22
22
  }
23
23
  }
24
24
  for (const row of owned) {
25
- if (row.type !== "user" || row.sessionId !== sessionId || row.isMeta || row.isSidechain)
25
+ if (row.type !== "user" || row.sessionId !== sessionId || row.isMeta || (row.isSidechain && !allowSidechain))
26
26
  continue;
27
27
  const content = object(row.message).content;
28
28
  const title = titleText(Array.isArray(content)
package/dist/tasksets.js CHANGED
@@ -7,6 +7,7 @@ export const RequiredOutputContractSchema = z.object({
7
7
  path: z.string().trim().min(1).max(2_000).refine(safeRelativePath),
8
8
  mediaType: z.string().trim().min(1).max(200),
9
9
  schemaRef: ImmutableAssetRefSchema.nullable().default(null),
10
+ submissionMode: z.literal("structured_json").optional(),
10
11
  maxBytes: z.number().int().positive().max(250_000_000).nullable().default(null),
11
12
  metadata: MetadataSchema,
12
13
  }).strict();
@@ -1 +1 @@
1
- {"version":3,"file":"artifact-verification.d.ts","sourceRoot":"","sources":["../../../../src/artifact-verification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAGL,KAAK,gBAAgB,EAGrB,KAAK,sBAAsB,EAC5B,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAE5D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,WAAW,CAAC,EAAE,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACpD,YAAY,CAAC,EAAE,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,aAAa,GAAG,IAAI,CAAC;IAC7D,YAAY,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,eAAe,EAAE,sBAAsB,EAAE,CAAC;IAC1C,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,GAAG,gBAAgB,CAwEnB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,eAAe,EAAE,sBAAsB,EAAE,CAAC;IAC1C,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,GAAG,sBAAsB,EAAE,CAqC3B"}
1
+ {"version":3,"file":"artifact-verification.d.ts","sourceRoot":"","sources":["../../src/artifact-verification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAGL,KAAK,gBAAgB,EAGrB,KAAK,sBAAsB,EAC5B,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAE5D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,WAAW,CAAC,EAAE,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACpD,YAAY,CAAC,EAAE,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,aAAa,GAAG,IAAI,CAAC;IAC7D,YAAY,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,eAAe,EAAE,sBAAsB,EAAE,CAAC;IAC1C,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,GAAG,gBAAgB,CAwEnB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,eAAe,EAAE,sBAAsB,EAAE,CAAC;IAC1C,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,GAAG,sBAAsB,EAAE,CAqC3B"}
@@ -2,10 +2,10 @@ import { z } from "zod";
2
2
  import { type AttemptReceipt, type EvaluationResult } from "./runs.js";
3
3
  export { harnessRefinerBenchmarkAssets, harnessRefinerBenchmarkRelease, } from "./builtin-benchmarks/harness-refiner.js";
4
4
  export declare const BenchmarkMetricSchema: z.ZodEnum<{
5
+ cost_usd: "cost_usd";
5
6
  foreground_tokens: "foreground_tokens";
6
- success_rate: "success_rate";
7
7
  latency_ms: "latency_ms";
8
- cost_usd: "cost_usd";
8
+ success_rate: "success_rate";
9
9
  }>;
10
10
  export declare const BenchmarkRunPhaseSchema: z.ZodEnum<{
11
11
  baseline: "baseline";
@@ -13,10 +13,10 @@ export declare const BenchmarkRunPhaseSchema: z.ZodEnum<{
13
13
  }>;
14
14
  export declare const BenchmarkProtocolSchema: z.ZodObject<{
15
15
  split: z.ZodEnum<{
16
+ frozen_eval: "frozen_eval";
17
+ test: "test";
16
18
  train: "train";
17
19
  validation: "validation";
18
- test: "test";
19
- frozen_eval: "frozen_eval";
20
20
  }>;
21
21
  taskIds: z.ZodArray<z.ZodString>;
22
22
  seeds: z.ZodArray<z.ZodString>;
@@ -36,27 +36,27 @@ export declare const BenchmarkDefinitionSchema: z.ZodObject<{
36
36
  contentHash: z.ZodString;
37
37
  }, z.core.$strict>;
38
38
  adaptationSplit: z.ZodEnum<{
39
+ frozen_eval: "frozen_eval";
40
+ test: "test";
39
41
  train: "train";
40
42
  validation: "validation";
41
- test: "test";
42
- frozen_eval: "frozen_eval";
43
43
  }>;
44
44
  evaluationSplit: z.ZodEnum<{
45
+ frozen_eval: "frozen_eval";
46
+ test: "test";
45
47
  train: "train";
46
48
  validation: "validation";
47
- test: "test";
48
- frozen_eval: "frozen_eval";
49
49
  }>;
50
50
  primaryMetric: z.ZodEnum<{
51
+ cost_usd: "cost_usd";
51
52
  foreground_tokens: "foreground_tokens";
52
- success_rate: "success_rate";
53
53
  latency_ms: "latency_ms";
54
- cost_usd: "cost_usd";
54
+ success_rate: "success_rate";
55
55
  }>;
56
56
  qualityGate: z.ZodEnum<{
57
- none: "none";
58
- non_regression: "non_regression";
59
57
  all_pass: "all_pass";
58
+ non_regression: "non_regression";
59
+ none: "none";
60
60
  }>;
61
61
  caseCounts: z.ZodObject<{
62
62
  adaptation: z.ZodNumber;
@@ -80,10 +80,10 @@ export declare const BenchmarkRunRequestSchema: z.ZodObject<{
80
80
  }, z.core.$strict>;
81
81
  reasoningEffort: z.ZodNullable<z.ZodString>;
82
82
  split: z.ZodEnum<{
83
+ frozen_eval: "frozen_eval";
84
+ test: "test";
83
85
  train: "train";
84
86
  validation: "validation";
85
- test: "test";
86
- frozen_eval: "frozen_eval";
87
87
  }>;
88
88
  seeds: z.ZodArray<z.ZodString>;
89
89
  repetitions: z.ZodNumber;
@@ -119,10 +119,10 @@ export declare const BenchmarkRunSummaryContentSchema: z.ZodObject<{
119
119
  reasoningEffort: z.ZodNullable<z.ZodString>;
120
120
  protocol: z.ZodObject<{
121
121
  split: z.ZodEnum<{
122
+ frozen_eval: "frozen_eval";
123
+ test: "test";
122
124
  train: "train";
123
125
  validation: "validation";
124
- test: "test";
125
- frozen_eval: "frozen_eval";
126
126
  }>;
127
127
  taskIds: z.ZodArray<z.ZodString>;
128
128
  seeds: z.ZodArray<z.ZodString>;
@@ -175,10 +175,10 @@ export declare const BenchmarkRunSummarySchema: z.ZodObject<{
175
175
  reasoningEffort: z.ZodNullable<z.ZodString>;
176
176
  protocol: z.ZodObject<{
177
177
  split: z.ZodEnum<{
178
+ frozen_eval: "frozen_eval";
179
+ test: "test";
178
180
  train: "train";
179
181
  validation: "validation";
180
- test: "test";
181
- frozen_eval: "frozen_eval";
182
182
  }>;
183
183
  taskIds: z.ZodArray<z.ZodString>;
184
184
  seeds: z.ZodArray<z.ZodString>;
@@ -218,10 +218,10 @@ export declare const BenchmarkComparisonContentSchema: z.ZodObject<{
218
218
  contentHash: z.ZodString;
219
219
  }, z.core.$strict>;
220
220
  primaryMetric: z.ZodEnum<{
221
+ cost_usd: "cost_usd";
221
222
  foreground_tokens: "foreground_tokens";
222
- success_rate: "success_rate";
223
223
  latency_ms: "latency_ms";
224
- cost_usd: "cost_usd";
224
+ success_rate: "success_rate";
225
225
  }>;
226
226
  qualityPassed: z.ZodBoolean;
227
227
  baselinePassRate: z.ZodNumber;
@@ -248,10 +248,10 @@ export declare const BenchmarkComparisonSchema: z.ZodObject<{
248
248
  contentHash: z.ZodString;
249
249
  }, z.core.$strict>;
250
250
  primaryMetric: z.ZodEnum<{
251
+ cost_usd: "cost_usd";
251
252
  foreground_tokens: "foreground_tokens";
252
- success_rate: "success_rate";
253
253
  latency_ms: "latency_ms";
254
- cost_usd: "cost_usd";
254
+ success_rate: "success_rate";
255
255
  }>;
256
256
  qualityPassed: z.ZodBoolean;
257
257
  baselinePassRate: z.ZodNumber;