@interf/compiler 0.6.1 → 0.6.3

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 (341) hide show
  1. package/README.md +94 -74
  2. package/builtin-workflows/interf/README.md +5 -5
  3. package/builtin-workflows/interf/compile/stages/shape/SKILL.md +4 -4
  4. package/builtin-workflows/interf/improve/SKILL.md +2 -2
  5. package/builtin-workflows/interf/use/query/SKILL.md +1 -1
  6. package/builtin-workflows/interf/workflow.json +6 -6
  7. package/builtin-workflows/interf/workflow.schema.json +1 -1
  8. package/dist/bin.js +2 -28
  9. package/dist/{commands → cli/commands}/check-draft.d.ts +2 -2
  10. package/dist/{commands → cli/commands}/check-draft.js +12 -12
  11. package/dist/{commands → cli/commands}/compile-controller.d.ts +3 -3
  12. package/dist/{commands → cli/commands}/compile-controller.js +36 -34
  13. package/dist/{commands → cli/commands}/compile.d.ts +2 -2
  14. package/dist/{commands → cli/commands}/compile.js +15 -11
  15. package/dist/{commands → cli/commands}/compiled-flow.d.ts +3 -4
  16. package/dist/{commands → cli/commands}/compiled-flow.js +9 -14
  17. package/dist/{commands → cli/commands}/create-workflow-wizard.d.ts +3 -3
  18. package/dist/{commands → cli/commands}/create-workflow-wizard.js +61 -34
  19. package/dist/{commands → cli/commands}/create.d.ts +1 -1
  20. package/dist/{commands → cli/commands}/create.js +15 -18
  21. package/dist/{commands → cli/commands}/dataset-selection.d.ts +1 -1
  22. package/dist/{commands → cli/commands}/default.js +3 -3
  23. package/dist/{commands → cli/commands}/doctor.js +5 -6
  24. package/dist/{commands → cli/commands}/executor-flow.d.ts +1 -1
  25. package/dist/{commands → cli/commands}/executor-flow.js +13 -16
  26. package/dist/{commands → cli/commands}/init.d.ts +4 -1
  27. package/dist/{commands → cli/commands}/init.js +157 -72
  28. package/dist/{commands → cli/commands}/list.js +5 -5
  29. package/dist/{commands → cli/commands}/reset.js +4 -4
  30. package/dist/{commands → cli/commands}/source-config-wizard.d.ts +8 -3
  31. package/dist/{commands → cli/commands}/source-config-wizard.js +161 -87
  32. package/dist/{commands → cli/commands}/status.js +20 -11
  33. package/dist/{commands → cli/commands}/test-flow.d.ts +13 -4
  34. package/dist/{commands → cli/commands}/test-flow.js +30 -26
  35. package/dist/cli/commands/test.d.ts +14 -0
  36. package/dist/{commands → cli/commands}/test.js +39 -23
  37. package/dist/{commands → cli/commands}/verify.js +4 -4
  38. package/dist/cli/index.d.ts +21 -0
  39. package/dist/cli/index.js +33 -0
  40. package/dist/index.d.ts +22 -11
  41. package/dist/index.js +15 -6
  42. package/dist/lib/agent-args.d.ts +1 -4
  43. package/dist/lib/agent-args.js +1 -52
  44. package/dist/lib/agent-constants.d.ts +1 -5
  45. package/dist/lib/agent-constants.js +1 -28
  46. package/dist/lib/agent-detection.d.ts +1 -7
  47. package/dist/lib/agent-detection.js +1 -65
  48. package/dist/lib/agent-execution.d.ts +1 -2
  49. package/dist/lib/agent-execution.js +1 -243
  50. package/dist/lib/agent-logs.d.ts +1 -2
  51. package/dist/lib/agent-logs.js +1 -17
  52. package/dist/lib/agent-preflight.d.ts +1 -7
  53. package/dist/lib/agent-preflight.js +1 -77
  54. package/dist/lib/agent-render.d.ts +1 -8
  55. package/dist/lib/agent-render.js +1 -218
  56. package/dist/lib/agent-shells.d.ts +1 -69
  57. package/dist/lib/agent-shells.js +1 -1021
  58. package/dist/lib/agent-status.d.ts +1 -3
  59. package/dist/lib/agent-status.js +1 -58
  60. package/dist/lib/agent-types.d.ts +1 -30
  61. package/dist/lib/agent-types.js +1 -1
  62. package/dist/lib/agents.d.ts +1 -6
  63. package/dist/lib/agents.js +1 -5
  64. package/dist/lib/builtin-compiled-workflow.d.ts +1 -38
  65. package/dist/lib/builtin-compiled-workflow.js +1 -94
  66. package/dist/lib/compiled-compile.d.ts +1 -48
  67. package/dist/lib/compiled-compile.js +1 -255
  68. package/dist/lib/compiled-paths.d.ts +1 -40
  69. package/dist/lib/compiled-paths.js +3 -106
  70. package/dist/lib/compiled-raw.d.ts +1 -49
  71. package/dist/lib/compiled-raw.js +3 -102
  72. package/dist/lib/compiled-reset.d.ts +1 -2
  73. package/dist/lib/compiled-reset.js +3 -72
  74. package/dist/lib/compiled-schema.d.ts +1 -31
  75. package/dist/lib/compiled-schema.js +1 -141
  76. package/dist/lib/execution-profile.d.ts +1 -17
  77. package/dist/lib/execution-profile.js +1 -84
  78. package/dist/lib/executors.d.ts +1 -32
  79. package/dist/lib/executors.js +1 -43
  80. package/dist/lib/interf-bootstrap.d.ts +1 -3
  81. package/dist/lib/interf-bootstrap.js +3 -18
  82. package/dist/lib/interf-detect.d.ts +1 -33
  83. package/dist/lib/interf-detect.js +3 -176
  84. package/dist/lib/interf-scaffold.d.ts +1 -2
  85. package/dist/lib/interf-scaffold.js +3 -114
  86. package/dist/lib/interf-workflow-package.d.ts +1 -25
  87. package/dist/lib/interf-workflow-package.js +1 -342
  88. package/dist/lib/interf.d.ts +1 -5
  89. package/dist/lib/interf.js +3 -4
  90. package/dist/lib/local-workflows.d.ts +1 -54
  91. package/dist/lib/local-workflows.js +1 -422
  92. package/dist/lib/package-root.d.ts +1 -0
  93. package/dist/lib/package-root.js +1 -0
  94. package/dist/lib/project-paths.d.ts +1 -11
  95. package/dist/lib/project-paths.js +3 -32
  96. package/dist/lib/runtime-acceptance.d.ts +1 -9
  97. package/dist/lib/runtime-acceptance.js +1 -269
  98. package/dist/lib/runtime-contracts.d.ts +1 -2
  99. package/dist/lib/runtime-contracts.js +1 -48
  100. package/dist/lib/runtime-inventory.d.ts +1 -7
  101. package/dist/lib/runtime-inventory.js +1 -29
  102. package/dist/lib/runtime-paths.d.ts +1 -8
  103. package/dist/lib/runtime-paths.js +1 -26
  104. package/dist/lib/runtime-prompt.d.ts +1 -2
  105. package/dist/lib/runtime-prompt.js +1 -48
  106. package/dist/lib/runtime-reconcile.d.ts +1 -2
  107. package/dist/lib/runtime-reconcile.js +1 -193
  108. package/dist/lib/runtime-runs.d.ts +1 -11
  109. package/dist/lib/runtime-runs.js +1 -262
  110. package/dist/lib/runtime-types.d.ts +1 -43
  111. package/dist/lib/runtime-types.js +1 -1
  112. package/dist/lib/runtime.d.ts +1 -6
  113. package/dist/lib/runtime.js +1 -5
  114. package/dist/lib/schema.d.ts +4 -1073
  115. package/dist/lib/schema.js +6 -542
  116. package/dist/lib/source-config.d.ts +1 -39
  117. package/dist/lib/source-config.js +3 -293
  118. package/dist/lib/state-artifacts.d.ts +1 -8
  119. package/dist/lib/state-artifacts.js +1 -13
  120. package/dist/lib/state-health.d.ts +1 -4
  121. package/dist/lib/state-health.js +1 -132
  122. package/dist/lib/state-io.d.ts +1 -10
  123. package/dist/lib/state-io.js +1 -76
  124. package/dist/lib/state-paths.d.ts +1 -4
  125. package/dist/lib/state-paths.js +1 -13
  126. package/dist/lib/state-view.d.ts +1 -4
  127. package/dist/lib/state-view.js +1 -103
  128. package/dist/lib/state.d.ts +1 -7
  129. package/dist/lib/state.js +1 -12
  130. package/dist/lib/test-execution.d.ts +1 -14
  131. package/dist/lib/test-execution.js +3 -525
  132. package/dist/lib/test-matrices.d.ts +1 -90
  133. package/dist/lib/test-matrices.js +3 -96
  134. package/dist/lib/test-paths.d.ts +1 -12
  135. package/dist/lib/test-paths.js +3 -59
  136. package/dist/lib/test-profile-presets.d.ts +1 -57
  137. package/dist/lib/test-profile-presets.js +3 -50
  138. package/dist/lib/test-sandbox.d.ts +1 -11
  139. package/dist/lib/test-sandbox.js +3 -105
  140. package/dist/lib/test-specs.d.ts +1 -7
  141. package/dist/lib/test-specs.js +3 -114
  142. package/dist/lib/test-targets.d.ts +1 -5
  143. package/dist/lib/test-targets.js +3 -38
  144. package/dist/lib/test-types.d.ts +1 -17
  145. package/dist/lib/test-types.js +3 -1
  146. package/dist/lib/test.d.ts +1 -4
  147. package/dist/lib/test.js +3 -3
  148. package/dist/lib/validate-compiled.d.ts +1 -27
  149. package/dist/lib/validate-compiled.js +1 -241
  150. package/dist/lib/validate-helpers.d.ts +1 -12
  151. package/dist/lib/validate-helpers.js +1 -41
  152. package/dist/lib/validate.d.ts +1 -21
  153. package/dist/lib/validate.js +1 -249
  154. package/dist/lib/workflow-authoring.d.ts +1 -26
  155. package/dist/lib/workflow-authoring.js +1 -119
  156. package/dist/lib/workflow-definitions.d.ts +1 -78
  157. package/dist/lib/workflow-definitions.js +1 -203
  158. package/dist/lib/workflow-edit-session.d.ts +1 -16
  159. package/dist/lib/workflow-edit-session.js +1 -57
  160. package/dist/lib/workflow-edit-utils.d.ts +1 -10
  161. package/dist/lib/workflow-edit-utils.js +1 -39
  162. package/dist/lib/workflow-helpers.d.ts +1 -38
  163. package/dist/lib/workflow-helpers.js +1 -167
  164. package/dist/lib/workflow-improvement.d.ts +1 -22
  165. package/dist/lib/workflow-improvement.js +1 -209
  166. package/dist/lib/workflow-primitives.d.ts +1 -2
  167. package/dist/lib/workflow-primitives.js +1 -5
  168. package/dist/lib/workflow-review-paths.d.ts +1 -10
  169. package/dist/lib/workflow-review-paths.js +1 -27
  170. package/dist/lib/workflow-stage-policy.d.ts +1 -5
  171. package/dist/lib/workflow-stage-policy.js +1 -31
  172. package/dist/lib/workflow-stage-runner.d.ts +1 -41
  173. package/dist/lib/workflow-stage-runner.js +1 -109
  174. package/dist/lib/workflows.d.ts +1 -15
  175. package/dist/lib/workflows.js +1 -31
  176. package/dist/packages/agents/index.d.ts +17 -0
  177. package/dist/packages/agents/index.js +15 -0
  178. package/dist/packages/agents/lib/agents.d.ts +6 -0
  179. package/dist/packages/agents/lib/agents.js +5 -0
  180. package/dist/packages/agents/lib/args.d.ts +4 -0
  181. package/dist/packages/agents/lib/args.js +52 -0
  182. package/dist/packages/agents/lib/constants.d.ts +5 -0
  183. package/dist/packages/agents/lib/constants.js +28 -0
  184. package/dist/packages/agents/lib/detection.d.ts +7 -0
  185. package/dist/packages/agents/lib/detection.js +65 -0
  186. package/dist/packages/agents/lib/execution-profile.d.ts +17 -0
  187. package/dist/packages/agents/lib/execution-profile.js +84 -0
  188. package/dist/packages/agents/lib/execution.d.ts +2 -0
  189. package/dist/packages/agents/lib/execution.js +243 -0
  190. package/dist/packages/agents/lib/executors.d.ts +32 -0
  191. package/dist/packages/agents/lib/executors.js +45 -0
  192. package/dist/packages/agents/lib/logs.d.ts +2 -0
  193. package/dist/packages/agents/lib/logs.js +17 -0
  194. package/dist/packages/agents/lib/preflight.d.ts +7 -0
  195. package/dist/packages/agents/lib/preflight.js +77 -0
  196. package/dist/packages/agents/lib/render.d.ts +8 -0
  197. package/dist/packages/agents/lib/render.js +218 -0
  198. package/dist/packages/agents/lib/schema.d.ts +8 -0
  199. package/dist/packages/agents/lib/schema.js +7 -0
  200. package/dist/packages/agents/lib/shells.d.ts +69 -0
  201. package/dist/packages/agents/lib/shells.js +1021 -0
  202. package/dist/packages/agents/lib/status.d.ts +3 -0
  203. package/dist/packages/agents/lib/status.js +58 -0
  204. package/dist/packages/agents/lib/types.d.ts +30 -0
  205. package/dist/packages/agents/lib/types.js +1 -0
  206. package/dist/{lib → packages/agents/lib}/user-config.d.ts +1 -0
  207. package/dist/{lib → packages/agents/lib}/user-config.js +3 -2
  208. package/dist/packages/compiler/compiled-compile.d.ts +48 -0
  209. package/dist/packages/compiler/compiled-compile.js +256 -0
  210. package/dist/packages/compiler/compiled-schema.d.ts +31 -0
  211. package/dist/packages/compiler/compiled-schema.js +141 -0
  212. package/dist/packages/compiler/index.d.ts +24 -0
  213. package/dist/packages/compiler/index.js +23 -0
  214. package/dist/packages/compiler/lib/schema.d.ts +684 -0
  215. package/dist/packages/compiler/lib/schema.js +361 -0
  216. package/dist/packages/compiler/runtime-acceptance.d.ts +9 -0
  217. package/dist/packages/compiler/runtime-acceptance.js +269 -0
  218. package/dist/packages/compiler/runtime-contracts.d.ts +2 -0
  219. package/dist/packages/compiler/runtime-contracts.js +48 -0
  220. package/dist/packages/compiler/runtime-inventory.d.ts +7 -0
  221. package/dist/packages/compiler/runtime-inventory.js +29 -0
  222. package/dist/packages/compiler/runtime-paths.d.ts +8 -0
  223. package/dist/packages/compiler/runtime-paths.js +26 -0
  224. package/dist/packages/compiler/runtime-prompt.d.ts +2 -0
  225. package/dist/packages/compiler/runtime-prompt.js +48 -0
  226. package/dist/packages/compiler/runtime-reconcile.d.ts +2 -0
  227. package/dist/packages/compiler/runtime-reconcile.js +193 -0
  228. package/dist/packages/compiler/runtime-runs.d.ts +11 -0
  229. package/dist/packages/compiler/runtime-runs.js +262 -0
  230. package/dist/packages/compiler/runtime-types.d.ts +43 -0
  231. package/dist/packages/compiler/runtime-types.js +1 -0
  232. package/dist/packages/compiler/runtime.d.ts +6 -0
  233. package/dist/packages/compiler/runtime.js +5 -0
  234. package/dist/packages/compiler/state-artifacts.d.ts +8 -0
  235. package/dist/packages/compiler/state-artifacts.js +13 -0
  236. package/dist/packages/compiler/state-health.d.ts +4 -0
  237. package/dist/packages/compiler/state-health.js +132 -0
  238. package/dist/packages/compiler/state-io.d.ts +10 -0
  239. package/dist/packages/compiler/state-io.js +76 -0
  240. package/dist/packages/compiler/state-paths.d.ts +4 -0
  241. package/dist/packages/compiler/state-paths.js +13 -0
  242. package/dist/packages/compiler/state-view.d.ts +4 -0
  243. package/dist/packages/compiler/state-view.js +103 -0
  244. package/dist/packages/compiler/state.d.ts +7 -0
  245. package/dist/packages/compiler/state.js +12 -0
  246. package/dist/packages/compiler/validate-compiled.d.ts +27 -0
  247. package/dist/packages/compiler/validate-compiled.js +241 -0
  248. package/dist/packages/compiler/validate-helpers.d.ts +12 -0
  249. package/dist/packages/compiler/validate-helpers.js +41 -0
  250. package/dist/packages/compiler/validate.d.ts +21 -0
  251. package/dist/packages/compiler/validate.js +249 -0
  252. package/dist/packages/compiler/workflow-primitives.d.ts +2 -0
  253. package/dist/packages/compiler/workflow-primitives.js +5 -0
  254. package/dist/packages/compiler/workflows.d.ts +15 -0
  255. package/dist/packages/compiler/workflows.js +31 -0
  256. package/dist/packages/project-model/compiled-paths.d.ts +40 -0
  257. package/dist/packages/project-model/compiled-paths.js +106 -0
  258. package/dist/packages/project-model/compiled-raw.d.ts +49 -0
  259. package/dist/packages/project-model/compiled-raw.js +102 -0
  260. package/dist/packages/project-model/compiled-reset.d.ts +2 -0
  261. package/dist/packages/project-model/compiled-reset.js +72 -0
  262. package/dist/packages/project-model/index.d.ts +11 -0
  263. package/dist/packages/project-model/index.js +10 -0
  264. package/dist/packages/project-model/interf-bootstrap.d.ts +3 -0
  265. package/dist/packages/project-model/interf-bootstrap.js +18 -0
  266. package/dist/packages/project-model/interf-detect.d.ts +33 -0
  267. package/dist/packages/project-model/interf-detect.js +176 -0
  268. package/dist/packages/project-model/interf-scaffold.d.ts +2 -0
  269. package/dist/packages/project-model/interf-scaffold.js +124 -0
  270. package/dist/packages/project-model/interf.d.ts +5 -0
  271. package/dist/packages/project-model/interf.js +4 -0
  272. package/dist/packages/project-model/lib/schema.d.ts +125 -0
  273. package/dist/packages/project-model/lib/schema.js +62 -0
  274. package/dist/packages/project-model/project-paths.d.ts +11 -0
  275. package/dist/packages/project-model/project-paths.js +32 -0
  276. package/dist/packages/project-model/source-config.d.ts +38 -0
  277. package/dist/packages/project-model/source-config.js +297 -0
  278. package/dist/packages/testing/index.d.ts +13 -0
  279. package/dist/packages/testing/index.js +10 -0
  280. package/dist/packages/testing/lib/schema.d.ts +261 -0
  281. package/dist/packages/testing/lib/schema.js +119 -0
  282. package/dist/packages/testing/test-execution.d.ts +14 -0
  283. package/dist/packages/testing/test-execution.js +525 -0
  284. package/dist/packages/testing/test-matrices.d.ts +90 -0
  285. package/dist/packages/testing/test-matrices.js +96 -0
  286. package/dist/packages/testing/test-paths.d.ts +12 -0
  287. package/dist/packages/testing/test-paths.js +59 -0
  288. package/dist/packages/testing/test-profile-presets.d.ts +57 -0
  289. package/dist/packages/testing/test-profile-presets.js +50 -0
  290. package/dist/packages/testing/test-sandbox.d.ts +11 -0
  291. package/dist/packages/testing/test-sandbox.js +105 -0
  292. package/dist/packages/testing/test-specs.d.ts +7 -0
  293. package/dist/packages/testing/test-specs.js +114 -0
  294. package/dist/packages/testing/test-targets.d.ts +5 -0
  295. package/dist/packages/testing/test-targets.js +38 -0
  296. package/dist/packages/testing/test-types.d.ts +16 -0
  297. package/dist/packages/testing/test-types.js +1 -0
  298. package/dist/packages/testing/test.d.ts +4 -0
  299. package/dist/packages/testing/test.js +3 -0
  300. package/dist/packages/workflow-authoring/index.d.ts +4 -0
  301. package/dist/packages/workflow-authoring/index.js +4 -0
  302. package/dist/packages/workflow-authoring/lib/workflow-edit-utils.d.ts +10 -0
  303. package/dist/packages/workflow-authoring/lib/workflow-edit-utils.js +39 -0
  304. package/dist/packages/workflow-authoring/workflow-authoring.d.ts +26 -0
  305. package/dist/packages/workflow-authoring/workflow-authoring.js +120 -0
  306. package/dist/packages/workflow-authoring/workflow-edit-session.d.ts +16 -0
  307. package/dist/packages/workflow-authoring/workflow-edit-session.js +57 -0
  308. package/dist/packages/workflow-authoring/workflow-improvement.d.ts +23 -0
  309. package/dist/packages/workflow-authoring/workflow-improvement.js +209 -0
  310. package/dist/packages/workflow-package/builtin-compiled-workflow.d.ts +38 -0
  311. package/dist/packages/workflow-package/builtin-compiled-workflow.js +94 -0
  312. package/dist/packages/workflow-package/index.d.ts +9 -0
  313. package/dist/packages/workflow-package/index.js +9 -0
  314. package/dist/packages/workflow-package/interf-workflow-package.d.ts +25 -0
  315. package/dist/packages/workflow-package/interf-workflow-package.js +342 -0
  316. package/dist/{lib/config.d.ts → packages/workflow-package/lib/package-root.d.ts} +0 -1
  317. package/dist/packages/workflow-package/lib/package-root.js +6 -0
  318. package/dist/packages/workflow-package/local-workflows.d.ts +54 -0
  319. package/dist/packages/workflow-package/local-workflows.js +422 -0
  320. package/dist/packages/workflow-package/workflow-definitions.d.ts +78 -0
  321. package/dist/packages/workflow-package/workflow-definitions.js +203 -0
  322. package/dist/packages/workflow-package/workflow-helpers.d.ts +38 -0
  323. package/dist/packages/workflow-package/workflow-helpers.js +167 -0
  324. package/dist/packages/workflow-package/workflow-review-paths.d.ts +10 -0
  325. package/dist/packages/workflow-package/workflow-review-paths.js +27 -0
  326. package/dist/packages/workflow-package/workflow-stage-policy.d.ts +5 -0
  327. package/dist/packages/workflow-package/workflow-stage-policy.js +31 -0
  328. package/dist/packages/workflow-package/workflow-stage-runner.d.ts +41 -0
  329. package/dist/packages/workflow-package/workflow-stage-runner.js +109 -0
  330. package/package.json +43 -19
  331. package/dist/commands/test.d.ts +0 -3
  332. package/dist/lib/compiled-home.d.ts +0 -5
  333. package/dist/lib/compiled-home.js +0 -32
  334. package/dist/lib/config.js +0 -9
  335. /package/dist/{commands → cli/commands}/dataset-selection.js +0 -0
  336. /package/dist/{commands → cli/commands}/default.d.ts +0 -0
  337. /package/dist/{commands → cli/commands}/doctor.d.ts +0 -0
  338. /package/dist/{commands → cli/commands}/list.d.ts +0 -0
  339. /package/dist/{commands → cli/commands}/reset.d.ts +0 -0
  340. /package/dist/{commands → cli/commands}/status.d.ts +0 -0
  341. /package/dist/{commands → cli/commands}/verify.d.ts +0 -0
@@ -0,0 +1,361 @@
1
+ import { z } from "zod";
2
+ import { COMPILED_ZONE_KINDS, } from "../workflow-primitives.js";
3
+ const JsonRecordSchema = z.record(z.string(), z.unknown());
4
+ const COMPILED_RELATIVE_PATH_SEGMENT = /^(?!\.{1,2}$)[^/\\]+$/;
5
+ function isCompiledRelativePath(value) {
6
+ if (value.length === 0)
7
+ return false;
8
+ if (value.startsWith("/") || value.startsWith("\\"))
9
+ return false;
10
+ return value
11
+ .split(/[\\/]+/)
12
+ .every((segment) => COMPILED_RELATIVE_PATH_SEGMENT.test(segment));
13
+ }
14
+ export const RuntimeTargetTypeSchema = z.enum(["compiled"]);
15
+ export const TestTargetTypeSchema = z.enum(["compiled", "raw"]);
16
+ export const WorkflowIdPattern = /^[a-z0-9][a-z0-9-]{0,79}$/;
17
+ export const RuntimeStageSchema = z.string().regex(WorkflowIdPattern);
18
+ export const RuntimeContractTypeSchema = z.string().regex(WorkflowIdPattern);
19
+ export const WorkflowIdSchema = z.string().regex(WorkflowIdPattern);
20
+ export const WorkflowZoneIdSchema = z.string().regex(WorkflowIdPattern);
21
+ export const WorkflowCompiledZoneKindSchema = z.enum(COMPILED_ZONE_KINDS);
22
+ export const WorkflowZoneRoleSchema = z.enum(["input", "working", "output", "runtime"]);
23
+ export const CompiledStageStatusSchema = z.enum(["idle", "running", "succeeded", "failed"]);
24
+ export const SourceCompiledMaxAttemptsSchema = z.number().int().min(1).max(5);
25
+ export const SourceCompiledMaxLoopsSchema = z.number().int().min(1).max(3);
26
+ export const CompiledStageStateSchema = z.object({
27
+ contract_type: RuntimeContractTypeSchema.optional(),
28
+ status: CompiledStageStatusSchema.optional(),
29
+ started_at: z.string().nullable().optional(),
30
+ finished_at: z.string().nullable().optional(),
31
+ counts: z.record(z.string(), z.number()).optional(),
32
+ zone_counts: z.record(z.string(), z.number()).optional(),
33
+ artifacts: z.array(z.string()).optional(),
34
+ summary: z.string().nullable().optional(),
35
+ run_id: z.string().nullable().optional(),
36
+ });
37
+ export const CompiledStateSchema = z.object({
38
+ version: z.number().int().min(1),
39
+ pending: z.array(z.string()),
40
+ stages: z.record(z.string().regex(WorkflowIdPattern), CompiledStageStateSchema).optional(),
41
+ last_add: z.string().nullable().optional(),
42
+ last_compile: z.string().nullable().optional(),
43
+ warning_count: z.number().optional(),
44
+ error_count: z.number().optional(),
45
+ }).strict();
46
+ export const ViewSectionSchema = z.object({
47
+ id: z.string(),
48
+ type: z.enum(["status", "cards", "graph", "documents", "table"]),
49
+ title: z.string(),
50
+ path: z.string().optional(),
51
+ paths: z.array(z.string()).optional(),
52
+ });
53
+ export const ViewCardSchema = z.object({
54
+ id: z.string(),
55
+ label: z.string(),
56
+ metric: z.string(),
57
+ denominator_metric: z.string().optional(),
58
+ format: z.enum(["number", "fraction", "timestamp"]),
59
+ });
60
+ export const CompiledHealthSchema = z.object({
61
+ kind: z.literal("compiled-health"),
62
+ version: z.number().int().min(1),
63
+ generated_at: z.string(),
64
+ target_name: z.string(),
65
+ status: z.enum(["idle", "running", "compiled", "stale", "failed"]),
66
+ stage: z.union([
67
+ z.enum(["idle", "compiled", "failed"]),
68
+ RuntimeStageSchema,
69
+ ]),
70
+ summary: z.string(),
71
+ metrics: z.record(z.string(), z.number()),
72
+ checks: z.record(z.string(), z.boolean()),
73
+ });
74
+ export const CompiledViewSpecSchema = z.object({
75
+ kind: z.literal("compiled-view-spec"),
76
+ version: z.number().int().min(1),
77
+ generated_at: z.string(),
78
+ target_name: z.string(),
79
+ health_source: z.string(),
80
+ state_source: z.string(),
81
+ default_note: z.string().nullable(),
82
+ graph_scope: z.array(z.string()),
83
+ cards: z.array(ViewCardSchema),
84
+ sections: z.array(ViewSectionSchema),
85
+ });
86
+ export const CompiledRawSnapshotSchema = z.object({
87
+ kind: z.literal("compiled-raw-snapshot"),
88
+ version: z.literal(1),
89
+ generated_at: z.string(),
90
+ target_name: z.string(),
91
+ source_root: z.string(),
92
+ raw_root: z.string(),
93
+ source_total: z.number(),
94
+ sample_files: z.array(z.string()),
95
+ });
96
+ export const WorkflowPurposeSchema = z.object({
97
+ label: z.string().min(1),
98
+ task_hint: z.string().min(1),
99
+ }).strict();
100
+ export const WorkflowZoneSchema = z.object({
101
+ id: WorkflowZoneIdSchema,
102
+ role: WorkflowZoneRoleSchema,
103
+ path: z.string().min(1).refine(isCompiledRelativePath, {
104
+ message: "Zone paths must stay inside the compiled root",
105
+ }),
106
+ kind: WorkflowCompiledZoneKindSchema,
107
+ required: z.boolean(),
108
+ owned_by: z.array(z.string().regex(WorkflowIdPattern)),
109
+ description: z.string().min(1),
110
+ });
111
+ export const WorkflowCompiledZoneSchema = WorkflowZoneSchema;
112
+ export const WorkflowSchemaSchema = z.object({
113
+ kind: z.literal("workflow-schema"),
114
+ version: z.literal(1),
115
+ target_type: z.literal("compiled"),
116
+ label: z.string().min(1),
117
+ zones: z.array(WorkflowZoneSchema).min(1),
118
+ });
119
+ export const WorkflowCompiledSchemaSchema = WorkflowSchemaSchema;
120
+ export const WorkflowCompilerApiSchema = z.object({
121
+ kind: z.literal("compiled"),
122
+ version: z.literal(1),
123
+ });
124
+ export const WorkflowStageZoneAccessSchema = z.array(WorkflowZoneIdSchema).min(1);
125
+ export const ExecutionShellZoneMountSchema = z.object({
126
+ zone_id: WorkflowZoneIdSchema,
127
+ compiled_path: z.string(),
128
+ shell_root_path: z.string(),
129
+ input_mount_path: z.string().nullable(),
130
+ output_mount_path: z.string().nullable(),
131
+ });
132
+ export const ExecutionShellPathsSchema = z.object({
133
+ kind: z.literal("interf-execution-shell"),
134
+ version: z.literal(1),
135
+ workflow: WorkflowIdSchema,
136
+ stage: RuntimeStageSchema,
137
+ reads: z.array(ExecutionShellZoneMountSchema),
138
+ writes: z.array(ExecutionShellZoneMountSchema),
139
+ });
140
+ export const RuntimeExecutorInfoSchema = z.object({
141
+ kind: z.enum(["local-agent", "connected-provider", "managed"]),
142
+ name: z.string(),
143
+ display_name: z.string(),
144
+ command: z.string().nullable(),
145
+ model: z.string().nullable().optional(),
146
+ effort: z.string().nullable().optional(),
147
+ profile: z.string().nullable().optional(),
148
+ timeout_ms: z.number().nullable().optional(),
149
+ });
150
+ export const RuntimeStageInstructionsSchema = z.object({
151
+ stage_skill_dir: z.string().regex(WorkflowIdPattern),
152
+ effective_mode: z.enum(["builtin", "extend", "override"]),
153
+ local_mode: z.enum(["extend", "override"]).nullable(),
154
+ local_docs: z.array(z.string()),
155
+ mode_sources: z.array(z.string()),
156
+ }).strict();
157
+ export const RuntimeStageAcceptanceSchema = z.object({
158
+ artifacts_exist: z.array(z.string()).optional(),
159
+ stage_truthy: z.array(z.string()).optional(),
160
+ stage_equals_counts: z.record(z.string(), z.string()).optional(),
161
+ stage_at_least: z.record(z.string(), z.number()).optional(),
162
+ stage_at_least_counts: z.record(z.string(), z.string()).optional(),
163
+ zone_counts_at_least: z.record(z.string().regex(WorkflowIdPattern), z.number()).optional(),
164
+ zone_counts_at_least_counts: z.record(z.string().regex(WorkflowIdPattern), z.string()).optional(),
165
+ markdown_frontmatter_valid_zones: z.array(WorkflowZoneIdSchema).optional(),
166
+ frontmatter_required_keys_in_zones: z.record(WorkflowZoneIdSchema, z.array(z.string().min(1)).min(1)).optional(),
167
+ markdown_abstract_valid_zones: z.array(WorkflowZoneIdSchema).optional(),
168
+ wikilinks_valid_in_zones: z.array(WorkflowZoneIdSchema).optional(),
169
+ artifacts_must_not_contain: z.record(z.string(), z.array(z.string().min(1))).optional(),
170
+ }).strict();
171
+ export const RuntimeStageContractSchema = z.object({
172
+ kind: z.literal("interf-stage-contract"),
173
+ version: z.literal(1),
174
+ generated_at: z.string(),
175
+ run_id: z.string(),
176
+ target_type: RuntimeTargetTypeSchema,
177
+ target_name: z.string(),
178
+ workflow: z.object({
179
+ id: WorkflowIdSchema,
180
+ stage_index: z.number().nullable(),
181
+ stage_total: z.number(),
182
+ stages: z.array(RuntimeStageSchema),
183
+ }),
184
+ stage: RuntimeStageSchema,
185
+ stage_label: z.string(),
186
+ contract_type: RuntimeContractTypeSchema,
187
+ executor: RuntimeExecutorInfoSchema,
188
+ instructions: RuntimeStageInstructionsSchema,
189
+ counts: z.record(z.string(), z.number()),
190
+ acceptance: RuntimeStageAcceptanceSchema.optional(),
191
+ artifacts: z.object({
192
+ reads: z.array(z.string()),
193
+ writes: z.array(z.string()),
194
+ verifies: z.array(z.string()).optional(),
195
+ }),
196
+ policies: z.object({
197
+ execution_mode: z.literal("deterministic"),
198
+ status_prefixes: z.array(z.string()),
199
+ notes: z.array(z.string()),
200
+ evidence_weighting: z.object({
201
+ required_fields: z.array(z.string()),
202
+ preserve_tiers: z.boolean(),
203
+ }).optional(),
204
+ working_set: z.object({
205
+ target_context_fraction: z.number(),
206
+ strategy: z.string(),
207
+ }).optional(),
208
+ }),
209
+ });
210
+ export const RuntimeRunSchema = z.object({
211
+ kind: z.literal("interf-run"),
212
+ version: z.literal(1),
213
+ run_id: z.string(),
214
+ target_type: RuntimeTargetTypeSchema,
215
+ target_name: z.string(),
216
+ workflow: WorkflowIdSchema,
217
+ stage: RuntimeStageSchema,
218
+ stage_label: z.string(),
219
+ contract_type: RuntimeContractTypeSchema,
220
+ status: z.enum(["running", "succeeded", "failed"]),
221
+ executor: RuntimeExecutorInfoSchema,
222
+ started_at: z.string(),
223
+ updated_at: z.string(),
224
+ finished_at: z.string().nullable(),
225
+ contract_path: z.string(),
226
+ execution_path: z.string().optional(),
227
+ counts: z.record(z.string(), z.number()),
228
+ output_artifacts: z.array(z.string()),
229
+ logs: z.object({
230
+ prompt_path: z.string(),
231
+ event_stream_path: z.string(),
232
+ status_path: z.string().optional(),
233
+ }).optional(),
234
+ summary: z.string(),
235
+ exit_code: z.number().nullable(),
236
+ error: z.string().nullable(),
237
+ });
238
+ export const CompiledInventoryEntrySchema = z.object({
239
+ input_zone: WorkflowZoneIdSchema.optional(),
240
+ input_path: z.string().min(1).optional(),
241
+ output_zone: WorkflowZoneIdSchema,
242
+ output_path: z.string().min(1),
243
+ state: z.string().min(1).optional(),
244
+ metadata: JsonRecordSchema.optional(),
245
+ }).strict();
246
+ export const CompiledInventorySchema = z.object({
247
+ kind: z.literal("compiled-runtime-ledger").optional(),
248
+ version: z.number().int().min(1).optional(),
249
+ stage: RuntimeStageSchema.optional(),
250
+ entries: z.array(CompiledInventoryEntrySchema),
251
+ total: z.number().int().nonnegative(),
252
+ });
253
+ export const TestCaseExpectSchema = z.object({
254
+ must_include: z.array(z.string().min(1)).optional(),
255
+ must_include_one_of: z.array(z.array(z.string().min(1)).min(1)).optional(),
256
+ must_not_include: z.array(z.string().min(1)).optional(),
257
+ min_words: z.number().int().nonnegative().optional(),
258
+ max_words: z.number().int().nonnegative().optional(),
259
+ }).refine((value) => value.min_words === undefined ||
260
+ value.max_words === undefined ||
261
+ value.max_words >= value.min_words, {
262
+ message: "max_words must be greater than or equal to min_words",
263
+ }).refine((value) => (value.must_include?.length ?? 0) > 0 ||
264
+ (value.must_include_one_of?.length ?? 0) > 0 ||
265
+ (value.must_not_include?.length ?? 0) > 0 ||
266
+ value.min_words !== undefined ||
267
+ value.max_words !== undefined, {
268
+ message: "Test expectations must include at least one check",
269
+ });
270
+ export const WorkflowImprovementLoopSummarySchema = z.object({
271
+ variation: z.number().int().min(1),
272
+ kind: z.enum(["baseline", "edited"]),
273
+ attempts_run: z.number().int().min(1),
274
+ passed: z.boolean(),
275
+ passed_questions: z.number().int().min(0),
276
+ total_questions: z.number().int().min(0),
277
+ failed_stage: z.string().nullable().optional(),
278
+ test_run_path: z.string().nullable().optional(),
279
+ test_sandbox_path: z.string().nullable().optional(),
280
+ summary: z.string().min(1),
281
+ });
282
+ export const WorkflowImprovementContextSchema = z.object({
283
+ kind: z.literal("interf-workflow-improvement-loop"),
284
+ version: z.literal(1),
285
+ generated_at: z.string(),
286
+ target_name: z.string(),
287
+ workflow_id: WorkflowIdSchema,
288
+ loop_index: z.number().int().min(1),
289
+ max_loops: SourceCompiledMaxLoopsSchema,
290
+ max_attempts: SourceCompiledMaxAttemptsSchema,
291
+ review_paths: z.object({
292
+ workflow_root: z.string(),
293
+ compiled_runtime: z.string().nullable(),
294
+ test_comparisons: z.string().nullable(),
295
+ execution_shells: z.string().nullable(),
296
+ test_runs: z.string().nullable(),
297
+ test_sandboxes: z.string().nullable(),
298
+ }),
299
+ truth_checks: z.object({
300
+ count: z.number().int().min(0),
301
+ questions: z.array(z.object({
302
+ id: z.string(),
303
+ question: z.string(),
304
+ })),
305
+ }),
306
+ previous_variations: z.array(WorkflowImprovementLoopSummarySchema),
307
+ latest_failure: WorkflowImprovementLoopSummarySchema.nullable(),
308
+ });
309
+ export const PreservedShellTypeSchema = z.enum([
310
+ "stage-execution",
311
+ "workflow-improvement",
312
+ ]);
313
+ export const PreservedShellSnapshotSchema = z.object({
314
+ kind: z.literal("interf-preserved-shell"),
315
+ version: z.literal(1),
316
+ shell_type: PreservedShellTypeSchema,
317
+ generated_at: z.string(),
318
+ root_path: z.string(),
319
+ materialized_symlinks: z.number().int().min(0),
320
+ });
321
+ export const WorkflowPackageValidationSchema = z.object({
322
+ ok: z.boolean(),
323
+ summary: z.string(),
324
+ errors: z.array(z.string()),
325
+ counts: z.record(z.string(), z.number()),
326
+ });
327
+ export const WorkflowImprovementLoopRecordSchema = z.object({
328
+ kind: z.literal("interf-workflow-improvement-loop-record"),
329
+ version: z.literal(1),
330
+ recorded_at: z.string(),
331
+ run_id: z.string(),
332
+ loop_index: z.number().int().min(1),
333
+ target_name: z.string(),
334
+ workflow_id: WorkflowIdSchema,
335
+ result: z.enum(["updated", "no-change", "invalid", "executor-failed"]),
336
+ changed: z.boolean(),
337
+ applied: z.boolean(),
338
+ summary: z.string(),
339
+ shell_path: z.string(),
340
+ loop_root_path: z.string(),
341
+ context_path: z.string(),
342
+ workflow_before_path: z.string(),
343
+ workflow_after_path: z.string(),
344
+ prompt_log_path: z.string(),
345
+ event_log_path: z.string(),
346
+ status_log_path: z.string(),
347
+ preserved_shell_manifest_path: z.string().nullable(),
348
+ validation: WorkflowPackageValidationSchema.nullable(),
349
+ });
350
+ export const WorkflowImprovementRunLedgerSchema = z.object({
351
+ kind: z.literal("interf-workflow-improvement-run"),
352
+ version: z.literal(1),
353
+ generated_at: z.string(),
354
+ updated_at: z.string(),
355
+ run_id: z.string(),
356
+ target_name: z.string(),
357
+ workflow_id: WorkflowIdSchema,
358
+ max_loops: SourceCompiledMaxLoopsSchema,
359
+ max_attempts: SourceCompiledMaxAttemptsSchema,
360
+ loops: z.array(WorkflowImprovementLoopRecordSchema),
361
+ });
@@ -0,0 +1,9 @@
1
+ import { type CompiledState, type RuntimeStageAcceptance, type RuntimeStageContract } from "./lib/schema.js";
2
+ import { type RuntimeStageAcceptanceValidation } from "./runtime-types.js";
3
+ export declare function stageRecordFromState(state: CompiledState | null, stageId: string): Record<string, unknown> | null;
4
+ export declare function validateResolvedStageAcceptance(dirPath: string, options: {
5
+ stageId: string;
6
+ acceptance?: RuntimeStageAcceptance;
7
+ counts?: Record<string, number>;
8
+ }): RuntimeStageAcceptanceValidation;
9
+ export declare function validateStageContractAcceptance(dirPath: string, contract?: RuntimeStageContract | null): RuntimeStageAcceptanceValidation;
@@ -0,0 +1,269 @@
1
+ import { existsSync, } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { listFilesRecursive } from "../../lib/filesystem.js";
4
+ import { readJsonFileWithSchema } from "../../lib/parse.js";
5
+ import { WORKFLOW_SCHEMA_FILE, compiledZoneAbsolutePath, findCompiledSchemaZone, readCompiledSchemaFile, } from "./compiled-schema.js";
6
+ import { RuntimeStageContractSchema, } from "./lib/schema.js";
7
+ import { stageContractPath } from "./runtime-paths.js";
8
+ import { workflowPackagePathForCompiled } from "../project-model/compiled-paths.js";
9
+ import { loadState } from "./state-io.js";
10
+ import { countBrokenWikilinks, isOutputMarkdownFile, safeReadText, validateSynthFiles } from "./validate.js";
11
+ function toFiniteNumber(value) {
12
+ if (typeof value !== "number" || !Number.isFinite(value))
13
+ return null;
14
+ return value;
15
+ }
16
+ function hasAcceptanceRules(acceptance) {
17
+ if (!acceptance)
18
+ return false;
19
+ return (acceptance.artifacts_exist?.length ?? 0) > 0 ||
20
+ (acceptance.stage_truthy?.length ?? 0) > 0 ||
21
+ Object.keys(acceptance.stage_equals_counts ?? {}).length > 0 ||
22
+ Object.keys(acceptance.stage_at_least ?? {}).length > 0 ||
23
+ Object.keys(acceptance.stage_at_least_counts ?? {}).length > 0 ||
24
+ Object.keys(acceptance.zone_counts_at_least ?? {}).length > 0 ||
25
+ Object.keys(acceptance.zone_counts_at_least_counts ?? {}).length > 0 ||
26
+ (acceptance.markdown_frontmatter_valid_zones?.length ?? 0) > 0 ||
27
+ Object.keys(acceptance.frontmatter_required_keys_in_zones ?? {}).length > 0 ||
28
+ (acceptance.markdown_abstract_valid_zones?.length ?? 0) > 0 ||
29
+ (acceptance.wikilinks_valid_in_zones?.length ?? 0) > 0 ||
30
+ Object.keys(acceptance.artifacts_must_not_contain ?? {}).length > 0;
31
+ }
32
+ function readPathValue(record, keyPath) {
33
+ if (!record)
34
+ return undefined;
35
+ return keyPath
36
+ .split(".")
37
+ .filter((segment) => segment.length > 0)
38
+ .reduce((current, segment) => {
39
+ if (!current || typeof current !== "object" || Array.isArray(current))
40
+ return undefined;
41
+ return current[segment];
42
+ }, record);
43
+ }
44
+ function countZoneArtifacts(compiledPath, zonePath, kind) {
45
+ const absolutePath = compiledZoneAbsolutePath(compiledPath, { path: zonePath });
46
+ if (!existsSync(absolutePath))
47
+ return 0;
48
+ if (kind === "file")
49
+ return 1;
50
+ return listFilesRecursive(absolutePath).length;
51
+ }
52
+ function markdownFilesForZone(compiledPath, zonePath, kind) {
53
+ const absolutePath = compiledZoneAbsolutePath(compiledPath, { path: zonePath });
54
+ if (!existsSync(absolutePath))
55
+ return [];
56
+ if (kind === "file") {
57
+ return isOutputMarkdownFile(absolutePath) ? [absolutePath] : [];
58
+ }
59
+ return listFilesRecursive(absolutePath, isOutputMarkdownFile);
60
+ }
61
+ function zoneRoots(compiledPath, acceptanceZones) {
62
+ const schema = readCompiledSchemaFile(workflowPackagePathForCompiled(compiledPath));
63
+ if (!schema)
64
+ return [];
65
+ return acceptanceZones
66
+ .map((zoneId) => findCompiledSchemaZone(schema, zoneId))
67
+ .filter((zone) => zone !== null)
68
+ .map((zone) => compiledZoneAbsolutePath(compiledPath, zone));
69
+ }
70
+ function readArtifactText(compiledPath, relativePath) {
71
+ const artifactPath = join(compiledPath, relativePath);
72
+ if (!existsSync(artifactPath))
73
+ return null;
74
+ return safeReadText(artifactPath);
75
+ }
76
+ function resolveStageCounts(contract, stageRecord) {
77
+ const merged = { ...contract.counts };
78
+ const fromStage = stageRecord?.counts;
79
+ if (fromStage && typeof fromStage === "object" && !Array.isArray(fromStage)) {
80
+ for (const [key, value] of Object.entries(fromStage)) {
81
+ const numeric = toFiniteNumber(value);
82
+ if (numeric !== null)
83
+ merged[key] = numeric;
84
+ }
85
+ }
86
+ return merged;
87
+ }
88
+ export function stageRecordFromState(state, stageId) {
89
+ const stages = state?.stages;
90
+ if (!stages || typeof stages !== "object")
91
+ return null;
92
+ const stage = stages[stageId];
93
+ if (!stage || typeof stage !== "object" || Array.isArray(stage))
94
+ return null;
95
+ return stage;
96
+ }
97
+ export function validateResolvedStageAcceptance(dirPath, options) {
98
+ const acceptance = options.acceptance;
99
+ if (!hasAcceptanceRules(acceptance)) {
100
+ return {
101
+ ok: true,
102
+ summary: "No additional stage acceptance criteria were declared.",
103
+ failures: [],
104
+ };
105
+ }
106
+ const schema = readCompiledSchemaFile(workflowPackagePathForCompiled(dirPath));
107
+ if (!schema) {
108
+ return {
109
+ ok: false,
110
+ summary: `Stage acceptance failed for ${options.stageId}: missing workflow schema.`,
111
+ failures: [`Missing workflow/${WORKFLOW_SCHEMA_FILE}.`],
112
+ };
113
+ }
114
+ const failures = [];
115
+ const state = loadState(dirPath);
116
+ const stageRecord = stageRecordFromState(state, options.stageId);
117
+ const counts = options.counts ?? {};
118
+ for (const relativePath of acceptance?.artifacts_exist ?? []) {
119
+ if (!existsSync(join(dirPath, relativePath))) {
120
+ failures.push(`Missing required artifact: ${relativePath}.`);
121
+ }
122
+ }
123
+ for (const keyPath of acceptance?.stage_truthy ?? []) {
124
+ if (!readPathValue(stageRecord, keyPath)) {
125
+ failures.push(`Expected truthy stage value at "${keyPath}".`);
126
+ }
127
+ }
128
+ for (const [keyPath, countKey] of Object.entries(acceptance?.stage_equals_counts ?? {})) {
129
+ const actual = readPathValue(stageRecord, keyPath);
130
+ const expected = counts[countKey];
131
+ if (typeof expected !== "number") {
132
+ failures.push(`Acceptance references missing count "${countKey}" for "${keyPath}".`);
133
+ continue;
134
+ }
135
+ if (actual !== expected) {
136
+ failures.push(`Expected stage "${keyPath}" to equal count "${countKey}" (${expected}), got ${JSON.stringify(actual)}.`);
137
+ }
138
+ }
139
+ for (const [keyPath, minimum] of Object.entries(acceptance?.stage_at_least ?? {})) {
140
+ const actual = toFiniteNumber(readPathValue(stageRecord, keyPath));
141
+ if (actual === null || actual < minimum) {
142
+ failures.push(`Expected stage "${keyPath}" to be at least ${minimum}, got ${actual === null ? "non-numeric" : actual}.`);
143
+ }
144
+ }
145
+ for (const [keyPath, countKey] of Object.entries(acceptance?.stage_at_least_counts ?? {})) {
146
+ const actual = toFiniteNumber(readPathValue(stageRecord, keyPath));
147
+ const expected = counts[countKey];
148
+ if (typeof expected !== "number") {
149
+ failures.push(`Acceptance references missing count "${countKey}" for "${keyPath}".`);
150
+ continue;
151
+ }
152
+ if (actual === null || actual < expected) {
153
+ failures.push(`Expected stage "${keyPath}" to be at least count "${countKey}" (${expected}), got ${actual === null ? "non-numeric" : actual}.`);
154
+ }
155
+ }
156
+ for (const [zoneId, minimum] of Object.entries(acceptance?.zone_counts_at_least ?? {})) {
157
+ const zone = findCompiledSchemaZone(schema, zoneId);
158
+ if (!zone) {
159
+ failures.push(`Acceptance references unknown zone "${zoneId}".`);
160
+ continue;
161
+ }
162
+ const actual = countZoneArtifacts(dirPath, zone.path, zone.kind);
163
+ if (actual < minimum) {
164
+ failures.push(`Expected zone "${zoneId}" to contain at least ${minimum} artifact(s), got ${actual}.`);
165
+ }
166
+ }
167
+ for (const [zoneId, countKey] of Object.entries(acceptance?.zone_counts_at_least_counts ?? {})) {
168
+ const zone = findCompiledSchemaZone(schema, zoneId);
169
+ if (!zone) {
170
+ failures.push(`Acceptance references unknown zone "${zoneId}".`);
171
+ continue;
172
+ }
173
+ const expected = counts[countKey];
174
+ if (typeof expected !== "number") {
175
+ failures.push(`Acceptance references missing count "${countKey}" for zone "${zoneId}".`);
176
+ continue;
177
+ }
178
+ const actual = countZoneArtifacts(dirPath, zone.path, zone.kind);
179
+ if (actual < expected) {
180
+ failures.push(`Expected zone "${zoneId}" to contain at least count "${countKey}" (${expected}) artifact(s), got ${actual}.`);
181
+ }
182
+ }
183
+ for (const zoneId of acceptance?.markdown_frontmatter_valid_zones ?? []) {
184
+ const zone = findCompiledSchemaZone(schema, zoneId);
185
+ if (!zone) {
186
+ failures.push(`Acceptance references unknown zone "${zoneId}".`);
187
+ continue;
188
+ }
189
+ const validation = validateSynthFiles(markdownFilesForZone(dirPath, zone.path, zone.kind));
190
+ if (validation.invalid_frontmatter > 0) {
191
+ failures.push(`Zone "${zoneId}" has ${validation.invalid_frontmatter} markdown file(s) with invalid or incomplete frontmatter.`);
192
+ }
193
+ }
194
+ for (const [zoneId, requiredKeys] of Object.entries(acceptance?.frontmatter_required_keys_in_zones ?? {})) {
195
+ const zone = findCompiledSchemaZone(schema, zoneId);
196
+ if (!zone) {
197
+ failures.push(`Acceptance references unknown zone "${zoneId}".`);
198
+ continue;
199
+ }
200
+ const validation = validateSynthFiles(markdownFilesForZone(dirPath, zone.path, zone.kind), { requiredFrontmatterKeys: requiredKeys });
201
+ if (validation.invalid_frontmatter > 0) {
202
+ failures.push(`Zone "${zoneId}" has ${validation.invalid_frontmatter} markdown file(s) missing required frontmatter keys (${requiredKeys.join(", ")}).`);
203
+ }
204
+ }
205
+ for (const zoneId of acceptance?.markdown_abstract_valid_zones ?? []) {
206
+ const zone = findCompiledSchemaZone(schema, zoneId);
207
+ if (!zone) {
208
+ failures.push(`Acceptance references unknown zone "${zoneId}".`);
209
+ continue;
210
+ }
211
+ const validation = validateSynthFiles(markdownFilesForZone(dirPath, zone.path, zone.kind));
212
+ if (validation.short_abstracts > 0) {
213
+ failures.push(`Zone "${zoneId}" has ${validation.short_abstracts} markdown file(s) with missing or weak abstracts.`);
214
+ }
215
+ }
216
+ if ((acceptance?.wikilinks_valid_in_zones?.length ?? 0) > 0) {
217
+ const roots = zoneRoots(dirPath, acceptance?.wikilinks_valid_in_zones ?? []);
218
+ const brokenLinks = countBrokenWikilinks(dirPath, roots, roots);
219
+ if (brokenLinks > 0) {
220
+ failures.push(`Detected ${brokenLinks} broken wikilink(s) across the declared acceptance zones.`);
221
+ }
222
+ }
223
+ for (const [relativePath, disallowedTexts] of Object.entries(acceptance?.artifacts_must_not_contain ?? {})) {
224
+ const content = readArtifactText(dirPath, relativePath);
225
+ if (content === null) {
226
+ failures.push(`Missing artifact required for content check: ${relativePath}.`);
227
+ continue;
228
+ }
229
+ for (const disallowed of disallowedTexts) {
230
+ if (content.includes(disallowed)) {
231
+ failures.push(`Artifact "${relativePath}" still contains forbidden text: ${JSON.stringify(disallowed)}.`);
232
+ }
233
+ }
234
+ }
235
+ if (failures.length === 0) {
236
+ return {
237
+ ok: true,
238
+ summary: `Stage acceptance satisfied for ${options.stageId}.`,
239
+ failures: [],
240
+ };
241
+ }
242
+ return {
243
+ ok: false,
244
+ summary: `Stage acceptance failed for ${options.stageId}: ${failures.join(" ")}`,
245
+ failures,
246
+ };
247
+ }
248
+ export function validateStageContractAcceptance(dirPath, contract = null) {
249
+ const resolvedContract = contract ?? (() => {
250
+ const path = stageContractPath(dirPath);
251
+ if (!existsSync(path))
252
+ return null;
253
+ return readJsonFileWithSchema(path, "stage contract", RuntimeStageContractSchema);
254
+ })();
255
+ if (!resolvedContract) {
256
+ return {
257
+ ok: true,
258
+ summary: "No active stage contract found for acceptance validation.",
259
+ failures: [],
260
+ };
261
+ }
262
+ const state = loadState(dirPath);
263
+ const stageRecord = stageRecordFromState(state, resolvedContract.stage);
264
+ return validateResolvedStageAcceptance(dirPath, {
265
+ stageId: resolvedContract.stage,
266
+ acceptance: resolvedContract.acceptance,
267
+ counts: resolveStageCounts(resolvedContract, stageRecord),
268
+ });
269
+ }
@@ -0,0 +1,2 @@
1
+ import { type RuntimeStageContractDraft, type RuntimeStageContractOptions } from "./runtime-types.js";
2
+ export declare function buildRuntimeStageContract(options: RuntimeStageContractOptions): RuntimeStageContractDraft;