@intentius/chant 0.57.0 → 0.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (504) hide show
  1. package/dist/audit/catalog.d.ts +51 -1
  2. package/dist/audit/catalog.d.ts.map +1 -1
  3. package/dist/audit/core.d.ts +20 -1
  4. package/dist/audit/core.d.ts.map +1 -1
  5. package/dist/audit/discover.d.ts +14 -8
  6. package/dist/audit/discover.d.ts.map +1 -1
  7. package/dist/audit/lineage.d.ts +10 -0
  8. package/dist/audit/lineage.d.ts.map +1 -0
  9. package/dist/audit/prior-art.d.ts +385 -0
  10. package/dist/audit/prior-art.d.ts.map +1 -0
  11. package/dist/audit/proof.d.ts +16 -0
  12. package/dist/audit/proof.d.ts.map +1 -1
  13. package/dist/audit/report-html.d.ts.map +1 -1
  14. package/dist/audit/report-model.d.ts +8 -1
  15. package/dist/audit/report-model.d.ts.map +1 -1
  16. package/dist/audit/report.d.ts.map +1 -1
  17. package/dist/audit/rules-doc.d.ts +3 -0
  18. package/dist/audit/rules-doc.d.ts.map +1 -1
  19. package/dist/audit/secrets.d.ts +15 -0
  20. package/dist/audit/secrets.d.ts.map +1 -1
  21. package/dist/audit/terraform-state.d.ts +46 -0
  22. package/dist/audit/terraform-state.d.ts.map +1 -0
  23. package/dist/build.d.ts +17 -1
  24. package/dist/build.d.ts.map +1 -1
  25. package/dist/claimed-fields.d.ts +161 -0
  26. package/dist/claimed-fields.d.ts.map +1 -0
  27. package/dist/cli/build-params-cli.d.ts +2 -2
  28. package/dist/cli/command-group.d.ts +14 -0
  29. package/dist/cli/command-group.d.ts.map +1 -1
  30. package/dist/cli/commands/audit.d.ts +17 -1
  31. package/dist/cli/commands/audit.d.ts.map +1 -1
  32. package/dist/cli/commands/build.d.ts.map +1 -1
  33. package/dist/cli/commands/check-lexicon-docs.d.ts +1 -1
  34. package/dist/cli/commands/check-lexicon-examples.d.ts +16 -6
  35. package/dist/cli/commands/check-lexicon-examples.d.ts.map +1 -1
  36. package/dist/cli/commands/init-lexicon/templates/codegen.d.ts +1 -0
  37. package/dist/cli/commands/init-lexicon/templates/codegen.d.ts.map +1 -1
  38. package/dist/cli/commands/init-lexicon/templates/project.d.ts +7 -0
  39. package/dist/cli/commands/init-lexicon/templates/project.d.ts.map +1 -1
  40. package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
  41. package/dist/cli/commands/init.d.ts.map +1 -1
  42. package/dist/cli/commands/lint.d.ts.map +1 -1
  43. package/dist/cli/commands/onboard.d.ts +2 -0
  44. package/dist/cli/commands/onboard.d.ts.map +1 -1
  45. package/dist/cli/handlers/build.d.ts.map +1 -1
  46. package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
  47. package/dist/cli/handlers/operator.d.ts +82 -16
  48. package/dist/cli/handlers/operator.d.ts.map +1 -1
  49. package/dist/cli/handlers/run.d.ts +49 -42
  50. package/dist/cli/handlers/run.d.ts.map +1 -1
  51. package/dist/cli/main.d.ts +28 -1
  52. package/dist/cli/main.d.ts.map +1 -1
  53. package/dist/cli/mcp/op-tools.d.ts +16 -1
  54. package/dist/cli/mcp/op-tools.d.ts.map +1 -1
  55. package/dist/cli/mcp/resource-handlers.d.ts.map +1 -1
  56. package/dist/cli/mcp/resources/context.d.ts.map +1 -1
  57. package/dist/cli/registry.d.ts +26 -9
  58. package/dist/cli/registry.d.ts.map +1 -1
  59. package/dist/codegen/generate-post-synth-barrel.d.ts +1 -1
  60. package/dist/components/auto-release.d.ts +10 -20
  61. package/dist/components/auto-release.d.ts.map +1 -1
  62. package/dist/components/capability.d.ts +4 -4
  63. package/dist/components/cli-support.d.ts +20 -21
  64. package/dist/components/cli-support.d.ts.map +1 -1
  65. package/dist/components/component.d.ts +3 -3
  66. package/dist/components/component.d.ts.map +1 -1
  67. package/dist/components/driver-output.d.ts.map +1 -1
  68. package/dist/components/driver.d.ts +66 -36
  69. package/dist/components/driver.d.ts.map +1 -1
  70. package/dist/components/index.d.ts +1 -2
  71. package/dist/components/index.d.ts.map +1 -1
  72. package/dist/components/manifest-persistence.d.ts +1 -9
  73. package/dist/components/manifest-persistence.d.ts.map +1 -1
  74. package/dist/components/run-progress.d.ts +6 -6
  75. package/dist/components/run-progress.d.ts.map +1 -1
  76. package/dist/components/verbs/run-agent.d.ts +9 -15
  77. package/dist/components/verbs/run-agent.d.ts.map +1 -1
  78. package/dist/components/verbs/verify.d.ts +2 -2
  79. package/dist/deep-observation.d.ts +17 -0
  80. package/dist/deep-observation.d.ts.map +1 -1
  81. package/dist/discovery/files.d.ts +4 -4
  82. package/dist/discovery/fold-import.d.ts.map +1 -1
  83. package/dist/discovery/param-deps.d.ts +33 -0
  84. package/dist/discovery/param-deps.d.ts.map +1 -1
  85. package/dist/discovery/sandbox/bundle.d.ts.map +1 -1
  86. package/dist/discovery/sandbox/config-wire.d.ts +2 -2
  87. package/dist/fold/foldable-helpers.d.ts +5 -1
  88. package/dist/fold/foldable-helpers.d.ts.map +1 -1
  89. package/dist/fold-provenance.d.ts +236 -0
  90. package/dist/fold-provenance.d.ts.map +1 -0
  91. package/dist/graph-ops.d.ts +1 -1
  92. package/dist/held-elsewhere.d.ts +85 -0
  93. package/dist/held-elsewhere.d.ts.map +1 -0
  94. package/dist/index.d.ts +3 -0
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/kubectl-context.d.ts +3 -3
  97. package/dist/lexicon-config.d.ts +4 -4
  98. package/dist/lexicon-plugin-helpers.d.ts +1 -1
  99. package/dist/lexicon.d.ts +104 -14
  100. package/dist/lexicon.d.ts.map +1 -1
  101. package/dist/lifecycle/change-set.d.ts +13 -0
  102. package/dist/lifecycle/change-set.d.ts.map +1 -1
  103. package/dist/lifecycle/deep-diff.d.ts +133 -6
  104. package/dist/lifecycle/deep-diff.d.ts.map +1 -1
  105. package/dist/lifecycle/deep-observe.d.ts.map +1 -1
  106. package/dist/lifecycle/gate-ledger.d.ts +71 -3
  107. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  108. package/dist/lifecycle/index.d.ts +1 -0
  109. package/dist/lifecycle/index.d.ts.map +1 -1
  110. package/dist/lifecycle/release-ledger.d.ts +2 -2
  111. package/dist/lifecycle/run-ledger.d.ts +53 -0
  112. package/dist/lifecycle/run-ledger.d.ts.map +1 -0
  113. package/dist/lifecycle/symptoms.d.ts +3 -3
  114. package/dist/lifecycle/symptoms.d.ts.map +1 -1
  115. package/dist/lint/config.d.ts +81 -2
  116. package/dist/lint/config.d.ts.map +1 -1
  117. package/dist/lint/post-synth.d.ts +55 -2
  118. package/dist/lint/post-synth.d.ts.map +1 -1
  119. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts +1 -1
  120. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts.map +1 -1
  121. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts +1 -1
  122. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts.map +1 -1
  123. package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.d.ts +44 -0
  124. package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.d.ts.map +1 -0
  125. package/dist/lint/rules/comp/index.d.ts +1 -1
  126. package/dist/lint/rules/comp/index.d.ts.map +1 -1
  127. package/dist/lint/rules/op/index.d.ts +16 -0
  128. package/dist/lint/rules/op/index.d.ts.map +1 -0
  129. package/dist/lint/rules/op/ops012-activity-contract.d.ts +27 -0
  130. package/dist/lint/rules/op/ops012-activity-contract.d.ts.map +1 -0
  131. package/dist/lint/rules/op/ops013-step-output-ref.d.ts +61 -0
  132. package/dist/lint/rules/op/ops013-step-output-ref.d.ts.map +1 -0
  133. package/dist/lint/rules/op/ops014-converge-rule-refusals.d.ts +55 -0
  134. package/dist/lint/rules/op/ops014-converge-rule-refusals.d.ts.map +1 -0
  135. package/dist/lint/rules/op/support.d.ts +12 -0
  136. package/dist/lint/rules/op/support.d.ts.map +1 -0
  137. package/dist/lint/suppressions.d.ts +108 -0
  138. package/dist/lint/suppressions.d.ts.map +1 -0
  139. package/dist/live-endpoint.d.ts +1 -1
  140. package/dist/op/activities/activity-contracts.d.ts +54 -0
  141. package/dist/op/activities/activity-contracts.d.ts.map +1 -0
  142. package/dist/op/activities/apply.d.ts +262 -0
  143. package/dist/op/activities/apply.d.ts.map +1 -0
  144. package/dist/op/activities/build.d.ts +13 -0
  145. package/dist/op/activities/build.d.ts.map +1 -0
  146. package/dist/op/activities/converge.d.ts +110 -0
  147. package/dist/op/activities/converge.d.ts.map +1 -0
  148. package/dist/op/activities/env-teardown.d.ts +76 -0
  149. package/dist/op/activities/env-teardown.d.ts.map +1 -0
  150. package/dist/op/activities/guard-validate.d.ts +64 -0
  151. package/dist/op/activities/guard-validate.d.ts.map +1 -0
  152. package/dist/op/activities/http-check.d.ts +34 -0
  153. package/dist/op/activities/http-check.d.ts.map +1 -0
  154. package/dist/op/activities/index.d.ts +31 -0
  155. package/dist/op/activities/index.d.ts.map +1 -0
  156. package/dist/op/activities/lexicon-upgrade.d.ts +182 -0
  157. package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -0
  158. package/dist/op/activities/lifecycle.d.ts +42 -0
  159. package/dist/op/activities/lifecycle.d.ts.map +1 -0
  160. package/dist/op/activities/pipeline-audit.d.ts +84 -0
  161. package/dist/op/activities/pipeline-audit.d.ts.map +1 -0
  162. package/dist/op/activities/policy.d.ts +17 -0
  163. package/dist/op/activities/policy.d.ts.map +1 -0
  164. package/dist/op/activities/reconcile.d.ts +89 -0
  165. package/dist/op/activities/reconcile.d.ts.map +1 -0
  166. package/dist/op/activities/shell.d.ts +13 -0
  167. package/dist/op/activities/shell.d.ts.map +1 -0
  168. package/dist/op/activities/teardown.d.ts +10 -0
  169. package/dist/op/activities/teardown.d.ts.map +1 -0
  170. package/dist/op/activities/util.d.ts +7 -0
  171. package/dist/op/activities/util.d.ts.map +1 -0
  172. package/dist/op/activities/wait.d.ts +28 -0
  173. package/dist/op/activities/wait.d.ts.map +1 -0
  174. package/dist/op/activities/workflow-audit.d.ts +92 -0
  175. package/dist/op/activities/workflow-audit.d.ts.map +1 -0
  176. package/dist/op/activity-contract-registry.d.ts +76 -0
  177. package/dist/op/activity-contract-registry.d.ts.map +1 -0
  178. package/dist/op/activity-contract.d.ts +25 -18
  179. package/dist/op/activity-contract.d.ts.map +1 -1
  180. package/dist/op/activity-failure.d.ts +28 -0
  181. package/dist/op/activity-failure.d.ts.map +1 -0
  182. package/dist/op/activity-profiles.d.ts +118 -0
  183. package/dist/op/activity-profiles.d.ts.map +1 -0
  184. package/dist/op/activity-registry.d.ts +22 -38
  185. package/dist/op/activity-registry.d.ts.map +1 -1
  186. package/dist/op/activity-runtime.d.ts +3 -14
  187. package/dist/op/activity-runtime.d.ts.map +1 -1
  188. package/dist/op/builders.d.ts +84 -29
  189. package/dist/op/builders.d.ts.map +1 -1
  190. package/dist/op/composites/apply-op.d.ts +113 -0
  191. package/dist/op/composites/apply-op.d.ts.map +1 -0
  192. package/dist/op/composites/converge-op.d.ts +120 -0
  193. package/dist/op/composites/converge-op.d.ts.map +1 -0
  194. package/dist/op/composites/index.d.ts +26 -0
  195. package/dist/op/composites/index.d.ts.map +1 -0
  196. package/dist/op/composites/lexicon-upgrade-op.d.ts +78 -0
  197. package/dist/op/composites/lexicon-upgrade-op.d.ts.map +1 -0
  198. package/dist/op/composites/pipeline-audit-op.d.ts +50 -0
  199. package/dist/op/composites/pipeline-audit-op.d.ts.map +1 -0
  200. package/dist/op/composites/reconcile-op.d.ts +57 -0
  201. package/dist/op/composites/reconcile-op.d.ts.map +1 -0
  202. package/dist/op/composites/watch-op.d.ts +60 -0
  203. package/dist/op/composites/watch-op.d.ts.map +1 -0
  204. package/dist/op/composites/workflow-audit-op.d.ts +57 -0
  205. package/dist/op/composites/workflow-audit-op.d.ts.map +1 -0
  206. package/dist/op/converge-rule.d.ts +12 -10
  207. package/dist/op/converge-rule.d.ts.map +1 -1
  208. package/dist/op/cron.d.ts +51 -0
  209. package/dist/op/cron.d.ts.map +1 -0
  210. package/dist/op/discover.d.ts +9 -0
  211. package/dist/op/discover.d.ts.map +1 -1
  212. package/dist/op/duration.d.ts +11 -0
  213. package/dist/op/duration.d.ts.map +1 -0
  214. package/dist/op/emulator-lifecycle.d.ts.map +1 -1
  215. package/dist/op/gate.d.ts +90 -0
  216. package/dist/op/gate.d.ts.map +1 -0
  217. package/dist/op/generate-pipeline.d.ts +9 -0
  218. package/dist/op/generate-pipeline.d.ts.map +1 -1
  219. package/dist/op/index.d.ts +23 -7
  220. package/dist/op/index.d.ts.map +1 -1
  221. package/dist/op/local-executor.d.ts +114 -28
  222. package/dist/op/local-executor.d.ts.map +1 -1
  223. package/dist/op/local-output.d.ts +11 -1
  224. package/dist/op/local-output.d.ts.map +1 -1
  225. package/dist/op/op-ir.d.ts +184 -0
  226. package/dist/op/op-ir.d.ts.map +1 -0
  227. package/dist/op/op-verb-class.d.ts +10 -2
  228. package/dist/op/op-verb-class.d.ts.map +1 -1
  229. package/dist/op/operator.d.ts +30 -5
  230. package/dist/op/operator.d.ts.map +1 -1
  231. package/dist/op/receipt-store.d.ts +1 -1
  232. package/dist/op/receipt-store.d.ts.map +1 -1
  233. package/dist/op/resource.d.ts +15 -1
  234. package/dist/op/resource.d.ts.map +1 -1
  235. package/dist/op/runtime.d.ts +200 -0
  236. package/dist/op/runtime.d.ts.map +1 -0
  237. package/dist/op/runtimes/local.d.ts +29 -0
  238. package/dist/op/runtimes/local.d.ts.map +1 -0
  239. package/dist/op/step-output-ref.d.ts +15 -13
  240. package/dist/op/step-output-ref.d.ts.map +1 -1
  241. package/dist/op/types.d.ts +79 -27
  242. package/dist/op/types.d.ts.map +1 -1
  243. package/dist/ownership.d.ts +1 -1
  244. package/dist/provenance.d.ts +21 -0
  245. package/dist/provenance.d.ts.map +1 -1
  246. package/dist/serializer-walker.d.ts.map +1 -1
  247. package/package.json +6 -1
  248. package/src/audit/catalog.test.ts +79 -3
  249. package/src/audit/catalog.ts +111 -13
  250. package/src/audit/core.test.ts +26 -0
  251. package/src/audit/core.ts +61 -17
  252. package/src/audit/discover.test.ts +39 -0
  253. package/src/audit/discover.ts +91 -15
  254. package/src/audit/lineage.ts +100 -0
  255. package/src/audit/prior-art.ts +153 -0
  256. package/src/audit/proof.test.ts +67 -0
  257. package/src/audit/proof.ts +70 -0
  258. package/src/audit/report-html.ts +9 -4
  259. package/src/audit/report-model.ts +16 -2
  260. package/src/audit/report.test.ts +33 -0
  261. package/src/audit/report.ts +5 -3
  262. package/src/audit/rules-doc.test.ts +34 -2
  263. package/src/audit/rules-doc.ts +82 -9
  264. package/src/audit/secrets.ts +15 -3
  265. package/src/audit/terraform-state.test.ts +144 -0
  266. package/src/audit/terraform-state.ts +131 -0
  267. package/src/build.ts +31 -1
  268. package/src/claimed-fields.test.ts +145 -0
  269. package/src/claimed-fields.ts +208 -0
  270. package/src/cli/build-params-cli.ts +2 -2
  271. package/src/cli/command-group.ts +14 -0
  272. package/src/cli/commands/__fixtures__/audit-terraform/infra/.terraform/providers/lock.txt +1 -0
  273. package/src/cli/commands/__fixtures__/audit-terraform/infra/main.tf +1 -0
  274. package/src/cli/commands/__fixtures__/audit-terraform/infra/modules/foo/main.tf +1 -0
  275. package/src/cli/commands/__fixtures__/audit-terraform/infra/variables.tf +3 -0
  276. package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +13 -4
  277. package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/docs-cli.ts +4 -0
  278. package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/package.ts +1 -0
  279. package/src/cli/commands/__fixtures__/init-lexicon-output/src/package-cli.ts +21 -0
  280. package/src/cli/commands/__snapshots__/init-lexicon.test.ts.snap +1 -0
  281. package/src/cli/commands/audit.test.ts +189 -11
  282. package/src/cli/commands/audit.ts +73 -27
  283. package/src/cli/commands/build.test.ts +292 -9
  284. package/src/cli/commands/build.ts +156 -24
  285. package/src/cli/commands/check-lexicon-docs.ts +1 -1
  286. package/src/cli/commands/check-lexicon-examples.test.ts +29 -1
  287. package/src/cli/commands/check-lexicon-examples.ts +42 -10
  288. package/src/cli/commands/init-lexicon/templates/codegen.ts +9 -0
  289. package/src/cli/commands/init-lexicon/templates/project.ts +44 -4
  290. package/src/cli/commands/init-lexicon.test.ts +97 -2
  291. package/src/cli/commands/init-lexicon.ts +4 -2
  292. package/src/cli/commands/init.test.ts +35 -1
  293. package/src/cli/commands/init.ts +14 -3
  294. package/src/cli/commands/lint.test.ts +48 -0
  295. package/src/cli/commands/lint.ts +123 -0
  296. package/src/cli/commands/onboard.test.ts +75 -0
  297. package/src/cli/commands/onboard.ts +54 -23
  298. package/src/cli/handlers/build.test.ts +81 -1
  299. package/src/cli/handlers/build.ts +15 -1
  300. package/src/cli/handlers/graph.test.ts +3 -3
  301. package/src/cli/handlers/lifecycle.test.ts +195 -12
  302. package/src/cli/handlers/lifecycle.ts +123 -6
  303. package/src/cli/handlers/misc.ts +1 -1
  304. package/src/cli/handlers/operator.test.ts +183 -11
  305. package/src/cli/handlers/operator.ts +260 -55
  306. package/src/cli/handlers/run.test.ts +431 -1287
  307. package/src/cli/handlers/run.ts +365 -915
  308. package/src/cli/main.test.ts +23 -15
  309. package/src/cli/main.ts +88 -33
  310. package/src/cli/mcp/op-tools.ts +147 -88
  311. package/src/cli/mcp/resource-handlers.ts +10 -37
  312. package/src/cli/mcp/resources/context.ts +11 -12
  313. package/src/cli/mcp/server.test.ts +25 -27
  314. package/src/cli/mcp/server.ts +2 -2
  315. package/src/cli/registry.ts +26 -9
  316. package/src/codegen/docs.ts +1 -1
  317. package/src/codegen/generate-post-synth-barrel.test.ts +1 -1
  318. package/src/codegen/generate-post-synth-barrel.ts +1 -1
  319. package/src/components/README.md +3 -2
  320. package/src/components/auto-release.test.ts +4 -20
  321. package/src/components/auto-release.ts +17 -42
  322. package/src/components/capability.ts +4 -4
  323. package/src/components/cli-support.test.ts +10 -5
  324. package/src/components/cli-support.ts +52 -44
  325. package/src/components/component.schema.json +2 -2
  326. package/src/components/component.ts +3 -3
  327. package/src/components/driver-output.ts +14 -2
  328. package/src/components/driver.test.ts +92 -22
  329. package/src/components/driver.ts +193 -83
  330. package/src/components/index.ts +1 -6
  331. package/src/components/manifest-persistence.test.ts +2 -20
  332. package/src/components/manifest-persistence.ts +4 -24
  333. package/src/components/pilots/pilots-lint-clean.test.ts +11 -10
  334. package/src/components/run-progress.ts +6 -6
  335. package/src/components/verbs/run-agent.ts +11 -17
  336. package/src/components/verbs/verify.ts +2 -2
  337. package/src/deep-observation.test.ts +75 -0
  338. package/src/deep-observation.ts +48 -0
  339. package/src/discovery/collect.test.ts +3 -3
  340. package/src/discovery/files.ts +4 -4
  341. package/src/discovery/fold-import.ts +105 -2
  342. package/src/discovery/param-deps.test.ts +112 -1
  343. package/src/discovery/param-deps.ts +193 -0
  344. package/src/discovery/sandbox/bundle.ts +15 -1
  345. package/src/discovery/sandbox/config-wire.test.ts +2 -2
  346. package/src/discovery/sandbox/config-wire.ts +2 -2
  347. package/src/fold/fold.test.ts +56 -0
  348. package/src/fold/foldable-helpers.ts +81 -1
  349. package/src/fold-provenance-exclusion.test.ts +186 -0
  350. package/src/fold-provenance.test.ts +495 -0
  351. package/src/fold-provenance.ts +441 -0
  352. package/src/graph-ops.test.ts +2 -2
  353. package/src/graph-ops.ts +1 -1
  354. package/src/held-elsewhere.test.ts +102 -0
  355. package/src/held-elsewhere.ts +114 -0
  356. package/src/index.ts +3 -0
  357. package/src/kubectl-context.ts +3 -3
  358. package/src/lexicon-config.test.ts +5 -5
  359. package/src/lexicon-config.ts +4 -4
  360. package/src/lexicon-plugin-helpers.ts +1 -1
  361. package/src/lexicon.ts +120 -14
  362. package/src/lifecycle/change-set.test.ts +49 -0
  363. package/src/lifecycle/change-set.ts +67 -0
  364. package/src/lifecycle/converge-ledger.ts +1 -1
  365. package/src/lifecycle/deep-diff.test.ts +267 -14
  366. package/src/lifecycle/deep-diff.ts +217 -14
  367. package/src/lifecycle/deep-observe.test.ts +3 -1
  368. package/src/lifecycle/deep-observe.ts +16 -6
  369. package/src/lifecycle/gate-ledger.test.ts +74 -2
  370. package/src/lifecycle/gate-ledger.ts +143 -36
  371. package/src/lifecycle/index.ts +1 -0
  372. package/src/lifecycle/release-ledger.ts +2 -2
  373. package/src/lifecycle/run-ledger.test.ts +268 -0
  374. package/src/lifecycle/run-ledger.ts +201 -0
  375. package/src/lifecycle/symptoms.ts +3 -3
  376. package/src/lint/config.test.ts +82 -1
  377. package/src/lint/config.ts +112 -3
  378. package/src/lint/policy.test.ts +1 -1
  379. package/src/lint/post-synth.test.ts +31 -0
  380. package/src/lint/post-synth.ts +54 -1
  381. package/src/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.ts +2 -2
  382. package/src/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.ts +1 -1
  383. package/src/lint/rules/comp/comp.test.ts +1 -1
  384. package/src/lint/rules/comp/comp004-gate-needs-durable-runtime.ts +74 -0
  385. package/src/lint/rules/comp/index.ts +3 -3
  386. package/src/lint/rules/op/index.ts +23 -0
  387. package/src/lint/rules/op/ops012-activity-contract.test.ts +161 -0
  388. package/src/lint/rules/op/ops012-activity-contract.ts +64 -0
  389. package/src/lint/rules/op/ops013-step-output-ref.test.ts +237 -0
  390. package/src/lint/rules/op/ops013-step-output-ref.ts +98 -0
  391. package/src/lint/rules/op/ops014-converge-rule-refusals.test.ts +263 -0
  392. package/src/lint/rules/op/ops014-converge-rule-refusals.ts +179 -0
  393. package/src/lint/rules/op/support.ts +11 -0
  394. package/src/lint/suppressions.test.ts +163 -0
  395. package/src/lint/suppressions.ts +204 -0
  396. package/src/live-endpoint.ts +1 -1
  397. package/src/op/activities/activity-contracts.ts +66 -0
  398. package/src/op/activities/apply.test.ts +567 -0
  399. package/src/op/activities/apply.ts +662 -0
  400. package/src/op/activities/build.ts +26 -0
  401. package/src/op/activities/converge.test.ts +330 -0
  402. package/src/op/activities/converge.ts +449 -0
  403. package/src/op/activities/env-teardown.test.ts +187 -0
  404. package/src/op/activities/env-teardown.ts +171 -0
  405. package/src/op/activities/guard-validate.test.ts +139 -0
  406. package/src/op/activities/guard-validate.ts +223 -0
  407. package/src/op/activities/http-check.test.ts +48 -0
  408. package/src/op/activities/http-check.ts +55 -0
  409. package/src/op/activities/index.ts +119 -0
  410. package/src/op/activities/lexicon-upgrade.test.ts +492 -0
  411. package/src/op/activities/lexicon-upgrade.ts +673 -0
  412. package/src/op/activities/lifecycle.ts +85 -0
  413. package/src/op/activities/pipeline-audit.test.ts +67 -0
  414. package/src/op/activities/pipeline-audit.ts +201 -0
  415. package/src/op/activities/policy.test.ts +19 -0
  416. package/src/op/activities/policy.ts +37 -0
  417. package/src/op/activities/reconcile.test.ts +81 -0
  418. package/src/op/activities/reconcile.ts +187 -0
  419. package/src/op/activities/shell.ts +26 -0
  420. package/src/op/activities/teardown.ts +22 -0
  421. package/src/op/activities/util.ts +6 -0
  422. package/src/op/activities/wait.ts +69 -0
  423. package/src/op/activities/workflow-audit.test.ts +90 -0
  424. package/src/op/activities/workflow-audit.ts +203 -0
  425. package/src/op/activity-contract-registry.test.ts +98 -0
  426. package/src/op/activity-contract-registry.ts +114 -0
  427. package/src/op/activity-contract.test.ts +1 -1
  428. package/src/op/activity-contract.ts +37 -33
  429. package/src/op/activity-failure.ts +34 -0
  430. package/src/op/activity-profiles.test.ts +56 -0
  431. package/src/op/activity-profiles.ts +116 -0
  432. package/src/op/activity-registry.test.ts +37 -28
  433. package/src/op/activity-registry.ts +27 -56
  434. package/src/op/activity-runtime.ts +3 -47
  435. package/src/op/builders-exports.test.ts +0 -49
  436. package/src/op/builders-typed.test.ts +164 -0
  437. package/src/op/builders.ts +123 -39
  438. package/src/op/composites/apply-op.ts +208 -0
  439. package/src/op/composites/composites.test.ts +366 -0
  440. package/src/op/composites/converge-op.test.ts +168 -0
  441. package/src/op/composites/converge-op.ts +214 -0
  442. package/src/op/composites/index.ts +26 -0
  443. package/src/op/composites/lexicon-upgrade-op.test.ts +68 -0
  444. package/src/op/composites/lexicon-upgrade-op.ts +134 -0
  445. package/src/op/composites/pipeline-audit-op.test.ts +25 -0
  446. package/src/op/composites/pipeline-audit-op.ts +78 -0
  447. package/src/op/composites/reconcile-op.test.ts +51 -0
  448. package/src/op/composites/reconcile-op.ts +107 -0
  449. package/src/op/composites/watch-op.ts +108 -0
  450. package/src/op/composites/workflow-audit-op.test.ts +25 -0
  451. package/src/op/composites/workflow-audit-op.ts +88 -0
  452. package/src/op/converge-rule.ts +12 -10
  453. package/src/op/cron.test.ts +128 -0
  454. package/src/op/cron.ts +149 -0
  455. package/src/op/discover-root.test.ts +105 -1
  456. package/src/op/discover.test.ts +6 -2
  457. package/src/op/discover.ts +84 -16
  458. package/src/op/duration.ts +21 -0
  459. package/src/op/effect-step.test.ts +26 -11
  460. package/src/op/emulator-lifecycle.ts +1 -2
  461. package/src/op/gate.ts +155 -0
  462. package/src/op/generate-pipeline.test.ts +65 -3
  463. package/src/op/generate-pipeline.ts +19 -2
  464. package/src/op/index.ts +39 -6
  465. package/src/op/local-executor.test.ts +163 -34
  466. package/src/op/local-executor.ts +370 -102
  467. package/src/op/local-output.test.ts +95 -11
  468. package/src/op/local-output.ts +33 -4
  469. package/src/op/op-ir.test.ts +281 -0
  470. package/src/op/op-ir.ts +417 -0
  471. package/src/op/op-verb-class.ts +19 -5
  472. package/src/op/op.test.ts +26 -5
  473. package/src/op/operator.test.ts +175 -6
  474. package/src/op/operator.ts +63 -16
  475. package/src/op/receipt-store.ts +1 -1
  476. package/src/op/resource.ts +20 -2
  477. package/src/op/runtime.ts +203 -0
  478. package/src/op/runtimes/local.test.ts +181 -0
  479. package/src/op/runtimes/local.ts +212 -0
  480. package/src/op/step-output-ref.ts +15 -13
  481. package/src/op/types.ts +84 -24
  482. package/src/ownership.ts +1 -1
  483. package/src/provenance.test.ts +6 -0
  484. package/src/provenance.ts +21 -1
  485. package/src/serializer-walker.test.ts +42 -0
  486. package/src/serializer-walker.ts +21 -2
  487. package/dist/cli/handlers/op-progress.d.ts +0 -90
  488. package/dist/cli/handlers/op-progress.d.ts.map +0 -1
  489. package/dist/cli/handlers/run-client.d.ts +0 -127
  490. package/dist/cli/handlers/run-client.d.ts.map +0 -1
  491. package/dist/cli/handlers/run-report.d.ts +0 -5
  492. package/dist/cli/handlers/run-report.d.ts.map +0 -1
  493. package/dist/components/temporal-codegen-loader.d.ts +0 -27
  494. package/dist/components/temporal-codegen-loader.d.ts.map +0 -1
  495. package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts +0 -37
  496. package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts.map +0 -1
  497. package/src/cli/handlers/op-progress.test.ts +0 -268
  498. package/src/cli/handlers/op-progress.ts +0 -248
  499. package/src/cli/handlers/run-client.test.ts +0 -82
  500. package/src/cli/handlers/run-client.ts +0 -219
  501. package/src/cli/handlers/run-report.test.ts +0 -62
  502. package/src/cli/handlers/run-report.ts +0 -122
  503. package/src/components/temporal-codegen-loader.ts +0 -41
  504. package/src/lint/rules/comp/comp004-gate-needs-temporal.ts +0 -66
@@ -9,7 +9,7 @@ import { searchTool, createSearchHandler } from "./tools/search";
9
9
  import type { LexiconPlugin } from "../../lexicon";
10
10
  import type { McpRequest, McpResponse, McpRequestMeta, ToolDefinition, ToolHandler, ResourceDefinition } from "./types";
11
11
  import { createSnapshotTool, createDiffTool } from "./lifecycle-tools";
12
- import { createOpListTool, createOpRunTool, createOpStatusTool, createOpSignalTool, createOpReportTool } from "./op-tools";
12
+ import { createOpListTool, createOpRunTool, createOpStatusTool, createOpApproveTool, createOpReportTool } from "./op-tools";
13
13
  import { buildResourcesList, handleResourcesRead } from "./resource-handlers";
14
14
 
15
15
  /**
@@ -103,7 +103,7 @@ export class McpServer {
103
103
  this.registerTool(diff.definition, diff.handler);
104
104
 
105
105
  // Register Op tools
106
- for (const factory of [createOpListTool, createOpRunTool, createOpStatusTool, createOpSignalTool, createOpReportTool]) {
106
+ for (const factory of [createOpListTool, createOpRunTool, createOpStatusTool, createOpApproveTool, createOpReportTool]) {
107
107
  const t = factory();
108
108
  this.registerTool(t.definition, t.handler);
109
109
  }
@@ -18,12 +18,26 @@ export interface ParsedArgs {
18
18
  watch: boolean;
19
19
  verbose: boolean;
20
20
  help: boolean;
21
- profile?: string;
22
21
  report?: boolean;
23
22
  /** `chant run` — force the local in-process executor (the default). */
24
23
  local?: boolean;
25
- /** `chant run` — run via a Temporal cluster instead of the local executor. */
26
- temporal?: boolean;
24
+ /**
25
+ * `chant run <op> --on <lexicon>` (#2121) — which runtime hosts the run.
26
+ * The named lexicon's `opRuntime` (`../lexicon.ts`) takes it; omitted, core's
27
+ * built-in `local` provider does. Applies to every `run` subcommand, so
28
+ * `run status`/`log`/`list`/`cancel`/`approve` all address the same runtime
29
+ * the run started on.
30
+ */
31
+ on?: string;
32
+ /**
33
+ * `-p, --profile <name>` (#2124, restored in #2192) — which named connection
34
+ * profile the hosting runtime targets, handed to it as
35
+ * {@link OpRunStartOptions.profile}. Only a runtime that declares profiles
36
+ * reads it: fountain resolves it through `fountain.profiles` in
37
+ * `chant.config.ts` and refuses a name it does not find. Omitted, each
38
+ * runtime keeps its own default (fountain's `defaultProfile`).
39
+ */
40
+ profile?: string;
27
41
  /** `chant run` — emit the structured OpRunResult as JSON on stdout. */
28
42
  json?: boolean;
29
43
  /**
@@ -32,10 +46,9 @@ export interface ParsedArgs {
32
46
  * per line to stdout while the run executes, so a consumer can render live
33
47
  * wave/component/phase/step progress instead of tailing raw logs.
34
48
  *
35
- * `chant run <name> --temporal --progress-json` (chant #1676) — the same
36
- * flag on an Op's durable path streams one NDJSON `StepRecord`
37
- * (../../op/local-executor.ts, reconstructed from workflow history by
38
- * ../handlers/op-progress.ts) per settled step instead.
49
+ * `chant run <name> --progress-json` streams one NDJSON `StepRecord`
50
+ * (../../op/local-executor.ts) per settled step instead, fed by whatever
51
+ * the resolved runtime reports through its `progress` hook (#2121).
39
52
  *
40
53
  * Both are purely additive: run semantics, ordering, and exit code are
41
54
  * unchanged; omitted (undefined, not false) when the flag isn't passed.
@@ -173,7 +186,7 @@ export interface ParsedArgs {
173
186
  * registered in `~/.claude.json`, not just the path argument.
174
187
  */
175
188
  allProjects?: boolean;
176
- /** `chant audit --fail-on merge-worthy|warning|none` */
189
+ /** `chant audit --fail-on merge-worthy|warning|error|none` */
177
190
  failOn?: string;
178
191
  /** `chant audit --theme <file>` — JSON theme knobs for the HTML report */
179
192
  theme?: string;
@@ -251,8 +264,10 @@ export interface ParsedArgs {
251
264
  runId?: string;
252
265
  /** `chant components release record --actor <name>` (#568) — who/what triggered the deploy. */
253
266
  actor?: string;
254
- /** `--approver <name>` (#1035) — who approved a gated change. Supplied to `chant run signal` (rides the gate signal payload into workflow history) and to `chant components release` (recorded on the release ledger). Optional; absent for ungated changes. */
267
+ /** `--approver <name>` (#1035) — who approved a gated change. Read by `chant approve` and `chant run approve` (recorded as `resolvedBy` on the gate-resolution fact, taking precedence over `--actor`) and by `chant components release` (recorded on the release ledger). Optional; absent for ungated changes. */
255
268
  approver?: string;
269
+ /** `chant run approve <op> <gate> --on <lexicon> --durable-requests` (#2126) — reserved. It would resolve the gate by answering the hosting runtime's own pending request instead of posting a follow-up prompt. No runtime implements it: fountain's needs the request-answer path from BinaryBourbon/fountain#1635, which has not shipped, and refuses by name rather than reporting a resolution it did not make. */
270
+ durableRequests?: boolean;
256
271
  /** `chant components status <env> --compare-to <env>` (#568) — a second environment to cross-check the same component's recorded digest against. */
257
272
  compareTo?: string;
258
273
  /** `chant run --components <name> --env <env> --no-release-record` (#597) — opt out of auto-emitting a release-ledger record after a successful component deploy. Default (flag omitted): recording is ON. Also settable project-wide via `chant.config.ts`'s `release.autoRecord: false`. */
@@ -287,6 +302,8 @@ export interface ParsedArgs {
287
302
  once?: boolean;
288
303
  /** `chant approve <op> <gate> --note <text>` (#1485) — optional free-text prose recorded on the gate-resolution fact. The PR link belongs in `--url` since #2028; this is for everything that isn't the link. */
289
304
  note?: string;
305
+ /** `chant approve <op> <gate> --expire` (#2119) — clear the gate's standing pending fact instead of approving it, so the next run decides the gate from scratch and records a fresh one. Writes no resolution: nothing is approved, the wait is only restarted. */
306
+ expire?: boolean;
290
307
  /** `chant operator log --op <name>` (#2029) — restrict the tick history to one ConvergeOp by name. Omitted, every discovered ConvergeOp's ticks are merged into one timeline. */
291
308
  op?: string;
292
309
  /** `chant operator log --since <iso>` (#2029) — only entries at or after this ISO-8601 instant. */
@@ -325,7 +325,7 @@ export function writeDocsSite(config: DocsConfig, result: DocsResult): void {
325
325
  // Starlight does not auto-discover pages, so a page absent from the sidebar
326
326
  // is reachable only by typing its URL. The pipeline deliberately preserves
327
327
  // hand-written pages it did not emit (above), which makes it easy to add one
328
- // and never wire it up — azure, temporal, helm and github each accumulated
328
+ // and never wire it up — azure, helm and github each accumulated
329
329
  // several that way (#1312). Report them; `chant dev check-lexicon` gates on
330
330
  // the same condition.
331
331
  const unreachable = unreachablePages(contentDir, sidebar);
@@ -12,7 +12,7 @@ describe("generatePostSynthBarrel", () => {
12
12
 
13
13
  expect(out).toContain("// Code generated by chant generate. DO NOT EDIT.");
14
14
  expect(out).toContain('import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";');
15
- // Export name may differ from the module name (docker/helm/temporal).
15
+ // Export name may differ from the module name (docker/helm).
16
16
  expect(out).toContain('import { dkrd010 } from "./apt-no-recommends";');
17
17
  // Array is ordered by id, not insertion order.
18
18
  const arrayBody = out.slice(out.indexOf("postSynthChecks: PostSynthCheck[] = ["));
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * Detection reuses the runtime's own `isPostSynthCheck`, so the barrel contains
11
11
  * exactly the checks discovery would — including files whose export name differs
12
- * from the filename (docker/helm/temporal) and excluding helper modules
12
+ * from the filename (docker/helm) and excluding helper modules
13
13
  * (cf-refs, arm-refs, …) that export no check.
14
14
  */
15
15
 
@@ -50,8 +50,9 @@ adopting chant.
50
50
  be a nested `Phase`, which is how fan-out (e.g. a Neo4j cluster seeding one
51
51
  node then rolling through the rest) is expressed as composition rather than
52
52
  orchestrator knowledge.
53
- - **Gates** — a distinct step shape (`kind: "gate"`, `signalName`) for a
54
- durable, human-approval wait.
53
+ - **Gates** — a distinct step shape (`kind: "gate"`, `signalName`) for a human
54
+ approval, decided against the gate ledger: a run that reaches one with no
55
+ resolution stops there with status `gated` and the pending fact recorded.
55
56
  - **Wiring reference forms**, all resolved by the graph, never by orchestrator
56
57
  code:
57
58
  - `$env.<path>` — environment config (e.g. `$env.registry`).
@@ -22,7 +22,6 @@ vi.mock("../lifecycle/release-ledger", async () => {
22
22
  const {
23
23
  maybeRecordAutoRelease,
24
24
  extractRunDigest,
25
- extractRunDigestFromPhaseOutputs,
26
25
  } = await import("./auto-release");
27
26
 
28
27
  function publishRecord(digest: string): DriverStepRecord {
@@ -64,21 +63,6 @@ describe("extractRunDigest", () => {
64
63
  });
65
64
  });
66
65
 
67
- describe("extractRunDigestFromPhaseOutputs", () => {
68
- test("finds the digest across phase outputs (Temporal workflow result shape)", () => {
69
- expect(extractRunDigestFromPhaseOutputs({ Publish: { digest: "sha256:abc", uri: "repo@sha256:abc" }, Apply: { ok: true } })).toBe("sha256:abc");
70
- });
71
-
72
- test("returns undefined for undefined/empty phaseOutputs", () => {
73
- expect(extractRunDigestFromPhaseOutputs(undefined)).toBeUndefined();
74
- expect(extractRunDigestFromPhaseOutputs({})).toBeUndefined();
75
- });
76
-
77
- test("ignores a phase output carrying only a content digest (SBOM, #665)", () => {
78
- expect(extractRunDigestFromPhaseOutputs({ Sbom: { digest: "sha256:sbombytes" } })).toBeUndefined();
79
- });
80
- });
81
-
82
66
  describe("maybeRecordAutoRelease", () => {
83
67
  beforeEach(() => {
84
68
  getHeadCommitMock.mockReset().mockResolvedValue("abc123headsha");
@@ -111,19 +95,19 @@ describe("maybeRecordAutoRelease", () => {
111
95
  expect(pushLifecycleMock).toHaveBeenCalledTimes(1);
112
96
  });
113
97
 
114
- test("a pre-resolved digest (Temporal path) takes precedence and is used directly", async () => {
98
+ test("a pre-resolved digest takes precedence and is used directly", async () => {
115
99
  appendReleaseRecordMock.mockResolvedValue({
116
100
  commit: "b".repeat(40),
117
- record: { version: 1, component: "svc", env: "prod", digest: "sha256:temporal", gitSha: "x", runId: "r", timestamp: "t", actor: "a" },
101
+ record: { version: 1, component: "svc", env: "prod", digest: "sha256:preresolved", gitSha: "x", runId: "r", timestamp: "t", actor: "a" },
118
102
  });
119
103
 
120
104
  await maybeRecordAutoRelease(
121
- { component: "svc", env: "prod", success: true, digest: "sha256:temporal", records: [publishRecord("sha256:ignored")], runId: "run-1" },
105
+ { component: "svc", env: "prod", success: true, digest: "sha256:preresolved", records: [publishRecord("sha256:ignored")], runId: "run-1" },
122
106
  { actor: "alice" },
123
107
  );
124
108
 
125
109
  const [input] = appendReleaseRecordMock.mock.calls[0];
126
- expect(input.digest).toBe("sha256:temporal");
110
+ expect(input.digest).toBe("sha256:preresolved");
127
111
  });
128
112
 
129
113
  test("failure (run.success = false) -> writes nothing", async () => {
@@ -4,23 +4,19 @@
4
4
  * release ledger (../lifecycle/release-ledger.ts) was only populated by the
5
5
  * standalone `chant components release <env>` command — a deploy that never
6
6
  * called it left the ledger silently empty. This module makes recording
7
- * happen *by construction*: the CLI post-run step for both the local
8
- * executor (`runOpComponents`) and the durable Temporal path
9
- * (`runComponentTemporal`) calls `maybeRecordAutoRelease` after the run
10
- * reports success.
7
+ * happen *by construction*: the CLI's post-run step (`runOpComponents`)
8
+ * calls `maybeRecordAutoRelease` after the run reports success.
11
9
  *
12
10
  * Deliberately CLI-side, not driver-side or workflow-side:
13
11
  * - `../components/driver.ts` stays capability-agnostic — it already
14
12
  * resists per-component/per-capability branching, and "write to git"
15
13
  * is exactly the kind of side effect that doesn't belong in a step
16
14
  * dispatcher tests exercise against a bare `CapabilityRegistry`.
17
- * - The Temporal workflow (lexicons/temporal/src/component-op/) must stay
18
- * deterministic and replay-safe. A ledger write is a non-idempotent git
19
- * push with real-world side effects (network, `Date.now()`, file writes
20
- * outside workflow state) — precisely what Temporal workflow code must
21
- * never do directly. It happens in the CLI, after `handle.describe()`
22
- * reports a terminal COMPLETED status, the same place `runOpTemporal`
23
- * already writes its deployment report post-run.
15
+ * - A ledger write is a non-idempotent git push with real-world side
16
+ * effects (network, `Date.now()`, file writes) — the kind of thing that
17
+ * belongs at the edge of a run rather than inside a step a retry may run
18
+ * a second time. It happens in the CLI, once the run has reported a
19
+ * terminal outcome.
24
20
  *
25
21
  * Reuses ../lifecycle/release-ledger.ts's `appendReleaseRecord` verbatim —
26
22
  * this module only decides *whether* to call it and *what digest* to record,
@@ -72,27 +68,6 @@ export function extractRunDigest(records: DriverStepRecord[]): string | undefine
72
68
  return found;
73
69
  }
74
70
 
75
- /**
76
- * Same digest extraction as `extractRunDigest`, but over a component
77
- * Temporal workflow's returned `phaseOutputs` (`{ [phase]: output }`) instead
78
- * of a `DriverStepRecord[]` — the shape `handle.result()` resolves to for a
79
- * COMPLETED component workflow (see lexicons/temporal/src/component-op/
80
- * serializer.ts's generated `return { phaseOutputs, componentOutputs }`).
81
- * Used by the `--temporal` CLI path, which never sees individual step
82
- * records (those exist only inside the workflow/activities).
83
- */
84
- export function extractRunDigestFromPhaseOutputs(
85
- phaseOutputs: Record<string, Record<string, unknown>> | undefined,
86
- ): string | undefined {
87
- let found: string | undefined;
88
- for (const output of Object.values(phaseOutputs ?? {})) {
89
- if (isPromotedArtifact(output) && typeof output.digest === "string") {
90
- found = output.digest;
91
- }
92
- }
93
- return found;
94
- }
95
-
96
71
  /** Explicit reasons `maybeRecordAutoRelease` declined to write a record — never a thrown error, since "nothing to record" (or "opted out") is an expected, common outcome. */
97
72
  export type AutoReleaseSkipReason =
98
73
  | "opted-out"
@@ -105,19 +80,19 @@ export type AutoReleaseResult =
105
80
  | { recorded: false; reason: AutoReleaseSkipReason; detail?: string }
106
81
  | { recorded: false; reason: "error"; error: string };
107
82
 
108
- /** Input describing one component's completed run, common to both the local-executor and Temporal-durable CLI paths. */
83
+ /** Input describing one component's completed run. */
109
84
  export interface AutoReleaseRunInfo {
110
85
  component: string;
111
86
  env: string;
112
- /** Whether the run reported overall success — `DriverRunResult.ok` (local) or a terminal `COMPLETED` Temporal status. A caller must not call this for a non-terminal/in-progress run. */
87
+ /** Whether the run reported overall success (`DriverRunResult.ok`). A caller must not call this for a non-terminal/in-progress run. */
113
88
  success: boolean;
114
89
  /** The component's step records (local executor), used to locate the published digest via `extractRunDigest`. Mutually exclusive with `digest` — pass whichever the caller already has. */
115
90
  records?: DriverStepRecord[];
116
- /** A digest already resolved by the caller (e.g. the `--temporal` path, via `extractRunDigestFromPhaseOutputs` over the workflow's `handle.result()`). Takes precedence over `records` when both are given. */
91
+ /** A digest the caller already resolved by its own means. Takes precedence over `records` when both are given. */
117
92
  digest?: string;
118
- /** Orchestrator run identifier — a Temporal `runId`, or a locally generated id for the local executor (mirrors `runComponentsReleaseRecord`'s `--run-id` default). */
93
+ /** Orchestrator run identifier — a hosting runtime's own run id, or a locally generated one (mirrors `runComponentsReleaseRecord`'s `--run-id` default). */
119
94
  runId: string;
120
- /** The id space `runId` lives in (#2045) — `{ forge: "op" }` for a Temporal run, `{ forge: "local" }` for a local-executor mint. Recorded verbatim as the release record's `runOrigin`. */
95
+ /** The id space `runId` lives in (#2045) — `{ forge: "op" }` for a hosted run, `{ forge: "local" }` for a local-executor mint. Recorded verbatim as the release record's `runOrigin`. */
121
96
  runOrigin?: RunOrigin;
122
97
  /** The bypassed capability-profile divergences, when the caller deliberately overrode a deploy-time profile assertion (chant #1244) — recorded verbatim as the release record's `profileOverride`. */
123
98
  profileOverride?: string;
@@ -142,11 +117,11 @@ function resolveActor(override?: string): string | undefined {
142
117
  }
143
118
 
144
119
  /**
145
- * After a successful `chant run --components <name> --env <env>` (local or
146
- * `--temporal`), append exactly one immutable release record to the ledger
147
- * and push it — or explain, without throwing, why it didn't. Never called
148
- * for a failed run (`run.success` must be true before the caller invokes
149
- * this at all; see `runOpComponents`/`runComponentTemporal`) — a failed
120
+ * After a successful `chant run --components <name> --env <env>`, append
121
+ * exactly one immutable release record to the ledger and push it — or
122
+ * explain, without throwing, why it didn't. Never called for a failed run
123
+ * (`run.success` must be true before the caller invokes this at all; see
124
+ * `runOpComponents`) — a failed
150
125
  * deploy writes nothing, by construction, since this function is simply
151
126
  * never reached on that path.
152
127
  *
@@ -50,10 +50,10 @@ export interface Capability<In = unknown, Out = unknown> {
50
50
  * returned (#1944, epic #1564 phase 4) — a serializable identity channel a
51
51
  * capability can use to recover state `rollback` needs when it cannot rely
52
52
  * on in-process object identity between its `run`/`rollback` calls. The
53
- * local interpret driver (../driver.ts) always threads it through; the
54
- * durable Temporal path (lexicons/temporal/src/component-op/*.ts) threads
55
- * it across the Activity boundary as plain JSON, which is exactly the case
56
- * this exists for — see ./verbs/run-agent.ts's "Rollback identity" doc
53
+ * local interpret driver (../driver.ts) always threads it through; a
54
+ * hosting runtime that splits a run across process boundaries threads it
55
+ * across as plain JSON, which is exactly the case this exists for — see
56
+ * ./verbs/run-agent.ts's "Rollback identity" doc
57
57
  * comment for the motivating gap (a fresh sprite's checkpoint id, recorded
58
58
  * only in an in-process `WeakMap` keyed by `run()`'s `input` object, never
59
59
  * survives to a `rollback()` call that runs as a separate Activity with its
@@ -25,6 +25,7 @@ import {
25
25
  generateComponentsPipeline,
26
26
  } from "./cli-support";
27
27
  import { CapabilityRegistry, type DeployContext } from "./capability";
28
+ import { memoryGateLedgerPort } from "../op/gate";
28
29
  import type { DriverComponent, RunProgressEvent } from "./driver";
29
30
 
30
31
  // A minimal stand-in for the real gitlab lexicon plugin, satisfying
@@ -587,7 +588,7 @@ describe("runComponents", () => {
587
588
  expect(result.error).toContain("svc");
588
589
  });
589
590
 
590
- test("a gate in the selected component is rejected before any step runs", async () => {
591
+ test("a gate in the selected component ends the run pending approval (#2119)", async () => {
591
592
  await writeFile(
592
593
  join(testDir, "svc.component.ts"),
593
594
  `export const svc = { name: "svc", dependsOn: [], deploy: [
@@ -600,11 +601,15 @@ describe("runComponents", () => {
600
601
  const registry = new CapabilityRegistry();
601
602
  registry.register(capability);
602
603
 
603
- const result = await runComponents(testDir, "svc", { registry });
604
+ const gates = memoryGateLedgerPort();
605
+ const result = await runComponents(testDir, "svc", { registry, gates });
604
606
 
605
607
  expect(result.success).toBe(false);
606
- expect(result.gateUnsupported).toEqual({ component: "svc", signalName: "release-approval" });
607
- // Pre-flighted: the deploy-thing step after the gate never ran.
608
+ expect(result.gated?.component).toBe("svc");
609
+ expect(result.gated?.gate.gate).toBe("release-approval");
610
+ expect(result.run?.status).toBe("gated");
611
+ expect(gates.appended).toHaveLength(1);
612
+ // Nothing after the gate ran.
608
613
  expect(capability.calls).toHaveLength(0);
609
614
  });
610
615
 
@@ -844,7 +849,7 @@ describe("resolveComponentTargets — buildParams (chant #1108)", () => {
844
849
  await rm(testDir, { recursive: true, force: true });
845
850
  });
846
851
 
847
- test("forwards buildParams into discovery — the durable (--temporal) path's entrypoint", async () => {
852
+ test("forwards buildParams into discovery — the selector-resolution entrypoint", async () => {
848
853
  await writeFile(
849
854
  join(testDir, "svc.component.ts"),
850
855
  `
@@ -31,12 +31,13 @@ import {
31
31
  runComponentDeploy,
32
32
  UnknownDependencyError,
33
33
  DependencyCycleError,
34
- DriverGateUnsupportedError,
35
34
  DriverRunFailure,
36
35
  type DriverComponent,
37
36
  type DriverPhase,
38
37
  type DriverRunResult,
39
38
  } from "./driver";
39
+ import type { PendingGateRecord } from "../lifecycle/gate-ledger";
40
+ import type { GateLedgerPort } from "../op/gate";
40
41
  import { isLexiconPlugin, type LexiconPlugin, type ComponentPipelineOptions } from "../lexicon";
41
42
  import type { RunProgressEvent } from "./run-progress";
42
43
  import { relative } from "node:path";
@@ -313,11 +314,11 @@ function toDriverComponent(component: { name: string; dependsOn: string[]; deplo
313
314
 
314
315
  /**
315
316
  * Find the first `gate` step anywhere in a component's `deploy`/`rollback`
316
- * composition (including nested fan-out phases), mirroring
317
- * `../op/local-executor.ts`'s `findGate`. Used as a pre-flight check so
318
- * `chant run --components` fails before any step runs — matching
319
- * `runOpLocal`'s behavior for Ops — rather than only failing mid-run when the
320
- * driver itself reaches the gated phase (`DriverGateUnsupportedError`).
317
+ * composition (including nested fan-out phases).
318
+ *
319
+ * A declaration-time question, not a pre-flight refusal: since #2119 the
320
+ * driver decides a gate against the ledger when it reaches one, so nothing
321
+ * needs to know up front that a component has one.
321
322
  */
322
323
  export function findComponentGate(component: DriverComponent): { signalName: string } | undefined {
323
324
  const search = (phases: DriverPhase[] | undefined): { signalName: string } | undefined => {
@@ -406,6 +407,8 @@ export interface RunComponentsOptions {
406
407
  * every test in `cli-support.test.ts`) that doesn't supply this.
407
408
  */
408
409
  buildParams?: BuildParamProvenance[];
410
+ /** Where a `gate` step's facts are read and written (#2119). Defaults to the `chant/lifecycle` orphan branch; a test passes `memoryGateLedgerPort()` from `../op/gate.ts`. */
411
+ gates?: GateLedgerPort;
409
412
  }
410
413
 
411
414
  /** Result of `chant run --components <name|all>`. */
@@ -416,8 +419,8 @@ export interface RunComponentsResult {
416
419
  /** Component names actually dispatched to the driver, in run order. */
417
420
  selected: string[];
418
421
  error?: string;
419
- /** Set when a selected component (or one of its `deploy`/`rollback` phases) contains a `gate` the local executor cannot run. */
420
- gateUnsupported?: { component: string; signalName: string };
422
+ /** Set when the run stopped at a `gate` nobody has approved (#2119): the component it stopped at and the pending fact recorded for it. */
423
+ gated?: { component: string; gate: PendingGateRecord };
421
424
  /** This run's resolved build-time parameters (chant #1108) — the component-driver counterpart of `../cli/commands/build.ts`'s `BuildResult.buildParams`. Present only once the run actually reached dispatch (mirrors `BuildResult.buildParams`, which is likewise absent on an early-error return). */
422
425
  buildParams?: BuildParamProvenance[];
423
426
  }
@@ -428,8 +431,7 @@ export interface RunComponentsResult {
428
431
  * local in-process executor — the CLI entrypoint the driver never had (#585,
429
432
  * follow-up to #556). Discovers the full component set first, then either:
430
433
  * - `selector === "all"`: resolves the whole set's dependency order/waves
431
- * and dispatches every component through `runInterpretDriver`, matching
432
- * what the generated orchestrator Op will eventually do — the same
434
+ * and dispatches every component through `runInterpretDriver`, in the same
433
435
  * order `chant graph --components` reports.
434
436
  * - a single name: dispatches just that component via `runComponentDeploy`,
435
437
  * without requiring the rest of its `dependsOn` graph to be present in
@@ -441,14 +443,12 @@ export interface RunComponentsResult {
441
443
  * infra outside the discovered set (e.g. a shared stack, per the
442
444
  * `search-service` pilot), which is exactly the common case.
443
445
  *
444
- * Pre-flights every selected component for a `gate` step and fails before any
445
- * step runs (`gateUnsupported`), matching `runOpLocal`'s pre-flight
446
- * `findGate` check for Ops — gated components need a durable (Temporal)
447
- * backend, which is out of scope here (issue #585 scopes Temporal-backed
448
- * component execution to what already exists for Ops; the epic tracks
449
- * graduating a gated component to `--temporal` separately).
446
+ * A `gate` no longer refuses the run up front (#2119). The driver decides each
447
+ * one against the gate ledger as it reaches it; a gate nobody has approved
448
+ * stops the run there with `gated` set, which the CLI turns into exit code 3
449
+ * and the `chant approve` line.
450
450
  */
451
- /** Result of resolving a `<name|all>` selector against discovered components — shared by the local (`runComponents`) and durable (Temporal codegen, #589) entrypoints. */
451
+ /** Result of resolving a `<name|all>` selector against discovered components. */
452
452
  export interface ResolvedComponentTargets {
453
453
  success: boolean;
454
454
  targets: DriverComponent[];
@@ -459,10 +459,8 @@ export interface ResolvedComponentTargets {
459
459
  * Discover every component under `path` and resolve `selector` (`"all"` or a
460
460
  * single component name) to the `DriverComponent`(s) to run, with no gate
461
461
  * check and no dispatch — just discovery + selection, factored out of
462
- * `runComponents` so the durable Temporal entrypoint (`chant run --components
463
- * <name> --temporal`, #589) can reuse the exact same selection semantics
464
- * without also inheriting the local executor's pre-flight gate rejection
465
- * (gates are exactly what the durable path exists to support).
462
+ * `runComponents` so another entrypoint can reuse the exact same selection
463
+ * semantics without inheriting the run itself.
466
464
  */
467
465
  export async function resolveComponentTargets(
468
466
  path: string,
@@ -526,17 +524,6 @@ export async function runComponents(
526
524
  }
527
525
  const targets = resolved.targets;
528
526
 
529
- for (const component of targets) {
530
- const gate = findComponentGate(component);
531
- if (gate) {
532
- return {
533
- success: false,
534
- selected: targets.map((c) => c.name),
535
- gateUnsupported: { component: component.name, signalName: gate.signalName },
536
- };
537
- }
538
- }
539
-
540
527
  // (#629) Resolve `chant.config.ts`'s `sbom`/`signing`/`vulnPolicy` sections
541
528
  // and fill their defaults into every recognized step (`generate-sbom`,
542
529
  // `sign`/`attest-provenance`, `verify`, `vuln-gate`) that didn't already
@@ -563,10 +550,25 @@ export async function runComponents(
563
550
  const seedOutputs = options.componentOutputs ?? {};
564
551
  const { onProgress } = options;
565
552
 
553
+ const gates = options.gates;
554
+
566
555
  try {
567
556
  if (selector === "all") {
568
- const run = await runInterpretDriver(resolvedTargets, registry, { env, componentOutputs: seedOutputs, onProgress });
569
- return { success: true, run, selected, buildParams: options.buildParams };
557
+ const run = await runInterpretDriver(resolvedTargets, registry, {
558
+ env,
559
+ componentOutputs: seedOutputs,
560
+ onProgress,
561
+ ...(gates ? { gates } : {}),
562
+ });
563
+ return {
564
+ success: run.status === "ok",
565
+ run,
566
+ selected,
567
+ buildParams: options.buildParams,
568
+ ...(run.status === "gated" && run.gate
569
+ ? { gated: { component: run.gatedComponent ?? selected[0], gate: run.gate } }
570
+ : {}),
571
+ };
570
572
  }
571
573
 
572
574
  // Single-component invocation: run just this component, bypassing
@@ -592,8 +594,9 @@ export async function runComponents(
592
594
  registry,
593
595
  componentOutputs,
594
596
  onProgress,
597
+ gates ? { port: gates } : undefined,
595
598
  );
596
- const status: "ok" | "failed" = componentResult.ok ? "ok" : "failed";
599
+ const status = componentResult.status === "fail" ? "failed" : componentResult.status;
597
600
  onProgress?.({ type: "component-done", wave: 1, component: componentName, status });
598
601
  onProgress?.({ type: "wave-done", wave: 1, status });
599
602
  onProgress?.({ type: "run-done", status });
@@ -602,21 +605,26 @@ export async function runComponents(
602
605
  waves: [selected],
603
606
  results: [componentResult],
604
607
  ok: componentResult.ok,
605
- failedComponent: componentResult.ok ? undefined : componentResult.component,
608
+ status: componentResult.status,
609
+ failedComponent: componentResult.status === "fail" ? componentResult.component : undefined,
610
+ ...(componentResult.status === "gated"
611
+ ? { gatedComponent: componentResult.component, gate: componentResult.gate }
612
+ : {}),
606
613
  componentOutputs,
607
614
  };
608
- return { success: componentResult.ok, run, selected, buildParams: options.buildParams };
615
+ return {
616
+ success: componentResult.ok,
617
+ run,
618
+ selected,
619
+ buildParams: options.buildParams,
620
+ ...(componentResult.status === "gated" && componentResult.gate
621
+ ? { gated: { component: componentResult.component, gate: componentResult.gate } }
622
+ : {}),
623
+ };
609
624
  } catch (err) {
610
625
  if (err instanceof DriverRunFailure) {
611
626
  return { success: false, run: err.result, selected, error: err.message };
612
627
  }
613
- if (err instanceof DriverGateUnsupportedError) {
614
- return {
615
- success: false,
616
- selected,
617
- gateUnsupported: { component: err.component, signalName: err.signalName },
618
- };
619
- }
620
628
  if (err instanceof UnknownDependencyError || err instanceof DependencyCycleError) {
621
629
  return { success: false, selected, error: err.message };
622
630
  }
@@ -162,7 +162,7 @@
162
162
 
163
163
  "Gate": {
164
164
  "type": "object",
165
- "description": "Pauses the composition for an external signal (typically human approval) before continuing. A gate in a component's composition requires the durable (Temporal) execution backend; it cannot run on the local in-process executor.",
165
+ "description": "Ends the run pending human approval. The driver decides a gate against the gate ledger when it reaches one; a gate nobody has approved stops the run there, and `chant approve <component> <gate>` records the resolution the next run reads.",
166
166
  "required": ["kind", "signalName"],
167
167
  "additionalProperties": false,
168
168
  "properties": {
@@ -170,7 +170,7 @@
170
170
  "signalName": {
171
171
  "type": "string",
172
172
  "minLength": 1,
173
- "description": "Signal name the generated workflow waits for before continuing."
173
+ "description": "The gate's name — what `chant approve <component> <gate>` resolves."
174
174
  },
175
175
  "timeout": {
176
176
  "type": "string",
@@ -77,11 +77,11 @@ export interface Step {
77
77
  [param: string]: unknown;
78
78
  }
79
79
 
80
- /** Mirrors `$defs.Gate` — pauses the composition for an external signal (typically human approval). */
80
+ /** Mirrors `$defs.Gate` — a human approval decided against the gate ledger; the run stops here with status `gated` until `chant approve` has answered it. */
81
81
  export interface Gate {
82
82
  kind: "gate";
83
83
  signalName: string;
84
- /** Duration string bounding the wait, e.g. "48h". Default: "48h". */
84
+ /** How long a recorded pending gate stays valid, as a duration string. Default: "48h". */
85
85
  timeout?: string;
86
86
  /** Human-readable description of the action required to unblock this gate. */
87
87
  description?: string;
@@ -170,7 +170,7 @@ export function phase(name: string, steps: Array<Step | Gate | Phase>, opts?: {
170
170
  return { phase: name, steps, ...(opts?.parallel ? { parallel: true } : {}) };
171
171
  }
172
172
 
173
- /** Author a gate step — pauses the composition for an external signal (typically human approval). */
173
+ /** Author a gate step — a human approval the driver decides against the gate ledger, stopping the run `gated` when nothing has answered it. */
174
174
  export function gate(signalName: string, opts?: { timeout?: string; description?: string }): Gate {
175
175
  return { kind: "gate", signalName, ...opts };
176
176
  }
@@ -51,15 +51,27 @@ export function renderDriverHuman(result: DriverRunResult, write: Writer = stder
51
51
  } else {
52
52
  write(` ${mark} ${record.kind} ${formatDuration(record.durationMs)}`);
53
53
  }
54
+ if (record.approval) {
55
+ write(` [approved] ${record.approval.resolvedBy} at ${record.approval.timestamp}` +
56
+ (record.approval.url ? ` (${record.approval.url})` : ""));
57
+ }
54
58
  if (record.error) {
55
59
  write(` ${record.error}`);
56
60
  }
57
61
  }
58
- write(componentResult.ok ? ` component "${componentResult.component}" completed` : ` component "${componentResult.component}" failed`);
62
+ write(
63
+ componentResult.status === "ok"
64
+ ? ` component "${componentResult.component}" completed`
65
+ : componentResult.status === "gated"
66
+ ? ` component "${componentResult.component}" gated on "${componentResult.gate?.gate ?? "?"}"`
67
+ : ` component "${componentResult.component}" failed`,
68
+ );
59
69
  }
60
70
 
61
- if (result.ok) {
71
+ if (result.status === "ok") {
62
72
  write(`interpret run completed (${result.order.length} component(s))`);
73
+ } else if (result.status === "gated") {
74
+ write(`interpret run is gated at component "${result.gatedComponent}"`);
63
75
  } else {
64
76
  write(`interpret run failed at component "${result.failedComponent}"`);
65
77
  }