@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,7 +4,7 @@ import { readFileSync, writeFileSync, readdirSync, statSync } from "fs";
4
4
  import { execFileSync } from "child_process";
5
5
  import { runLint, parseDisableComments } from "../../lint/engine";
6
6
  import type { LintRule, LintDiagnostic, LintFix } from "../../lint/rule";
7
- import type { IntrinsicDef } from "../../lexicon";
7
+ import type { IntrinsicDef, LexiconPlugin } from "../../lexicon";
8
8
  import { loadPlugins, resolveProjectLexicons } from "../plugins";
9
9
  import { formatStylish, formatJson, formatSarif } from "../reporters/stylish";
10
10
  import { loadLocalRules } from "../../lint/rule-loader";
@@ -13,14 +13,19 @@ import { loadComponentChecks } from "../../lint/rules/comp/index";
13
13
  import { runComponentChecks, type ComponentCheckDiagnostic } from "../../lint/component-checks";
14
14
  import { buildCapabilityRegistry } from "../../components/capability-plugin-loader";
15
15
  import type { RollbackPolicy } from "../../components/capability";
16
+ import { coreOpChecks } from "../../lint/rules/op";
17
+ import { loadActivityContracts } from "../../op/activity-contract-registry";
18
+ import { runPostSynthChecks } from "../../lint/post-synth";
16
19
  import { rule } from "../../lint/declarative";
17
20
  import { watchDirectory, formatTimestamp, formatChangedFiles } from "../watch";
18
21
  import { formatError, formatInfo } from "../format";
19
22
  import { GENERATED_MARKER } from "../../discovery/files";
23
+ import { isNoLexiconDetected } from "../../detectLexicon";
20
24
 
21
25
  // Import config loader
22
26
  import { loadConfig, resolveRulesForFile, resolveConfiguredSeverity, findProjectRoot } from "../../lint/config";
23
27
  import { loadChantConfig, resolveKnowledgeDir } from "../../config";
28
+ import { findProjectConfig } from "../../project-root";
24
29
  import type { LintProjectConfig } from "../../lint/rule";
25
30
  import { loadOkfBundle, type OkfBundle } from "../../okf-read";
26
31
 
@@ -88,6 +93,40 @@ export async function loadPluginRules(
88
93
  return pluginRules;
89
94
  }
90
95
 
96
+ /**
97
+ * The diagnostic id `chant lint` reports a lexicon it could not resolve under
98
+ * (chant #2222).
99
+ *
100
+ * Deliberately outside the COR/EVL/COMP/OPS families: those are *rules*, each
101
+ * with a `check()` the engine runs per file, a documented page, a configurable
102
+ * severity and a `chant-disable` escape hatch. This is none of those. It is
103
+ * the lint run reporting that it could not assemble the rule set the project
104
+ * asked for, so it is not silenceable through `rules: { ... : "off" }` or a
105
+ * disable comment. Silencing it would put back the exact "green on a broken
106
+ * project" this id exists to prevent.
107
+ */
108
+ export const LEXICON_RESOLUTION_RULE_ID = "LEX001";
109
+
110
+ /**
111
+ * Turn a lexicon-resolution failure into the error diagnostic `chant lint`
112
+ * reports it as. The message is the underlying error's own, unwrapped, so it
113
+ * is character-for-character what `chant build` prints after `error: ` for the
114
+ * same project (`loadPluginsOrExit`, ../main.ts): one failure, one wording.
115
+ *
116
+ * Attributed to the project's `chant.config.*` where there is one, since that
117
+ * is the file that names the lexicon; to the project root otherwise.
118
+ */
119
+ function lexiconResolutionDiagnostic(projectRoot: string, error: Error): LintDiagnostic {
120
+ return {
121
+ file: findProjectConfig(projectRoot).configPath ?? projectRoot,
122
+ line: 1,
123
+ column: 1,
124
+ ruleId: LEXICON_RESOLUTION_RULE_ID,
125
+ severity: "error",
126
+ message: error.message,
127
+ };
128
+ }
129
+
91
130
  /**
92
131
  * Load all lint rules: core COR/EVL rules, then lexicon plugin rules.
93
132
  *
@@ -100,7 +139,7 @@ export async function loadPluginRules(
100
139
  */
101
140
  async function loadAllPluginRules(
102
141
  projectPath: string,
103
- ): Promise<{ rules: Map<string, LintRule>; intrinsics: IntrinsicDef[] }> {
142
+ ): Promise<{ rules: Map<string, LintRule>; intrinsics: IntrinsicDef[]; lexiconError?: Error }> {
104
143
  const rules = new Map<string, LintRule>();
105
144
 
106
145
  // Load core COR/EVL rules directly
@@ -108,16 +147,47 @@ async function loadAllPluginRules(
108
147
  rules.set(r.id, r);
109
148
  }
110
149
 
111
- // Resolve project lexicons (e.g. ["aws"]) from config or detection
150
+ // Resolve project lexicons (e.g. ["aws"]) from config or detection, then
151
+ // load their plugins.
152
+ //
153
+ // chant #2222: a failure in either step is handed back to `lintCommand`
154
+ // (which reports it as {@link LEXICON_RESOLUTION_RULE_ID}) rather than
155
+ // swallowed or thrown. Both steps fail on the same project state: a
156
+ // `chant.config.ts` that names a lexicon whose package is not installed
157
+ // throws out of `loadPlugins`, and one that *imports* that package throws
158
+ // out of `resolveProjectLexicons` before the names are ever read. Before
159
+ // this, the first case crashed `chant lint` with a stack trace and the
160
+ // second was caught here and discarded, so `chant lint` printed "No
161
+ // problems found" and exited 0 on a project `chant build` refuses to
162
+ // build. A CI job that lints before it builds reported green on a project
163
+ // whose lexicon was missing.
164
+ //
165
+ // The one failure that stays quiet is the one the original `catch` was
166
+ // written for and named in its comment: a project that declares no
167
+ // `lexicons` and imports none from its source files, where the detection
168
+ // fallback throws `NO_LEXICON_DETECTED_MESSAGE`. That project lints under
169
+ // the core rules alone and always has. It is told apart by the exported
170
+ // sentinel rather than by a string literal copied to this file, so the two
171
+ // cannot drift apart.
112
172
  let lexiconNames: string[] = [];
173
+ let lexiconError: Error | undefined;
113
174
  try {
114
175
  lexiconNames = await resolveProjectLexicons(projectPath);
115
- } catch {
116
- // No lexicons detected — core rules only
176
+ } catch (err) {
177
+ if (!isNoLexiconDetected(err)) {
178
+ lexiconError = err instanceof Error ? err : new Error(String(err));
179
+ }
117
180
  }
118
181
 
119
182
  // Load only project lexicon plugins (no "chant" injection)
120
- const plugins = await loadPlugins(lexiconNames);
183
+ let plugins: LexiconPlugin[] = [];
184
+ if (!lexiconError) {
185
+ try {
186
+ plugins = await loadPlugins(lexiconNames);
187
+ } catch (err) {
188
+ lexiconError = err instanceof Error ? err : new Error(String(err));
189
+ }
190
+ }
121
191
 
122
192
  // chant #1106 — the same plugins' registered intrinsics (`Ref`, `GetAtt`,
123
193
  // ...), so EVL001 can answer "does this call fold?" exactly like fold()
@@ -147,7 +217,7 @@ async function loadAllPluginRules(
147
217
  rules.set(r.id, r);
148
218
  }
149
219
 
150
- return { rules, intrinsics };
220
+ return { rules, intrinsics, ...(lexiconError ? { lexiconError } : {}) };
151
221
  }
152
222
 
153
223
  /**
@@ -420,6 +490,113 @@ async function runComponentCheckDiagnostics(
420
490
  return { diagnostics, suppressed };
421
491
  }
422
492
 
493
+ /**
494
+ * Run the OPS* Op-model post-synth checks (#2122, epic #2114 sub-issue 6 —
495
+ * OPS012/OPS013/OPS014, ported from a hosting lexicon's own
496
+ * TMP012/TMP013/TMP014) over every `*.op.ts` file under the lint target and
497
+ * merge them into the same diagnostics/suppressed lists `chant lint` already
498
+ * reports through, the same treatment {@link runComponentCheckDiagnostics}
499
+ * above gives COMP*.
500
+ *
501
+ * Deliberately scoped DOWNWARD from `infraPath` — the same scan
502
+ * `getTypeScriptFiles` already ran to build `files` — rather than
503
+ * `../../op/discover.ts`'s `discoverOps`, which walks UP to the nearest
504
+ * project root (or the git root, absent a config file) precisely because a
505
+ * real project's `ops/` convention sits outside `sourceDir`. That upward
506
+ * walk is right for `chant run`/`chant build`, which always operate on one
507
+ * whole project; it is wrong here, because `chant lint <path>` (and every
508
+ * fixture-scoped test that calls this file's `lintCommand`) may point at a
509
+ * directory with no `chant.config.*` above it short of this repo's own git
510
+ * root — which would make this check import every `*.op.ts` file in the
511
+ * entire monorepo on every such call. Scanning only under `infraPath`, like
512
+ * every other check in this function, keeps this check's cost proportional
513
+ * to the target the caller actually asked to lint.
514
+ *
515
+ * Each `*.op.ts` file's default export is imported directly and used as-is
516
+ * (it is already the `Declarable` `OpResource` instance `Op()` built) — no
517
+ * serializer and no lexicon plugin needed, since OPS012/OPS013/OPS014 only
518
+ * ever read `ctx.entities`, never `ctx.outputs`. That's what lets this fire
519
+ * even on a project with no lexicons configured at all.
520
+ *
521
+ * The project's configured lexicon NAMES are read, though (chant #2101), to
522
+ * resolve the activity contracts each one declares at
523
+ * `@intentius/chant-lexicon-<name>/op/activity-contracts` — one dynamic
524
+ * import per lexicon, no plugin load. Without them a step calling a
525
+ * lexicon's activity is flagged for the absence of a contract that lexicon
526
+ * does declare, which is the whole point of OPS013 firing outside a build.
527
+ *
528
+ * Reported at `1:1` in the file the Op was declared in, the same whole-file
529
+ * convention COMP* diagnostics use — a post-synth finding carries no real
530
+ * line/column (../../lint/post-synth.ts's `PostSynthDiagnostic` doc) and
531
+ * there's no per-file disable-directive suppression for the same reason
532
+ * (that doc again), so this reads only `lint.rules` severity overrides, not
533
+ * `chant-disable` comments.
534
+ */
535
+ async function runOpCheckDiagnostics(
536
+ infraPath: string,
537
+ files: string[],
538
+ ): Promise<{ diagnostics: LintDiagnostic[]; suppressed: Array<LintDiagnostic & { reason?: string }> }> {
539
+ const config = loadConfig(findProjectRoot(infraPath));
540
+ const opFiles = files.filter((f) => f.endsWith(".op.ts"));
541
+ if (opFiles.length === 0) return { diagnostics: [], suppressed: [] };
542
+
543
+ const entities = new Map<string, unknown>();
544
+ const fileByOpName = new Map<string, string>();
545
+ for (const filePath of opFiles) {
546
+ try {
547
+ const mod: unknown = await import(filePath);
548
+ const entity = (mod as { default?: unknown }).default;
549
+ if (!entity || typeof entity !== "object") continue;
550
+ const opConfig = (entity as { props?: unknown }).props as { name?: unknown; phases?: unknown } | undefined;
551
+ if (!opConfig || typeof opConfig.name !== "string" || !Array.isArray(opConfig.phases)) continue;
552
+ entities.set(opConfig.name, entity);
553
+ fileByOpName.set(opConfig.name, filePath);
554
+ } catch {
555
+ // A file that fails to import is somebody else's problem — a syntax
556
+ // error surfaces through the AST rule pass over the same file instead
557
+ // of crashing this one.
558
+ continue;
559
+ }
560
+ }
561
+
562
+ if (entities.size === 0) return { diagnostics: [], suppressed: [] };
563
+
564
+ const lexiconNames = await resolveProjectLexicons(infraPath).catch(() => [] as string[]);
565
+ const activityContracts = await loadActivityContracts(lexiconNames);
566
+
567
+ const raw = runPostSynthChecks(
568
+ coreOpChecks(),
569
+ {
570
+ outputs: new Map(),
571
+ entities: entities as Map<string, never>,
572
+ warnings: [],
573
+ errors: [],
574
+ sourceFileCount: opFiles.length,
575
+ },
576
+ undefined,
577
+ { activityContracts },
578
+ );
579
+
580
+ const diagnostics: LintDiagnostic[] = [];
581
+ const suppressed: Array<LintDiagnostic & { reason?: string }> = [];
582
+
583
+ for (const d of raw) {
584
+ const resolved = resolveConfiguredSeverity(config.rules, d.checkId, d.severity);
585
+ if (resolved.severity === "off") continue;
586
+
587
+ diagnostics.push({
588
+ file: (d.entity && fileByOpName.get(d.entity)) ?? infraPath,
589
+ line: 1,
590
+ column: 1,
591
+ ruleId: d.checkId,
592
+ severity: resolved.severity,
593
+ message: d.message,
594
+ });
595
+ }
596
+
597
+ return { diagnostics, suppressed };
598
+ }
599
+
423
600
  /**
424
601
  * Apply fixes to a file
425
602
  */
@@ -523,6 +700,13 @@ export async function lintCommand(options: LintOptions): Promise<LintResult> {
523
700
  diagnostics.push(...componentResult.diagnostics);
524
701
  suppressed.push(...componentResult.suppressed);
525
702
 
703
+ // Run the OPS* Op-model post-synth checks (#2122) over every `*.op.ts`
704
+ // file under the lint target — see runOpCheckDiagnostics's doc for why
705
+ // this needs no lexicon or build to fire.
706
+ const opResult = await runOpCheckDiagnostics(infraPath, files);
707
+ diagnostics.push(...opResult.diagnostics);
708
+ suppressed.push(...opResult.suppressed);
709
+
526
710
  // Apply fixes if requested
527
711
  if (options.fix) {
528
712
  // Group fixes by file
@@ -570,6 +754,20 @@ export async function lintCommand(options: LintOptions): Promise<LintResult> {
570
754
  const postComponentResult = await runComponentCheckDiagnostics(infraPath, options.sandbox, options.buildParams);
571
755
  diagnostics.push(...postComponentResult.diagnostics);
572
756
  suppressed.push(...postComponentResult.suppressed);
757
+
758
+ // OPS* checks have no `.fix` either; re-run for the same consistency
759
+ // reason as the COMP* re-run just above.
760
+ const postOpResult = await runOpCheckDiagnostics(infraPath, files);
761
+ diagnostics.push(...postOpResult.diagnostics);
762
+ suppressed.push(...postOpResult.suppressed);
763
+ }
764
+
765
+ // chant #2222: a lexicon the project declared but this run could not
766
+ // resolve. Appended here, after the `--fix` re-lint block above has finished
767
+ // reassigning `diagnostics`, so it survives every path; it is a property of
768
+ // the run, not of any file a fix could touch.
769
+ if (loaded.lexiconError) {
770
+ diagnostics.push(lexiconResolutionDiagnostic(projectRoot, loaded.lexiconError));
573
771
  }
574
772
 
575
773
  // Count errors and warnings
@@ -72,6 +72,53 @@ jobs:
72
72
  run: npm run --prefix lexicons/k8s prepack
73
73
  `;
74
74
 
75
+ // Mirrors the real chant.yml's check + test jobs: a comment (the cedar note)
76
+ // sitting mid-list splits what would otherwise be one contiguous run of
77
+ // prepack lines into two groups of 2+, so the old grouping wrote the new
78
+ // lexicon's line twice per job (#2098).
79
+ const ciContentWithMidListComment = `name: chant
80
+ on: [push]
81
+ jobs:
82
+ check:
83
+ steps:
84
+ - name: Generate lexicon artifacts
85
+ run: |
86
+ npm run --prefix lexicons/aws prepack
87
+ npm run --prefix lexicons/gitlab prepack
88
+ # cedar generates from the project's own .cedarschema, falling
89
+ # back to the schema bundled at src/spec/default-schema.cedarschema
90
+ # so a clean checkout still produces a surface to gate (#1650).
91
+ npm run --prefix lexicons/cedar prepack
92
+ npm run --prefix lexicons/k8s prepack
93
+ - name: Run tests
94
+ run: npx vitest run
95
+
96
+ test:
97
+ steps:
98
+ - name: Generate lexicon artifacts
99
+ run: |
100
+ npm run --prefix lexicons/aws prepack
101
+ npm run --prefix lexicons/gitlab prepack
102
+ # cedar generates from the project's own .cedarschema, falling
103
+ # back to the schema bundled at src/spec/default-schema.cedarschema
104
+ # so a clean checkout still produces a surface to gate (#1650).
105
+ npm run --prefix lexicons/cedar prepack
106
+ npm run --prefix lexicons/k8s prepack
107
+ - name: Run tests
108
+ run: npx vitest run
109
+
110
+ validate:
111
+ steps:
112
+ - name: Generate and validate AWS lexicon
113
+ run: npm run --prefix lexicons/aws prepack
114
+
115
+ - name: Generate and validate GitLab lexicon
116
+ run: npm run --prefix lexicons/gitlab prepack
117
+
118
+ - name: Generate and validate K8s lexicon
119
+ run: npm run --prefix lexicons/k8s prepack
120
+ `;
121
+
75
122
  const publishContent = `name: publish
76
123
  on:
77
124
  push:
@@ -217,6 +264,34 @@ describe("onboardCommand", () => {
217
264
  const docker = readFileSync(join(root, "test/Dockerfile.smoke"), "utf-8");
218
265
  expect(docker.match(/terraform/g)?.length).toBe(1);
219
266
  });
267
+
268
+ test("a comment mid-list in check/test run blocks does not split the group: one insertion per block (#2098)", () => {
269
+ writeFileSync(join(root, ".github/workflows/chant.yml"), ciContentWithMidListComment);
270
+
271
+ const result = onboardCommand({ name: "terraform", root });
272
+ expect(result.patched).toContain("chant.yml (prepack + validate)");
273
+
274
+ const ci = readFileSync(join(root, ".github/workflows/chant.yml"), "utf-8");
275
+ // check + test + validate: exactly one new line per job, not two per job
276
+ // from the comment splitting the run: | block into two groups.
277
+ expect(ci.match(/lexicons\/terraform prepack/g)?.length).toBe(3);
278
+
279
+ const [checkBlock, rest] = ci.split(" test:");
280
+ const [testBlock, validateBlock] = rest.split(" validate:");
281
+
282
+ expect(checkBlock.match(/lexicons\/terraform prepack/g)?.length).toBe(1);
283
+ expect(testBlock.match(/lexicons\/terraform prepack/g)?.length).toBe(1);
284
+ expect(validateBlock.match(/lexicons\/terraform prepack/g)?.length).toBe(1);
285
+
286
+ // The new line lands after the block's last prepack line (k8s, past the
287
+ // comment), not right after the comment's first half of the group.
288
+ expect(checkBlock).toContain(
289
+ " npm run --prefix lexicons/k8s prepack\n npm run --prefix lexicons/terraform prepack\n",
290
+ );
291
+ expect(testBlock).toContain(
292
+ " npm run --prefix lexicons/k8s prepack\n npm run --prefix lexicons/terraform prepack\n",
293
+ );
294
+ });
220
295
  });
221
296
 
222
297
  describe("root tsconfig.json paths (#1614)", () => {
@@ -5,6 +5,7 @@ import { formatSuccess, formatError, formatWarning } from "../format";
5
5
 
6
6
  export interface OnboardOptions {
7
7
  name: string;
8
+ /** Run `chant dev check-lexicon` and print its full output (see `printOnboardResult`). */
8
9
  verbose?: boolean;
9
10
  /** Monorepo root to patch. Defaults to the root this module lives in. */
10
11
  root?: string;
@@ -14,6 +15,7 @@ export interface OnboardResult {
14
15
  success: boolean;
15
16
  patched: string[];
16
17
  skipped: string[];
18
+ verbose?: boolean;
17
19
  error?: string;
18
20
  }
19
21
 
@@ -41,6 +43,13 @@ function isPrepackLine(line: string): boolean {
41
43
  return PREPACK_LINE.test(line);
42
44
  }
43
45
 
46
+ /** A YAML comment line, e.g. the cedar note sitting mid-list in chant.yml. */
47
+ const COMMENT_LINE = /^\s*#/;
48
+
49
+ function isCommentLine(line: string): boolean {
50
+ return COMMENT_LINE.test(line);
51
+ }
52
+
44
53
  function hasPrepackLine(lines: string[], name: string): boolean {
45
54
  return lines.some((l) => isPrepackLine(l) && l.includes(`lexicons/${name} prepack`));
46
55
  }
@@ -137,27 +146,46 @@ export function patchRootTsconfigPaths(root: string, name: string): PatchResult
137
146
 
138
147
  /**
139
148
  * Insert a new prepack line after the last prepack line in each contiguous group
140
- * of 2+ lines. Single standalone lines (like YAML `run:` values) are ignored.
141
- * Used for multi-line `run: |` blocks in workflows.
149
+ * of 2+ prepack lines. Single standalone lines (like YAML `run:` values) are
150
+ * ignored. Used for multi-line `run: |` blocks in workflows.
151
+ *
152
+ * A comment line between two prepack lines (the cedar note in chant.yml's
153
+ * check and test jobs) does not end the group: it is skipped when scanning,
154
+ * so the block still gets exactly one insertion, anchored after its last
155
+ * real prepack line rather than after the comment (#2098).
142
156
  */
143
157
  function insertPrepackInContiguousGroups(lines: string[], name: string): boolean {
144
158
  if (hasPrepackLine(lines, name)) return false;
145
159
 
146
- // Identify contiguous groups of prepack lines
147
- const groups: { start: number; end: number }[] = [];
160
+ // Identify contiguous groups of prepack lines, treating comment lines
161
+ // inside a group as pass-through rather than a boundary.
162
+ const groups: { lastPrepackIdx: number; count: number }[] = [];
148
163
  let groupStart = -1;
149
- for (let i = 0; i <= lines.length; i++) {
150
- const isPrepack = i < lines.length && isPrepackLine(lines[i]);
151
- if (isPrepack && groupStart === -1) {
152
- groupStart = i;
153
- } else if (!isPrepack && groupStart !== -1) {
154
- groups.push({ start: groupStart, end: i - 1 });
155
- groupStart = -1;
164
+ let lastPrepackIdx = -1;
165
+ let count = 0;
166
+
167
+ const closeGroup = () => {
168
+ if (groupStart !== -1) groups.push({ lastPrepackIdx, count });
169
+ groupStart = -1;
170
+ count = 0;
171
+ };
172
+
173
+ for (let i = 0; i < lines.length; i++) {
174
+ if (isPrepackLine(lines[i])) {
175
+ if (groupStart === -1) groupStart = i;
176
+ lastPrepackIdx = i;
177
+ count++;
178
+ } else if (isCommentLine(lines[i])) {
179
+ // Skip: does not extend a group on its own, and does not close one.
180
+ continue;
181
+ } else {
182
+ closeGroup();
156
183
  }
157
184
  }
185
+ closeGroup();
158
186
 
159
- // Only insert into groups of 2+ lines (multi-line blocks, not standalone steps)
160
- const insertAfter = groups.filter((g) => g.end > g.start).map((g) => g.end);
187
+ // Only insert into groups of 2+ prepack lines (multi-line blocks, not standalone steps)
188
+ const insertAfter = groups.filter((g) => g.count > 1).map((g) => g.lastPrepackIdx);
161
189
 
162
190
  if (insertAfter.length === 0) return false;
163
191
 
@@ -332,7 +360,7 @@ export function onboardCommand(options: OnboardOptions): OnboardResult {
332
360
  patchDockerfile(join(root, "test/Dockerfile.smoke-npm"), options.name),
333
361
  );
334
362
 
335
- return { success: true, patched, skipped };
363
+ return { success: true, patched, skipped, verbose: options.verbose };
336
364
  }
337
365
 
338
366
  /**
@@ -365,20 +393,23 @@ export async function printOnboardResult(result: OnboardResult, name: string): P
365
393
  console.log(` (must depend on @intentius/chant-lexicon-${name} for workspace resolution)`);
366
394
  console.log(` 2. Add smoke tests to test/integration.sh`);
367
395
  console.log(` 3. Run: npm install (to update workspace links)`);
368
- console.log(` 4. First npm publish: tag with v<version> and push`);
396
+ console.log(` 4. First release: just release-lexicon ${name} patch`);
369
397
  console.log(` 5. Run: chant dev check-lexicon lexicons/${name} (to see completeness status)`);
370
398
  console.log(formatWarning({
371
399
  message: "First-time scoped packages may publish as private despite --access public",
372
400
  }));
373
401
  console.log(` Check https://www.npmjs.com/org/intentius and toggle visibility if needed`);
374
402
 
375
- // Run check-lexicon if the lexicon directory exists
376
- const lexiconDir = join(findRepoRoot(), "lexicons", name);
377
- if (existsSync(lexiconDir)) {
378
- console.log("");
379
- console.log("Lexicon completeness:");
380
- const { checkLexicon, printCheckResult } = await import("./check-lexicon");
381
- const checkResult = await checkLexicon(lexiconDir);
382
- printCheckResult(checkResult, false);
403
+ // Under --verbose, run check-lexicon now instead of leaving step 5 to the
404
+ // author, printing the full tier 1/2/3 detail rather than just the summary above.
405
+ if (result.verbose) {
406
+ const lexiconDir = join(findRepoRoot(), "lexicons", name);
407
+ if (existsSync(lexiconDir)) {
408
+ console.log("");
409
+ console.log("Lexicon completeness:");
410
+ const { checkLexicon, printCheckResult } = await import("./check-lexicon");
411
+ const checkResult = await checkLexicon(lexiconDir);
412
+ printCheckResult(checkResult, false);
413
+ }
383
414
  }
384
415
  }
@@ -6,7 +6,7 @@
6
6
  * `buildParams`, so a `*.component.ts` file reading `params.<name>` always
7
7
  * saw `{}` under `chant build --components --generate`, exactly like `chant
8
8
  * run --components` (see ../handlers/run.test.ts's "build-time parameters"
9
- * describe block for the equivalent local/`--temporal` coverage).
9
+ * describe block for the equivalent local-run coverage).
10
10
  *
11
11
  * Mocks `generateComponentsPipeline` and `loadChantConfigUpward` (chant
12
12
  * #1117 — `runGenerateComponents` walks up to the project root now, same as
@@ -149,3 +149,83 @@ describe("runBuild --components --generate (chant #1108 build-time parameters)",
149
149
  expect(generateComponentsPipelineMock).not.toHaveBeenCalled();
150
150
  });
151
151
  });
152
+
153
+ /**
154
+ * chant #2060. `chant build --components --generate --format json` forwarded
155
+ * only `{ stages, jobs, yaml }`, dropping `result.env` even though the
156
+ * generator (#2046, PR #2050) resolves and returns it. A consumer reading the
157
+ * structured output (behold does) had no environment identity except by
158
+ * parsing the YAML back, which #2046 was meant to retire.
159
+ */
160
+ describe("runBuild --components --generate --format json (chant #2060 env passthrough)", () => {
161
+ beforeEach(() => {
162
+ generateComponentsPipelineMock.mockReset();
163
+ loadChantConfigUpwardMock.mockReset().mockResolvedValue({ config: {} });
164
+ });
165
+
166
+ test("--format json includes result.env alongside stages, jobs and yaml", async () => {
167
+ generateComponentsPipelineMock.mockResolvedValue({
168
+ success: true,
169
+ yaml: "name: chant-components-prod\nenv:\n CHANT_ENV: prod\n",
170
+ stages: ["deploy"],
171
+ jobs: [{ jobName: "deploy-web", component: "web", stage: "deploy", needs: [] }],
172
+ env: "prod",
173
+ });
174
+ const stdout: string[] = [];
175
+ vi.spyOn(console, "log").mockImplementation((s: string) => { stdout.push(s); });
176
+
177
+ const exit = await runBuild({
178
+ args: makeArgs({ format: "json", env: "prod" }),
179
+ plugins: [],
180
+ serializers: [],
181
+ });
182
+
183
+ expect(exit).toBe(0);
184
+ expect(stdout).toHaveLength(1);
185
+ const printed = JSON.parse(stdout[0]);
186
+ expect(printed).toEqual({
187
+ stages: ["deploy"],
188
+ jobs: [{ jobName: "deploy-web", component: "web", stage: "deploy", needs: [] }],
189
+ yaml: "name: chant-components-prod\nenv:\n CHANT_ENV: prod\n",
190
+ env: "prod",
191
+ });
192
+ vi.restoreAllMocks();
193
+ });
194
+
195
+ test("--format json omits env when the generator's result carries none", async () => {
196
+ generateComponentsPipelineMock.mockResolvedValue({
197
+ success: true,
198
+ yaml: "stages: []",
199
+ stages: [],
200
+ jobs: [],
201
+ });
202
+ const stdout: string[] = [];
203
+ vi.spyOn(console, "log").mockImplementation((s: string) => { stdout.push(s); });
204
+
205
+ const exit = await runBuild({ args: makeArgs({ format: "json" }), plugins: [], serializers: [] });
206
+
207
+ expect(exit).toBe(0);
208
+ const printed = JSON.parse(stdout[0]);
209
+ expect(printed).toEqual({ stages: [], jobs: [], yaml: "stages: []" });
210
+ expect(printed).not.toHaveProperty("env");
211
+ vi.restoreAllMocks();
212
+ });
213
+
214
+ test("the default text format is unchanged: env is not forwarded and only the raw yaml is printed", async () => {
215
+ generateComponentsPipelineMock.mockResolvedValue({
216
+ success: true,
217
+ yaml: "name: chant-components-prod\nenv:\n CHANT_ENV: prod\n",
218
+ stages: ["deploy"],
219
+ jobs: [{ jobName: "deploy-web", component: "web", stage: "deploy", needs: [] }],
220
+ env: "prod",
221
+ });
222
+ const stdout: string[] = [];
223
+ vi.spyOn(console, "log").mockImplementation((s: string) => { stdout.push(s); });
224
+
225
+ const exit = await runBuild({ args: makeArgs({ env: "prod" }), plugins: [], serializers: [] });
226
+
227
+ expect(exit).toBe(0);
228
+ expect(stdout).toEqual(["name: chant-components-prod\nenv:\n CHANT_ENV: prod\n"]);
229
+ vi.restoreAllMocks();
230
+ });
231
+ });
@@ -63,7 +63,21 @@ async function runGenerateComponents(ctx: CommandContext): Promise<number> {
63
63
 
64
64
  const yaml = result.yaml ?? "";
65
65
  if (args.format === "json") {
66
- console.log(JSON.stringify({ stages: result.stages, jobs: result.jobs, yaml }, null, 2));
66
+ console.log(
67
+ JSON.stringify(
68
+ {
69
+ stages: result.stages,
70
+ jobs: result.jobs,
71
+ yaml,
72
+ // The environment the generated pipeline deploys (#2046), the
73
+ // generator's own resolution, forwarded rather than left for a
74
+ // consumer to re-derive by parsing the YAML back (#2060).
75
+ ...(result.env ? { env: result.env } : {}),
76
+ },
77
+ null,
78
+ 2,
79
+ ),
80
+ );
67
81
  } else if (args.output) {
68
82
  const outputPath = resolve(args.output);
69
83
  mkdirSync(dirname(outputPath), { recursive: true });
@@ -233,14 +233,14 @@ describe("runGraph", () => {
233
233
  filePath: file,
234
234
  });
235
235
 
236
- test("an op discoverOps finds at the project root becomes a Temporal::Op node", async () => {
236
+ test("an op discoverOps finds at the project root becomes a Chant::Op node", async () => {
237
237
  lintClean(); discovered();
238
238
  discoverOpsMock.mockResolvedValue({ ops: new Map([["deploy", rootOp("/proj/deploy.op.ts")]]), errors: [] });
239
239
  const exit = await runGraph({ args: makeArgs({ format: "ir", path: "/proj", detail: 3 }), plugins: [], serializers: [] });
240
240
  expect(exit).toBe(0);
241
241
  const ir = JSON.parse(stdoutBuf.join("\n"));
242
242
  const node = ir.nodes.find((n: { id: string }) => n.id === "deploy");
243
- expect(node).toMatchObject({ kind: "Temporal::Op", lexicon: "temporal", sourceLoc: { file: "deploy.op.ts" } });
243
+ expect(node).toMatchObject({ kind: "Chant::Op", lexicon: "chant", sourceLoc: { file: "deploy.op.ts" } });
244
244
  expect(node.attrs.phases[0].name).toBe("Apply");
245
245
  expect(node.attrs.depends).toEqual(["infra"]);
246
246
  });
@@ -248,7 +248,7 @@ describe("runGraph", () => {
248
248
  test("an op discovery already loaded from sourceDir is not added twice", async () => {
249
249
  lintClean();
250
250
  const entities = sampleEntities();
251
- entities.set("deploy", decl({ lexicon: "temporal", entityType: "Temporal::Op", props: { name: "deploy", phases: [] } }));
251
+ entities.set("deploy", decl({ lexicon: "chant", entityType: "Chant::Op", props: { name: "deploy", phases: [] } }));
252
252
  discoverMock.mockResolvedValue({ entities, errors: [], dependencies: new Map(), sourceFiles: ["/proj/src/deploy.op.ts"] });
253
253
  discoverOpsMock.mockResolvedValue({ ops: new Map([["deploy", rootOp("/proj/src/deploy.op.ts")]]), errors: [] });
254
254
  const exit = await runGraph({ args: makeArgs({ format: "ir", path: "/proj", detail: 3 }), plugins: [], serializers: [] });