@intentius/chant 0.57.0 → 0.59.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 (558) 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 +36 -1
  4. package/dist/audit/core.d.ts.map +1 -1
  5. package/dist/audit/discover.d.ts +26 -9
  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/carve-bridge.d.ts.map +1 -1
  34. package/dist/cli/commands/check-lexicon-docs.d.ts +1 -1
  35. package/dist/cli/commands/check-lexicon-examples.d.ts +16 -6
  36. package/dist/cli/commands/check-lexicon-examples.d.ts.map +1 -1
  37. package/dist/cli/commands/init-lexicon/templates/codegen.d.ts +1 -0
  38. package/dist/cli/commands/init-lexicon/templates/codegen.d.ts.map +1 -1
  39. package/dist/cli/commands/init-lexicon/templates/project.d.ts +7 -0
  40. package/dist/cli/commands/init-lexicon/templates/project.d.ts.map +1 -1
  41. package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
  42. package/dist/cli/commands/init.d.ts.map +1 -1
  43. package/dist/cli/commands/lint.d.ts +13 -0
  44. package/dist/cli/commands/lint.d.ts.map +1 -1
  45. package/dist/cli/commands/onboard.d.ts +2 -0
  46. package/dist/cli/commands/onboard.d.ts.map +1 -1
  47. package/dist/cli/handlers/build.d.ts.map +1 -1
  48. package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
  49. package/dist/cli/handlers/operator.d.ts +82 -16
  50. package/dist/cli/handlers/operator.d.ts.map +1 -1
  51. package/dist/cli/handlers/run.d.ts +49 -42
  52. package/dist/cli/handlers/run.d.ts.map +1 -1
  53. package/dist/cli/main.d.ts +12 -1
  54. package/dist/cli/main.d.ts.map +1 -1
  55. package/dist/cli/mcp/op-tools.d.ts +16 -1
  56. package/dist/cli/mcp/op-tools.d.ts.map +1 -1
  57. package/dist/cli/mcp/resource-handlers.d.ts.map +1 -1
  58. package/dist/cli/mcp/resources/context.d.ts.map +1 -1
  59. package/dist/cli/plugins.d.ts +22 -0
  60. package/dist/cli/plugins.d.ts.map +1 -1
  61. package/dist/cli/registry.d.ts +40 -9
  62. package/dist/cli/registry.d.ts.map +1 -1
  63. package/dist/codegen/generate-post-synth-barrel.d.ts +1 -1
  64. package/dist/components/auto-release.d.ts +10 -20
  65. package/dist/components/auto-release.d.ts.map +1 -1
  66. package/dist/components/capability.d.ts +4 -4
  67. package/dist/components/cli-support.d.ts +24 -22
  68. package/dist/components/cli-support.d.ts.map +1 -1
  69. package/dist/components/component.d.ts +21 -6
  70. package/dist/components/component.d.ts.map +1 -1
  71. package/dist/components/driver-output.d.ts.map +1 -1
  72. package/dist/components/driver.d.ts +73 -37
  73. package/dist/components/driver.d.ts.map +1 -1
  74. package/dist/components/index.d.ts +1 -2
  75. package/dist/components/index.d.ts.map +1 -1
  76. package/dist/components/manifest-persistence.d.ts +1 -9
  77. package/dist/components/manifest-persistence.d.ts.map +1 -1
  78. package/dist/components/run-progress.d.ts +6 -6
  79. package/dist/components/run-progress.d.ts.map +1 -1
  80. package/dist/components/verbs/run-agent.d.ts +10 -22
  81. package/dist/components/verbs/run-agent.d.ts.map +1 -1
  82. package/dist/components/verbs/verify.d.ts +2 -2
  83. package/dist/deep-observation.d.ts +17 -0
  84. package/dist/deep-observation.d.ts.map +1 -1
  85. package/dist/detectLexicon.d.ts +13 -0
  86. package/dist/detectLexicon.d.ts.map +1 -1
  87. package/dist/discovery/files.d.ts +4 -4
  88. package/dist/discovery/fold-import.d.ts.map +1 -1
  89. package/dist/discovery/param-deps.d.ts +33 -0
  90. package/dist/discovery/param-deps.d.ts.map +1 -1
  91. package/dist/discovery/sandbox/bundle.d.ts.map +1 -1
  92. package/dist/discovery/sandbox/config-wire.d.ts +2 -2
  93. package/dist/fold/foldable-helpers.d.ts +5 -1
  94. package/dist/fold/foldable-helpers.d.ts.map +1 -1
  95. package/dist/fold-provenance.d.ts +236 -0
  96. package/dist/fold-provenance.d.ts.map +1 -0
  97. package/dist/graph-ops.d.ts +1 -1
  98. package/dist/held-elsewhere.d.ts +85 -0
  99. package/dist/held-elsewhere.d.ts.map +1 -0
  100. package/dist/index.d.ts +3 -0
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/kubectl-context.d.ts +3 -3
  103. package/dist/lexicon-config.d.ts +4 -4
  104. package/dist/lexicon-plugin-helpers.d.ts +1 -1
  105. package/dist/lexicon.d.ts +273 -16
  106. package/dist/lexicon.d.ts.map +1 -1
  107. package/dist/lifecycle/change-set.d.ts +13 -0
  108. package/dist/lifecycle/change-set.d.ts.map +1 -1
  109. package/dist/lifecycle/deep-diff.d.ts +133 -6
  110. package/dist/lifecycle/deep-diff.d.ts.map +1 -1
  111. package/dist/lifecycle/deep-observe.d.ts.map +1 -1
  112. package/dist/lifecycle/gate-ledger.d.ts +79 -3
  113. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  114. package/dist/lifecycle/index.d.ts +1 -0
  115. package/dist/lifecycle/index.d.ts.map +1 -1
  116. package/dist/lifecycle/release-ledger.d.ts +2 -2
  117. package/dist/lifecycle/run-ledger.d.ts +53 -0
  118. package/dist/lifecycle/run-ledger.d.ts.map +1 -0
  119. package/dist/lifecycle/symptoms.d.ts +3 -3
  120. package/dist/lifecycle/symptoms.d.ts.map +1 -1
  121. package/dist/lint/config.d.ts +81 -2
  122. package/dist/lint/config.d.ts.map +1 -1
  123. package/dist/lint/post-synth.d.ts +55 -2
  124. package/dist/lint/post-synth.d.ts.map +1 -1
  125. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts +1 -1
  126. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts.map +1 -1
  127. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts +1 -1
  128. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts.map +1 -1
  129. package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.d.ts +44 -0
  130. package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.d.ts.map +1 -0
  131. package/dist/lint/rules/comp/index.d.ts +1 -1
  132. package/dist/lint/rules/comp/index.d.ts.map +1 -1
  133. package/dist/lint/rules/op/index.d.ts +16 -0
  134. package/dist/lint/rules/op/index.d.ts.map +1 -0
  135. package/dist/lint/rules/op/ops012-activity-contract.d.ts +27 -0
  136. package/dist/lint/rules/op/ops012-activity-contract.d.ts.map +1 -0
  137. package/dist/lint/rules/op/ops013-step-output-ref.d.ts +61 -0
  138. package/dist/lint/rules/op/ops013-step-output-ref.d.ts.map +1 -0
  139. package/dist/lint/rules/op/ops014-converge-rule-refusals.d.ts +55 -0
  140. package/dist/lint/rules/op/ops014-converge-rule-refusals.d.ts.map +1 -0
  141. package/dist/lint/rules/op/support.d.ts +12 -0
  142. package/dist/lint/rules/op/support.d.ts.map +1 -0
  143. package/dist/lint/suppressions.d.ts +108 -0
  144. package/dist/lint/suppressions.d.ts.map +1 -0
  145. package/dist/live-endpoint.d.ts +1 -1
  146. package/dist/op/activities/activity-contracts.d.ts +54 -0
  147. package/dist/op/activities/activity-contracts.d.ts.map +1 -0
  148. package/dist/op/activities/apply.d.ts +262 -0
  149. package/dist/op/activities/apply.d.ts.map +1 -0
  150. package/dist/op/activities/build.d.ts +13 -0
  151. package/dist/op/activities/build.d.ts.map +1 -0
  152. package/dist/op/activities/converge.d.ts +110 -0
  153. package/dist/op/activities/converge.d.ts.map +1 -0
  154. package/dist/op/activities/env-teardown.d.ts +76 -0
  155. package/dist/op/activities/env-teardown.d.ts.map +1 -0
  156. package/dist/op/activities/guard-validate.d.ts +64 -0
  157. package/dist/op/activities/guard-validate.d.ts.map +1 -0
  158. package/dist/op/activities/http-check.d.ts +34 -0
  159. package/dist/op/activities/http-check.d.ts.map +1 -0
  160. package/dist/op/activities/index.d.ts +31 -0
  161. package/dist/op/activities/index.d.ts.map +1 -0
  162. package/dist/op/activities/lexicon-upgrade.d.ts +182 -0
  163. package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -0
  164. package/dist/op/activities/lifecycle.d.ts +42 -0
  165. package/dist/op/activities/lifecycle.d.ts.map +1 -0
  166. package/dist/op/activities/pipeline-audit.d.ts +84 -0
  167. package/dist/op/activities/pipeline-audit.d.ts.map +1 -0
  168. package/dist/op/activities/policy.d.ts +17 -0
  169. package/dist/op/activities/policy.d.ts.map +1 -0
  170. package/dist/op/activities/reconcile.d.ts +149 -0
  171. package/dist/op/activities/reconcile.d.ts.map +1 -0
  172. package/dist/op/activities/shell.d.ts +13 -0
  173. package/dist/op/activities/shell.d.ts.map +1 -0
  174. package/dist/op/activities/teardown.d.ts +10 -0
  175. package/dist/op/activities/teardown.d.ts.map +1 -0
  176. package/dist/op/activities/util.d.ts +7 -0
  177. package/dist/op/activities/util.d.ts.map +1 -0
  178. package/dist/op/activities/wait.d.ts +28 -0
  179. package/dist/op/activities/wait.d.ts.map +1 -0
  180. package/dist/op/activities/workflow-audit.d.ts +92 -0
  181. package/dist/op/activities/workflow-audit.d.ts.map +1 -0
  182. package/dist/op/activity-contract-registry.d.ts +76 -0
  183. package/dist/op/activity-contract-registry.d.ts.map +1 -0
  184. package/dist/op/activity-contract.d.ts +25 -18
  185. package/dist/op/activity-contract.d.ts.map +1 -1
  186. package/dist/op/activity-failure.d.ts +28 -0
  187. package/dist/op/activity-failure.d.ts.map +1 -0
  188. package/dist/op/activity-profiles.d.ts +118 -0
  189. package/dist/op/activity-profiles.d.ts.map +1 -0
  190. package/dist/op/activity-registry.d.ts +22 -38
  191. package/dist/op/activity-registry.d.ts.map +1 -1
  192. package/dist/op/activity-runtime.d.ts +3 -14
  193. package/dist/op/activity-runtime.d.ts.map +1 -1
  194. package/dist/op/builders.d.ts +85 -30
  195. package/dist/op/builders.d.ts.map +1 -1
  196. package/dist/op/change-signal.d.ts +91 -0
  197. package/dist/op/change-signal.d.ts.map +1 -0
  198. package/dist/op/composites/apply-op.d.ts +118 -0
  199. package/dist/op/composites/apply-op.d.ts.map +1 -0
  200. package/dist/op/composites/converge-op.d.ts +120 -0
  201. package/dist/op/composites/converge-op.d.ts.map +1 -0
  202. package/dist/op/composites/index.d.ts +26 -0
  203. package/dist/op/composites/index.d.ts.map +1 -0
  204. package/dist/op/composites/lexicon-upgrade-op.d.ts +78 -0
  205. package/dist/op/composites/lexicon-upgrade-op.d.ts.map +1 -0
  206. package/dist/op/composites/pipeline-audit-op.d.ts +50 -0
  207. package/dist/op/composites/pipeline-audit-op.d.ts.map +1 -0
  208. package/dist/op/composites/reconcile-op.d.ts +57 -0
  209. package/dist/op/composites/reconcile-op.d.ts.map +1 -0
  210. package/dist/op/composites/watch-op.d.ts +60 -0
  211. package/dist/op/composites/watch-op.d.ts.map +1 -0
  212. package/dist/op/composites/workflow-audit-op.d.ts +57 -0
  213. package/dist/op/composites/workflow-audit-op.d.ts.map +1 -0
  214. package/dist/op/converge-rule.d.ts +12 -10
  215. package/dist/op/converge-rule.d.ts.map +1 -1
  216. package/dist/op/cron.d.ts +51 -0
  217. package/dist/op/cron.d.ts.map +1 -0
  218. package/dist/op/discover.d.ts +9 -0
  219. package/dist/op/discover.d.ts.map +1 -1
  220. package/dist/op/duration.d.ts +11 -0
  221. package/dist/op/duration.d.ts.map +1 -0
  222. package/dist/op/emulator-lifecycle.d.ts.map +1 -1
  223. package/dist/op/gate-name.d.ts +40 -0
  224. package/dist/op/gate-name.d.ts.map +1 -0
  225. package/dist/op/gate-summary.d.ts +43 -0
  226. package/dist/op/gate-summary.d.ts.map +1 -0
  227. package/dist/op/gate.d.ts +90 -0
  228. package/dist/op/gate.d.ts.map +1 -0
  229. package/dist/op/generate-pipeline.d.ts +9 -0
  230. package/dist/op/generate-pipeline.d.ts.map +1 -1
  231. package/dist/op/index.d.ts +29 -9
  232. package/dist/op/index.d.ts.map +1 -1
  233. package/dist/op/local-executor.d.ts +114 -28
  234. package/dist/op/local-executor.d.ts.map +1 -1
  235. package/dist/op/local-output.d.ts +11 -1
  236. package/dist/op/local-output.d.ts.map +1 -1
  237. package/dist/op/op-ir.d.ts +185 -0
  238. package/dist/op/op-ir.d.ts.map +1 -0
  239. package/dist/op/op-verb-class.d.ts +10 -2
  240. package/dist/op/op-verb-class.d.ts.map +1 -1
  241. package/dist/op/operator.d.ts +93 -5
  242. package/dist/op/operator.d.ts.map +1 -1
  243. package/dist/op/receipt-store.d.ts +1 -1
  244. package/dist/op/receipt-store.d.ts.map +1 -1
  245. package/dist/op/resource.d.ts +15 -1
  246. package/dist/op/resource.d.ts.map +1 -1
  247. package/dist/op/runtime.d.ts +200 -0
  248. package/dist/op/runtime.d.ts.map +1 -0
  249. package/dist/op/runtimes/local.d.ts +29 -0
  250. package/dist/op/runtimes/local.d.ts.map +1 -0
  251. package/dist/op/step-output-ref.d.ts +15 -13
  252. package/dist/op/step-output-ref.d.ts.map +1 -1
  253. package/dist/op/types.d.ts +96 -29
  254. package/dist/op/types.d.ts.map +1 -1
  255. package/dist/ownership.d.ts +1 -1
  256. package/dist/provenance.d.ts +21 -0
  257. package/dist/provenance.d.ts.map +1 -1
  258. package/dist/serializer-walker.d.ts.map +1 -1
  259. package/dist/terraform/bridge.d.ts +26 -7
  260. package/dist/terraform/bridge.d.ts.map +1 -1
  261. package/dist/terraform/carve-provider.d.ts +28 -2
  262. package/dist/terraform/carve-provider.d.ts.map +1 -1
  263. package/dist/terraform/data-source-shape.d.ts +77 -0
  264. package/dist/terraform/data-source-shape.d.ts.map +1 -0
  265. package/dist/terraform/graph.d.ts.map +1 -1
  266. package/dist/terraform/providers/kubernetes.d.ts +5 -0
  267. package/dist/terraform/providers/kubernetes.d.ts.map +1 -1
  268. package/dist/terraform/tier-map.d.ts +16 -4
  269. package/dist/terraform/tier-map.d.ts.map +1 -1
  270. package/dist/terraform/types.d.ts +8 -0
  271. package/dist/terraform/types.d.ts.map +1 -1
  272. package/package.json +6 -1
  273. package/src/audit/catalog.test.ts +79 -3
  274. package/src/audit/catalog.ts +111 -13
  275. package/src/audit/core.test.ts +26 -0
  276. package/src/audit/core.ts +84 -18
  277. package/src/audit/discover.test.ts +39 -0
  278. package/src/audit/discover.ts +202 -18
  279. package/src/audit/lineage.ts +100 -0
  280. package/src/audit/prior-art.ts +153 -0
  281. package/src/audit/proof.test.ts +67 -0
  282. package/src/audit/proof.ts +70 -0
  283. package/src/audit/report-html.ts +9 -4
  284. package/src/audit/report-model.ts +16 -2
  285. package/src/audit/report.test.ts +33 -0
  286. package/src/audit/report.ts +5 -3
  287. package/src/audit/rules-doc.test.ts +34 -2
  288. package/src/audit/rules-doc.ts +82 -9
  289. package/src/audit/secrets.ts +15 -3
  290. package/src/audit/terraform-state.test.ts +144 -0
  291. package/src/audit/terraform-state.ts +131 -0
  292. package/src/build.ts +31 -1
  293. package/src/claimed-fields.test.ts +145 -0
  294. package/src/claimed-fields.ts +208 -0
  295. package/src/cli/build-params-cli.ts +2 -2
  296. package/src/cli/command-group.ts +14 -0
  297. package/src/cli/commands/__fixtures__/audit-terraform/infra/.terraform/providers/lock.txt +1 -0
  298. package/src/cli/commands/__fixtures__/audit-terraform/infra/main.tf +1 -0
  299. package/src/cli/commands/__fixtures__/audit-terraform/infra/modules/foo/main.tf +1 -0
  300. package/src/cli/commands/__fixtures__/audit-terraform/infra/variables.tf +3 -0
  301. package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +13 -4
  302. package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/docs-cli.ts +4 -0
  303. package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/package.ts +1 -0
  304. package/src/cli/commands/__fixtures__/init-lexicon-output/src/package-cli.ts +21 -0
  305. package/src/cli/commands/__snapshots__/init-lexicon.test.ts.snap +1 -0
  306. package/src/cli/commands/audit.test.ts +191 -11
  307. package/src/cli/commands/audit.ts +78 -28
  308. package/src/cli/commands/build.test.ts +330 -9
  309. package/src/cli/commands/build.ts +170 -24
  310. package/src/cli/commands/carve-bridge.test.ts +237 -14
  311. package/src/cli/commands/carve-bridge.ts +21 -17
  312. package/src/cli/commands/carve-emit-k8s.test.ts +17 -10
  313. package/src/cli/commands/check-lexicon-docs.ts +1 -1
  314. package/src/cli/commands/check-lexicon-examples.test.ts +29 -1
  315. package/src/cli/commands/check-lexicon-examples.ts +42 -10
  316. package/src/cli/commands/init-lexicon/templates/codegen.ts +9 -0
  317. package/src/cli/commands/init-lexicon/templates/project.ts +44 -4
  318. package/src/cli/commands/init-lexicon.test.ts +97 -2
  319. package/src/cli/commands/init-lexicon.ts +4 -2
  320. package/src/cli/commands/init.test.ts +35 -1
  321. package/src/cli/commands/init.ts +14 -3
  322. package/src/cli/commands/lint.test.ts +194 -1
  323. package/src/cli/commands/lint.ts +205 -7
  324. package/src/cli/commands/onboard.test.ts +75 -0
  325. package/src/cli/commands/onboard.ts +54 -23
  326. package/src/cli/handlers/build.test.ts +81 -1
  327. package/src/cli/handlers/build.ts +15 -1
  328. package/src/cli/handlers/graph.test.ts +3 -3
  329. package/src/cli/handlers/lifecycle.test.ts +195 -12
  330. package/src/cli/handlers/lifecycle.ts +123 -6
  331. package/src/cli/handlers/misc.ts +1 -1
  332. package/src/cli/handlers/operator.test.ts +183 -11
  333. package/src/cli/handlers/operator.ts +341 -55
  334. package/src/cli/handlers/run.test.ts +568 -1295
  335. package/src/cli/handlers/run.ts +446 -912
  336. package/src/cli/main.test.ts +22 -16
  337. package/src/cli/main.ts +66 -33
  338. package/src/cli/mcp/op-tools.ts +147 -88
  339. package/src/cli/mcp/resource-handlers.ts +10 -37
  340. package/src/cli/mcp/resources/context.ts +11 -12
  341. package/src/cli/mcp/server.test.ts +25 -27
  342. package/src/cli/mcp/server.ts +2 -2
  343. package/src/cli/plugins.test.ts +68 -2
  344. package/src/cli/plugins.ts +39 -0
  345. package/src/cli/registry.ts +40 -9
  346. package/src/codegen/docs.ts +1 -1
  347. package/src/codegen/generate-post-synth-barrel.test.ts +1 -1
  348. package/src/codegen/generate-post-synth-barrel.ts +1 -1
  349. package/src/components/README.md +4 -3
  350. package/src/components/__fixtures__/neo4j-fanout.json +1 -1
  351. package/src/components/auto-release.test.ts +4 -20
  352. package/src/components/auto-release.ts +17 -42
  353. package/src/components/capability.ts +4 -4
  354. package/src/components/cli-support.test.ts +28 -12
  355. package/src/components/cli-support.ts +60 -47
  356. package/src/components/component-schema.test.ts +18 -2
  357. package/src/components/component.schema.json +18 -5
  358. package/src/components/component.test.ts +2 -2
  359. package/src/components/component.ts +27 -7
  360. package/src/components/config-defaults.test.ts +2 -2
  361. package/src/components/driver-output.ts +14 -2
  362. package/src/components/driver.test.ts +109 -20
  363. package/src/components/driver.ts +201 -84
  364. package/src/components/index.ts +1 -6
  365. package/src/components/manifest-persistence.test.ts +2 -20
  366. package/src/components/manifest-persistence.ts +4 -24
  367. package/src/components/pilots/neo4j-fanout.pilot.ts +3 -3
  368. package/src/components/pilots/pilots-lint-clean.test.ts +11 -10
  369. package/src/components/run-progress.ts +6 -6
  370. package/src/components/verbs/run-agent.test.ts +19 -0
  371. package/src/components/verbs/run-agent.ts +12 -24
  372. package/src/components/verbs/verify.ts +2 -2
  373. package/src/deep-observation.test.ts +75 -0
  374. package/src/deep-observation.ts +48 -0
  375. package/src/detectLexicon.ts +18 -1
  376. package/src/discovery/collect.test.ts +3 -3
  377. package/src/discovery/files.ts +4 -4
  378. package/src/discovery/fold-import.test.ts +1 -1
  379. package/src/discovery/fold-import.ts +105 -2
  380. package/src/discovery/param-deps.test.ts +112 -1
  381. package/src/discovery/param-deps.ts +193 -0
  382. package/src/discovery/sandbox/bundle.ts +15 -1
  383. package/src/discovery/sandbox/config-wire.test.ts +2 -2
  384. package/src/discovery/sandbox/config-wire.ts +2 -2
  385. package/src/fold/fold.test.ts +56 -0
  386. package/src/fold/foldable-helpers.ts +82 -2
  387. package/src/fold-provenance-exclusion.test.ts +186 -0
  388. package/src/fold-provenance.test.ts +495 -0
  389. package/src/fold-provenance.ts +441 -0
  390. package/src/graph-ops.test.ts +3 -3
  391. package/src/graph-ops.ts +1 -1
  392. package/src/held-elsewhere.test.ts +102 -0
  393. package/src/held-elsewhere.ts +114 -0
  394. package/src/index.ts +3 -0
  395. package/src/kubectl-context.ts +3 -3
  396. package/src/lexicon-config.test.ts +5 -5
  397. package/src/lexicon-config.ts +4 -4
  398. package/src/lexicon-plugin-helpers.ts +1 -1
  399. package/src/lexicon.ts +296 -16
  400. package/src/lifecycle/change-set.test.ts +49 -0
  401. package/src/lifecycle/change-set.ts +67 -0
  402. package/src/lifecycle/converge-ledger.ts +1 -1
  403. package/src/lifecycle/deep-diff.test.ts +267 -14
  404. package/src/lifecycle/deep-diff.ts +217 -14
  405. package/src/lifecycle/deep-observe.test.ts +3 -1
  406. package/src/lifecycle/deep-observe.ts +16 -6
  407. package/src/lifecycle/gate-ledger.test.ts +74 -2
  408. package/src/lifecycle/gate-ledger.ts +154 -36
  409. package/src/lifecycle/index.ts +1 -0
  410. package/src/lifecycle/release-ledger.ts +2 -2
  411. package/src/lifecycle/run-ledger.test.ts +268 -0
  412. package/src/lifecycle/run-ledger.ts +201 -0
  413. package/src/lifecycle/symptoms.ts +3 -3
  414. package/src/lint/config.test.ts +82 -1
  415. package/src/lint/config.ts +112 -3
  416. package/src/lint/pipeline-change-gate.test.ts +2 -2
  417. package/src/lint/policy.test.ts +1 -1
  418. package/src/lint/post-synth.test.ts +31 -0
  419. package/src/lint/post-synth.ts +54 -1
  420. package/src/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.ts +2 -2
  421. package/src/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.ts +1 -1
  422. package/src/lint/rules/comp/comp.test.ts +27 -1
  423. package/src/lint/rules/comp/comp004-gate-needs-durable-runtime.ts +76 -0
  424. package/src/lint/rules/comp/index.ts +3 -3
  425. package/src/lint/rules/op/index.ts +23 -0
  426. package/src/lint/rules/op/ops012-activity-contract.test.ts +161 -0
  427. package/src/lint/rules/op/ops012-activity-contract.ts +64 -0
  428. package/src/lint/rules/op/ops013-step-output-ref.test.ts +237 -0
  429. package/src/lint/rules/op/ops013-step-output-ref.ts +98 -0
  430. package/src/lint/rules/op/ops014-converge-rule-refusals.test.ts +263 -0
  431. package/src/lint/rules/op/ops014-converge-rule-refusals.ts +179 -0
  432. package/src/lint/rules/op/support.ts +11 -0
  433. package/src/lint/suppressions.test.ts +163 -0
  434. package/src/lint/suppressions.ts +204 -0
  435. package/src/live-endpoint.ts +1 -1
  436. package/src/op/activities/activity-contracts.ts +66 -0
  437. package/src/op/activities/apply.test.ts +567 -0
  438. package/src/op/activities/apply.ts +662 -0
  439. package/src/op/activities/build.ts +26 -0
  440. package/src/op/activities/converge.test.ts +330 -0
  441. package/src/op/activities/converge.ts +449 -0
  442. package/src/op/activities/env-teardown.test.ts +187 -0
  443. package/src/op/activities/env-teardown.ts +171 -0
  444. package/src/op/activities/guard-validate.test.ts +139 -0
  445. package/src/op/activities/guard-validate.ts +223 -0
  446. package/src/op/activities/http-check.test.ts +48 -0
  447. package/src/op/activities/http-check.ts +55 -0
  448. package/src/op/activities/index.ts +119 -0
  449. package/src/op/activities/lexicon-upgrade.test.ts +492 -0
  450. package/src/op/activities/lexicon-upgrade.ts +673 -0
  451. package/src/op/activities/lifecycle.ts +85 -0
  452. package/src/op/activities/pipeline-audit.test.ts +67 -0
  453. package/src/op/activities/pipeline-audit.ts +201 -0
  454. package/src/op/activities/policy.test.ts +19 -0
  455. package/src/op/activities/policy.ts +37 -0
  456. package/src/op/activities/reconcile.test.ts +161 -0
  457. package/src/op/activities/reconcile.ts +354 -0
  458. package/src/op/activities/shell.ts +26 -0
  459. package/src/op/activities/teardown.ts +22 -0
  460. package/src/op/activities/util.ts +6 -0
  461. package/src/op/activities/wait.ts +69 -0
  462. package/src/op/activities/workflow-audit.test.ts +90 -0
  463. package/src/op/activities/workflow-audit.ts +203 -0
  464. package/src/op/activity-contract-registry.test.ts +98 -0
  465. package/src/op/activity-contract-registry.ts +114 -0
  466. package/src/op/activity-contract.test.ts +1 -1
  467. package/src/op/activity-contract.ts +37 -33
  468. package/src/op/activity-failure.ts +34 -0
  469. package/src/op/activity-profiles.test.ts +56 -0
  470. package/src/op/activity-profiles.ts +116 -0
  471. package/src/op/activity-registry.test.ts +37 -28
  472. package/src/op/activity-registry.ts +27 -56
  473. package/src/op/activity-runtime.ts +3 -47
  474. package/src/op/builders-exports.test.ts +0 -49
  475. package/src/op/builders-typed.test.ts +164 -0
  476. package/src/op/builders.ts +125 -41
  477. package/src/op/change-signal.test.ts +117 -0
  478. package/src/op/change-signal.ts +169 -0
  479. package/src/op/composites/apply-op.ts +218 -0
  480. package/src/op/composites/composites.test.ts +379 -0
  481. package/src/op/composites/converge-op.test.ts +168 -0
  482. package/src/op/composites/converge-op.ts +214 -0
  483. package/src/op/composites/index.ts +26 -0
  484. package/src/op/composites/lexicon-upgrade-op.test.ts +68 -0
  485. package/src/op/composites/lexicon-upgrade-op.ts +134 -0
  486. package/src/op/composites/pipeline-audit-op.test.ts +25 -0
  487. package/src/op/composites/pipeline-audit-op.ts +78 -0
  488. package/src/op/composites/reconcile-op.test.ts +51 -0
  489. package/src/op/composites/reconcile-op.ts +110 -0
  490. package/src/op/composites/watch-op.ts +108 -0
  491. package/src/op/composites/workflow-audit-op.test.ts +25 -0
  492. package/src/op/composites/workflow-audit-op.ts +88 -0
  493. package/src/op/converge-rule.ts +12 -10
  494. package/src/op/cron.test.ts +128 -0
  495. package/src/op/cron.ts +149 -0
  496. package/src/op/discover-root.test.ts +105 -1
  497. package/src/op/discover.test.ts +6 -2
  498. package/src/op/discover.ts +84 -16
  499. package/src/op/duration.ts +21 -0
  500. package/src/op/effect-step.test.ts +29 -14
  501. package/src/op/emulator-lifecycle.ts +1 -2
  502. package/src/op/gate-name.test.ts +65 -0
  503. package/src/op/gate-name.ts +60 -0
  504. package/src/op/gate-summary.ts +84 -0
  505. package/src/op/gate.ts +155 -0
  506. package/src/op/generate-pipeline.test.ts +65 -3
  507. package/src/op/generate-pipeline.ts +19 -2
  508. package/src/op/index.ts +48 -8
  509. package/src/op/local-executor.test.ts +178 -34
  510. package/src/op/local-executor.ts +371 -102
  511. package/src/op/local-output.test.ts +95 -11
  512. package/src/op/local-output.ts +33 -4
  513. package/src/op/op-ir.test.ts +292 -0
  514. package/src/op/op-ir.ts +419 -0
  515. package/src/op/op-verb-class.test.ts +2 -2
  516. package/src/op/op-verb-class.ts +19 -5
  517. package/src/op/op.test.ts +28 -7
  518. package/src/op/operator.test.ts +543 -6
  519. package/src/op/operator.ts +203 -20
  520. package/src/op/receipt-store.ts +1 -1
  521. package/src/op/resource.ts +20 -2
  522. package/src/op/runtime.ts +203 -0
  523. package/src/op/runtimes/local.test.ts +181 -0
  524. package/src/op/runtimes/local.ts +212 -0
  525. package/src/op/step-output-ref.ts +15 -13
  526. package/src/op/types.ts +106 -26
  527. package/src/ownership.ts +1 -1
  528. package/src/provenance.test.ts +6 -0
  529. package/src/provenance.ts +21 -1
  530. package/src/serializer-walker.test.ts +42 -0
  531. package/src/serializer-walker.ts +21 -2
  532. package/src/terraform/aws-resources.test.ts +13 -4
  533. package/src/terraform/bridge.test.ts +22 -9
  534. package/src/terraform/bridge.ts +89 -28
  535. package/src/terraform/carve-provider.ts +38 -2
  536. package/src/terraform/data-source-shape.ts +95 -0
  537. package/src/terraform/graph.ts +35 -7
  538. package/src/terraform/providers/kubernetes.ts +48 -2
  539. package/src/terraform/tier-map.ts +21 -6
  540. package/src/terraform/types.ts +8 -0
  541. package/dist/cli/handlers/op-progress.d.ts +0 -90
  542. package/dist/cli/handlers/op-progress.d.ts.map +0 -1
  543. package/dist/cli/handlers/run-client.d.ts +0 -127
  544. package/dist/cli/handlers/run-client.d.ts.map +0 -1
  545. package/dist/cli/handlers/run-report.d.ts +0 -5
  546. package/dist/cli/handlers/run-report.d.ts.map +0 -1
  547. package/dist/components/temporal-codegen-loader.d.ts +0 -27
  548. package/dist/components/temporal-codegen-loader.d.ts.map +0 -1
  549. package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts +0 -37
  550. package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts.map +0 -1
  551. package/src/cli/handlers/op-progress.test.ts +0 -268
  552. package/src/cli/handlers/op-progress.ts +0 -248
  553. package/src/cli/handlers/run-client.test.ts +0 -82
  554. package/src/cli/handlers/run-client.ts +0 -219
  555. package/src/cli/handlers/run-report.test.ts +0 -62
  556. package/src/cli/handlers/run-report.ts +0 -122
  557. package/src/components/temporal-codegen-loader.ts +0 -41
  558. package/src/lint/rules/comp/comp004-gate-needs-temporal.ts +0 -66
@@ -4,9 +4,7 @@ import type { ResourceDefinition } from "./types";
4
4
  import { getContext } from "./resources/context";
5
5
  import { readSnapshot, readEnvironmentSnapshots } from "../../lifecycle/git";
6
6
  import { discoverOps } from "../../op/discover";
7
- import { makeTemporalClient } from "../handlers/run";
8
- import { resolveWorkflowId, fetchNormalizedHistory } from "../handlers/run-client";
9
- import { extractStepRecords, countActivities, queryGateState } from "../handlers/op-progress";
7
+ import { createLocalOpRuntime } from "../../op/runtimes/local";
10
8
  import { loadOkfBundle } from "../../okf-read";
11
9
  import { loadChantConfigUpward, resolveKnowledgeDir } from "../../config";
12
10
 
@@ -37,7 +35,7 @@ export const coreResourceDefinitions: ResourceDefinition[] = [
37
35
  {
38
36
  uri: "chant://ops/{name}/runs",
39
37
  name: "Op run history",
40
- description: "Workflow run history for a named Op",
38
+ description: "Run history for a named Op, newest first",
41
39
  mimeType: "application/json",
42
40
  },
43
41
  {
@@ -95,10 +93,6 @@ export function collectExamples(
95
93
  return examples;
96
94
  }
97
95
 
98
- function opWorkflowFnName(opName: string): string {
99
- return opName.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase()) + "Workflow";
100
- }
101
-
102
96
  /**
103
97
  * Handle resources/read request — checks plugin resources after core
104
98
  */
@@ -167,7 +161,7 @@ export async function handleResourcesRead(
167
161
  name: config.name,
168
162
  overview: config.overview,
169
163
  phases: config.phases.length,
170
- taskQueue: config.taskQueue ?? config.name,
164
+ labels: config.labels ?? {},
171
165
  depends: config.depends ?? [],
172
166
  }));
173
167
  return {
@@ -175,33 +169,16 @@ export async function handleResourcesRead(
175
169
  };
176
170
  }
177
171
 
172
+ // Both run resources read the built-in local runtime (#2121, #2116) — the
173
+ // one an MCP client can address without naming a lexicon. `status` and `log`
174
+ // answer from the run ledger (#2118), so a run that ended in an earlier
175
+ // process still reads back here.
178
176
  if (uri.startsWith("chant://ops/") && uri.endsWith("/runs/latest")) {
179
177
  const name = uri.replace("chant://ops/", "").replace("/runs/latest", "");
180
178
  try {
181
- const { ops } = await discoverOps();
182
- const config = ops.get(name)?.config;
183
-
184
- const { client } = await makeTemporalClient(undefined, resolve("."));
185
- const handle = client.workflow.getHandle(resolveWorkflowId(name));
186
- const desc = await handle.describe();
187
- const history = await fetchNormalizedHistory(handle);
188
- const { completed: activitiesCompleted, scheduled: activitiesScheduled } = countActivities(history);
189
- const progress = config ? extractStepRecords(config, history, { final: Boolean(desc.closeTime) }) : undefined;
190
- const gate = await queryGateState(handle);
191
- const result = {
192
- workflowId: desc.workflowId,
193
- runId: desc.runId,
194
- status: desc.status.name,
195
- startTime: desc.startTime,
196
- closeTime: desc.closeTime ?? null,
197
- taskQueue: desc.taskQueue,
198
- activitiesCompleted,
199
- activitiesScheduled,
200
- ...(progress ? { progress } : {}),
201
- gate: gate ?? null,
202
- };
179
+ const status = await createLocalOpRuntime({ projectPath: resolve(".") }).status(name);
203
180
  return {
204
- contents: [{ uri, mimeType: "application/json", text: JSON.stringify(result, null, 2) }],
181
+ contents: [{ uri, mimeType: "application/json", text: JSON.stringify(status ?? null, null, 2) }],
205
182
  };
206
183
  } catch (err) {
207
184
  return {
@@ -213,11 +190,7 @@ export async function handleResourcesRead(
213
190
  if (uri.startsWith("chant://ops/") && uri.endsWith("/runs")) {
214
191
  const name = uri.replace("chant://ops/", "").replace("/runs", "");
215
192
  try {
216
- const { client } = await makeTemporalClient(undefined, resolve("."));
217
- const runs: unknown[] = [];
218
- for await (const run of client.workflow.list({ query: `WorkflowType = "${opWorkflowFnName(name)}"` })) {
219
- runs.push({ runId: run.runId, status: run.status.name, startTime: run.startTime, closeTime: run.closeTime ?? null });
220
- }
193
+ const runs = await createLocalOpRuntime({ projectPath: resolve(".") }).log(name);
221
194
  return {
222
195
  contents: [{ uri, mimeType: "application/json", text: JSON.stringify(runs, null, 2) }],
223
196
  };
@@ -49,32 +49,31 @@ chant import template.json # Convert external template
49
49
  chant import template.json -o ./src/ # Custom output dir
50
50
  \`\`\`
51
51
 
52
- ## Ops (Temporal Workflows)
52
+ ## Ops
53
53
 
54
- Ops are durable workflow definitions backed by Temporal. Each \`*.op.ts\` file declares an Op with named phases and activity steps.
54
+ An Op is a convergent verb. Each \`*.op.ts\` file declares one with named phases and activity steps; \`--on <lexicon>\` picks the runtime that hosts the run, and the built-in local runtime runs it in-process otherwise.
55
55
 
56
56
  ### Op MCP Tools
57
57
 
58
58
  | Tool | Description |
59
59
  |---|---|
60
- | \`op-list\` | List all discovered Ops with current run status. Optional \`profile\` param. |
61
- | \`op-run\` | Submit an Op workflow. Requires \`name\`. Worker must already be running via \`chant run <name>\`. |
62
- | \`op-status\` | Get current run state (status, activity counts, times). Requires \`name\`. |
63
- | \`op-signal\` | Send a signal to unblock a gate step. Requires \`name\` and \`signal\`. |
64
- | \`op-report\` | Return a markdown deployment report for the latest run. Requires \`name\`. |
60
+ | \`op-list\` | List all discovered Ops with their current run state. |
61
+ | \`op-run\` | Run an Op and return its result. Requires \`name\`. |
62
+ | \`op-status\` | Get current run state (state, step records, times). Requires \`name\`. |
63
+ | \`op-approve\` | Record a gate's resolution and wake the runtime hosting the run. Requires \`name\` and \`gate\`. |
64
+ | \`op-report\` | Return a markdown report for the latest run. Requires \`name\`. |
65
65
 
66
- All Op tools accept an optional \`profile\` parameter matching a profile name in \`chant.config.ts\` \`temporal.profiles\`.
66
+ All Op tools accept an optional \`runtime\` parameter: a lexicon name whose \`opRuntime\` hosts the run, or \`local\` (the default) for the built-in in-process runtime.
67
67
 
68
68
  ### Op MCP Resources
69
69
 
70
70
  | URI | Description |
71
71
  |---|---|
72
- | \`chant://ops\` | JSON array of all Op definitions (name, overview, phases, taskQueue, depends) |
73
- | \`chant://ops/{name}/runs\` | Workflow run history for a named Op |
72
+ | \`chant://ops\` | JSON array of all Op definitions (name, overview, phase count, labels, depends) |
73
+ | \`chant://ops/{name}/runs\` | Run ledger history for a named Op, newest first |
74
74
  | \`chant://ops/{name}/runs/latest\` | Latest run state for a named Op |
75
75
 
76
- ### Workflow IDs
77
- Ops use deterministic workflow IDs: \`chant-op-<opName>\` (e.g. \`chant-op-alb-deploy\`).
76
+ Both run resources read the built-in local runtime, the one an MCP client can address without naming a lexicon.
78
77
 
79
78
  ## Best Practices
80
79
 
@@ -467,50 +467,50 @@ describe("McpServer", () => {
467
467
  return tool.inputSchema.properties as Record<string, unknown>;
468
468
  }
469
469
 
470
- test("op-list has profile property", async () => {
470
+ test("op-list has a runtime property", async () => {
471
471
  const props = await getToolProps("op-list");
472
- expect(props.profile).toBeDefined();
472
+ expect(props.runtime).toBeDefined();
473
473
  });
474
474
 
475
- test("op-run has name (required) and profile", async () => {
475
+ test("op-run has name (required) and runtime", async () => {
476
476
  const response = await server.handleRequest({ jsonrpc: "2.0", id: 1, method: "tools/list" });
477
477
  const result = response.result as { tools: Array<{ name: string; inputSchema: Record<string, unknown> }> };
478
478
  const tool = result.tools.find((t) => t.name === "op-run")!;
479
479
  const props = tool.inputSchema.properties as Record<string, unknown>;
480
480
  expect(props.name).toBeDefined();
481
- expect(props.profile).toBeDefined();
481
+ expect(props.runtime).toBeDefined();
482
482
  expect(tool.inputSchema.required).toContain("name");
483
483
  });
484
484
 
485
- test("op-status has name (required) and profile", async () => {
485
+ test("op-status has name (required) and runtime", async () => {
486
486
  const response = await server.handleRequest({ jsonrpc: "2.0", id: 1, method: "tools/list" });
487
487
  const result = response.result as { tools: Array<{ name: string; inputSchema: Record<string, unknown> }> };
488
488
  const tool = result.tools.find((t) => t.name === "op-status")!;
489
489
  const props = tool.inputSchema.properties as Record<string, unknown>;
490
490
  expect(props.name).toBeDefined();
491
- expect(props.profile).toBeDefined();
491
+ expect(props.runtime).toBeDefined();
492
492
  expect(tool.inputSchema.required).toContain("name");
493
493
  });
494
494
 
495
- test("op-signal has name and signal (both required) and profile", async () => {
495
+ test("op-approve has name and gate (both required), plus runtime (#2121)", async () => {
496
496
  const response = await server.handleRequest({ jsonrpc: "2.0", id: 1, method: "tools/list" });
497
497
  const result = response.result as { tools: Array<{ name: string; inputSchema: Record<string, unknown> }> };
498
- const tool = result.tools.find((t) => t.name === "op-signal")!;
498
+ const tool = result.tools.find((t) => t.name === "op-approve")!;
499
499
  const props = tool.inputSchema.properties as Record<string, unknown>;
500
500
  expect(props.name).toBeDefined();
501
- expect(props.signal).toBeDefined();
502
- expect(props.profile).toBeDefined();
501
+ expect(props.gate).toBeDefined();
502
+ expect(props.runtime).toBeDefined();
503
503
  expect(tool.inputSchema.required).toContain("name");
504
- expect(tool.inputSchema.required).toContain("signal");
504
+ expect(tool.inputSchema.required).toContain("gate");
505
505
  });
506
506
 
507
- test("op-report has name (required) and profile", async () => {
507
+ test("op-report has name (required) and runtime", async () => {
508
508
  const response = await server.handleRequest({ jsonrpc: "2.0", id: 1, method: "tools/list" });
509
509
  const result = response.result as { tools: Array<{ name: string; inputSchema: Record<string, unknown> }> };
510
510
  const tool = result.tools.find((t) => t.name === "op-report")!;
511
511
  const props = tool.inputSchema.properties as Record<string, unknown>;
512
512
  expect(props.name).toBeDefined();
513
- expect(props.profile).toBeDefined();
513
+ expect(props.runtime).toBeDefined();
514
514
  expect(tool.inputSchema.required).toContain("name");
515
515
  });
516
516
  });
@@ -640,7 +640,7 @@ describe("McpServer", () => {
640
640
  });
641
641
 
642
642
  describe("Op tool handlers", () => {
643
- test("op-list returns list without throwing when Temporal unavailable", async () => {
643
+ test("op-list returns list without throwing when no runtime has a record", async () => {
644
644
  const response = await server.handleRequest({
645
645
  jsonrpc: "2.0",
646
646
  id: 1,
@@ -654,7 +654,7 @@ describe("McpServer", () => {
654
654
  expect(result.isError).toBeUndefined();
655
655
  });
656
656
 
657
- test("op-run returns isError when Temporal unavailable", async () => {
657
+ test("op-run answers for an Op that does not exist", async () => {
658
658
  const response = await server.handleRequest({
659
659
  jsonrpc: "2.0",
660
660
  id: 1,
@@ -663,11 +663,11 @@ describe("McpServer", () => {
663
663
  });
664
664
  expect(response.error).toBeUndefined();
665
665
  const result = response.result as { content: Array<{ text: string }>; isError?: boolean };
666
- // Either "not found" or Temporal error — either way should not be a protocol error
666
+ // Either "not found" or a runtime error — either way, not a protocol error
667
667
  expect(result.content[0].text.length).toBeGreaterThan(0);
668
668
  });
669
669
 
670
- test("op-status returns isError when Temporal unavailable", async () => {
670
+ test("op-status returns isError for an Op that does not exist", async () => {
671
671
  const response = await server.handleRequest({
672
672
  jsonrpc: "2.0",
673
673
  id: 1,
@@ -680,12 +680,12 @@ describe("McpServer", () => {
680
680
  expect(result.content[0].text).toContain("Error:");
681
681
  });
682
682
 
683
- test("op-signal returns isError when Temporal unavailable", async () => {
683
+ test("op-approve returns isError without a gate name (#2121)", async () => {
684
684
  const response = await server.handleRequest({
685
685
  jsonrpc: "2.0",
686
686
  id: 1,
687
687
  method: "tools/call",
688
- params: { name: "op-signal", arguments: { name: "nonexistent-op", signal: "gate" } },
688
+ params: { name: "op-approve", arguments: { name: "nonexistent-op" } },
689
689
  });
690
690
  expect(response.error).toBeUndefined();
691
691
  const result = response.result as { content: Array<{ text: string }>; isError: boolean };
@@ -702,7 +702,7 @@ describe("McpServer", () => {
702
702
  });
703
703
  expect(response.error).toBeUndefined();
704
704
  const result = response.result as { content: Array<{ text: string }>; isError?: boolean };
705
- // Op not found → returns a "not found" message or Temporal error, not a protocol error
705
+ // Op not found → returns a "not found" message or a runtime error, not a protocol error
706
706
  expect(result.content[0].text.length).toBeGreaterThan(0);
707
707
  });
708
708
  });
@@ -973,7 +973,7 @@ describe("McpServer", () => {
973
973
  expect(Array.isArray(ops)).toBe(true);
974
974
  });
975
975
 
976
- test("chant://ops/{name}/runs degrades gracefully when Temporal unavailable", async () => {
976
+ test("chant://ops/{name}/runs is an empty list for an Op with no recorded run", async () => {
977
977
  const response = await server.handleRequest({
978
978
  jsonrpc: "2.0",
979
979
  id: 1,
@@ -982,11 +982,10 @@ describe("McpServer", () => {
982
982
  });
983
983
  expect(response.error).toBeUndefined();
984
984
  const result = response.result as { contents: Array<{ text: string }> };
985
- const data = JSON.parse(result.contents[0].text);
986
- expect(data.error).toBeDefined();
985
+ expect(JSON.parse(result.contents[0].text)).toEqual([]);
987
986
  });
988
987
 
989
- test("chant://ops/{name}/runs/latest degrades gracefully when Temporal unavailable", async () => {
988
+ test("chant://ops/{name}/runs/latest is null for an Op with no recorded run", async () => {
990
989
  const response = await server.handleRequest({
991
990
  jsonrpc: "2.0",
992
991
  id: 1,
@@ -995,8 +994,7 @@ describe("McpServer", () => {
995
994
  });
996
995
  expect(response.error).toBeUndefined();
997
996
  const result = response.result as { contents: Array<{ text: string }> };
998
- const data = JSON.parse(result.contents[0].text);
999
- expect(data.error).toBeDefined();
997
+ expect(JSON.parse(result.contents[0].text)).toBeNull();
1000
998
  });
1001
999
  });
1002
1000
 
@@ -1471,7 +1469,7 @@ describe("McpServer", () => {
1471
1469
  expect(tools).toHaveLength(13);
1472
1470
  expect(tools.map((t) => t.name).sort()).toEqual([
1473
1471
  "build", "explain", "import", "lifecycle-diff", "lifecycle-snapshot", "lint",
1474
- "op-list", "op-report", "op-run", "op-signal", "op-status",
1472
+ "op-approve", "op-list", "op-report", "op-run", "op-status",
1475
1473
  "scaffold", "search",
1476
1474
  ]);
1477
1475
 
@@ -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
  }
@@ -1,6 +1,6 @@
1
1
  import { describe, test, expect } from "vitest";
2
- import { loadPlugin, loadPlugins, resolveLexiconVersions } from "./plugins";
3
- import { isLexiconPlugin } from "../lexicon";
2
+ import { collectChangeSubscribers, loadPlugin, loadPlugins, resolveLexiconVersions } from "./plugins";
3
+ import { isLexiconPlugin, type LexiconPlugin } from "../lexicon";
4
4
 
5
5
  describe("loadPlugin", () => {
6
6
  test("loads aws plugin with full LexiconPlugin interface", async () => {
@@ -61,3 +61,69 @@ describe("resolveLexiconVersions", () => {
61
61
  expect(resolveLexiconVersions([])).toEqual({});
62
62
  });
63
63
  });
64
+
65
+ describe("collectChangeSubscribers (#1981)", () => {
66
+ function fakePlugin(name: string, withSeam: boolean): LexiconPlugin {
67
+ const plugin = {
68
+ name,
69
+ serializer: { name, serialize: () => "" },
70
+ generate: async () => {},
71
+ validate: async () => {},
72
+ coverage: async () => {},
73
+ package: async () => {},
74
+ } as unknown as LexiconPlugin;
75
+ if (withSeam) {
76
+ plugin.subscribeChanges = async () => ({ close: async () => {} });
77
+ }
78
+ return plugin;
79
+ }
80
+
81
+ const entitiesFor = (lexicon: string) =>
82
+ new Map([[lexicon, new Map([["web", { entityType: "K8s::Apps::Deployment", props: {} }]])]]);
83
+
84
+ test("a lexicon without the seam contributes nothing", () => {
85
+ expect(
86
+ collectChangeSubscribers([fakePlugin("aws", false)], {
87
+ environment: "prod",
88
+ entities: entitiesFor("aws"),
89
+ }),
90
+ ).toEqual([]);
91
+ });
92
+
93
+ test("a lexicon with the seam but no declared entities is skipped rather than handed an empty scope", () => {
94
+ expect(
95
+ collectChangeSubscribers([fakePlugin("k8s", true)], {
96
+ environment: "prod",
97
+ entities: new Map(),
98
+ }),
99
+ ).toEqual([]);
100
+ });
101
+
102
+ test("binds the environment, cwd and this lexicon's own entity slice", async () => {
103
+ const plugin = fakePlugin("k8s", true);
104
+ let seen: Record<string, unknown> | undefined;
105
+ plugin.subscribeChanges = async (options) => {
106
+ seen = options as unknown as Record<string, unknown>;
107
+ return { close: async () => {} };
108
+ };
109
+
110
+ const entities = new Map([
111
+ ["k8s", new Map([["web", { entityType: "K8s::Apps::Deployment", props: {} }]])],
112
+ ["aws", new Map([["bucket", { entityType: "AWS::S3::Bucket", props: {} }]])],
113
+ ]);
114
+ const subscribers = collectChangeSubscribers([plugin], { environment: "prod", cwd: "/proj", entities });
115
+ expect(subscribers).toHaveLength(1);
116
+ expect(subscribers[0].lexicon).toBe("k8s");
117
+
118
+ const controller = new AbortController();
119
+ const onChange = () => {};
120
+ const onError = () => {};
121
+ await subscribers[0].subscribe({ onChange, onError, signal: controller.signal });
122
+ expect(seen!.environment).toBe("prod");
123
+ expect(seen!.cwd).toBe("/proj");
124
+ expect(seen!.onChange).toBe(onChange);
125
+ expect(seen!.signal).toBe(controller.signal);
126
+ // This lexicon's slice only: aws's bucket is not in scope for k8s.
127
+ expect([...(seen!.entities as Map<string, unknown>).keys()]).toEqual(["web"]);
128
+ });
129
+ });
@@ -114,6 +114,45 @@ export function collectBuildRootContributors(
114
114
  .map((plugin) => (ctx) => plugin.buildRoots!({ projectRoot, config, entities: ctx?.entities }));
115
115
  }
116
116
 
117
+ /**
118
+ * Bind each loaded plugin's `subscribeChanges` seam (#1981) to one environment
119
+ * and its declared entities, producing the `ChangeSubscriber` list `chant
120
+ * operator`'s loop takes, in the same extract-then-thread shape
121
+ * {@link collectBuildRootContributors} uses, and for the same reason: core's
122
+ * operator must not import plugins.
123
+ *
124
+ * Plugins without the seam contribute nothing, so a project whose lexicons all
125
+ * lack it gets a loop that is exactly the timer it always was. `entities` is
126
+ * the per-lexicon slice of a build's declared entities, which is the bound on
127
+ * what a subscription may watch; a lexicon with no declared entities is
128
+ * skipped rather than handed an empty scope to widen.
129
+ */
130
+ export function collectChangeSubscribers(
131
+ plugins: readonly LexiconPlugin[] | undefined,
132
+ options: {
133
+ environment: string;
134
+ cwd?: string;
135
+ /** Declared entities per lexicon name, from a build. */
136
+ entities: Map<string, Map<string, { entityType: string; props: Record<string, unknown> }>>;
137
+ },
138
+ ): Array<import("../op/operator").ChangeSubscriber> {
139
+ return (plugins ?? [])
140
+ .filter((plugin) => typeof plugin.subscribeChanges === "function")
141
+ .filter((plugin) => (options.entities.get(plugin.name)?.size ?? 0) > 0)
142
+ .map((plugin) => ({
143
+ lexicon: plugin.name,
144
+ subscribe: (ctx) =>
145
+ plugin.subscribeChanges!({
146
+ environment: options.environment,
147
+ ...(options.cwd ? { cwd: options.cwd } : {}),
148
+ entities: options.entities.get(plugin.name),
149
+ onChange: ctx.onChange,
150
+ onError: ctx.onError,
151
+ signal: ctx.signal,
152
+ }),
153
+ }));
154
+ }
155
+
117
156
  /**
118
157
  * Load plugins for all detected lexicon names.
119
158
  * Calls `init()` on each plugin if present.
@@ -18,24 +18,51 @@ 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;
43
+ /**
44
+ * `chant run <op> --gated-exit <code>` (#2243) — the process exit code a
45
+ * run that stopped at an unapproved gate returns, instead of the default 3.
46
+ *
47
+ * Only the gated outcome is remapped. A run that fails still returns 1 and a
48
+ * run that completes still returns 0, so `--gated-exit 0` on a CI job means
49
+ * "a pending approval is not a broken build" and nothing more. The `--json`
50
+ * payload is untouched by it: the record still says `status: "gated"` and
51
+ * still carries the gate and the `chant approve` line, so a job that maps the
52
+ * code to success can still tell the two apart.
53
+ *
54
+ * Accepts 0-255 (a POSIX exit status). Anything else is refused by name.
55
+ */
56
+ gatedExit?: number;
29
57
  /**
30
58
  * `chant run --components <name|all> --progress-json` (local executor) —
31
59
  * stream one NDJSON `RunProgressEvent` (../../components/run-progress.ts)
32
60
  * per line to stdout while the run executes, so a consumer can render live
33
61
  * wave/component/phase/step progress instead of tailing raw logs.
34
62
  *
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.
63
+ * `chant run <name> --progress-json` streams one NDJSON `StepRecord`
64
+ * (../../op/local-executor.ts) per settled step instead, fed by whatever
65
+ * the resolved runtime reports through its `progress` hook (#2121).
39
66
  *
40
67
  * Both are purely additive: run semantics, ordering, and exit code are
41
68
  * unchanged; omitted (undefined, not false) when the flag isn't passed.
@@ -173,7 +200,7 @@ export interface ParsedArgs {
173
200
  * registered in `~/.claude.json`, not just the path argument.
174
201
  */
175
202
  allProjects?: boolean;
176
- /** `chant audit --fail-on merge-worthy|warning|none` */
203
+ /** `chant audit --fail-on merge-worthy|warning|error|none` */
177
204
  failOn?: string;
178
205
  /** `chant audit --theme <file>` — JSON theme knobs for the HTML report */
179
206
  theme?: string;
@@ -251,8 +278,10 @@ export interface ParsedArgs {
251
278
  runId?: string;
252
279
  /** `chant components release record --actor <name>` (#568) — who/what triggered the deploy. */
253
280
  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. */
281
+ /** `--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
282
  approver?: string;
283
+ /** `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. */
284
+ durableRequests?: boolean;
256
285
  /** `chant components status <env> --compare-to <env>` (#568) — a second environment to cross-check the same component's recorded digest against. */
257
286
  compareTo?: string;
258
287
  /** `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 +316,8 @@ export interface ParsedArgs {
287
316
  once?: boolean;
288
317
  /** `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
318
  note?: string;
319
+ /** `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. */
320
+ expire?: boolean;
290
321
  /** `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
322
  op?: string;
292
323
  /** `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"`, `gate`) 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`).
@@ -88,7 +89,7 @@ Lambda function. `component-schema.test.ts` validates every fixture against
88
89
  `component.schema.json` with [ajv](https://ajv.js.org/) (`ajv/dist/2020` — the
89
90
  draft 2020-12 build) and exercises the schema's negative cases (missing
90
91
  required fields, malformed wiring references, an invalid archetype, a gate
91
- missing `signalName`, and so on).
92
+ naming neither `gate` nor its deprecated `signalName` spelling, and so on).
92
93
 
93
94
  ## Typed authoring form (`component.ts`, #560)
94
95
 
@@ -16,7 +16,7 @@
16
16
  {
17
17
  "phase": "Node 1",
18
18
  "steps": [
19
- { "kind": "gate", "signalName": "approve-neo4j-node-1", "description": "Confirm the seed node is healthy before rolling to node 1", "timeout": "24h" },
19
+ { "kind": "gate", "gate": "approve-neo4j-node-1", "description": "Confirm the seed node is healthy before rolling to node 1", "timeout": "24h" },
20
20
  { "kind": "cfn-deploy", "template": "archive:neo4j-1.template.json" },
21
21
  { "kind": "code-deploy", "instance": 1, "revision": "@Seed.templateUri" },
22
22
  { "kind": "wait-cluster-healthy", "quorum": true }