@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
@@ -1,7 +1,7 @@
1
1
  import * as ts from "typescript";
2
2
  import { describe, expect, test } from "vitest";
3
3
  import { collectConsts } from "../fold/fold";
4
- import { collectParamDependencies } from "./param-deps";
4
+ import { collectCompositeOrigins, collectParamDependencies } from "./param-deps";
5
5
  import type { PathOrigin } from "../provenance";
6
6
 
7
7
  /**
@@ -116,3 +116,114 @@ describe("collectParamDependencies", () => {
116
116
  expect(depsOf(source)).toEqual({ name: param("name") });
117
117
  });
118
118
  });
119
+
120
+ /**
121
+ * chant #2161 — the same walk over a composite factory's own parameter.
122
+ *
123
+ * The fixture shape is a factory body: the file is `const f = (<param>) => {
124
+ * <consts> return new Thing({...}); }`, so the body consts are in scope exactly
125
+ * as {@link import("./fold-import").interpretCompositeFactory} arranges them.
126
+ */
127
+ function compositeOriginsOf(
128
+ body: string,
129
+ scope: { whole?: string[]; destructured?: Record<string, string> } = { whole: ["props"] },
130
+ ): Record<string, PathOrigin> {
131
+ const source = `const f = (p) => { ${body} };`;
132
+ const file = ts.createSourceFile("factory.ts", source, ts.ScriptTarget.Latest, true);
133
+
134
+ const consts = new Map<string, ts.Expression>();
135
+ let props: ts.ObjectLiteralExpression | undefined;
136
+ const visit = (node: ts.Node): void => {
137
+ if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer) {
138
+ consts.set(node.name.text, node.initializer);
139
+ }
140
+ if (ts.isNewExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "Thing") {
141
+ for (const argument of node.arguments ?? []) {
142
+ if (ts.isObjectLiteralExpression(argument)) props ??= argument;
143
+ }
144
+ }
145
+ ts.forEachChild(node, visit);
146
+ };
147
+ visit(file);
148
+ if (!props) throw new Error("fixture has no `new Thing({...})`");
149
+
150
+ return collectCompositeOrigins(
151
+ props,
152
+ consts,
153
+ {
154
+ whole: new Set(scope.whole ?? []),
155
+ destructured: new Map(Object.entries(scope.destructured ?? {})),
156
+ },
157
+ "WebService",
158
+ );
159
+ }
160
+
161
+ const fromParam = (...names: string[]): PathOrigin => ({
162
+ kind: "composite-parameter",
163
+ composite: "WebService",
164
+ parameters: names,
165
+ });
166
+ const fixed: PathOrigin = { kind: "composite-literal", composite: "WebService" };
167
+
168
+ describe("collectCompositeOrigins", () => {
169
+ test("a parameter read and a fixed literal are both recorded, at their own paths", () => {
170
+ expect(compositeOriginsOf(`return new Thing({ name: props.name, tier: "prod" });`)).toEqual({
171
+ name: fromParam("name"),
172
+ tier: fixed,
173
+ });
174
+ });
175
+
176
+ test("a nested parameter path keeps its dots", () => {
177
+ expect(compositeOriginsOf(`return new Thing({ path: props.iam.path });`)).toEqual({
178
+ path: fromParam("iam.path"),
179
+ });
180
+ });
181
+
182
+ test("a destructured parameter is the path it was destructured from", () => {
183
+ expect(
184
+ compositeOriginsOf(`return new Thing({ name: name, max: scaling.max });`, {
185
+ destructured: { name: "name", scaling: "scaling" },
186
+ }),
187
+ ).toEqual({ name: fromParam("name"), max: fromParam("scaling.max") });
188
+ });
189
+
190
+ test("a value hoisted into a body const is still attributed", () => {
191
+ expect(
192
+ compositeOriginsOf("const roleName = `role-for-${props.name}`; return new Thing({ roleName });"),
193
+ ).toEqual({ roleName: fromParam("name") });
194
+ });
195
+
196
+ test("a const bound to a sibling resource is NOT followed, so the field reads as fixed", () => {
197
+ expect(
198
+ compositeOriginsOf(`const b = new Bucket({ BucketName: props.name }); return new Thing({ ref: b.Arn });`),
199
+ ).toEqual({ ref: fixed });
200
+ });
201
+
202
+ test("an object literal is descended into; an array is attributed whole", () => {
203
+ expect(
204
+ compositeOriginsOf(`return new Thing({ v: { Status: "Enabled" }, Tags: [{ Key: "t", Value: props.tier }] });`),
205
+ ).toEqual({ "v.Status": fixed, Tags: fromParam("tier") });
206
+ });
207
+
208
+ test("a bare props reference names no single parameter", () => {
209
+ expect(compositeOriginsOf(`return new Thing({ all: props });`)).toEqual({ all: fixed });
210
+ });
211
+
212
+ test("a spread records a parameter it finds and claims nothing when it finds none", () => {
213
+ expect(compositeOriginsOf(`return new Thing({ ...props.extra, name: "n" });`)).toEqual({
214
+ "": fromParam("extra"),
215
+ name: fixed,
216
+ });
217
+ expect(compositeOriginsOf(`return new Thing({ ...defaults, name: "n" });`)).toEqual({ name: fixed });
218
+ });
219
+
220
+ test("a factory with no parameters at all fixes everything", () => {
221
+ expect(compositeOriginsOf(`return new Thing({ name: "n" });`, {})).toEqual({ name: fixed });
222
+ });
223
+
224
+ test("a computed key is skipped rather than guessed at", () => {
225
+ expect(compositeOriginsOf(`return new Thing({ [props.key]: 1, name: props.name });`)).toEqual({
226
+ name: fromParam("name"),
227
+ });
228
+ });
229
+ });
@@ -31,6 +31,13 @@ import type { PathOrigin } from "../provenance";
31
31
  * consts without scope tracking. That reports a parameter the field could
32
32
  * plausibly be governed by rather than one it definitely is, which is the
33
33
  * failure the "could affect" reading is written to absorb.
34
+ *
35
+ * {@link collectCompositeOrigins} (chant #2161) is the same walk pointed at a
36
+ * different parameter object: a composite factory's own props, inside a body
37
+ * the fold interprets. It shares the path grammar, the const-following and the
38
+ * under-reporting posture, and adds the one answer a build parameter has no use
39
+ * for — a path that reads no parameter at all, which for a composite means the
40
+ * field is fixed.
34
41
  */
35
42
 
36
43
  /** The property name a member declares, when it is a literal one. */
@@ -168,3 +175,189 @@ export function collectParamDependencies(
168
175
  walk(props, "");
169
176
  return out;
170
177
  }
178
+
179
+ /**
180
+ * The factory-parameter names in scope inside one composite body (chant #2161).
181
+ *
182
+ * A `Composite()` factory takes at most one argument, so a parameter path is a
183
+ * path INTO that argument: `props.scaling.max` is the parameter path
184
+ * `scaling.max`. Two binding forms reach the same place — `(props) => …` binds
185
+ * the whole object under one name, `({ name, port }) => …` binds leaves — so
186
+ * the scope carries both.
187
+ */
188
+ export interface CompositeParamScope {
189
+ /** Local names bound to the whole props object (`(props) => …`). */
190
+ whole: ReadonlySet<string>;
191
+ /** Local name → the parameter path it was destructured from (`({ name }) => …`). */
192
+ destructured: ReadonlyMap<string, string>;
193
+ }
194
+
195
+ /** The parameter path `node` addresses, or `undefined` when it is not rooted at one. */
196
+ function parameterPathOf(node: ts.Expression, scope: CompositeParamScope): string | undefined {
197
+ const segments: string[] = [];
198
+ let current: ts.Expression = node;
199
+ for (;;) {
200
+ if (ts.isPropertyAccessExpression(current)) {
201
+ segments.unshift(current.name.text);
202
+ current = current.expression;
203
+ continue;
204
+ }
205
+ if (ts.isElementAccessExpression(current) && ts.isStringLiteralLike(current.argumentExpression)) {
206
+ segments.unshift(current.argumentExpression.text);
207
+ current = current.expression;
208
+ continue;
209
+ }
210
+ break;
211
+ }
212
+ if (!ts.isIdentifier(current)) return undefined;
213
+ if (scope.whole.has(current.text)) {
214
+ // A bare `props` addresses no single parameter — the same call the
215
+ // build-param collector makes about a bare `params`.
216
+ return segments.length === 0 ? undefined : segments.join(".");
217
+ }
218
+ const base = scope.destructured.get(current.text);
219
+ if (base === undefined) return undefined;
220
+ return segments.length === 0 ? base : `${base}.${segments.join(".")}`;
221
+ }
222
+
223
+ /**
224
+ * True for a `const` bound to a sibling ENTITY rather than to a value: a
225
+ * `new Type(...)`, or a call (a nested composite, a helper).
226
+ *
227
+ * Following one would answer the wrong question. `const bucket = new Bucket({
228
+ * BucketName: props.name })` and then `Description: bucket.Arn` reads a
229
+ * reference to a sibling the composite wired up, not the value of `name`.
230
+ * Chasing it would report `Description` as governed by `name`, and the return
231
+ * leg would propose editing `name` to fix a field that is a cross-reference. A
232
+ * field wired inside the composite is one the composite fixes, and the refusal
233
+ * is the right answer.
234
+ */
235
+ function isEntityBinding(initializer: ts.Expression): boolean {
236
+ const expr = unwrap(initializer);
237
+ return ts.isNewExpression(expr) || ts.isCallExpression(expr);
238
+ }
239
+
240
+ /**
241
+ * Every factory parameter path `expr` reads, following `consts` so a value
242
+ * hoisted into a body-local `const` is still attributed.
243
+ */
244
+ function readCompositeParameters(
245
+ expr: ts.Expression,
246
+ consts: ReadonlyMap<string, ts.Expression>,
247
+ scope: CompositeParamScope,
248
+ out: Set<string>,
249
+ ): void {
250
+ const followed = new Set<string>();
251
+
252
+ const visit = (node: ts.Node): void => {
253
+ if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) {
254
+ const path = parameterPathOf(node as ts.Expression, scope);
255
+ if (path !== undefined) {
256
+ out.add(path);
257
+ return;
258
+ }
259
+ visit(node.expression);
260
+ if (ts.isElementAccessExpression(node)) visit(node.argumentExpression);
261
+ return;
262
+ }
263
+
264
+ if (ts.isIdentifier(node)) {
265
+ const path = parameterPathOf(node, scope);
266
+ if (path !== undefined) {
267
+ out.add(path);
268
+ return;
269
+ }
270
+ if (scope.whole.has(node.text)) return;
271
+ const initializer = consts.get(node.text);
272
+ if (initializer && !followed.has(node.text) && !isEntityBinding(initializer)) {
273
+ followed.add(node.text);
274
+ visit(initializer);
275
+ }
276
+ return;
277
+ }
278
+
279
+ // A property KEY is not a reference — see `readParams` for the same guard.
280
+ if (ts.isPropertyAssignment(node)) {
281
+ visit(node.initializer);
282
+ return;
283
+ }
284
+
285
+ ts.forEachChild(node, visit);
286
+ };
287
+
288
+ visit(expr);
289
+ }
290
+
291
+ /**
292
+ * Path → composite origin for one `new Type({...})` inside an interpreted
293
+ * composite factory body (chant #2161).
294
+ *
295
+ * Same walk, same path grammar and the same under-reporting posture as
296
+ * {@link collectParamDependencies}, with one added answer: a path whose
297
+ * expression reads NO parameter is recorded as `composite-literal` rather than
298
+ * left silent, because "the composite fixes this" is a finding in its own
299
+ * right — it is what the reconcile refuses on.
300
+ *
301
+ * A spread is the one place nothing is recorded when no parameter is found.
302
+ * Which keys it contributes is not knowable here, so `composite-parameter` at
303
+ * the containing object is a safe over-approximation of "a parameter governs
304
+ * something under here", while `composite-literal` would be a claim that every
305
+ * key it brings is fixed. That claim is left unmade, and those paths come back
306
+ * `unknown` from ../fold-provenance.ts instead.
307
+ */
308
+ export function collectCompositeOrigins(
309
+ props: ts.ObjectLiteralExpression,
310
+ consts: ReadonlyMap<string, ts.Expression>,
311
+ scope: CompositeParamScope,
312
+ composite: string,
313
+ ): Record<string, PathOrigin> {
314
+ const out: Record<string, PathOrigin> = {};
315
+
316
+ const parametersOf = (expr: ts.Expression): string[] => {
317
+ const found = new Set<string>();
318
+ readCompositeParameters(expr, consts, scope, found);
319
+ return [...found].sort();
320
+ };
321
+
322
+ const record = (path: string, expr: ts.Expression, spread: boolean): void => {
323
+ const parameters = parametersOf(expr);
324
+ if (parameters.length > 0) {
325
+ const existing = out[path];
326
+ const merged =
327
+ existing && existing.kind === "composite-parameter"
328
+ ? [...new Set([...existing.parameters, ...parameters])].sort()
329
+ : parameters;
330
+ out[path] = { kind: "composite-parameter", composite, parameters: merged };
331
+ return;
332
+ }
333
+ if (spread) return;
334
+ out[path] ??= { kind: "composite-literal", composite };
335
+ };
336
+
337
+ const walk = (object: ts.ObjectLiteralExpression, prefix: string): void => {
338
+ for (const member of object.properties) {
339
+ if (ts.isSpreadAssignment(member)) {
340
+ record(prefix, member.expression, true);
341
+ continue;
342
+ }
343
+ if (ts.isShorthandPropertyAssignment(member)) {
344
+ const key = member.name.text;
345
+ record(prefix ? `${prefix}.${key}` : key, member.name, false);
346
+ continue;
347
+ }
348
+ if (!ts.isPropertyAssignment(member)) continue;
349
+ const key = literalName(member.name);
350
+ if (key === undefined) continue;
351
+ const path = prefix ? `${prefix}.${key}` : key;
352
+ const initializer = unwrap(member.initializer);
353
+ if (ts.isObjectLiteralExpression(initializer)) {
354
+ walk(initializer, path);
355
+ continue;
356
+ }
357
+ record(path, member.initializer, false);
358
+ }
359
+ };
360
+
361
+ walk(props, "");
362
+ return out;
363
+ }
@@ -27,8 +27,22 @@ const require = createRequire(import.meta.url);
27
27
  * objects re-export their lint rules eagerly — so bundling ANY run-fallback
28
28
  * file that imports a lexicon package pulls `typescript` in transitively,
29
29
  * every time, not just for the rare file that uses the compiler itself.
30
+ *
31
+ * `@cdktf/hcl2json` is here for the same reason and by a longer road. It is
32
+ * an OPTIONAL dependency — `../../terraform/parse.ts` reaches it through
33
+ * `await import(...)` and turns a missing module into an actionable "npm
34
+ * install -D @cdktf/hcl2json" — but esbuild follows a dynamic import as
35
+ * eagerly as a static one, and the package ships a Go `wasm_exec` shim whose
36
+ * `performance` reference does not resolve under `platform: "node"`. So a
37
+ * bundle that merely *reaches* the carve commands fails outright. Reaching
38
+ * them is easy: the fountain lexicon's ACP server dynamically imports
39
+ * `cli/main` to resolve a prompt against chant's verb registry (chant #2125),
40
+ * so every project that imports `@intentius/chant-lexicon-fountain` and needs
41
+ * the run fallback — a `Steward` declaration does, since a composite call
42
+ * cannot fold — pulled the whole CLI, and carve with it, into its sandbox
43
+ * bundle (chant #2129).
30
44
  */
31
- const EXTERNAL_PACKAGES = ["typescript"];
45
+ const EXTERNAL_PACKAGES = ["typescript", "@cdktf/hcl2json"];
32
46
 
33
47
  /**
34
48
  * Resolve each of {@link EXTERNAL_PACKAGES} to its real, absolute path on
@@ -20,9 +20,9 @@ describe("scanConfigWireSafety", () => {
20
20
  buildParams: { tier: { type: "string", default: "light", enum: ["light", "prod"] } },
21
21
  lint: { rules: { COR001: "error", COR002: ["warning", { max: 3 }] }, policies: ["policies/org.ts"] },
22
22
  vulnPolicy: { failSeverity: "critical", license: { allow: ["MIT"], deny: [] } },
23
- // A lexicon's passthrough extension (the temporal lexicon's shape) —
23
+ // A lexicon's passthrough extension —
24
24
  // still pure data.
25
- temporal: { profiles: { local: { address: "localhost:7233", tls: false } }, defaultProfile: "local" },
25
+ k8s: { profiles: { local: { context: "kind-chant", namespace: "default" } }, defaultProfile: "local" },
26
26
  }),
27
27
  ).toEqual([]);
28
28
  });
@@ -39,8 +39,8 @@
39
39
  *
40
40
  * The one way to get there is `ChantConfigSchema`'s `.passthrough()`, which
41
41
  * accepts unknown extra keys of any type (that is how a lexicon extends the
42
- * config — `temporal:` in the temporal lexicon's `TemporalChantConfig`, itself
43
- * pure data). A project that parks a function under such a key gets a clear
42
+ * config — a lexicon's own namespace key, itself pure data). A project that
43
+ * parks a function under such a key gets a clear
44
44
  * error naming it, rather than a config that silently lost it.
45
45
  *
46
46
  * ## The one accepted lossy case: `undefined` object properties
@@ -559,6 +559,62 @@ describe("fold — registered authoring helpers (#1082)", () => {
559
559
  });
560
560
  });
561
561
 
562
+ /**
563
+ * chant #2171. The ConvergeOp rule language joins the allowlist.
564
+ *
565
+ * A `ConvergeOp`'s `rules` table cannot be written without these, so before
566
+ * this every file declaring a converge rule fell back to run. They fold to the
567
+ * same symbolic envelope every other registered helper does; nothing is
568
+ * invoked here, and `../discovery/fold-import.ts` still decides separately
569
+ * whether the name is bound by an import from chant.
570
+ */
571
+ describe("fold: the ConvergeOp rule builders are registered helpers (#2171)", () => {
572
+ test("a whole rule folds to nested envelopes, predicate and action included", () => {
573
+ const consts = parseConsts(
574
+ `const x = when(gt("updateCount", 0), report("drift"), { id: "prod-drift", why: "because" });`,
575
+ );
576
+ const expr = consts.get("x");
577
+ if (!expr) throw new Error("fixture error");
578
+ expect(fold(expr, consts)).toEqual({
579
+ __helper: "when",
580
+ args: [
581
+ { __helper: "gt", args: ["updateCount", 0] },
582
+ { __helper: "report", args: ["drift"] },
583
+ { id: "prod-drift", why: "because" },
584
+ ],
585
+ });
586
+ });
587
+
588
+ test("every comparison, truthiness, combinator and action builder is registered", () => {
589
+ for (const call of [
590
+ `eq("status", "drifted")`,
591
+ `neq("status", "ok")`,
592
+ `gt("updateCount", 0)`,
593
+ `gte("updateCount", 1)`,
594
+ `lt("updateCount", 9)`,
595
+ `lte("updateCount", 9)`,
596
+ `truthy("drifted")`,
597
+ `falsy("drifted")`,
598
+ `allOf(truthy("drifted"))`,
599
+ `anyOf(falsy("drifted"))`,
600
+ `run("prod-apply")`,
601
+ `report("say so")`,
602
+ ]) {
603
+ const consts = parseConsts(`const x = ${call};`);
604
+ const expr = consts.get("x");
605
+ if (!expr) throw new Error(`fixture error: ${call}`);
606
+ expect(fold(expr, consts), call).toMatchObject({ __helper: expect.any(String) });
607
+ }
608
+ });
609
+
610
+ test("a rule builder SHADOWED by a local const is still rejected", () => {
611
+ const consts = parseConsts(`const gt = (f, v) => ({ f, v }); const x = gt("updateCount", 0);`);
612
+ const expr = consts.get("x");
613
+ if (!expr) throw new Error("fixture error");
614
+ expect(() => fold(expr, consts)).toThrow(FoldError);
615
+ });
616
+ });
617
+
562
618
  describe("fold — nullish coalescing, ternary, arithmetic", () => {
563
619
  test("?? falls through only on null/undefined", () => {
564
620
  expect(foldConst(`const x = null ?? "fallback";`, "x")).toBe("fallback");
@@ -66,7 +66,11 @@
66
66
  * `fold()` already rejects a nested `new Type(...)` used as a value for a
67
67
  * real, differential-caught reason (the envelope leaks into
68
68
  * serialization); a factory that returns one is the same hazard wearing a
69
- * call.
69
+ * call. Still true after #2171, which registered the ConvergeOp RULE
70
+ * builders below. Those return plain data that an Op carries; `Op()`
71
+ * itself returns the entity, and a top-level `export const x = Op({...})`
72
+ * folds through the composite spine in `../discovery/fold-import.ts`
73
+ * rather than through this list, which is why it needs no entry here.
70
74
  * - `propagate()`, `withDefaults()`, `resource()`, `mergeDefaults()`
71
75
  * (`../composite.ts`) are composite *definition* helpers, not value-position
72
76
  * helpers. `propagate()` in particular mutates its argument in place, and
@@ -119,7 +123,7 @@ export const FOLDABLE_AUTHORING_HELPERS: readonly FoldableHelperDef[] = [
119
123
  {
120
124
  name: "gate",
121
125
  module: "components/component.ts, op/builders.ts",
122
- note: "Returns a plain `{ kind: 'gate', signalName, ... }` object literal built from its arguments.",
126
+ note: "Returns a plain `{ kind: 'gate', gate, ... }` object literal built from its arguments.",
123
127
  },
124
128
  {
125
129
  name: "activity",
@@ -136,6 +140,82 @@ export const FOLDABLE_AUTHORING_HELPERS: readonly FoldableHelperDef[] = [
136
140
  module: "lexicon-output.ts",
137
141
  note: "Constructs a `LexiconOutput` from a real `AttrRef`/`Intrinsic` and a name. Pure, but identity-sensitive: it reads through the ref's `WeakRef` to its parent entity. Only folds when the ref argument revives to a REAL live reference (see fold-import.ts's `requireLiveRefs`); a symbolic `{ __attrRef }` envelope is rejected, not silently wrapped.",
138
142
  },
143
+ // chant #2171. The ConvergeOp rule language (`op/converge-rule.ts`). Its own
144
+ // module doc is the admission argument: a rule is evaluated per tick against
145
+ // freshly observed data inside an activity, so it must be plain JSON, and
146
+ // every builder below is one statement returning an object literal built from
147
+ // its arguments. `when()` additionally validates `id`, `why` and
148
+ // `flapThreshold` and throws on a bad rule, which is the same build-time
149
+ // refusal the run path performs, at the same point in the build.
150
+ //
151
+ // These are authoring surface in the same sense `phase`/`activity` are: a
152
+ // `ConvergeOp`'s `rules` table cannot be written without them, so before this
153
+ // every file declaring a converge rule fell back to run whatever else it did.
154
+ {
155
+ name: "when",
156
+ module: "op/converge-rule.ts",
157
+ note: "Returns a plain `{ id, when, then, why, flapThreshold? }` rule record built from its arguments. Throws at construction on a missing `id`/`why` or a non-positive `flapThreshold`, which is the build-time refusal the run path performs too, so a bad rule fails identically either way.",
158
+ },
159
+ {
160
+ name: "eq",
161
+ module: "op/converge-rule.ts",
162
+ note: "Returns a plain `{ kind: 'field-comparison', field, op: 'eq', value }` literal built from its arguments.",
163
+ },
164
+ {
165
+ name: "neq",
166
+ module: "op/converge-rule.ts",
167
+ note: "Returns a plain `{ kind: 'field-comparison', field, op: 'neq', value }` literal built from its arguments.",
168
+ },
169
+ {
170
+ name: "gt",
171
+ module: "op/converge-rule.ts",
172
+ note: "Returns a plain `{ kind: 'field-comparison', field, op: 'gt', value }` literal built from its arguments.",
173
+ },
174
+ {
175
+ name: "gte",
176
+ module: "op/converge-rule.ts",
177
+ note: "Returns a plain `{ kind: 'field-comparison', field, op: 'gte', value }` literal built from its arguments.",
178
+ },
179
+ {
180
+ name: "lt",
181
+ module: "op/converge-rule.ts",
182
+ note: "Returns a plain `{ kind: 'field-comparison', field, op: 'lt', value }` literal built from its arguments.",
183
+ },
184
+ {
185
+ name: "lte",
186
+ module: "op/converge-rule.ts",
187
+ note: "Returns a plain `{ kind: 'field-comparison', field, op: 'lte', value }` literal built from its arguments.",
188
+ },
189
+ {
190
+ name: "truthy",
191
+ module: "op/converge-rule.ts",
192
+ note: "Returns a plain `{ kind: 'field-truthiness', field, op: 'truthy' }` literal built from its argument.",
193
+ },
194
+ {
195
+ name: "falsy",
196
+ module: "op/converge-rule.ts",
197
+ note: "Returns a plain `{ kind: 'field-truthiness', field, op: 'falsy' }` literal built from its argument.",
198
+ },
199
+ {
200
+ name: "allOf",
201
+ module: "op/converge-rule.ts",
202
+ note: "Returns a plain `{ kind: 'all-of', predicates }` literal over its already-folded predicate arguments.",
203
+ },
204
+ {
205
+ name: "anyOf",
206
+ module: "op/converge-rule.ts",
207
+ note: "Returns a plain `{ kind: 'any-of', predicates }` literal over its already-folded predicate arguments.",
208
+ },
209
+ {
210
+ name: "run",
211
+ module: "op/converge-rule.ts",
212
+ note: "Returns a plain `{ kind: 'run', op }` action literal. Names an Op for a later tick to dispatch; it runs nothing at fold time, or at any other time.",
213
+ },
214
+ {
215
+ name: "report",
216
+ module: "op/converge-rule.ts",
217
+ note: "Returns a plain `{ kind: 'report', reason }` action literal built from its argument.",
218
+ },
139
219
  ];
140
220
 
141
221
  const HELPER_NAMES: ReadonlySet<string> = new Set(FOLDABLE_AUTHORING_HELPERS.map((h) => h.name));