@interf/compiler 0.9.1 → 0.9.4

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 (251) hide show
  1. package/README.md +9 -9
  2. package/agent-skills/interf-actions/SKILL.md +3 -0
  3. package/agent-skills/interf-actions/references/cli.md +13 -13
  4. package/{builtin-workflows/interf → builtin-methods/interf-default}/README.md +2 -2
  5. package/builtin-methods/interf-default/improve/SKILL.md +18 -0
  6. package/{builtin-workflows/interf/workflow.json → builtin-methods/interf-default/method.json} +4 -4
  7. package/{builtin-workflows/interf/workflow.schema.json → builtin-methods/interf-default/method.schema.json} +2 -2
  8. package/dist/cli/commands/check-draft.d.ts +6 -6
  9. package/dist/cli/commands/check-draft.js +5 -5
  10. package/dist/cli/commands/compile-controller.d.ts +7 -7
  11. package/dist/cli/commands/compile-controller.js +35 -38
  12. package/dist/cli/commands/compile.d.ts +3 -3
  13. package/dist/cli/commands/compile.js +23 -21
  14. package/dist/cli/commands/compiled-flow.d.ts +11 -11
  15. package/dist/cli/commands/compiled-flow.js +33 -30
  16. package/dist/cli/commands/create-method-wizard.d.ts +76 -0
  17. package/dist/cli/commands/{create-workflow-wizard.js → create-method-wizard.js} +153 -163
  18. package/dist/cli/commands/create.d.ts +3 -3
  19. package/dist/cli/commands/create.js +44 -45
  20. package/dist/cli/commands/default.js +1 -1
  21. package/dist/cli/commands/executor-flow.d.ts +6 -6
  22. package/dist/cli/commands/executor-flow.js +1 -1
  23. package/dist/cli/commands/init.d.ts +2 -2
  24. package/dist/cli/commands/init.js +139 -118
  25. package/dist/cli/commands/list.js +11 -10
  26. package/dist/cli/commands/preparation-selection.d.ts +3 -3
  27. package/dist/cli/commands/source-config-wizard.d.ts +9 -9
  28. package/dist/cli/commands/source-config-wizard.js +43 -43
  29. package/dist/cli/commands/status.js +36 -9
  30. package/dist/cli/commands/test-flow.d.ts +15 -15
  31. package/dist/cli/commands/test-flow.js +29 -219
  32. package/dist/cli/commands/test.d.ts +2 -2
  33. package/dist/cli/commands/test.js +50 -51
  34. package/dist/cli/commands/verify.js +7 -7
  35. package/dist/cli/commands/web.js +41 -28
  36. package/dist/compiler-ui/404.html +1 -0
  37. package/dist/compiler-ui/__next.__PAGE__.txt +10 -0
  38. package/dist/compiler-ui/__next._full.txt +20 -0
  39. package/dist/compiler-ui/__next._head.txt +5 -0
  40. package/dist/compiler-ui/__next._index.txt +5 -0
  41. package/dist/compiler-ui/__next._tree.txt +5 -0
  42. package/dist/compiler-ui/_next/static/chunks/06yhdspx~ca5-.js +5 -0
  43. package/{apps/compiler-ui/.next/static/chunks/0fgt_8knmicoz.js → dist/compiler-ui/_next/static/chunks/0d~8t0zm6545p.js} +15 -21
  44. package/dist/compiler-ui/_next/static/chunks/0xnel.ax9a.2c.css +3 -0
  45. package/{apps/compiler-ui/.next/static/chunks/turbopack-109rtik40vwh5.js → dist/compiler-ui/_next/static/chunks/turbopack-0.uq1k8c0j4s..js} +1 -1
  46. package/dist/compiler-ui/_not-found/__next._full.txt +15 -0
  47. package/dist/compiler-ui/_not-found/__next._head.txt +5 -0
  48. package/dist/compiler-ui/_not-found/__next._index.txt +5 -0
  49. package/dist/compiler-ui/_not-found/__next._not-found.__PAGE__.txt +5 -0
  50. package/dist/compiler-ui/_not-found/__next._not-found.txt +5 -0
  51. package/dist/compiler-ui/_not-found/__next._tree.txt +2 -0
  52. package/dist/compiler-ui/_not-found.html +1 -0
  53. package/dist/compiler-ui/_not-found.txt +15 -0
  54. package/{apps/compiler-ui/.next/server/app → dist/compiler-ui}/index.html +1 -1
  55. package/dist/compiler-ui/index.txt +20 -0
  56. package/dist/index.d.ts +8 -6
  57. package/dist/index.js +5 -3
  58. package/dist/packages/agents/index.d.ts +1 -1
  59. package/dist/packages/agents/lib/args.d.ts +2 -2
  60. package/dist/packages/agents/lib/compiled-bootstrap.js +7 -6
  61. package/dist/packages/agents/lib/execution-profile.d.ts +5 -5
  62. package/dist/packages/agents/lib/execution-profile.js +7 -6
  63. package/dist/packages/agents/lib/executors.d.ts +13 -13
  64. package/dist/packages/agents/lib/preflight.d.ts +1 -0
  65. package/dist/packages/agents/lib/preflight.js +32 -9
  66. package/dist/packages/agents/lib/shells.d.ts +25 -24
  67. package/dist/packages/agents/lib/shells.js +161 -154
  68. package/dist/packages/agents/lib/types.d.ts +2 -2
  69. package/dist/packages/compiler/artifact-counts.d.ts +1 -0
  70. package/dist/packages/compiler/artifact-counts.js +30 -0
  71. package/dist/packages/compiler/compiled-paths.d.ts +4 -7
  72. package/dist/packages/compiler/compiled-paths.js +9 -15
  73. package/dist/packages/compiler/compiled-pipeline.d.ts +11 -12
  74. package/dist/packages/compiler/compiled-pipeline.js +22 -22
  75. package/dist/packages/compiler/compiled-schema.d.ts +20 -20
  76. package/dist/packages/compiler/compiled-schema.js +29 -29
  77. package/dist/packages/compiler/compiled-stage-plan.d.ts +4 -4
  78. package/dist/packages/compiler/compiled-stage-plan.js +8 -8
  79. package/dist/packages/compiler/compiled-stage-runner.d.ts +5 -5
  80. package/dist/packages/compiler/compiled-stage-runner.js +7 -7
  81. package/dist/packages/compiler/compiled-target.d.ts +5 -5
  82. package/dist/packages/compiler/compiled-target.js +5 -5
  83. package/dist/packages/compiler/index.d.ts +3 -3
  84. package/dist/packages/compiler/index.js +2 -2
  85. package/dist/packages/compiler/lib/schema.d.ts +62 -247
  86. package/dist/packages/compiler/lib/schema.js +56 -174
  87. package/dist/packages/compiler/{workflows.d.ts → method-runs.d.ts} +4 -4
  88. package/dist/packages/compiler/{workflows.js → method-runs.js} +4 -3
  89. package/dist/packages/compiler/raw-snapshot.d.ts +0 -7
  90. package/dist/packages/compiler/raw-snapshot.js +0 -1
  91. package/dist/packages/compiler/reset.js +3 -3
  92. package/dist/packages/compiler/runtime-acceptance.js +9 -16
  93. package/dist/packages/compiler/runtime-contracts.js +9 -9
  94. package/dist/packages/compiler/runtime-prompt.js +4 -4
  95. package/dist/packages/compiler/runtime-reconcile.d.ts +2 -2
  96. package/dist/packages/compiler/runtime-reconcile.js +3 -3
  97. package/dist/packages/compiler/runtime-runs.js +9 -9
  98. package/dist/packages/compiler/runtime-types.d.ts +8 -7
  99. package/dist/packages/compiler/state-health.js +26 -35
  100. package/dist/packages/compiler/state-view.js +6 -6
  101. package/dist/packages/compiler/validate-compiled.d.ts +5 -5
  102. package/dist/packages/compiler/validate-compiled.js +56 -64
  103. package/dist/packages/compiler/validate.d.ts +2 -2
  104. package/dist/packages/compiler/validate.js +22 -14
  105. package/dist/packages/contracts/index.d.ts +2 -0
  106. package/dist/packages/contracts/index.js +1 -0
  107. package/dist/packages/contracts/lib/schema.d.ts +205 -0
  108. package/dist/packages/contracts/lib/schema.js +101 -0
  109. package/dist/packages/execution/index.d.ts +2 -2
  110. package/dist/packages/execution/index.js +1 -1
  111. package/dist/packages/execution/lib/schema.d.ts +80 -83
  112. package/dist/packages/execution/lib/schema.js +25 -48
  113. package/dist/packages/local-service/action-values.d.ts +1 -1
  114. package/dist/packages/local-service/action-values.js +1 -1
  115. package/dist/packages/local-service/client.d.ts +4 -4
  116. package/dist/packages/local-service/client.js +4 -4
  117. package/dist/packages/local-service/index.d.ts +3 -3
  118. package/dist/packages/local-service/index.js +2 -2
  119. package/dist/packages/local-service/lib/schema.d.ts +540 -974
  120. package/dist/packages/local-service/lib/schema.js +44 -160
  121. package/dist/packages/local-service/run-observability.d.ts +6 -0
  122. package/dist/packages/local-service/run-observability.js +592 -0
  123. package/dist/packages/local-service/runtime.d.ts +19 -23
  124. package/dist/packages/local-service/runtime.js +349 -913
  125. package/dist/packages/local-service/server.d.ts +1 -0
  126. package/dist/packages/local-service/server.js +25 -20
  127. package/dist/packages/method-authoring/index.d.ts +4 -0
  128. package/dist/packages/method-authoring/index.js +4 -0
  129. package/dist/packages/{workflow-authoring/lib/workflow-edit-utils.d.ts → method-authoring/lib/method-edit-utils.d.ts} +3 -3
  130. package/dist/packages/method-authoring/method-authoring.d.ts +24 -0
  131. package/dist/packages/method-authoring/method-authoring.js +116 -0
  132. package/dist/packages/method-authoring/method-edit-session.d.ts +18 -0
  133. package/dist/packages/method-authoring/method-edit-session.js +125 -0
  134. package/dist/packages/method-authoring/method-improvement.d.ts +23 -0
  135. package/dist/packages/{workflow-authoring/workflow-improvement.js → method-authoring/method-improvement.js} +63 -63
  136. package/dist/packages/{workflow-package/builtin-compiled-workflow.d.ts → method-package/builtin-compiled-method.d.ts} +1 -1
  137. package/dist/packages/{workflow-package/builtin-compiled-workflow.js → method-package/builtin-compiled-method.js} +17 -17
  138. package/dist/packages/{workflow-package → method-package}/context-interface.d.ts +12 -12
  139. package/dist/packages/{workflow-package → method-package}/context-interface.js +19 -19
  140. package/dist/packages/method-package/index.d.ts +11 -0
  141. package/dist/packages/method-package/index.js +11 -0
  142. package/dist/packages/method-package/interf-method-package.d.ts +31 -0
  143. package/dist/packages/{workflow-package/interf-workflow-package.js → method-package/interf-method-package.js} +145 -145
  144. package/dist/packages/{workflow-package → method-package}/lib/package-root.js +1 -1
  145. package/dist/packages/method-package/local-methods.d.ts +64 -0
  146. package/dist/packages/method-package/local-methods.js +466 -0
  147. package/dist/packages/method-package/method-definitions.d.ts +83 -0
  148. package/dist/packages/method-package/method-definitions.js +205 -0
  149. package/dist/packages/{workflow-package/workflow-helpers.d.ts → method-package/method-helpers.d.ts} +10 -10
  150. package/dist/packages/{workflow-package/workflow-helpers.js → method-package/method-helpers.js} +22 -26
  151. package/dist/packages/method-package/method-review-paths.d.ts +10 -0
  152. package/dist/packages/{workflow-package/workflow-review-paths.js → method-package/method-review-paths.js} +4 -4
  153. package/dist/packages/{workflow-package/workflow-stage-runner.d.ts → method-package/method-stage-runner.d.ts} +12 -11
  154. package/dist/packages/{workflow-package/workflow-stage-runner.js → method-package/method-stage-runner.js} +6 -6
  155. package/dist/packages/methods/index.d.ts +2 -0
  156. package/dist/packages/methods/index.js +2 -0
  157. package/dist/packages/methods/method-resolution.d.ts +6 -0
  158. package/dist/packages/methods/method-resolution.js +7 -0
  159. package/dist/packages/project-model/index.d.ts +1 -4
  160. package/dist/packages/project-model/index.js +0 -3
  161. package/dist/packages/project-model/interf-detect.d.ts +1 -5
  162. package/dist/packages/project-model/interf-detect.js +7 -18
  163. package/dist/packages/project-model/interf-scaffold.d.ts +2 -2
  164. package/dist/packages/project-model/interf-scaffold.js +38 -39
  165. package/dist/packages/project-model/interf.d.ts +1 -2
  166. package/dist/packages/project-model/interf.js +1 -2
  167. package/dist/packages/project-model/lib/schema.d.ts +2 -66
  168. package/dist/packages/project-model/lib/schema.js +5 -23
  169. package/dist/packages/project-model/project-paths.d.ts +9 -10
  170. package/dist/packages/project-model/project-paths.js +14 -17
  171. package/dist/packages/project-model/source-config.d.ts +11 -18
  172. package/dist/packages/project-model/source-config.js +42 -60
  173. package/dist/packages/project-model/source-folders.d.ts +4 -4
  174. package/dist/packages/project-model/source-folders.js +10 -10
  175. package/dist/packages/testing/index.d.ts +2 -2
  176. package/dist/packages/testing/index.js +1 -1
  177. package/dist/packages/testing/lib/schema.d.ts +11 -11
  178. package/dist/packages/testing/lib/schema.js +8 -9
  179. package/dist/packages/testing/readiness-check-run.d.ts +67 -0
  180. package/dist/packages/testing/readiness-check-run.js +258 -0
  181. package/dist/packages/testing/test-execution.d.ts +3 -3
  182. package/dist/packages/testing/test-execution.js +5 -5
  183. package/dist/packages/testing/test-paths.js +6 -6
  184. package/dist/packages/testing/test-profile-presets.js +2 -2
  185. package/dist/packages/testing/test-sandbox.js +10 -11
  186. package/dist/packages/testing/test-targets.d.ts +1 -1
  187. package/dist/packages/testing/test-targets.js +8 -7
  188. package/dist/packages/testing/test-types.d.ts +1 -1
  189. package/package.json +16 -33
  190. package/apps/compiler-ui/.next/static/chunks/0ti_66mx7~w2-.js +0 -5
  191. package/apps/compiler-ui/.next/static/chunks/13g~4mamjft.c.css +0 -3
  192. package/builtin-workflows/interf/improve/SKILL.md +0 -18
  193. package/dist/cli/commands/create-workflow-wizard.d.ts +0 -76
  194. package/dist/packages/project-model/compiled-paths.d.ts +0 -1
  195. package/dist/packages/project-model/compiled-paths.js +0 -1
  196. package/dist/packages/project-model/compiled-raw.d.ts +0 -1
  197. package/dist/packages/project-model/compiled-raw.js +0 -1
  198. package/dist/packages/project-model/compiled-reset.d.ts +0 -1
  199. package/dist/packages/project-model/compiled-reset.js +0 -1
  200. package/dist/packages/shared/index.d.ts +0 -7
  201. package/dist/packages/shared/index.js +0 -7
  202. package/dist/packages/shared/util.d.ts +0 -3
  203. package/dist/packages/shared/util.js +0 -3
  204. package/dist/packages/testing/test-matrices.d.ts +0 -90
  205. package/dist/packages/testing/test-matrices.js +0 -96
  206. package/dist/packages/workflow-authoring/index.d.ts +0 -4
  207. package/dist/packages/workflow-authoring/index.js +0 -4
  208. package/dist/packages/workflow-authoring/workflow-authoring.d.ts +0 -24
  209. package/dist/packages/workflow-authoring/workflow-authoring.js +0 -82
  210. package/dist/packages/workflow-authoring/workflow-edit-session.d.ts +0 -18
  211. package/dist/packages/workflow-authoring/workflow-edit-session.js +0 -91
  212. package/dist/packages/workflow-authoring/workflow-improvement.d.ts +0 -23
  213. package/dist/packages/workflow-package/index.d.ts +0 -11
  214. package/dist/packages/workflow-package/index.js +0 -11
  215. package/dist/packages/workflow-package/interf-workflow-package.d.ts +0 -31
  216. package/dist/packages/workflow-package/local-workflows.d.ts +0 -64
  217. package/dist/packages/workflow-package/local-workflows.js +0 -457
  218. package/dist/packages/workflow-package/workflow-definitions.d.ts +0 -82
  219. package/dist/packages/workflow-package/workflow-definitions.js +0 -211
  220. package/dist/packages/workflow-package/workflow-review-paths.d.ts +0 -10
  221. /package/{builtin-workflows/interf → builtin-methods/interf-default}/compile/stages/shape/SKILL.md +0 -0
  222. /package/{builtin-workflows/interf → builtin-methods/interf-default}/compile/stages/structure/SKILL.md +0 -0
  223. /package/{builtin-workflows/interf → builtin-methods/interf-default}/compile/stages/summarize/SKILL.md +0 -0
  224. /package/{builtin-workflows/interf → builtin-methods/interf-default}/use/query/SKILL.md +0 -0
  225. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/03~yq9q893hmn.js +0 -0
  226. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/06z~l3kwb891e.js +0 -0
  227. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/08g7lvje.te.u.js +0 -0
  228. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/08m7vf5asqlsm.js +0 -0
  229. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/0_i-3_5l9t2qe.js +0 -0
  230. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/0b-ywny_j0g~0.js +0 -0
  231. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/0b52v41o1gixx.js +0 -0
  232. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/0gpzgsv0w.q~m.js +0 -0
  233. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/0ilwfezfvu6~-.js +0 -0
  234. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/0n51hrfoufc7g.js +0 -0
  235. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/0xxmf45eskdt~.css +0 -0
  236. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/0y5z3t-z1c8ks.js.map +0 -0
  237. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/14wtz~vq25~qq.js +0 -0
  238. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/turbopack-10e~t1yzi4svj.js +0 -0
  239. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/chunks/turbopack-worker-0sjn--fhq~1cg.js +0 -0
  240. /package/{apps/compiler-ui/.next/static/XWKL548yXD_UOG4ID9G3J → dist/compiler-ui/_next/static/j7pdoqWrl4YJrJUVnksbl}/_buildManifest.js +0 -0
  241. /package/{apps/compiler-ui/.next/static/XWKL548yXD_UOG4ID9G3J → dist/compiler-ui/_next/static/j7pdoqWrl4YJrJUVnksbl}/_clientMiddlewareManifest.js +0 -0
  242. /package/{apps/compiler-ui/.next/static/XWKL548yXD_UOG4ID9G3J → dist/compiler-ui/_next/static/j7pdoqWrl4YJrJUVnksbl}/_ssgManifest.js +0 -0
  243. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/media/GeistMono_Variable.p.17jn9btb_52pq.woff2 +0 -0
  244. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/media/Geist_Variable-s.p.0-te~ja_gpvcf.woff2 +0 -0
  245. /package/{apps/compiler-ui/.next → dist/compiler-ui/_next}/static/media/worker.102zas1s52_pf.js +0 -0
  246. /package/dist/packages/compiler/{workflow-primitives.d.ts → method-primitives.d.ts} +0 -0
  247. /package/dist/packages/compiler/{workflow-primitives.js → method-primitives.js} +0 -0
  248. /package/dist/packages/{workflow-authoring/lib/workflow-edit-utils.js → method-authoring/lib/method-edit-utils.js} +0 -0
  249. /package/dist/packages/{workflow-package → method-package}/lib/package-root.d.ts +0 -0
  250. /package/dist/packages/{workflow-package/workflow-stage-policy.d.ts → method-package/method-stage-policy.d.ts} +0 -0
  251. /package/dist/packages/{workflow-package/workflow-stage-policy.js → method-package/method-stage-policy.js} +0 -0
@@ -4,22 +4,24 @@ import { CompileRunSchema, } from "../execution/lib/schema.js";
4
4
  import { createRunEventId, createRunEventTimestamp, } from "../execution/events.js";
5
5
  import { compiledRuntimeRunHistoryPath, compiledRuntimeRoot, testRootForCompiled, } from "../compiler/compiled-paths.js";
6
6
  import { loadState, } from "../compiler/state.js";
7
- import { ReadinessStateSchema, RuntimeRunSchema, } from "../compiler/lib/schema.js";
7
+ import { RuntimeRunSchema, } from "../compiler/lib/schema.js";
8
+ import { ReadinessStateSchema, } from "../contracts/lib/schema.js";
8
9
  import { discoverSourceFiles, } from "../compiler/discovery.js";
9
10
  import { ensurePortableContextScaffold, readInterfConfig, } from "../project-model/interf.js";
10
- import { findSourceDatasetConfig, fingerprintReadinessChecks, listSourceDatasetConfigs, loadSourceFolderConfig, methodIdForSourcePreparationConfig, resolveConfiguredSourceFolderPath, resolveSourceDatasetPath, syncCompiledInterfConfigFromSourceDatasetConfig, upsertSourceDatasetConfig, } from "../project-model/source-config.js";
11
- import { defaultDatasetNameForPath, listSourceFolderChoices, normalizeSourceDatasetPathForConfig, } from "../project-model/source-folders.js";
12
- import { datasetLatestTestStatePath, portableContextPath, } from "../project-model/project-paths.js";
13
- import { getCompiledWorkflow, listCompiledWorkflowChoices, } from "../workflow-package/workflow-definitions.js";
14
- import { resolveWorkflowPackageSourcePath, } from "../workflow-package/local-workflows.js";
11
+ import { findSourcePreparationConfig, fingerprintReadinessChecks, listSourcePreparationConfigs, loadSourceFolderConfig, DEFAULT_METHOD_ID, methodIdForSourcePreparationConfig, resolveConfiguredSourceFolderPath, resolveSourcePreparationPath, syncCompiledInterfConfigFromSourcePreparationConfig, upsertSourcePreparationConfig, } from "../project-model/source-config.js";
12
+ import { defaultPreparationNameForPath, listSourceFolderChoices, normalizeSourcePreparationPathForConfig, } from "../project-model/source-folders.js";
13
+ import { portableContextPath, } from "../project-model/project-paths.js";
14
+ import { getCompiledMethod, listCompiledMethodChoices, } from "../method-package/method-definitions.js";
15
+ import { resolveMethodPackageSourcePath, } from "../method-package/local-methods.js";
15
16
  import { resolveAgent, detectAgents, supportsAutomatedRuns, } from "../agents/lib/detection.js";
16
17
  import { AGENTS, } from "../agents/lib/constants.js";
17
18
  import { loadUserConfig, saveUserConfig, } from "../agents/lib/user-config.js";
18
- import { TestRunComparisonSchema, } from "../testing/lib/schema.js";
19
+ import { readSavedReadinessCheckRun, } from "../testing/readiness-check-run.js";
19
20
  import { createCompiledTestTarget, } from "../testing/test-targets.js";
20
- import { ActionProposalApprovalRequestSchema, ActionProposalCreateRequestSchema, ActionProposalPlanSchema, ActionProposalResourceSchema, CompileRunCreateRequestSchema, CompileRunResourceSchema, DatasetSetupCreateRequestSchema, DatasetResourceSchema, MethodResourceSchema, LocalExecutorStatusSchema, LocalExecutorSelectRequestSchema, LocalServiceHealthSchema, PreparationReadinessStateSchema, LocalRunHandlerResultSchema, LocalJobEventAppendRequestSchema, LocalJobRunCreateRequestSchema, LocalJobRunResourceSchema, SourceFileResourceSchema, WorkspaceFileResourceSchema, PortableContextResourceSchema, PreparationResourceSchema, ReadinessCheckDraftCreateRequestSchema, ReadinessCheckDraftResultSchema, RunObservabilityResourceSchema, TestRunCreateRequestSchema, TestRunResourceSchema, WorkflowAuthoringCreateRequestSchema, WorkflowAuthoringResultSchema, WorkflowPackageResourceSchema, } from "./lib/schema.js";
21
+ import { ActionProposalApprovalRequestSchema, ActionProposalCreateRequestSchema, ActionProposalPlanSchema, ActionProposalResourceSchema, CompileRunCreateRequestSchema, CompileRunResourceSchema, MethodResourceSchema, LocalExecutorStatusSchema, LocalExecutorSelectRequestSchema, LocalServiceHealthSchema, PreparationReadinessStateSchema, LocalRunHandlerResultSchema, LocalJobEventAppendRequestSchema, LocalJobRunCreateRequestSchema, LocalJobRunResourceSchema, SourceFileResourceSchema, WorkspaceFileResourceSchema, PortableContextResourceSchema, PreparationSetupCreateRequestSchema, PreparationResourceSchema, ReadinessCheckDraftCreateRequestSchema, ReadinessCheckDraftResultSchema, TestRunCreateRequestSchema, TestRunResourceSchema, MethodAuthoringCreateRequestSchema, MethodAuthoringResultSchema, } from "./lib/schema.js";
21
22
  import { buildLocalServiceUrl, } from "./routes.js";
22
23
  import { methodAuthoringTaskPrompt, MethodAuthoringActionValuesSchema, PreparationSetupActionValuesSchema, } from "./action-values.js";
24
+ import { compileRunToObservability, jobRunToObservability, testRunToObservability, uniqueArtifacts, } from "./run-observability.js";
23
25
  function createRunId(prefix) {
24
26
  return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
25
27
  }
@@ -39,6 +41,22 @@ function writeJsonFile(filePath, value) {
39
41
  mkdirSync(dirname(filePath), { recursive: true });
40
42
  writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`);
41
43
  }
44
+ function sanitizeActionProposalPlan(value) {
45
+ if (!value || typeof value !== "object" || Array.isArray(value))
46
+ return value;
47
+ const plan = { ...value };
48
+ for (const key of ["preparation", "method", "title", "summary", "assistant_message", "command_preview"]) {
49
+ const current = plan[key];
50
+ if (current === null || current === undefined) {
51
+ delete plan[key];
52
+ continue;
53
+ }
54
+ if (typeof current === "string" && current.trim().length === 0) {
55
+ delete plan[key];
56
+ }
57
+ }
58
+ return plan;
59
+ }
42
60
  function compileRunsRoot(compiledPath) {
43
61
  return join(compiledRuntimeRoot(compiledPath), "compile-runs");
44
62
  }
@@ -152,110 +170,6 @@ function detectedExecutorOptions(currentAgentName) {
152
170
  current: agent.name === currentAgentName,
153
171
  }));
154
172
  }
155
- function uniqueArtifacts(artifacts) {
156
- const seen = new Set();
157
- const result = [];
158
- for (const artifact of artifacts) {
159
- const key = `${artifact.role}:${artifact.stage_id ?? ""}:${artifact.path}`;
160
- if (seen.has(key))
161
- continue;
162
- seen.add(key);
163
- result.push(artifact);
164
- }
165
- return result;
166
- }
167
- function observableRunStatus(status) {
168
- if (status === "queued" || status === "pending")
169
- return "queued";
170
- if (status === "running")
171
- return "running";
172
- if (status === "failed")
173
- return "failed";
174
- if (status === "cancelled")
175
- return "cancelled";
176
- return "succeeded";
177
- }
178
- function workflowTraceRunStatus(status) {
179
- if (status === "queued" || status === "pending")
180
- return "pending";
181
- if (status === "running")
182
- return "running";
183
- if (status === "failed")
184
- return "failed";
185
- if (status === "cancelled")
186
- return "cancelled";
187
- return "completed";
188
- }
189
- function safeWorkflowNamePart(value) {
190
- return value
191
- .replace(/[^a-zA-Z0-9._/-]+/g, "-")
192
- .replace(/\/+/g, "/")
193
- .replace(/^-+|-+$/g, "")
194
- || "run";
195
- }
196
- function workflowTraceName(runType, name) {
197
- return `workflow//./interf/${runType}//${safeWorkflowNamePart(name)}`;
198
- }
199
- function workflowStepName(runType, label) {
200
- return `step//./interf/${runType}//${safeWorkflowNamePart(label)}`;
201
- }
202
- function structuredWorkflowError(message) {
203
- return {
204
- message: message || "Run failed.",
205
- code: "INTERF_RUN_ERROR",
206
- };
207
- }
208
- function traceEvent(runId, eventType, createdAt, index, eventData, correlationId) {
209
- return {
210
- runId,
211
- eventId: `${runId}:event:${index}`,
212
- eventType,
213
- specVersion: 1,
214
- createdAt: createdAt ?? createRunEventTimestamp(),
215
- ...(correlationId ? { correlationId } : {}),
216
- ...(eventData === undefined ? {} : { eventData }),
217
- };
218
- }
219
- function traceStreamChunk(runId, index, createdAt, text, data) {
220
- return {
221
- streamId: `${runId}:events`,
222
- chunkId: `${runId}:events:${index}`,
223
- index,
224
- createdAt: createdAt ?? createRunEventTimestamp(),
225
- text,
226
- ...(data === undefined ? {} : { data }),
227
- };
228
- }
229
- function buildTraceStreamChunks(runId, events) {
230
- return events.map((event, index) => traceStreamChunk(runId, index, event.timestamp, JSON.stringify({
231
- time: event.timestamp ?? null,
232
- type: event.type,
233
- scope: event.stage_id ?? event.step_id ?? event.type,
234
- message: event.message ?? event.summary ?? event.error ?? event.type,
235
- }), event));
236
- }
237
- function proofChecksForCompileRun(run) {
238
- return run.stages.flatMap((stage) => (stage.latest_proof?.checks ?? []).map((check) => ({
239
- ...check,
240
- detail: check.detail ?? `${stage.stage_label ?? stage.stage_id} / ${stage.status}`,
241
- })));
242
- }
243
- function agentLabelForJob(job) {
244
- return job.agent?.display_name ?? job.agent?.name ?? null;
245
- }
246
- function jobTypeLabelForMetric(type) {
247
- if (type === "readiness-check-draft")
248
- return "Readiness-check draft";
249
- if (type === "method-authoring")
250
- return "Method draft";
251
- if (type === "method-improvement")
252
- return "Method improvement";
253
- if (type === "compile")
254
- return "Compile";
255
- if (type === "test")
256
- return "Readiness check";
257
- return "Local job";
258
- }
259
173
  function stageArtifactRefs(stageId, artifacts) {
260
174
  return (artifacts ?? []).map((path) => ({
261
175
  path,
@@ -314,15 +228,6 @@ function logsForRuntimeRun(run) {
314
228
  contract_path: run.contract_path,
315
229
  };
316
230
  }
317
- function stageTracePayload(stage) {
318
- return {
319
- status: stage.status,
320
- ...(stage.summary ? { summary: stage.summary } : {}),
321
- ...(stage.artifacts.length > 0 ? { artifacts: stage.artifacts } : {}),
322
- ...(stage.logs ? { logs: stage.logs } : {}),
323
- ...(stage.latest_proof ? { proof: stage.latest_proof } : {}),
324
- };
325
- }
326
231
  function timestampKey(value) {
327
232
  const parsed = Date.parse(value ?? "");
328
233
  return Number.isFinite(parsed) ? parsed : 0;
@@ -495,481 +400,6 @@ function applyEventToLocalJob(run, event) {
495
400
  events: [...run.events, event],
496
401
  };
497
402
  }
498
- function compileRunToObservability(run) {
499
- const artifacts = uniqueArtifacts(run.stages.flatMap((stage) => stage.artifacts));
500
- const proof = proofChecksForCompileRun(run);
501
- const executor = run.stages.find((stage) => stage.executor)?.executor ?? null;
502
- const traceStatus = workflowTraceRunStatus(run.status);
503
- const workflowName = workflowTraceName("compile", run.method);
504
- const completedAt = run.finished_at ?? (traceStatus === "completed" || traceStatus === "failed" || traceStatus === "cancelled"
505
- ? run.started_at ?? run.created_at
506
- : undefined);
507
- let eventIndex = 0;
508
- const events = [
509
- traceEvent(run.run_id, "run_created", run.created_at, eventIndex++, {
510
- deploymentId: "local-interf",
511
- workflowName,
512
- input: {
513
- kind: "compile",
514
- preparation: run.preparation,
515
- method: run.method,
516
- source_path: run.source_path,
517
- },
518
- executionContext: {
519
- backend: run.backend,
520
- executor,
521
- },
522
- }),
523
- ];
524
- if (run.started_at) {
525
- events.push(traceEvent(run.run_id, "run_started", run.started_at, eventIndex++, {
526
- workflowName,
527
- input: {
528
- preparation: run.preparation,
529
- method: run.method,
530
- },
531
- executionContext: {
532
- backend: run.backend,
533
- executor,
534
- },
535
- }));
536
- }
537
- for (const stage of run.stages) {
538
- const stepName = workflowStepName("compile", stage.stage_label ?? stage.stage_id);
539
- const stepCreatedAt = stage.started_at ?? run.started_at ?? run.created_at;
540
- events.push(traceEvent(run.run_id, "step_created", stepCreatedAt, eventIndex++, {
541
- stepName,
542
- input: {
543
- stage_id: stage.stage_id,
544
- stage_label: stage.stage_label ?? null,
545
- stage_index: stage.stage_index ?? null,
546
- stage_total: stage.stage_total ?? null,
547
- reads: stage.contract?.reads ?? [],
548
- writes: stage.contract?.writes ?? [],
549
- acceptance: stage.contract?.acceptance ?? null,
550
- executor: stage.executor ?? null,
551
- },
552
- }, stage.stage_id));
553
- if (stage.started_at || stage.status !== "queued") {
554
- events.push(traceEvent(run.run_id, "step_started", stage.started_at ?? stepCreatedAt, eventIndex++, {
555
- attempt: 1,
556
- }, stage.stage_id));
557
- }
558
- if (stage.status === "failed") {
559
- events.push(traceEvent(run.run_id, "step_failed", stage.finished_at ?? run.finished_at ?? stepCreatedAt, eventIndex++, {
560
- error: structuredWorkflowError(stage.failure ?? stage.summary),
561
- output: stageTracePayload(stage),
562
- }, stage.stage_id));
563
- }
564
- else if (stage.status === "succeeded" || stage.status === "skipped") {
565
- events.push(traceEvent(run.run_id, "step_completed", stage.finished_at ?? run.finished_at ?? stepCreatedAt, eventIndex++, {
566
- result: stageTracePayload(stage),
567
- }, stage.stage_id));
568
- }
569
- }
570
- if (traceStatus === "completed") {
571
- events.push(traceEvent(run.run_id, "run_completed", completedAt, eventIndex++, {
572
- output: {
573
- portable_context_path: run.portable_context_path,
574
- artifacts,
575
- proof,
576
- latest_proof: run.latest_proof ?? null,
577
- },
578
- }));
579
- }
580
- else if (traceStatus === "failed") {
581
- events.push(traceEvent(run.run_id, "run_failed", completedAt, eventIndex++, {
582
- error: structuredWorkflowError(run.stages.find((stage) => stage.failure)?.failure ?? run.latest_proof?.summary),
583
- }));
584
- }
585
- else if (traceStatus === "cancelled") {
586
- events.push(traceEvent(run.run_id, "run_cancelled", completedAt, eventIndex++));
587
- }
588
- return RunObservabilityResourceSchema.parse({
589
- kind: "interf-run-observability",
590
- version: 1,
591
- run_id: run.run_id,
592
- run_type: "compile",
593
- title: `Prepare ${run.preparation}`,
594
- status: observableRunStatus(run.status),
595
- preparation: run.preparation,
596
- method: run.method,
597
- source_path: run.source_path,
598
- output_path: run.portable_context_path,
599
- executor,
600
- agent_label: executor?.display_name ?? run.backend,
601
- created_at: run.created_at,
602
- started_at: run.started_at ?? null,
603
- finished_at: run.finished_at ?? null,
604
- metrics: [
605
- { label: "Preparation", value: run.preparation },
606
- { label: "Method", value: run.method },
607
- { label: "Executor", value: executor?.display_name ?? run.backend },
608
- { label: "Stages", value: `${run.stages.filter((stage) => stage.status === "succeeded").length}/${run.stages.length}` },
609
- { label: "Proof", value: `${proof.filter((check) => check.ok).length}/${proof.length}` },
610
- { label: "Artifacts", value: String(artifacts.length) },
611
- ],
612
- artifacts,
613
- proof,
614
- trace: {
615
- run: {
616
- runId: run.run_id,
617
- status: traceStatus,
618
- deploymentId: "local-interf",
619
- workflowName,
620
- specVersion: 1,
621
- executionContext: {
622
- product: "Interf",
623
- run_type: "compile",
624
- preparation: run.preparation,
625
- method: run.method,
626
- backend: run.backend,
627
- executor,
628
- },
629
- input: {
630
- preparation: run.preparation,
631
- method: run.method,
632
- source_path: run.source_path,
633
- },
634
- ...(traceStatus === "completed"
635
- ? {
636
- output: {
637
- portable_context_path: run.portable_context_path,
638
- artifacts,
639
- proof,
640
- },
641
- }
642
- : {}),
643
- ...(traceStatus === "failed" ? { error: structuredWorkflowError(run.stages.find((stage) => stage.failure)?.failure) } : {}),
644
- ...(run.started_at ? { startedAt: run.started_at } : {}),
645
- ...(completedAt ? { completedAt } : {}),
646
- createdAt: run.created_at,
647
- updatedAt: completedAt ?? run.started_at ?? run.created_at,
648
- },
649
- events,
650
- streams: buildTraceStreamChunks(run.run_id, run.events),
651
- },
652
- });
653
- }
654
- function testRunToObservability(run) {
655
- const traceStatus = workflowTraceRunStatus(run.status);
656
- const title = `Check readiness ${run.preparation}`;
657
- const workflowName = workflowTraceName("test", title);
658
- const completedAt = run.finished_at ?? (traceStatus === "completed" || traceStatus === "failed" || traceStatus === "cancelled"
659
- ? run.started_at ?? new Date().toISOString()
660
- : undefined);
661
- const raw = run.comparison?.raw ?? null;
662
- const compiled = run.comparison?.compiled ?? null;
663
- const proofCandidates = [
664
- raw
665
- ? {
666
- id: `${run.run_id}-source-files`,
667
- label: "source files baseline",
668
- ok: raw.ok ?? raw.passed_cases === raw.total_cases,
669
- detail: `${raw.passed_cases}/${raw.total_cases} checks`,
670
- }
671
- : null,
672
- compiled
673
- ? {
674
- id: `${run.run_id}-portable-context`,
675
- label: "portable context",
676
- ok: compiled.ok ?? compiled.passed_cases === compiled.total_cases,
677
- detail: `${compiled.passed_cases}/${compiled.total_cases} checks`,
678
- }
679
- : null,
680
- ];
681
- const proof = proofCandidates.filter((value) => value !== null);
682
- const artifacts = uniqueArtifacts([
683
- ...(raw?.run_path ? [{ path: raw.run_path, role: "test", label: "source files readiness run" }] : []),
684
- ...(compiled?.run_path ? [{ path: compiled.run_path, role: "test", label: "portable context readiness run" }] : []),
685
- ]);
686
- let eventIndex = 0;
687
- const events = [
688
- traceEvent(run.run_id, "run_created", run.started_at, eventIndex++, {
689
- deploymentId: "local-interf",
690
- workflowName,
691
- input: {
692
- kind: "test",
693
- preparation: run.preparation,
694
- mode: run.mode,
695
- },
696
- }),
697
- ];
698
- if (run.started_at) {
699
- events.push(traceEvent(run.run_id, "run_started", run.started_at, eventIndex++, {
700
- workflowName,
701
- input: {
702
- preparation: run.preparation,
703
- mode: run.mode,
704
- },
705
- }));
706
- }
707
- const targetStepCandidates = [
708
- raw
709
- ? {
710
- id: "source-files-baseline",
711
- label: "Source files baseline",
712
- status: raw.ok ?? raw.passed_cases === raw.total_cases ? "succeeded" : "failed",
713
- input: raw.target ?? { type: "source-files", path: run.source_path ?? null },
714
- output: raw,
715
- }
716
- : null,
717
- compiled
718
- ? {
719
- id: "portable-context-check",
720
- label: "Portable context",
721
- status: compiled.ok ?? compiled.passed_cases === compiled.total_cases ? "succeeded" : "failed",
722
- input: compiled.target ?? { type: "portable-context", path: run.portable_context_path ?? null },
723
- output: compiled,
724
- }
725
- : null,
726
- ];
727
- const targetSteps = targetStepCandidates.filter((value) => value !== null);
728
- if (targetSteps.length === 0) {
729
- targetSteps.push({
730
- id: "check-readiness",
731
- label: "Run readiness checks",
732
- status: run.status === "failed" ? "failed" : "succeeded",
733
- input: {
734
- preparation: run.preparation,
735
- mode: run.mode,
736
- },
737
- output: run.comparison ?? null,
738
- });
739
- }
740
- for (const step of targetSteps) {
741
- const timestamp = run.started_at ?? run.finished_at ?? new Date().toISOString();
742
- events.push(traceEvent(run.run_id, "step_created", timestamp, eventIndex++, {
743
- stepName: workflowStepName("test", step.label),
744
- input: step.input,
745
- }, step.id));
746
- events.push(traceEvent(run.run_id, "step_started", timestamp, eventIndex++, {
747
- attempt: 1,
748
- }, step.id));
749
- events.push(traceEvent(run.run_id, step.status === "failed" ? "step_failed" : "step_completed", run.finished_at ?? timestamp, eventIndex++, step.status === "failed"
750
- ? { error: structuredWorkflowError(run.error ?? `${step.label} did not pass.`), output: step.output }
751
- : { result: step.output }, step.id));
752
- }
753
- if (traceStatus === "completed") {
754
- events.push(traceEvent(run.run_id, "run_completed", completedAt, eventIndex++, {
755
- output: {
756
- comparison: run.comparison,
757
- proof,
758
- },
759
- }));
760
- }
761
- else if (traceStatus === "failed") {
762
- events.push(traceEvent(run.run_id, "run_failed", completedAt, eventIndex++, {
763
- error: structuredWorkflowError(run.error),
764
- }));
765
- }
766
- else if (traceStatus === "cancelled") {
767
- events.push(traceEvent(run.run_id, "run_cancelled", completedAt, eventIndex++));
768
- }
769
- return RunObservabilityResourceSchema.parse({
770
- kind: "interf-run-observability",
771
- version: 1,
772
- run_id: run.run_id,
773
- run_type: "test",
774
- title,
775
- status: observableRunStatus(run.status),
776
- preparation: run.preparation,
777
- method: compiled?.target?.workflow ?? null,
778
- source_path: run.source_path ?? null,
779
- output_path: run.portable_context_path ?? null,
780
- created_at: run.started_at ?? completedAt ?? new Date().toISOString(),
781
- started_at: run.started_at ?? null,
782
- finished_at: run.finished_at ?? null,
783
- metrics: [
784
- { label: "Preparation", value: run.preparation },
785
- { label: "Mode", value: run.mode },
786
- { label: "Readiness checks", value: compiled ? `${compiled.passed_cases}/${compiled.total_cases}` : raw ? `${raw.passed_cases}/${raw.total_cases}` : "0/0" },
787
- { label: "Source files", value: raw ? `${raw.passed_cases}/${raw.total_cases}` : "-" },
788
- { label: "Portable context", value: compiled ? `${compiled.passed_cases}/${compiled.total_cases}` : "-" },
789
- ],
790
- artifacts,
791
- proof,
792
- trace: {
793
- run: {
794
- runId: run.run_id,
795
- status: traceStatus,
796
- deploymentId: "local-interf",
797
- workflowName,
798
- specVersion: 1,
799
- executionContext: {
800
- product: "Interf",
801
- run_type: "test",
802
- preparation: run.preparation,
803
- mode: run.mode,
804
- },
805
- input: {
806
- preparation: run.preparation,
807
- mode: run.mode,
808
- source_path: run.source_path ?? null,
809
- portable_context_path: run.portable_context_path ?? null,
810
- },
811
- ...(traceStatus === "completed" ? { output: { comparison: run.comparison, proof } } : {}),
812
- ...(traceStatus === "failed" ? { error: structuredWorkflowError(run.error) } : {}),
813
- ...(run.started_at ? { startedAt: run.started_at } : {}),
814
- ...(completedAt ? { completedAt } : {}),
815
- createdAt: run.started_at ?? completedAt ?? new Date().toISOString(),
816
- updatedAt: completedAt ?? run.started_at ?? new Date().toISOString(),
817
- },
818
- events,
819
- streams: buildTraceStreamChunks(run.run_id, run.events ?? []),
820
- },
821
- });
822
- }
823
- function jobRunToObservability(job) {
824
- const runType = (job.job_type === "preparation-setup" ||
825
- job.job_type === "readiness-check-draft" ||
826
- job.job_type === "method-authoring" ||
827
- job.job_type === "method-improvement"
828
- ? job.job_type
829
- : "job");
830
- const executor = job.agent
831
- ? {
832
- kind: "local-agent",
833
- name: job.agent.name,
834
- display_name: job.agent.display_name,
835
- command: job.agent.command ?? null,
836
- }
837
- : null;
838
- const traceStatus = workflowTraceRunStatus(job.status);
839
- const workflowName = workflowTraceName(runType, job.title);
840
- const completedAt = job.finished_at ?? (traceStatus === "completed" || traceStatus === "failed" || traceStatus === "cancelled"
841
- ? job.started_at ?? job.created_at
842
- : undefined);
843
- let eventIndex = 0;
844
- const events = [
845
- traceEvent(job.run_id, "run_created", job.created_at, eventIndex++, {
846
- deploymentId: "local-interf",
847
- workflowName,
848
- input: {
849
- job_type: job.job_type,
850
- preparation: job.preparation ?? null,
851
- method: job.method ?? null,
852
- },
853
- executionContext: {
854
- executor,
855
- },
856
- }),
857
- ];
858
- if (job.started_at) {
859
- events.push(traceEvent(job.run_id, "run_started", job.started_at, eventIndex++, {
860
- workflowName,
861
- input: {
862
- job_type: job.job_type,
863
- preparation: job.preparation ?? null,
864
- },
865
- executionContext: {
866
- executor,
867
- },
868
- }));
869
- }
870
- for (const step of job.steps) {
871
- const timestamp = step.started_at ?? job.started_at ?? job.created_at;
872
- events.push(traceEvent(job.run_id, "step_created", timestamp, eventIndex++, {
873
- stepName: workflowStepName(runType, step.label),
874
- input: step.input ?? {
875
- step_id: step.id,
876
- label: step.label,
877
- },
878
- }, step.id));
879
- if (step.started_at || step.status !== "queued") {
880
- events.push(traceEvent(job.run_id, "step_started", step.started_at ?? timestamp, eventIndex++, {
881
- attempt: 1,
882
- }, step.id));
883
- }
884
- if (step.status === "failed") {
885
- events.push(traceEvent(job.run_id, "step_failed", step.finished_at ?? completedAt ?? timestamp, eventIndex++, {
886
- error: structuredWorkflowError(step.summary ?? job.error),
887
- output: step.output ?? null,
888
- }, step.id));
889
- }
890
- else if (step.status === "succeeded") {
891
- events.push(traceEvent(job.run_id, "step_completed", step.finished_at ?? completedAt ?? timestamp, eventIndex++, {
892
- result: step.output ?? {
893
- summary: step.summary ?? null,
894
- },
895
- }, step.id));
896
- }
897
- }
898
- if (traceStatus === "completed") {
899
- events.push(traceEvent(job.run_id, "run_completed", completedAt, eventIndex++, {
900
- output: job.result ?? {
901
- output_path: job.output_path ?? null,
902
- },
903
- }));
904
- }
905
- else if (traceStatus === "failed") {
906
- events.push(traceEvent(job.run_id, "run_failed", completedAt, eventIndex++, {
907
- error: structuredWorkflowError(job.error),
908
- }));
909
- }
910
- else if (traceStatus === "cancelled") {
911
- events.push(traceEvent(job.run_id, "run_cancelled", completedAt, eventIndex++));
912
- }
913
- const outputPath = job.output_path ?? (typeof job.result?.path === "string" ? job.result.path : null);
914
- const artifacts = uniqueArtifacts(outputPath ? [{ path: outputPath, role: "output" }] : []);
915
- return RunObservabilityResourceSchema.parse({
916
- kind: "interf-run-observability",
917
- version: 1,
918
- run_id: job.run_id,
919
- run_type: runType,
920
- title: job.title,
921
- status: observableRunStatus(job.status),
922
- preparation: job.preparation ?? null,
923
- method: job.method ?? null,
924
- source_path: job.source_path ?? null,
925
- output_path: outputPath,
926
- executor,
927
- agent_label: agentLabelForJob(job),
928
- created_at: job.created_at,
929
- started_at: job.started_at ?? null,
930
- finished_at: job.finished_at ?? null,
931
- metrics: [
932
- { label: "Kind", value: jobTypeLabelForMetric(job.job_type) },
933
- { label: "Executor", value: agentLabelForJob(job) ?? "local executor" },
934
- { label: "Phases", value: `${job.steps.filter((step) => step.status === "succeeded").length}/${job.steps.length}` },
935
- { label: "Preparation", value: job.preparation ?? "-" },
936
- { label: "Method", value: job.method ?? "-" },
937
- ],
938
- artifacts,
939
- proof: [],
940
- trace: {
941
- run: {
942
- runId: job.run_id,
943
- status: traceStatus,
944
- deploymentId: "local-interf",
945
- workflowName,
946
- specVersion: 1,
947
- executionContext: {
948
- product: "Interf",
949
- run_type: runType,
950
- job_type: job.job_type,
951
- preparation: job.preparation ?? null,
952
- method: job.method ?? null,
953
- executor,
954
- },
955
- input: {
956
- job_type: job.job_type,
957
- preparation: job.preparation ?? null,
958
- method: job.method ?? null,
959
- source_path: job.source_path ?? null,
960
- },
961
- ...(traceStatus === "completed" ? { output: job.result ?? { output_path: outputPath } } : {}),
962
- ...(traceStatus === "failed" ? { error: structuredWorkflowError(job.error) } : {}),
963
- ...(job.started_at ? { startedAt: job.started_at } : {}),
964
- ...(completedAt ? { completedAt } : {}),
965
- createdAt: job.created_at,
966
- updatedAt: completedAt ?? job.started_at ?? job.created_at,
967
- },
968
- events,
969
- streams: buildTraceStreamChunks(job.run_id, job.events),
970
- },
971
- });
972
- }
973
403
  function slugFromText(value) {
974
404
  const slug = value
975
405
  .toLowerCase()
@@ -989,12 +419,23 @@ function numberValue(values, key) {
989
419
  }
990
420
  function testModeFromValues(values) {
991
421
  const value = stringValue(values, "mode") ?? stringValue(values, "target");
422
+ if (value === "source-files")
423
+ return "raw";
424
+ if (value === "portable-context")
425
+ return "compiled";
992
426
  return value === "raw" || value === "compiled" || value === "both" ? value : null;
993
427
  }
994
428
  function testModeValue(values, defaultMode = "both") {
995
429
  return testModeFromValues(values) ?? defaultMode;
996
430
  }
997
- function workflowIdForProposal(message, values) {
431
+ function testModeCliTarget(mode) {
432
+ if (mode === "raw")
433
+ return "source-files";
434
+ if (mode === "compiled")
435
+ return "portable-context";
436
+ return "both";
437
+ }
438
+ function methodIdForProposal(message, values) {
998
439
  const explicit = stringValue(values, "method_id") ??
999
440
  stringValue(values, "method");
1000
441
  return explicit ?? `custom-${slugFromText(message)}`;
@@ -1003,35 +444,53 @@ function actionValueMethodTaskPrompt(values) {
1003
444
  const parsed = MethodAuthoringActionValuesSchema.safeParse(values);
1004
445
  return parsed.success ? methodAuthoringTaskPrompt(parsed.data) : null;
1005
446
  }
1006
- function datasetSetupPathValue(values) {
447
+ function booleanValue(values, key) {
448
+ const value = values?.[key];
449
+ if (typeof value === "boolean")
450
+ return value;
451
+ if (typeof value === "string") {
452
+ const normalized = value.trim().toLowerCase();
453
+ if (normalized === "true" || normalized === "yes" || normalized === "1")
454
+ return true;
455
+ if (normalized === "false" || normalized === "no" || normalized === "0")
456
+ return false;
457
+ }
458
+ return null;
459
+ }
460
+ function preparationSetupPathValue(values) {
1007
461
  return stringValue(values, "path") ??
1008
462
  stringValue(values, "source_folder_path") ??
1009
463
  stringValue(values, "source_path") ??
1010
464
  stringValue(values, "source_folder") ??
1011
465
  stringValue(values, "folder");
1012
466
  }
1013
- function datasetSetupNameValue(values) {
467
+ function preparationSetupNameValue(values) {
1014
468
  const parsed = PreparationSetupActionValuesSchema.safeParse(values);
1015
469
  return parsed.success ? parsed.data.name : stringValue(values, "name") ??
1016
470
  stringValue(values, "preparation") ??
1017
471
  stringValue(values, "preparation_name");
1018
472
  }
1019
- function actionCommandPreview(actionType, datasetName, workflowId, values) {
473
+ function actionCommandPreview(actionType, preparationName, methodId, values) {
1020
474
  if (actionType === "preparation-setup") {
1021
- const datasetPart = datasetName ? ` # Preparation: ${datasetName}` : "";
1022
- const pathPart = datasetSetupPathValue(values);
1023
- return pathPart ? `interf init # source: ${pathPart}${datasetPart}` : `interf init${datasetPart}`;
475
+ const preparationPart = preparationName ? ` # Preparation: ${preparationName}` : "";
476
+ const pathPart = preparationSetupPathValue(values);
477
+ const methodSuffix = methodId ? ` # Method: ${methodId}` : "";
478
+ const setupPreview = pathPart ? `interf init # source: ${pathPart}${preparationPart}` : `interf init${preparationPart}`;
479
+ if (booleanValue(values, "prepare_after_setup") && preparationName) {
480
+ return `${setupPreview}\ninterf compile --preparation ${preparationName}${methodSuffix}`;
481
+ }
482
+ return setupPreview;
1024
483
  }
1025
484
  if (actionType === "compile") {
1026
- const workflowSuffix = workflowId ? ` # Method: ${workflowId}` : "";
1027
- return datasetName
1028
- ? `interf compile --preparation ${datasetName}${workflowSuffix}`
1029
- : `interf compile${workflowSuffix}`;
485
+ const methodSuffix = methodId ? ` # Method: ${methodId}` : "";
486
+ return preparationName
487
+ ? `interf compile --preparation ${preparationName}${methodSuffix}`
488
+ : `interf compile${methodSuffix}`;
1030
489
  }
1031
490
  if (actionType === "test") {
1032
- const mode = testModeValue(values);
1033
- return datasetName
1034
- ? `interf test --preparation ${datasetName} --target ${mode}`
491
+ const mode = testModeCliTarget(testModeValue(values));
492
+ return preparationName
493
+ ? `interf test --preparation ${preparationName} --target ${mode}`
1035
494
  : `interf test --target ${mode}`;
1036
495
  }
1037
496
  if (actionType === "readiness-check-draft") {
@@ -1042,28 +501,31 @@ function actionCommandPreview(actionType, datasetName, workflowId, values) {
1042
501
  }
1043
502
  return "Try: create a Preparation, prepare, check readiness, draft readiness checks, or draft a Method.";
1044
503
  }
1045
- function hasCompiledTestTarget(sourcePath, datasetConfig) {
1046
- const compiledPath = portableContextPath(sourcePath, datasetConfig.name);
504
+ function hasCompiledTestTarget(sourcePath, preparationConfig) {
505
+ const compiledPath = portableContextPath(sourcePath, preparationConfig.name);
1047
506
  if (!existsSync(compiledPath))
1048
507
  return false;
1049
- return createCompiledTestTarget(compiledPath, datasetConfig.name, methodIdForSourcePreparationConfig(datasetConfig) ?? "interf").eligible;
508
+ return createCompiledTestTarget(compiledPath, preparationConfig.name, methodIdForSourcePreparationConfig(preparationConfig) ?? DEFAULT_METHOD_ID).eligible;
1050
509
  }
1051
- function actionAssistantMessage(actionType, datasetName, commandPreview) {
1052
- const datasetSuffix = datasetName ? ` for Preparation "${datasetName}"` : "";
510
+ function actionAssistantMessage(actionType, preparationName, commandPreview, options = {}) {
511
+ const preparationSuffix = preparationName ? ` for Preparation "${preparationName}"` : "";
1053
512
  if (actionType === "preparation-setup") {
1054
- return `Interf prepared a Preparation setup proposal${datasetSuffix}. Approve to save the source folder and create the portable-context scaffold. CLI equivalent: ${commandPreview}`;
513
+ if (options.prepareAfterSetup) {
514
+ return `Interf prepared a prepare proposal${preparationSuffix}. Approve to save the Preparation and run the selected Method against the Source Folder. CLI equivalent: ${commandPreview}`;
515
+ }
516
+ return `Interf prepared a Preparation setup proposal${preparationSuffix}. Approve to save the source folder as a Preparation. Preparing portable context is a separate compile run. CLI equivalent: ${commandPreview}`;
1055
517
  }
1056
518
  if (actionType === "compile") {
1057
- return `Interf prepared a prepare-run proposal${datasetSuffix}. Approve to submit it through the local Interf service and watch the run in Interf. CLI equivalent: ${commandPreview}`;
519
+ return `Interf prepared a prepare-run proposal${preparationSuffix}. Approve to submit it through the local Interf service and watch the run in Interf. CLI equivalent: ${commandPreview}`;
1058
520
  }
1059
521
  if (actionType === "test") {
1060
- return `Interf prepared a readiness-check proposal${datasetSuffix}. Approve to run the requested target against saved readiness checks. CLI equivalent: ${commandPreview}`;
522
+ return `Interf prepared a readiness-check proposal${preparationSuffix}. Approve to run the requested target against saved readiness checks. CLI equivalent: ${commandPreview}`;
1061
523
  }
1062
524
  if (actionType === "readiness-check-draft") {
1063
- return `Interf prepared a readiness-check draft proposal${datasetSuffix}. Approve to ask the configured local executor to draft checks as a visible run. CLI equivalent: ${commandPreview}`;
525
+ return `Interf prepared a readiness-check draft proposal${preparationSuffix}. Approve to ask the configured local executor to draft checks as a visible run. CLI equivalent: ${commandPreview}`;
1064
526
  }
1065
527
  if (actionType === "method-authoring" || actionType === "method-improvement") {
1066
- return `Interf prepared a Method draft proposal${datasetSuffix}. Approve to draft a reusable local Method as a visible run. CLI equivalent: ${commandPreview}`;
528
+ return `Interf prepared a Method draft proposal${preparationSuffix}. Approve to draft a reusable local Method as a visible run. CLI equivalent: ${commandPreview}`;
1067
529
  }
1068
530
  return "I could not map that to a safe Interf action. Ask for one action in plain English, such as create a Preparation, prepare the data, check readiness, draft readiness checks, or draft a Method.";
1069
531
  }
@@ -1111,27 +573,25 @@ function readinessStateToPreparationReadiness(readiness) {
1111
573
  checks: readiness.checks.map((check) => ({ ...check })),
1112
574
  });
1113
575
  }
1114
- function datasetResourceToPreparationResource(rootPath, resource) {
1115
- const latestCompileRunId = resource.latest_compile_run_id ?? null;
1116
- const latestTestRunId = resource.latest_test_run_id ?? null;
1117
- const methodId = methodIdForSourcePreparationConfig(resource.dataset);
576
+ function buildPreparationResource(rootPath, preparation, readiness, latestCompileRunId, latestTestRunId) {
577
+ const methodId = methodIdForSourcePreparationConfig(preparation);
1118
578
  return PreparationResourceSchema.parse({
1119
- id: resource.dataset.name,
1120
- name: resource.dataset.name,
1121
- preparation: resource.dataset,
1122
- source_path: resolveSourceDatasetPath(rootPath, resource.dataset),
579
+ id: preparation.name,
580
+ name: preparation.name,
581
+ preparation,
582
+ source_path: resolveSourcePreparationPath(rootPath, preparation),
1123
583
  method_id: methodId,
1124
- checks: resource.dataset.checks,
584
+ checks: preparation.checks,
1125
585
  portable_context: {
1126
- preparation: resource.dataset.name,
1127
- path: resource.portable_context_path,
1128
- exists: resource.portable_context_path !== null,
586
+ preparation: preparation.name,
587
+ path: readiness.portable_context_path,
588
+ exists: readiness.portable_context_path !== null,
1129
589
  method_id: methodId,
1130
590
  latest_compile_run_id: latestCompileRunId,
1131
591
  latest_test_run_id: latestTestRunId,
1132
592
  },
1133
- portable_context_path: resource.portable_context_path,
1134
- readiness: readinessStateToPreparationReadiness(resource.readiness),
593
+ portable_context_path: readiness.portable_context_path,
594
+ readiness: readinessStateToPreparationReadiness(readiness),
1135
595
  runs: {
1136
596
  latest_compile_run_id: latestCompileRunId,
1137
597
  latest_test_run_id: latestTestRunId,
@@ -1140,7 +600,7 @@ function datasetResourceToPreparationResource(rootPath, resource) {
1140
600
  latest_test_run_id: latestTestRunId,
1141
601
  });
1142
602
  }
1143
- function workflowPackageResourceToMethodResource(resource) {
603
+ function buildMethodResource(resource) {
1144
604
  return MethodResourceSchema.parse({
1145
605
  id: resource.id,
1146
606
  method_id: resource.id,
@@ -1149,7 +609,7 @@ function workflowPackageResourceToMethodResource(resource) {
1149
609
  ...(resource.hint ? { hint: resource.hint } : {}),
1150
610
  source_kind: resource.source_kind,
1151
611
  built_in: resource.built_in,
1152
- active_for_preparations: resource.active_for_datasets,
612
+ active_for_preparations: resource.active_for_preparations,
1153
613
  stages: resource.stages,
1154
614
  });
1155
615
  }
@@ -1183,31 +643,17 @@ export class LocalServiceRuntime {
1183
643
  ...(this.packageVersion ? { package_version: this.packageVersion } : {}),
1184
644
  });
1185
645
  }
1186
- listDatasets() {
646
+ listPreparations() {
1187
647
  const config = loadSourceFolderConfig(this.rootPath);
1188
- return listSourceDatasetConfigs(config).map((dataset) => {
1189
- const compileRuns = this.listCompileRunsForDataset(dataset.name);
1190
- const testRuns = this.listTestRunsForDataset(dataset.name);
1191
- const path = portableContextPath(this.rootPath, dataset.name);
1192
- const readiness = this.computeDatasetReadiness(dataset);
1193
- return DatasetResourceSchema.parse({
1194
- dataset,
1195
- portable_context_path: existsSync(path) ? path : null,
1196
- readiness,
1197
- latest_compile_run_id: compileRuns[0]?.run_id ?? null,
1198
- latest_test_run_id: testRuns[0]?.run_id ?? null,
1199
- });
648
+ return listSourcePreparationConfigs(config).map((preparation) => {
649
+ const compileRuns = this.listCompileRunsForPreparation(preparation.name);
650
+ const testRuns = this.listTestRunsForPreparation(preparation.name);
651
+ const readiness = this.computePreparationReadiness(preparation);
652
+ return buildPreparationResource(this.rootPath, preparation, readiness, compileRuns[0]?.run_id ?? null, testRuns[0]?.run_id ?? null);
1200
653
  });
1201
654
  }
1202
- getDataset(datasetName) {
1203
- return this.listDatasets().find((dataset) => dataset.dataset.name === datasetName) ?? null;
1204
- }
1205
- listPreparations() {
1206
- return this.listDatasets().map((resource) => datasetResourceToPreparationResource(this.rootPath, resource));
1207
- }
1208
655
  getPreparation(preparationName) {
1209
- const dataset = this.getDataset(preparationName);
1210
- return dataset ? datasetResourceToPreparationResource(this.rootPath, dataset) : null;
656
+ return this.listPreparations().find((preparation) => preparation.name === preparationName) ?? null;
1211
657
  }
1212
658
  listPreparationReadiness() {
1213
659
  return this.listReadiness().map(readinessStateToPreparationReadiness);
@@ -1218,21 +664,23 @@ export class LocalServiceRuntime {
1218
664
  }
1219
665
  listReadiness() {
1220
666
  const config = loadSourceFolderConfig(this.rootPath);
1221
- return listSourceDatasetConfigs(config).map((dataset) => this.computeDatasetReadiness(dataset));
667
+ return listSourcePreparationConfigs(config).map((preparation) => this.computePreparationReadiness(preparation));
1222
668
  }
1223
- getReadiness(datasetName) {
1224
- const dataset = findSourceDatasetConfig(loadSourceFolderConfig(this.rootPath), datasetName);
1225
- return dataset ? this.computeDatasetReadiness(dataset) : null;
669
+ getReadiness(preparationName) {
670
+ const preparation = findSourcePreparationConfig(loadSourceFolderConfig(this.rootPath), preparationName);
671
+ return preparation ? this.computePreparationReadiness(preparation) : null;
1226
672
  }
1227
- computeDatasetReadiness(dataset) {
673
+ computePreparationReadiness(preparation) {
1228
674
  const generatedAt = new Date().toISOString();
1229
- const compiledPath = portableContextPath(this.rootPath, dataset.name);
675
+ const compiledPath = portableContextPath(this.rootPath, preparation.name);
1230
676
  const contextExists = existsSync(compiledPath);
1231
- const compileRun = this.listCompileRunsForDataset(dataset.name)[0] ?? null;
1232
- const testRun = this.listTestRunsForDataset(dataset.name)[0] ?? null;
1233
- const comparison = testRun?.comparison ?? this.readLatestComparison(dataset.name);
1234
- const configuredChecks = dataset.checks.length;
1235
- const currentFingerprint = configuredChecks > 0 ? fingerprintReadinessChecks(dataset.checks) : null;
677
+ const compiledTarget = createCompiledTestTarget(compiledPath, preparation.name, methodIdForSourcePreparationConfig(preparation) ?? DEFAULT_METHOD_ID);
678
+ const contextReady = compiledTarget.eligible;
679
+ const compileRun = this.listCompileRunsForPreparation(preparation.name)[0] ?? null;
680
+ const testRun = this.listTestRunsForPreparation(preparation.name)[0] ?? null;
681
+ const comparison = this.readLatestComparison(preparation.name);
682
+ const configuredChecks = preparation.checks.length;
683
+ const currentFingerprint = configuredChecks > 0 ? fingerprintReadinessChecks(preparation.checks) : null;
1236
684
  const comparisonFingerprint = comparison?.checks_fingerprint ?? null;
1237
685
  const sourceResult = readinessTargetResult(comparison?.raw, currentFingerprint, comparisonFingerprint);
1238
686
  const contextResult = readinessTargetResult(comparison?.compiled, currentFingerprint, comparisonFingerprint);
@@ -1244,19 +692,19 @@ export class LocalServiceRuntime {
1244
692
  ok: false,
1245
693
  status: "not-built",
1246
694
  summary: "No compile run has built portable context yet.",
1247
- artifact_path: contextExists ? compiledPath : null,
695
+ artifact_path: contextReady ? compiledPath : null,
1248
696
  };
1249
697
  }
1250
698
  if (compileRun.status === "succeeded") {
1251
699
  return {
1252
700
  gate: "compile-run",
1253
- ok: contextExists,
1254
- status: contextExists ? "built" : "failed",
1255
- summary: contextExists
701
+ ok: contextReady,
702
+ status: contextReady ? "built" : "failed",
703
+ summary: contextReady
1256
704
  ? "Latest compile run built portable context."
1257
705
  : "Latest compile run finished, but portable context is missing.",
1258
706
  run_id: compileRun.run_id,
1259
- artifact_path: contextExists ? compiledPath : null,
707
+ artifact_path: contextReady ? compiledPath : null,
1260
708
  };
1261
709
  }
1262
710
  if (compileRun.status === "queued" || compileRun.status === "running") {
@@ -1277,7 +725,7 @@ export class LocalServiceRuntime {
1277
725
  ? "Latest compile run was cancelled."
1278
726
  : "Latest compile run failed.",
1279
727
  run_id: compileRun.run_id,
1280
- artifact_path: contextExists ? compiledPath : null,
728
+ artifact_path: contextReady ? compiledPath : null,
1281
729
  };
1282
730
  })();
1283
731
  const checks = [
@@ -1288,12 +736,12 @@ export class LocalServiceRuntime {
1288
736
  },
1289
737
  {
1290
738
  gate: "portable-context",
1291
- ok: contextExists,
1292
- status: contextExists ? "built" : "not-built",
1293
- summary: contextExists
1294
- ? "Portable context folder exists."
1295
- : "Portable context folder has not been created.",
1296
- artifact_path: contextExists ? compiledPath : null,
739
+ ok: contextReady,
740
+ status: contextReady ? "built" : "not-built",
741
+ summary: contextReady
742
+ ? "Portable context is built."
743
+ : "Portable context has not been built.",
744
+ artifact_path: contextReady ? compiledPath : null,
1297
745
  },
1298
746
  compileCheck,
1299
747
  {
@@ -1320,7 +768,7 @@ export class LocalServiceRuntime {
1320
768
  return "checking";
1321
769
  if (compileRun?.status === "failed" || compileRun?.status === "cancelled")
1322
770
  return "failed";
1323
- if (!compileRun || !contextExists)
771
+ if (!compileRun || !contextReady)
1324
772
  return "not-built";
1325
773
  if (configuredChecks === 0)
1326
774
  return "not-configured";
@@ -1335,11 +783,11 @@ export class LocalServiceRuntime {
1335
783
  kind: "interf-readiness-state",
1336
784
  version: 1,
1337
785
  generated_at: generatedAt,
1338
- preparation: dataset.name,
786
+ preparation: preparation.name,
1339
787
  status,
1340
788
  ready,
1341
789
  summary: readinessSummaryForStatus(status),
1342
- portable_context_path: contextExists ? compiledPath : null,
790
+ portable_context_path: contextReady ? compiledPath : null,
1343
791
  latest_compile_run_id: compileRun?.run_id ?? null,
1344
792
  latest_test_run_id: testRun?.run_id ?? null,
1345
793
  compile: compileCheck,
@@ -1353,12 +801,12 @@ export class LocalServiceRuntime {
1353
801
  checks,
1354
802
  });
1355
803
  }
1356
- listSourceFiles(datasetName) {
1357
- const datasets = listSourceDatasetConfigs(loadSourceFolderConfig(this.rootPath))
1358
- .filter((dataset) => !datasetName || dataset.name === datasetName);
1359
- return datasets.flatMap((dataset) => {
1360
- const sourceFolderPath = resolveSourceDatasetPath(this.rootPath, dataset);
1361
- const compiledPath = portableContextPath(this.rootPath, dataset.name);
804
+ listSourceFiles(preparationName) {
805
+ const preparations = listSourcePreparationConfigs(loadSourceFolderConfig(this.rootPath))
806
+ .filter((preparation) => !preparationName || preparation.name === preparationName);
807
+ return preparations.flatMap((preparation) => {
808
+ const sourceFolderPath = resolveSourcePreparationPath(this.rootPath, preparation);
809
+ const compiledPath = portableContextPath(this.rootPath, preparation.name);
1362
810
  return discoverSourceFiles(sourceFolderPath, compiledPath).sourceFiles.map((relativePath) => {
1363
811
  const absolutePath = join(sourceFolderPath, relativePath);
1364
812
  let sizeBytes = 0;
@@ -1373,7 +821,7 @@ export class LocalServiceRuntime {
1373
821
  modifiedAt = null;
1374
822
  }
1375
823
  return SourceFileResourceSchema.parse({
1376
- preparation: dataset.name,
824
+ preparation: preparation.name,
1377
825
  path: relativePath,
1378
826
  absolute_path: absolutePath,
1379
827
  size_bytes: sizeBytes,
@@ -1406,24 +854,22 @@ export class LocalServiceRuntime {
1406
854
  });
1407
855
  });
1408
856
  }
1409
- listWorkflowPackages() {
1410
- const datasets = listSourceDatasetConfigs(loadSourceFolderConfig(this.rootPath));
1411
- const choices = listCompiledWorkflowChoices(this.rootPath);
1412
- const hasLocalDefault = choices.some((workflow) => workflow.scope === "local" && workflow.id === "interf-default");
1413
- const implicitDefaultWorkflowId = hasLocalDefault ? "interf-default" : "interf";
1414
- return choices.filter((workflow) => !(hasLocalDefault && workflow.scope === "builtin" && workflow.id === "interf")).map((workflow) => {
1415
- const activeForDatasets = datasets
1416
- .filter((dataset) => (methodIdForSourcePreparationConfig(dataset) ?? implicitDefaultWorkflowId) === workflow.id)
1417
- .map((dataset) => dataset.name);
1418
- return WorkflowPackageResourceSchema.parse({
1419
- id: workflow.id,
1420
- path: resolveWorkflowPackageSourcePath(this.rootPath, workflow.id) ?? workflow.id,
1421
- label: workflow.label,
1422
- hint: workflow.hint,
1423
- source_kind: workflow.scope === "builtin" ? "builtin" : "local",
1424
- built_in: workflow.scope === "builtin",
1425
- active_for_datasets: activeForDatasets,
1426
- stages: workflow.stages.map((stage) => ({
857
+ listMethods() {
858
+ const preparations = listSourcePreparationConfigs(loadSourceFolderConfig(this.rootPath));
859
+ const choices = listCompiledMethodChoices(this.rootPath);
860
+ return choices.map((method) => {
861
+ const activeForPreparations = preparations
862
+ .filter((preparation) => (methodIdForSourcePreparationConfig(preparation) ?? DEFAULT_METHOD_ID) === method.id)
863
+ .map((preparation) => preparation.name);
864
+ return buildMethodResource({
865
+ id: method.id,
866
+ path: resolveMethodPackageSourcePath(this.rootPath, method.id) ?? method.id,
867
+ label: method.label,
868
+ hint: method.hint,
869
+ source_kind: method.scope === "builtin" ? "builtin" : "local",
870
+ built_in: method.scope === "builtin",
871
+ active_for_preparations: activeForPreparations,
872
+ stages: method.stages.map((stage) => ({
1427
873
  id: stage.id,
1428
874
  label: stage.label,
1429
875
  description: stage.description,
@@ -1436,15 +882,8 @@ export class LocalServiceRuntime {
1436
882
  });
1437
883
  });
1438
884
  }
1439
- getWorkflowPackage(workflowId) {
1440
- return this.listWorkflowPackages().find((workflow) => workflow.id === workflowId) ?? null;
1441
- }
1442
- listMethods() {
1443
- return this.listWorkflowPackages().map(workflowPackageResourceToMethodResource);
1444
- }
1445
885
  getMethod(methodId) {
1446
- const workflowPackage = this.getWorkflowPackage(methodId);
1447
- return workflowPackage ? workflowPackageResourceToMethodResource(workflowPackage) : null;
886
+ return this.listMethods().find((method) => method.id === methodId) ?? null;
1448
887
  }
1449
888
  listJobs() {
1450
889
  return newestJobFirst(listJsonFiles(localJobsRoot(this.rootPath))
@@ -1713,27 +1152,29 @@ export class LocalServiceRuntime {
1713
1152
  void this.runReadinessCheckDraftInBackground(request, job.run_id);
1714
1153
  return this.getJob(job.run_id) ?? job;
1715
1154
  }
1716
- async createDatasetSetupRun(requestValue) {
1717
- const request = DatasetSetupCreateRequestSchema.parse(requestValue);
1718
- const datasetConfig = request.preparation;
1719
- const methodId = methodIdForSourcePreparationConfig(datasetConfig) ?? "interf-default";
1720
- const sourceFolderPath = resolveSourceDatasetPath(this.rootPath, datasetConfig);
1721
- const outputPath = portableContextPath(this.rootPath, datasetConfig.name);
1155
+ async createPreparationSetupRun(requestValue) {
1156
+ const request = PreparationSetupCreateRequestSchema.parse(requestValue);
1157
+ const preparationConfig = request.preparation;
1158
+ const methodId = methodIdForSourcePreparationConfig(preparationConfig) ?? "interf-default";
1159
+ const normalizedPreparationConfig = {
1160
+ ...preparationConfig,
1161
+ method: methodId,
1162
+ };
1163
+ const sourceFolderPath = resolveSourcePreparationPath(this.rootPath, preparationConfig);
1722
1164
  const job = this.createJobRun({
1723
1165
  job_type: "preparation-setup",
1724
- title: `Create Preparation ${datasetConfig.name}`,
1725
- preparation: datasetConfig.name,
1166
+ title: `Create Preparation ${preparationConfig.name}`,
1167
+ preparation: preparationConfig.name,
1726
1168
  method: methodId,
1727
1169
  source_path: sourceFolderPath,
1728
- output_path: outputPath,
1729
1170
  agent: this.getExecutorStatus().executor,
1730
1171
  steps: [
1731
1172
  {
1732
1173
  id: "validate-source",
1733
1174
  label: "Validate source folder",
1734
1175
  input: {
1735
- preparation: datasetConfig.name,
1736
- path: datasetConfig.path,
1176
+ preparation: preparationConfig.name,
1177
+ path: preparationConfig.path,
1737
1178
  },
1738
1179
  },
1739
1180
  {
@@ -1743,14 +1184,6 @@ export class LocalServiceRuntime {
1743
1184
  config_path: join(this.rootPath, "interf", "interf.json"),
1744
1185
  },
1745
1186
  },
1746
- {
1747
- id: "prepare-scaffold",
1748
- label: "Prepare portable context",
1749
- input: {
1750
- output_path: outputPath,
1751
- method: methodId,
1752
- },
1753
- },
1754
1187
  ],
1755
1188
  });
1756
1189
  let activeStep = "validate-source";
@@ -1760,12 +1193,12 @@ export class LocalServiceRuntime {
1760
1193
  step_id: "validate-source",
1761
1194
  message: "Validating source folder.",
1762
1195
  input: {
1763
- path: datasetConfig.path,
1196
+ path: preparationConfig.path,
1764
1197
  source_folder_path: sourceFolderPath,
1765
1198
  },
1766
1199
  });
1767
1200
  if (!existsSync(sourceFolderPath) || !statSync(sourceFolderPath).isDirectory()) {
1768
- throw new Error(`Source folder "${datasetConfig.path}" is not available.`);
1201
+ throw new Error(`Source folder "${preparationConfig.path}" is not available.`);
1769
1202
  }
1770
1203
  this.appendJobRunEvent(job.run_id, {
1771
1204
  type: "step.completed",
@@ -1781,48 +1214,28 @@ export class LocalServiceRuntime {
1781
1214
  step_id: "write-config",
1782
1215
  message: "Saving Preparation in the control plane config.",
1783
1216
  input: {
1784
- preparation: datasetConfig.name,
1785
- path: datasetConfig.path,
1217
+ preparation: preparationConfig.name,
1218
+ path: preparationConfig.path,
1786
1219
  },
1787
1220
  });
1788
- upsertSourceDatasetConfig(this.rootPath, datasetConfig);
1221
+ upsertSourcePreparationConfig(this.rootPath, normalizedPreparationConfig);
1789
1222
  this.appendJobRunEvent(job.run_id, {
1790
1223
  type: "step.completed",
1791
1224
  step_id: "write-config",
1792
1225
  message: "Preparation config saved.",
1793
1226
  output: {
1794
1227
  config_path: join(this.rootPath, "interf", "interf.json"),
1795
- preparation: datasetConfig.name,
1796
- },
1797
- });
1798
- activeStep = "prepare-scaffold";
1799
- this.appendJobRunEvent(job.run_id, {
1800
- type: "step.started",
1801
- step_id: "prepare-scaffold",
1802
- message: "Preparing portable-context scaffold.",
1803
- input: {
1804
- output_path: outputPath,
1805
- method: methodId,
1806
- },
1807
- });
1808
- const compiledPath = ensurePortableContextScaffold(this.rootPath, datasetConfig.name, methodId);
1809
- syncCompiledInterfConfigFromSourceDatasetConfig(compiledPath, datasetConfig);
1810
- this.appendJobRunEvent(job.run_id, {
1811
- type: "step.completed",
1812
- step_id: "prepare-scaffold",
1813
- message: "Portable-context scaffold is ready.",
1814
- output: {
1815
- portable_context_path: compiledPath,
1228
+ preparation: preparationConfig.name,
1816
1229
  },
1817
1230
  });
1818
1231
  this.setJobRunResult(job.run_id, {
1819
- preparation: datasetConfig,
1232
+ preparation: normalizedPreparationConfig,
1820
1233
  source_folder_path: sourceFolderPath,
1821
- portable_context_path: compiledPath,
1234
+ config_path: join(this.rootPath, "interf", "interf.json"),
1822
1235
  });
1823
1236
  this.appendJobRunEvent(job.run_id, {
1824
1237
  type: "job.completed",
1825
- message: `Preparation ${datasetConfig.name} is ready for Interf runs.`,
1238
+ message: `Preparation ${preparationConfig.name} is saved. Run prepare to build portable context.`,
1826
1239
  });
1827
1240
  }
1828
1241
  catch (error) {
@@ -1842,8 +1255,8 @@ export class LocalServiceRuntime {
1842
1255
  }
1843
1256
  return this.getJob(job.run_id) ?? job;
1844
1257
  }
1845
- async createWorkflowAuthoringRun(requestValue) {
1846
- const request = WorkflowAuthoringCreateRequestSchema.parse(requestValue);
1258
+ async createMethodAuthoringRun(requestValue) {
1259
+ const request = MethodAuthoringCreateRequestSchema.parse(requestValue);
1847
1260
  const job = this.createJobRun({
1848
1261
  job_type: "method-authoring",
1849
1262
  title: `Draft Method ${request.method_id}`,
@@ -1908,25 +1321,26 @@ export class LocalServiceRuntime {
1908
1321
  task_prompt: request.task_prompt,
1909
1322
  },
1910
1323
  });
1911
- void this.runWorkflowAuthoringInBackground(request, job.run_id);
1324
+ void this.runMethodAuthoringInBackground(request, job.run_id);
1912
1325
  return this.getJob(job.run_id) ?? job;
1913
1326
  }
1914
1327
  listPortableContexts() {
1915
- return this.listDatasets().map((dataset) => this.getPortableContext(dataset.dataset.name))
1328
+ return listSourcePreparationConfigs(loadSourceFolderConfig(this.rootPath))
1329
+ .map((preparation) => this.getPortableContext(preparation.name))
1916
1330
  .filter((context) => context !== null);
1917
1331
  }
1918
- getPortableContext(datasetName) {
1919
- const dataset = findSourceDatasetConfig(loadSourceFolderConfig(this.rootPath), datasetName);
1920
- if (!dataset)
1332
+ getPortableContext(preparationName) {
1333
+ const preparation = findSourcePreparationConfig(loadSourceFolderConfig(this.rootPath), preparationName);
1334
+ if (!preparation)
1921
1335
  return null;
1922
- const path = portableContextPath(this.rootPath, dataset.name);
1336
+ const path = portableContextPath(this.rootPath, preparation.name);
1923
1337
  const config = readInterfConfig(path);
1924
- const compileRuns = this.listCompileRunsForDataset(dataset.name);
1925
- const testRuns = this.listTestRunsForDataset(dataset.name);
1926
- const readiness = this.computeDatasetReadiness(dataset);
1927
- const method = config?.method ?? config?.workflow ?? methodIdForSourcePreparationConfig(dataset);
1338
+ const compileRuns = this.listCompileRunsForPreparation(preparation.name);
1339
+ const testRuns = this.listTestRunsForPreparation(preparation.name);
1340
+ const readiness = this.computePreparationReadiness(preparation);
1341
+ const method = config?.method ?? methodIdForSourcePreparationConfig(preparation);
1928
1342
  return PortableContextResourceSchema.parse({
1929
- preparation: dataset.name,
1343
+ preparation: preparation.name,
1930
1344
  path,
1931
1345
  exists: existsSync(path),
1932
1346
  readiness,
@@ -1937,10 +1351,11 @@ export class LocalServiceRuntime {
1937
1351
  });
1938
1352
  }
1939
1353
  listCompileRuns() {
1940
- return newestCompileFirst(this.listDatasets().flatMap((dataset) => this.listCompileRunsForDataset(dataset.dataset.name))).map((run) => CompileRunResourceSchema.parse({ run }));
1354
+ return newestCompileFirst(listSourcePreparationConfigs(loadSourceFolderConfig(this.rootPath))
1355
+ .flatMap((preparation) => this.listCompileRunsForPreparation(preparation.name))).map((run) => CompileRunResourceSchema.parse({ run }));
1941
1356
  }
1942
- listCompileRunsForDataset(datasetName) {
1943
- const compiledPath = portableContextPath(this.rootPath, datasetName);
1357
+ listCompileRunsForPreparation(preparationName) {
1358
+ const compiledPath = portableContextPath(this.rootPath, preparationName);
1944
1359
  return newestCompileFirst(listJsonFiles(compileRunsRoot(compiledPath))
1945
1360
  .map(readCompileRunAt)
1946
1361
  .filter((run) => run !== null));
@@ -1971,47 +1386,50 @@ export class LocalServiceRuntime {
1971
1386
  }
1972
1387
  async createCompileRun(requestValue) {
1973
1388
  const request = CompileRunCreateRequestSchema.parse(requestValue);
1974
- const datasetConfig = this.resolveDatasetConfig(request.preparation, {
1389
+ const preparationConfig = this.resolvePreparationConfig(request.preparation, {
1975
1390
  method: request.method,
1976
1391
  max_attempts: request.max_attempts,
1977
1392
  max_loops: request.max_loops,
1978
1393
  });
1979
- const compiledPath = this.ensureCompiledForRun(datasetConfig);
1394
+ const compiledPath = this.ensureCompiledForRun(preparationConfig);
1980
1395
  const runId = createRunId("compile");
1981
1396
  const now = new Date().toISOString();
1982
- const workflow = getCompiledWorkflow(methodIdForSourcePreparationConfig(datasetConfig) ?? "interf", {
1397
+ const method = getCompiledMethod(methodIdForSourcePreparationConfig(preparationConfig) ?? DEFAULT_METHOD_ID, {
1983
1398
  sourcePath: this.rootPath,
1984
1399
  });
1985
- const stageTotal = workflow.stages.length;
1400
+ const stageTotal = method.stages.length;
1986
1401
  const run = CompileRunSchema.parse({
1987
1402
  kind: "interf-compile-run",
1988
1403
  version: 1,
1989
1404
  run_id: runId,
1990
1405
  status: "running",
1991
- preparation: datasetConfig.name,
1992
- method: workflow.id,
1406
+ preparation: preparationConfig.name,
1407
+ method: method.id,
1993
1408
  backend: "native",
1994
- source_path: resolveSourceDatasetPath(this.rootPath, datasetConfig),
1409
+ source_path: resolveSourcePreparationPath(this.rootPath, preparationConfig),
1995
1410
  portable_context_path: compiledPath,
1996
1411
  created_at: now,
1997
1412
  started_at: now,
1998
- stages: workflow.stages.map((stage, index) => ({
1999
- run_id: runId,
2000
- stage_id: stage.id,
2001
- stage_label: stage.label,
2002
- stage_index: index,
2003
- stage_total: stageTotal,
2004
- status: "queued",
2005
- contract: {
1413
+ stages: method.stages
1414
+ .map((stage, index) => {
1415
+ return {
1416
+ run_id: runId,
1417
+ stage_id: stage.id,
2006
1418
  stage_label: stage.label,
2007
1419
  stage_index: index,
2008
1420
  stage_total: stageTotal,
2009
- reads: stage.reads,
2010
- writes: stage.writes,
2011
- ...(stage.acceptance ? { acceptance: stage.acceptance } : {}),
2012
- },
2013
- artifacts: [],
2014
- })),
1421
+ status: "queued",
1422
+ contract: {
1423
+ stage_label: stage.label,
1424
+ stage_index: index,
1425
+ stage_total: stageTotal,
1426
+ reads: stage.reads,
1427
+ writes: stage.writes,
1428
+ ...(stage.acceptance ? { acceptance: stage.acceptance } : {}),
1429
+ },
1430
+ artifacts: [],
1431
+ };
1432
+ }),
2015
1433
  events: [],
2016
1434
  });
2017
1435
  this.writeCompileRun(compiledPath, run);
@@ -2020,8 +1438,8 @@ export class LocalServiceRuntime {
2020
1438
  event_id: createRunEventId("event"),
2021
1439
  run_id: runId,
2022
1440
  timestamp: now,
2023
- preparation: datasetConfig.name,
2024
- method: workflow.id,
1441
+ preparation: preparationConfig.name,
1442
+ method: method.id,
2025
1443
  portable_context_path: compiledPath,
2026
1444
  backend: "native",
2027
1445
  });
@@ -2032,17 +1450,18 @@ export class LocalServiceRuntime {
2032
1450
  runId,
2033
1451
  sourcePath: this.rootPath,
2034
1452
  compiledPath,
2035
- datasetConfig,
1453
+ preparationConfig,
2036
1454
  events: sink,
2037
1455
  });
2038
1456
  const saved = this.readCompileRun(compiledPath, runId) ?? run;
2039
1457
  return CompileRunResourceSchema.parse({ run: saved });
2040
1458
  }
2041
1459
  listTestRuns() {
2042
- return newestFirst(this.listDatasets().flatMap((dataset) => this.listTestRunsForDataset(dataset.dataset.name)));
1460
+ return newestFirst(listSourcePreparationConfigs(loadSourceFolderConfig(this.rootPath))
1461
+ .flatMap((preparation) => this.listTestRunsForPreparation(preparation.name)));
2043
1462
  }
2044
- listTestRunsForDataset(datasetName) {
2045
- const compiledPath = portableContextPath(this.rootPath, datasetName);
1463
+ listTestRunsForPreparation(preparationName) {
1464
+ const compiledPath = portableContextPath(this.rootPath, preparationName);
2046
1465
  return newestFirst(listJsonFiles(testRunsRoot(compiledPath))
2047
1466
  .map(readTestRunAt)
2048
1467
  .filter((run) => run !== null));
@@ -2052,15 +1471,15 @@ export class LocalServiceRuntime {
2052
1471
  }
2053
1472
  async createTestRun(requestValue) {
2054
1473
  const request = TestRunCreateRequestSchema.parse(requestValue);
2055
- const datasetConfig = this.resolveDatasetConfig(request.preparation);
2056
- const compiledPath = portableContextPath(this.rootPath, datasetConfig.name);
2057
- const compiledTarget = createCompiledTestTarget(compiledPath, datasetConfig.name, methodIdForSourcePreparationConfig(datasetConfig) ?? "interf");
1474
+ const preparationConfig = this.resolvePreparationConfig(request.preparation);
1475
+ const compiledPath = portableContextPath(this.rootPath, preparationConfig.name);
1476
+ const compiledTarget = createCompiledTestTarget(compiledPath, preparationConfig.name, methodIdForSourcePreparationConfig(preparationConfig) ?? DEFAULT_METHOD_ID);
2058
1477
  const runId = createRunId("test");
2059
1478
  const now = new Date().toISOString();
2060
1479
  const initial = TestRunResourceSchema.parse({
2061
1480
  run_id: runId,
2062
1481
  status: "running",
2063
- preparation: datasetConfig.name,
1482
+ preparation: preparationConfig.name,
2064
1483
  mode: request.mode,
2065
1484
  source_path: this.rootPath,
2066
1485
  portable_context_path: compiledTarget.eligible ? compiledPath : null,
@@ -2073,7 +1492,7 @@ export class LocalServiceRuntime {
2073
1492
  runId,
2074
1493
  sourcePath: this.rootPath,
2075
1494
  compiledPath,
2076
- datasetConfig,
1495
+ preparationConfig,
2077
1496
  }, initial);
2078
1497
  return initial;
2079
1498
  }
@@ -2120,7 +1539,7 @@ export class LocalServiceRuntime {
2120
1539
  throw new Error("No test-run handler is configured for this local service.");
2121
1540
  }
2122
1541
  const result = LocalRunHandlerResultSchema.parse(await this.handlers.createTestRun(request, context));
2123
- const comparison = this.readLatestComparison(context.datasetConfig.name);
1542
+ const comparison = result.comparison ?? this.readLatestComparison(context.preparationConfig.name);
2124
1543
  const resultEvent = comparison
2125
1544
  ? this.checksEvaluatedEvent(context.runId, comparison)
2126
1545
  : null;
@@ -2133,13 +1552,13 @@ export class LocalServiceRuntime {
2133
1552
  ...(!result.ok ? { error: result.error ?? "Readiness check failed." } : {}),
2134
1553
  });
2135
1554
  this.writeTestRun(context.compiledPath, nextWithoutReadiness);
2136
- const readiness = this.computeDatasetReadiness(context.datasetConfig);
1555
+ const readiness = this.computePreparationReadiness(context.preparationConfig);
2137
1556
  const next = TestRunResourceSchema.parse({
2138
1557
  ...nextWithoutReadiness,
2139
1558
  readiness,
2140
1559
  events: [
2141
1560
  ...nextWithoutReadiness.events,
2142
- this.readinessUpdatedEvent(context.runId, context.datasetConfig.name, readiness),
1561
+ this.readinessUpdatedEvent(context.runId, context.preparationConfig.name, readiness),
2143
1562
  ],
2144
1563
  });
2145
1564
  this.writeTestRun(context.compiledPath, next);
@@ -2152,11 +1571,11 @@ export class LocalServiceRuntime {
2152
1571
  error: error instanceof Error ? error.message : String(error),
2153
1572
  });
2154
1573
  this.writeTestRun(context.compiledPath, failedWithoutReadiness);
2155
- const readiness = this.computeDatasetReadiness(context.datasetConfig);
1574
+ const readiness = this.computePreparationReadiness(context.preparationConfig);
2156
1575
  const next = TestRunResourceSchema.parse({
2157
1576
  ...failedWithoutReadiness,
2158
1577
  readiness,
2159
- events: [this.readinessUpdatedEvent(context.runId, context.datasetConfig.name, readiness)],
1578
+ events: [this.readinessUpdatedEvent(context.runId, context.preparationConfig.name, readiness)],
2160
1579
  });
2161
1580
  this.writeTestRun(context.compiledPath, next);
2162
1581
  }
@@ -2213,12 +1632,12 @@ export class LocalServiceRuntime {
2213
1632
  });
2214
1633
  }
2215
1634
  }
2216
- async runWorkflowAuthoringInBackground(request, runId) {
1635
+ async runMethodAuthoringInBackground(request, runId) {
2217
1636
  try {
2218
- if (!this.handlers.createWorkflowAuthoringRun) {
1637
+ if (!this.handlers.createMethodAuthoringRun) {
2219
1638
  throw new Error("No Method-authoring handler is configured for this local service.");
2220
1639
  }
2221
- const result = WorkflowAuthoringResultSchema.parse(await this.handlers.createWorkflowAuthoringRun(request, this.jobRunContext(runId)));
1640
+ const result = MethodAuthoringResultSchema.parse(await this.handlers.createMethodAuthoringRun(request, this.jobRunContext(runId)));
2222
1641
  this.setJobRunResult(runId, result);
2223
1642
  this.appendJobRunEvent(runId, {
2224
1643
  type: result.status === "executor-failed" ? "step.failed" : "step.completed",
@@ -2295,12 +1714,12 @@ export class LocalServiceRuntime {
2295
1714
  },
2296
1715
  };
2297
1716
  }
2298
- defaultDatasetName() {
2299
- const dataset = listSourceDatasetConfigs(loadSourceFolderConfig(this.rootPath))[0];
2300
- if (!dataset) {
1717
+ defaultPreparationName() {
1718
+ const preparation = listSourcePreparationConfigs(loadSourceFolderConfig(this.rootPath))[0];
1719
+ if (!preparation) {
2301
1720
  throw new Error("No Preparation is saved in this control plane folder.");
2302
1721
  }
2303
- return dataset.name;
1722
+ return preparation.name;
2304
1723
  }
2305
1724
  async planActionProposal(request) {
2306
1725
  if (!this.handlers.planActionProposal) {
@@ -2310,17 +1729,17 @@ export class LocalServiceRuntime {
2310
1729
  assistant_message: "No local action planner is configured for this Interf Workspace.",
2311
1730
  });
2312
1731
  }
2313
- const datasets = listSourceDatasetConfigs(loadSourceFolderConfig(this.rootPath));
1732
+ const preparations = listSourcePreparationConfigs(loadSourceFolderConfig(this.rootPath));
2314
1733
  let rawPlan;
2315
1734
  try {
2316
1735
  rawPlan = await this.handlers.planActionProposal(request, {
2317
1736
  sourcePath: this.rootPath,
2318
- datasets,
2319
- preparationHealth: datasets.map((dataset) => {
2320
- const readinessChecks = dataset.checks?.length ?? 0;
2321
- const portableContextReady = hasCompiledTestTarget(this.rootPath, dataset);
1737
+ preparations,
1738
+ preparationHealth: preparations.map((preparation) => {
1739
+ const readinessChecks = preparation.checks?.length ?? 0;
1740
+ const portableContextReady = hasCompiledTestTarget(this.rootPath, preparation);
2322
1741
  return {
2323
- name: dataset.name,
1742
+ name: preparation.name,
2324
1743
  readiness_checks: readinessChecks,
2325
1744
  portable_context_ready: portableContextReady,
2326
1745
  can_check_readiness: readinessChecks > 0 && portableContextReady,
@@ -2342,7 +1761,7 @@ export class LocalServiceRuntime {
2342
1761
  assistant_message: ACTION_PLANNER_CLARIFICATION_MESSAGE,
2343
1762
  });
2344
1763
  }
2345
- const parsed = ActionProposalPlanSchema.safeParse(rawPlan);
1764
+ const parsed = ActionProposalPlanSchema.safeParse(sanitizeActionProposalPlan(rawPlan));
2346
1765
  if (parsed.success)
2347
1766
  return parsed.data;
2348
1767
  return ActionProposalPlanSchema.parse({
@@ -2351,9 +1770,9 @@ export class LocalServiceRuntime {
2351
1770
  assistant_message: ACTION_PLANNER_CLARIFICATION_MESSAGE,
2352
1771
  });
2353
1772
  }
2354
- buildDatasetSetupRequest(request, plan, values) {
1773
+ buildPreparationSetupRequest(request, plan, values) {
2355
1774
  const sourceFolderChoices = listSourceFolderChoices(this.rootPath);
2356
- const selectedPath = datasetSetupPathValue(values) ??
1775
+ const selectedPath = preparationSetupPathValue(values) ??
2357
1776
  (sourceFolderChoices.length === 1 ? sourceFolderChoices[0].value : null);
2358
1777
  if (!selectedPath) {
2359
1778
  return {
@@ -2362,30 +1781,33 @@ export class LocalServiceRuntime {
2362
1781
  }
2363
1782
  let normalizedPath;
2364
1783
  try {
2365
- normalizedPath = normalizeSourceDatasetPathForConfig(this.rootPath, selectedPath);
1784
+ normalizedPath = normalizeSourcePreparationPathForConfig(this.rootPath, selectedPath);
2366
1785
  }
2367
1786
  catch (error) {
2368
1787
  return {
2369
1788
  error: error instanceof Error ? error.message : String(error),
2370
1789
  };
2371
1790
  }
2372
- const explicitName = datasetSetupNameValue(values) ?? plan.preparation ?? request.preparation;
2373
- const datasetName = explicitName
1791
+ const explicitName = preparationSetupNameValue(values) ?? plan.preparation ?? request.preparation;
1792
+ const preparationName = explicitName
2374
1793
  ? slugFromText(explicitName)
2375
- : defaultDatasetNameForPath(normalizedPath);
2376
- const requestWorkflowId = stringValue(request.values, "method") ?? stringValue(request.values, "workflow");
2377
- const valueWorkflowId = stringValue(values, "method") ?? stringValue(values, "workflow");
2378
- const workflowId = requestWorkflowId ?? plan.method ?? valueWorkflowId ?? "interf-default";
1794
+ : defaultPreparationNameForPath(normalizedPath);
1795
+ const requestMethodId = stringValue(request.values, "method");
1796
+ const valueMethodId = stringValue(values, "method");
1797
+ const methodId = requestMethodId ?? plan.method ?? valueMethodId ?? "interf-default";
1798
+ const prepareAfterSetup = booleanValue(values, "prepare_after_setup") ?? false;
2379
1799
  try {
2380
1800
  return {
2381
- datasetName,
2382
- workflowId,
2383
- request: DatasetSetupCreateRequestSchema.parse({
1801
+ preparationName,
1802
+ methodId,
1803
+ prepareAfterSetup,
1804
+ request: PreparationSetupCreateRequestSchema.parse({
1805
+ prepare_after_setup: prepareAfterSetup,
2384
1806
  preparation: {
2385
- name: datasetName,
1807
+ name: preparationName,
2386
1808
  path: normalizedPath,
2387
1809
  about: stringValue(values, "about") ?? stringValue(values, "task_prompt") ?? request.message,
2388
- method: workflowId,
1810
+ method: methodId,
2389
1811
  checks: [],
2390
1812
  },
2391
1813
  }),
@@ -2399,7 +1821,9 @@ export class LocalServiceRuntime {
2399
1821
  }
2400
1822
  async buildActionProposal(request) {
2401
1823
  const plan = await this.planActionProposal(request);
2402
- const actionType = plan.action_type;
1824
+ const structuredPreparationSetup = PreparationSetupActionValuesSchema.safeParse(request.values);
1825
+ const actionType = structuredPreparationSetup.success ? "preparation-setup" : plan.action_type;
1826
+ const usePlannerText = plan.action_type === actionType;
2403
1827
  const now = new Date().toISOString();
2404
1828
  if (actionType === "clarification") {
2405
1829
  return ActionProposalResourceSchema.parse({
@@ -2433,7 +1857,7 @@ export class LocalServiceRuntime {
2433
1857
  ...(request.values ?? {}),
2434
1858
  };
2435
1859
  if (actionType === "preparation-setup") {
2436
- const setup = this.buildDatasetSetupRequest(request, plan, proposalValues);
1860
+ const setup = this.buildPreparationSetupRequest(request, plan, proposalValues);
2437
1861
  if ("error" in setup) {
2438
1862
  return ActionProposalResourceSchema.parse({
2439
1863
  kind: "interf-action-proposal",
@@ -2460,10 +1884,14 @@ export class LocalServiceRuntime {
2460
1884
  error: null,
2461
1885
  });
2462
1886
  }
2463
- const commandPreview = plan.command_preview ??
2464
- actionCommandPreview(actionType, setup.datasetName, setup.workflowId, {
2465
- ...proposalValues,
2466
- path: setup.request.preparation.path,
1887
+ const commandValues = {
1888
+ ...proposalValues,
1889
+ path: setup.request.preparation.path,
1890
+ prepare_after_setup: setup.prepareAfterSetup,
1891
+ };
1892
+ const commandPreview = (usePlannerText ? plan.command_preview : undefined) ??
1893
+ actionCommandPreview(actionType, setup.preparationName, setup.methodId, {
1894
+ ...commandValues,
2467
1895
  });
2468
1896
  return ActionProposalResourceSchema.parse({
2469
1897
  kind: "interf-action-proposal",
@@ -2471,13 +1899,17 @@ export class LocalServiceRuntime {
2471
1899
  proposal_id: createActionProposalId(),
2472
1900
  status: "awaiting_approval",
2473
1901
  action_type: actionType,
2474
- title: plan.title ?? `Create Preparation ${setup.datasetName}`,
2475
- summary: plan.summary ?? "Save this source folder as an Interf Preparation.",
2476
- assistant_message: plan.assistant_message ?? actionAssistantMessage(actionType, setup.datasetName, commandPreview),
1902
+ title: (usePlannerText ? plan.title : undefined) ?? (setup.prepareAfterSetup ? `Prepare ${setup.preparationName}` : `Create Preparation ${setup.preparationName}`),
1903
+ summary: (usePlannerText ? plan.summary : undefined) ?? (setup.prepareAfterSetup
1904
+ ? "Save this source folder as a Preparation and run the selected Method."
1905
+ : "Save this source folder as an Interf Preparation."),
1906
+ assistant_message: (usePlannerText ? plan.assistant_message : undefined) ?? actionAssistantMessage(actionType, setup.preparationName, commandPreview, {
1907
+ prepareAfterSetup: setup.prepareAfterSetup,
1908
+ }),
2477
1909
  command_preview: commandPreview,
2478
1910
  message: request.message,
2479
- preparation: setup.datasetName,
2480
- method: setup.workflowId,
1911
+ preparation: setup.preparationName,
1912
+ method: setup.methodId,
2481
1913
  request: setup.request,
2482
1914
  created_at: now,
2483
1915
  updated_at: now,
@@ -2488,18 +1920,16 @@ export class LocalServiceRuntime {
2488
1920
  error: null,
2489
1921
  });
2490
1922
  }
2491
- const datasetConfig = this.resolveDatasetConfig(plan.preparation ?? request.preparation ?? this.defaultDatasetName());
2492
- const datasetPath = resolveSourceDatasetPath(this.rootPath, datasetConfig);
2493
- const requestedWorkflowId = stringValue(request.values, "method_id") ??
2494
- stringValue(request.values, "method") ??
2495
- stringValue(request.values, "workflow");
2496
- const plannedWorkflowId = plan.method ??
1923
+ const preparationConfig = this.resolvePreparationConfig(plan.preparation ?? request.preparation ?? this.defaultPreparationName());
1924
+ const preparationPath = resolveSourcePreparationPath(this.rootPath, preparationConfig);
1925
+ const requestedMethodId = stringValue(request.values, "method_id") ??
1926
+ stringValue(request.values, "method");
1927
+ const plannedMethodId = plan.method ??
2497
1928
  stringValue(plan.values, "method_id") ??
2498
- stringValue(plan.values, "method") ??
2499
- stringValue(plan.values, "workflow");
2500
- const workflowId = actionType === "method-authoring"
2501
- ? requestedWorkflowId ?? plannedWorkflowId ?? workflowIdForProposal(request.message, proposalValues)
2502
- : requestedWorkflowId ?? plannedWorkflowId ?? methodIdForSourcePreparationConfig(datasetConfig);
1929
+ stringValue(plan.values, "method");
1930
+ const methodId = actionType === "method-authoring"
1931
+ ? requestedMethodId ?? plannedMethodId ?? methodIdForProposal(request.message, proposalValues)
1932
+ : requestedMethodId ?? plannedMethodId ?? methodIdForSourcePreparationConfig(preparationConfig);
2503
1933
  const clarifyResolvedAction = (options) => ActionProposalResourceSchema.parse({
2504
1934
  kind: "interf-action-proposal",
2505
1935
  version: 1,
@@ -2510,8 +1940,8 @@ export class LocalServiceRuntime {
2510
1940
  summary: options.summary,
2511
1941
  assistant_message: options.assistantMessage,
2512
1942
  message: request.message,
2513
- preparation: datasetConfig.name,
2514
- method: workflowId ?? null,
1943
+ preparation: preparationConfig.name,
1944
+ method: methodId ?? null,
2515
1945
  request: {
2516
1946
  message: request.message,
2517
1947
  ...(proposalValues ? { values: proposalValues } : {}),
@@ -2526,65 +1956,65 @@ export class LocalServiceRuntime {
2526
1956
  });
2527
1957
  if (actionType === "test") {
2528
1958
  const requestedMode = testModeFromValues(proposalValues);
2529
- const hasReadinessChecks = (datasetConfig.checks ?? []).length > 0;
2530
- const portableContextReady = hasCompiledTestTarget(this.rootPath, datasetConfig);
1959
+ const hasReadinessChecks = (preparationConfig.checks ?? []).length > 0;
1960
+ const portableContextReady = hasCompiledTestTarget(this.rootPath, preparationConfig);
2531
1961
  if (!hasReadinessChecks) {
2532
1962
  return clarifyResolvedAction({
2533
- title: `Add readiness checks for ${datasetConfig.name}`,
1963
+ title: `Add readiness checks for ${preparationConfig.name}`,
2534
1964
  summary: "Readiness cannot be checked until this Preparation has saved checks.",
2535
- assistantMessage: `Preparation "${datasetConfig.name}" does not have saved readiness checks yet. Ask me to draft readiness checks after the Source Folder is prepared, or add readiness guidance first.`,
1965
+ assistantMessage: `Preparation "${preparationConfig.name}" does not have saved readiness checks yet. Ask me to draft readiness checks after the Source Folder is prepared, or add readiness guidance first.`,
2536
1966
  });
2537
1967
  }
2538
1968
  if (!portableContextReady && requestedMode !== "raw") {
2539
1969
  return clarifyResolvedAction({
2540
- title: `Prepare ${datasetConfig.name} first`,
1970
+ title: `Prepare ${preparationConfig.name} first`,
2541
1971
  summary: "Readiness checks need portable context unless you explicitly ask for a source-files-only baseline.",
2542
- assistantMessage: `Preparation "${datasetConfig.name}" has no prepared portable context yet. Prepare it first; after that Interf can check readiness. If you specifically want a source-files-only baseline, ask for source files only.`,
1972
+ assistantMessage: `Preparation "${preparationConfig.name}" has no prepared portable context yet. Prepare it first; after that Interf can check readiness. If you specifically want a source-files-only baseline, ask for source files only.`,
2543
1973
  });
2544
1974
  }
2545
1975
  }
2546
1976
  const actionRequest = (() => {
2547
1977
  if (actionType === "compile") {
2548
1978
  return {
2549
- preparation: datasetConfig.name,
2550
- ...(workflowId ? { method: workflowId } : {}),
1979
+ preparation: preparationConfig.name,
1980
+ ...(methodId ? { method: methodId } : {}),
2551
1981
  };
2552
1982
  }
2553
1983
  if (actionType === "test") {
2554
- const defaultMode = hasCompiledTestTarget(this.rootPath, datasetConfig) ? "both" : "raw";
1984
+ const defaultMode = hasCompiledTestTarget(this.rootPath, preparationConfig) ? "both" : "raw";
2555
1985
  return {
2556
- preparation: datasetConfig.name,
1986
+ preparation: preparationConfig.name,
2557
1987
  mode: testModeValue(proposalValues, defaultMode),
2558
1988
  };
2559
1989
  }
2560
1990
  if (actionType === "readiness-check-draft") {
2561
1991
  return {
2562
- preparation: datasetConfig.name,
2563
- source_folder_path: datasetPath,
2564
- about: stringValue(proposalValues, "about") ?? datasetConfig.about ?? request.message,
1992
+ preparation: preparationConfig.name,
1993
+ source_folder_path: preparationPath,
1994
+ about: stringValue(proposalValues, "about") ?? preparationConfig.about ?? request.message,
2565
1995
  target_count: Math.max(1, Math.min(8, Math.round(numberValue(proposalValues, "target_count") ?? 4))),
2566
1996
  };
2567
1997
  }
2568
1998
  return {
2569
- preparation: datasetConfig.name,
2570
- source_folder_path: datasetPath,
2571
- method_id: workflowId,
2572
- label: stringValue(proposalValues, "label") ?? `Custom ${datasetConfig.name}`,
1999
+ preparation: preparationConfig.name,
2000
+ source_folder_path: preparationPath,
2001
+ method_id: methodId,
2002
+ label: stringValue(proposalValues, "label") ?? `Custom ${preparationConfig.name}`,
2573
2003
  hint: stringValue(proposalValues, "hint") ?? request.message,
2574
2004
  task_prompt: actionValueMethodTaskPrompt(proposalValues) ?? stringValue(proposalValues, "task_prompt") ?? request.message,
2575
- checks: datasetConfig.checks ?? [],
2005
+ checks: preparationConfig.checks ?? [],
2576
2006
  };
2577
2007
  })();
2578
2008
  const title = (() => {
2579
2009
  if (plan.title)
2580
2010
  return plan.title;
2581
2011
  if (actionType === "compile")
2582
- return `Prepare ${datasetConfig.name}`;
2012
+ return `Prepare ${preparationConfig.name}`;
2583
2013
  if (actionType === "test")
2584
- return `Check readiness for ${datasetConfig.name}`;
2014
+ return `Check readiness for ${preparationConfig.name}`;
2585
2015
  if (actionType === "readiness-check-draft")
2586
- return `Draft readiness checks for ${datasetConfig.name}`;
2587
- return `Draft Method ${workflowId}`;
2016
+ return `Draft readiness checks for ${preparationConfig.name}`;
2017
+ return `Draft Method ${methodId}`;
2588
2018
  })();
2589
2019
  const summary = (() => {
2590
2020
  if (plan.summary)
@@ -2600,7 +2030,7 @@ export class LocalServiceRuntime {
2600
2030
  const previewValues = actionType === "test"
2601
2031
  ? { mode: actionRequest.mode }
2602
2032
  : proposalValues;
2603
- const commandPreview = plan.command_preview ?? actionCommandPreview(actionType, datasetConfig.name, workflowId, previewValues);
2033
+ const commandPreview = plan.command_preview ?? actionCommandPreview(actionType, preparationConfig.name, methodId, previewValues);
2604
2034
  return ActionProposalResourceSchema.parse({
2605
2035
  kind: "interf-action-proposal",
2606
2036
  version: 1,
@@ -2609,11 +2039,11 @@ export class LocalServiceRuntime {
2609
2039
  action_type: actionType,
2610
2040
  title,
2611
2041
  summary,
2612
- assistant_message: plan.assistant_message ?? actionAssistantMessage(actionType, datasetConfig.name, commandPreview),
2042
+ assistant_message: plan.assistant_message ?? actionAssistantMessage(actionType, preparationConfig.name, commandPreview),
2613
2043
  command_preview: commandPreview,
2614
2044
  message: request.message,
2615
- preparation: datasetConfig.name,
2616
- method: workflowId,
2045
+ preparation: preparationConfig.name,
2046
+ method: methodId,
2617
2047
  request: actionRequest,
2618
2048
  created_at: now,
2619
2049
  updated_at: now,
@@ -2643,7 +2073,17 @@ export class LocalServiceRuntime {
2643
2073
  };
2644
2074
  }
2645
2075
  if (proposal.action_type === "preparation-setup") {
2646
- const job = await this.createDatasetSetupRun(proposal.request);
2076
+ const job = await this.createPreparationSetupRun(proposal.request);
2077
+ if (proposal.request.prepare_after_setup) {
2078
+ const resource = await this.createCompileRun({
2079
+ preparation: proposal.request.preparation.name,
2080
+ method: methodIdForSourcePreparationConfig(proposal.request.preparation) ?? DEFAULT_METHOD_ID,
2081
+ });
2082
+ return {
2083
+ runId: resource.run.run_id,
2084
+ runType: "compile-run",
2085
+ };
2086
+ }
2647
2087
  return {
2648
2088
  runId: job.run_id,
2649
2089
  runType: "job-run",
@@ -2656,29 +2096,29 @@ export class LocalServiceRuntime {
2656
2096
  runType: "job-run",
2657
2097
  };
2658
2098
  }
2659
- const job = await this.createWorkflowAuthoringRun(proposal.request);
2099
+ const job = await this.createMethodAuthoringRun(proposal.request);
2660
2100
  return {
2661
2101
  runId: job.run_id,
2662
2102
  runType: "job-run",
2663
2103
  };
2664
2104
  }
2665
- resolveDatasetConfig(datasetName, overrides = {}) {
2666
- const dataset = findSourceDatasetConfig(loadSourceFolderConfig(this.rootPath), datasetName);
2667
- if (!dataset) {
2668
- throw new Error(`Preparation "${datasetName}" is not saved in this control plane folder.`);
2105
+ resolvePreparationConfig(preparationName, overrides = {}) {
2106
+ const preparation = findSourcePreparationConfig(loadSourceFolderConfig(this.rootPath), preparationName);
2107
+ if (!preparation) {
2108
+ throw new Error(`Preparation "${preparationName}" is not saved in this control plane folder.`);
2669
2109
  }
2670
- const method = overrides.method ?? overrides.workflow ?? methodIdForSourcePreparationConfig(dataset) ?? undefined;
2110
+ const method = overrides.method ?? methodIdForSourcePreparationConfig(preparation) ?? undefined;
2671
2111
  return {
2672
- ...dataset,
2112
+ ...preparation,
2673
2113
  ...(method ? { method } : {}),
2674
2114
  ...(typeof overrides.max_attempts === "number" ? { max_attempts: overrides.max_attempts } : {}),
2675
2115
  ...(typeof overrides.max_loops === "number" ? { max_loops: overrides.max_loops } : {}),
2676
2116
  };
2677
2117
  }
2678
- ensureCompiledForRun(datasetConfig) {
2679
- const workflowId = methodIdForSourcePreparationConfig(datasetConfig) ?? "interf";
2680
- const compiledPath = ensurePortableContextScaffold(this.rootPath, datasetConfig.name, workflowId);
2681
- syncCompiledInterfConfigFromSourceDatasetConfig(compiledPath, datasetConfig);
2118
+ ensureCompiledForRun(preparationConfig) {
2119
+ const methodId = methodIdForSourcePreparationConfig(preparationConfig) ?? DEFAULT_METHOD_ID;
2120
+ const compiledPath = ensurePortableContextScaffold(this.rootPath, preparationConfig.name, methodId);
2121
+ syncCompiledInterfConfigFromSourcePreparationConfig(compiledPath, preparationConfig);
2682
2122
  return compiledPath;
2683
2123
  }
2684
2124
  readCompileRun(compiledPath, runId) {
@@ -2802,12 +2242,8 @@ export class LocalServiceRuntime {
2802
2242
  });
2803
2243
  }
2804
2244
  }
2805
- readLatestComparison(datasetName) {
2806
- const latestPath = datasetLatestTestStatePath(this.rootPath, datasetName);
2807
- if (!existsSync(latestPath))
2808
- return null;
2809
- const parsed = TestRunComparisonSchema.safeParse(readJsonFile(latestPath));
2810
- return parsed.success ? parsed.data : null;
2245
+ readLatestComparison(preparationName) {
2246
+ return readSavedReadinessCheckRun(this.rootPath, preparationName);
2811
2247
  }
2812
2248
  checksEvaluatedEvent(runId, comparison) {
2813
2249
  const target = comparison.compiled ?? comparison.raw;