@intentius/chant 0.56.0 → 0.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (515) hide show
  1. package/dist/audit/catalog.d.ts +51 -1
  2. package/dist/audit/catalog.d.ts.map +1 -1
  3. package/dist/audit/core.d.ts +20 -1
  4. package/dist/audit/core.d.ts.map +1 -1
  5. package/dist/audit/discover.d.ts +14 -8
  6. package/dist/audit/discover.d.ts.map +1 -1
  7. package/dist/audit/lineage.d.ts +10 -0
  8. package/dist/audit/lineage.d.ts.map +1 -0
  9. package/dist/audit/prior-art.d.ts +385 -0
  10. package/dist/audit/prior-art.d.ts.map +1 -0
  11. package/dist/audit/proof.d.ts +16 -0
  12. package/dist/audit/proof.d.ts.map +1 -1
  13. package/dist/audit/report-html.d.ts.map +1 -1
  14. package/dist/audit/report-model.d.ts +8 -1
  15. package/dist/audit/report-model.d.ts.map +1 -1
  16. package/dist/audit/report.d.ts.map +1 -1
  17. package/dist/audit/rules-doc.d.ts +3 -0
  18. package/dist/audit/rules-doc.d.ts.map +1 -1
  19. package/dist/audit/secrets.d.ts +15 -0
  20. package/dist/audit/secrets.d.ts.map +1 -1
  21. package/dist/audit/terraform-state.d.ts +46 -0
  22. package/dist/audit/terraform-state.d.ts.map +1 -0
  23. package/dist/build.d.ts +17 -1
  24. package/dist/build.d.ts.map +1 -1
  25. package/dist/claimed-fields.d.ts +161 -0
  26. package/dist/claimed-fields.d.ts.map +1 -0
  27. package/dist/cli/build-params-cli.d.ts +2 -2
  28. package/dist/cli/command-group.d.ts +14 -0
  29. package/dist/cli/command-group.d.ts.map +1 -1
  30. package/dist/cli/commands/audit.d.ts +17 -1
  31. package/dist/cli/commands/audit.d.ts.map +1 -1
  32. package/dist/cli/commands/build.d.ts.map +1 -1
  33. package/dist/cli/commands/check-lexicon-docs.d.ts +1 -1
  34. package/dist/cli/commands/check-lexicon-examples.d.ts +16 -6
  35. package/dist/cli/commands/check-lexicon-examples.d.ts.map +1 -1
  36. package/dist/cli/commands/import.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.map +1 -1
  44. package/dist/cli/commands/onboard.d.ts +2 -0
  45. package/dist/cli/commands/onboard.d.ts.map +1 -1
  46. package/dist/cli/handlers/build.d.ts.map +1 -1
  47. package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
  48. package/dist/cli/handlers/operator.d.ts +82 -16
  49. package/dist/cli/handlers/operator.d.ts.map +1 -1
  50. package/dist/cli/handlers/run.d.ts +49 -42
  51. package/dist/cli/handlers/run.d.ts.map +1 -1
  52. package/dist/cli/main.d.ts +28 -1
  53. package/dist/cli/main.d.ts.map +1 -1
  54. package/dist/cli/mcp/op-tools.d.ts +16 -1
  55. package/dist/cli/mcp/op-tools.d.ts.map +1 -1
  56. package/dist/cli/mcp/resource-handlers.d.ts.map +1 -1
  57. package/dist/cli/mcp/resources/context.d.ts.map +1 -1
  58. package/dist/cli/registry.d.ts +26 -9
  59. package/dist/cli/registry.d.ts.map +1 -1
  60. package/dist/codegen/generate-post-synth-barrel.d.ts +1 -1
  61. package/dist/components/auto-release.d.ts +10 -20
  62. package/dist/components/auto-release.d.ts.map +1 -1
  63. package/dist/components/capability.d.ts +4 -4
  64. package/dist/components/cli-support.d.ts +20 -21
  65. package/dist/components/cli-support.d.ts.map +1 -1
  66. package/dist/components/component.d.ts +3 -3
  67. package/dist/components/component.d.ts.map +1 -1
  68. package/dist/components/driver-output.d.ts.map +1 -1
  69. package/dist/components/driver.d.ts +66 -36
  70. package/dist/components/driver.d.ts.map +1 -1
  71. package/dist/components/index.d.ts +1 -2
  72. package/dist/components/index.d.ts.map +1 -1
  73. package/dist/components/manifest-persistence.d.ts +1 -9
  74. package/dist/components/manifest-persistence.d.ts.map +1 -1
  75. package/dist/components/run-progress.d.ts +6 -6
  76. package/dist/components/run-progress.d.ts.map +1 -1
  77. package/dist/components/verbs/run-agent.d.ts +9 -15
  78. package/dist/components/verbs/run-agent.d.ts.map +1 -1
  79. package/dist/components/verbs/verify.d.ts +2 -2
  80. package/dist/deep-observation.d.ts +17 -0
  81. package/dist/deep-observation.d.ts.map +1 -1
  82. package/dist/discovery/files.d.ts +4 -4
  83. package/dist/discovery/fold-import.d.ts.map +1 -1
  84. package/dist/discovery/param-deps.d.ts +33 -0
  85. package/dist/discovery/param-deps.d.ts.map +1 -1
  86. package/dist/discovery/sandbox/bundle.d.ts.map +1 -1
  87. package/dist/discovery/sandbox/config-wire.d.ts +2 -2
  88. package/dist/fold/foldable-helpers.d.ts +5 -1
  89. package/dist/fold/foldable-helpers.d.ts.map +1 -1
  90. package/dist/fold-provenance.d.ts +236 -0
  91. package/dist/fold-provenance.d.ts.map +1 -0
  92. package/dist/graph-ops.d.ts +1 -1
  93. package/dist/held-elsewhere.d.ts +85 -0
  94. package/dist/held-elsewhere.d.ts.map +1 -0
  95. package/dist/import/ir-utils.d.ts +1 -1
  96. package/dist/import/ir-utils.d.ts.map +1 -1
  97. package/dist/import/parser.d.ts +33 -0
  98. package/dist/import/parser.d.ts.map +1 -1
  99. package/dist/index.d.ts +3 -0
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/kubectl-context.d.ts +3 -3
  102. package/dist/lexicon-config.d.ts +4 -4
  103. package/dist/lexicon-plugin-helpers.d.ts +1 -1
  104. package/dist/lexicon.d.ts +104 -14
  105. package/dist/lexicon.d.ts.map +1 -1
  106. package/dist/lifecycle/change-set.d.ts +13 -0
  107. package/dist/lifecycle/change-set.d.ts.map +1 -1
  108. package/dist/lifecycle/deep-diff.d.ts +133 -6
  109. package/dist/lifecycle/deep-diff.d.ts.map +1 -1
  110. package/dist/lifecycle/deep-observe.d.ts.map +1 -1
  111. package/dist/lifecycle/gate-ledger.d.ts +71 -3
  112. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  113. package/dist/lifecycle/index.d.ts +1 -0
  114. package/dist/lifecycle/index.d.ts.map +1 -1
  115. package/dist/lifecycle/release-ledger.d.ts +2 -2
  116. package/dist/lifecycle/run-ledger.d.ts +53 -0
  117. package/dist/lifecycle/run-ledger.d.ts.map +1 -0
  118. package/dist/lifecycle/symptoms.d.ts +3 -3
  119. package/dist/lifecycle/symptoms.d.ts.map +1 -1
  120. package/dist/lint/config.d.ts +81 -2
  121. package/dist/lint/config.d.ts.map +1 -1
  122. package/dist/lint/post-synth.d.ts +55 -2
  123. package/dist/lint/post-synth.d.ts.map +1 -1
  124. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts +1 -1
  125. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts.map +1 -1
  126. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts +1 -1
  127. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts.map +1 -1
  128. package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.d.ts +44 -0
  129. package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.d.ts.map +1 -0
  130. package/dist/lint/rules/comp/index.d.ts +1 -1
  131. package/dist/lint/rules/comp/index.d.ts.map +1 -1
  132. package/dist/lint/rules/op/index.d.ts +16 -0
  133. package/dist/lint/rules/op/index.d.ts.map +1 -0
  134. package/dist/lint/rules/op/ops012-activity-contract.d.ts +27 -0
  135. package/dist/lint/rules/op/ops012-activity-contract.d.ts.map +1 -0
  136. package/dist/lint/rules/op/ops013-step-output-ref.d.ts +61 -0
  137. package/dist/lint/rules/op/ops013-step-output-ref.d.ts.map +1 -0
  138. package/dist/lint/rules/op/ops014-converge-rule-refusals.d.ts +55 -0
  139. package/dist/lint/rules/op/ops014-converge-rule-refusals.d.ts.map +1 -0
  140. package/dist/lint/rules/op/support.d.ts +12 -0
  141. package/dist/lint/rules/op/support.d.ts.map +1 -0
  142. package/dist/lint/suppressions.d.ts +108 -0
  143. package/dist/lint/suppressions.d.ts.map +1 -0
  144. package/dist/live-endpoint.d.ts +1 -1
  145. package/dist/op/activities/activity-contracts.d.ts +54 -0
  146. package/dist/op/activities/activity-contracts.d.ts.map +1 -0
  147. package/dist/op/activities/apply.d.ts +262 -0
  148. package/dist/op/activities/apply.d.ts.map +1 -0
  149. package/dist/op/activities/build.d.ts +13 -0
  150. package/dist/op/activities/build.d.ts.map +1 -0
  151. package/dist/op/activities/converge.d.ts +110 -0
  152. package/dist/op/activities/converge.d.ts.map +1 -0
  153. package/dist/op/activities/env-teardown.d.ts +76 -0
  154. package/dist/op/activities/env-teardown.d.ts.map +1 -0
  155. package/dist/op/activities/guard-validate.d.ts +64 -0
  156. package/dist/op/activities/guard-validate.d.ts.map +1 -0
  157. package/dist/op/activities/http-check.d.ts +34 -0
  158. package/dist/op/activities/http-check.d.ts.map +1 -0
  159. package/dist/op/activities/index.d.ts +31 -0
  160. package/dist/op/activities/index.d.ts.map +1 -0
  161. package/dist/op/activities/lexicon-upgrade.d.ts +182 -0
  162. package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -0
  163. package/dist/op/activities/lifecycle.d.ts +42 -0
  164. package/dist/op/activities/lifecycle.d.ts.map +1 -0
  165. package/dist/op/activities/pipeline-audit.d.ts +84 -0
  166. package/dist/op/activities/pipeline-audit.d.ts.map +1 -0
  167. package/dist/op/activities/policy.d.ts +17 -0
  168. package/dist/op/activities/policy.d.ts.map +1 -0
  169. package/dist/op/activities/reconcile.d.ts +89 -0
  170. package/dist/op/activities/reconcile.d.ts.map +1 -0
  171. package/dist/op/activities/shell.d.ts +13 -0
  172. package/dist/op/activities/shell.d.ts.map +1 -0
  173. package/dist/op/activities/teardown.d.ts +10 -0
  174. package/dist/op/activities/teardown.d.ts.map +1 -0
  175. package/dist/op/activities/util.d.ts +7 -0
  176. package/dist/op/activities/util.d.ts.map +1 -0
  177. package/dist/op/activities/wait.d.ts +28 -0
  178. package/dist/op/activities/wait.d.ts.map +1 -0
  179. package/dist/op/activities/workflow-audit.d.ts +92 -0
  180. package/dist/op/activities/workflow-audit.d.ts.map +1 -0
  181. package/dist/op/activity-contract-registry.d.ts +76 -0
  182. package/dist/op/activity-contract-registry.d.ts.map +1 -0
  183. package/dist/op/activity-contract.d.ts +25 -18
  184. package/dist/op/activity-contract.d.ts.map +1 -1
  185. package/dist/op/activity-failure.d.ts +28 -0
  186. package/dist/op/activity-failure.d.ts.map +1 -0
  187. package/dist/op/activity-profiles.d.ts +118 -0
  188. package/dist/op/activity-profiles.d.ts.map +1 -0
  189. package/dist/op/activity-registry.d.ts +22 -38
  190. package/dist/op/activity-registry.d.ts.map +1 -1
  191. package/dist/op/activity-runtime.d.ts +3 -14
  192. package/dist/op/activity-runtime.d.ts.map +1 -1
  193. package/dist/op/builders.d.ts +84 -29
  194. package/dist/op/builders.d.ts.map +1 -1
  195. package/dist/op/composites/apply-op.d.ts +113 -0
  196. package/dist/op/composites/apply-op.d.ts.map +1 -0
  197. package/dist/op/composites/converge-op.d.ts +120 -0
  198. package/dist/op/composites/converge-op.d.ts.map +1 -0
  199. package/dist/op/composites/index.d.ts +26 -0
  200. package/dist/op/composites/index.d.ts.map +1 -0
  201. package/dist/op/composites/lexicon-upgrade-op.d.ts +78 -0
  202. package/dist/op/composites/lexicon-upgrade-op.d.ts.map +1 -0
  203. package/dist/op/composites/pipeline-audit-op.d.ts +50 -0
  204. package/dist/op/composites/pipeline-audit-op.d.ts.map +1 -0
  205. package/dist/op/composites/reconcile-op.d.ts +57 -0
  206. package/dist/op/composites/reconcile-op.d.ts.map +1 -0
  207. package/dist/op/composites/watch-op.d.ts +60 -0
  208. package/dist/op/composites/watch-op.d.ts.map +1 -0
  209. package/dist/op/composites/workflow-audit-op.d.ts +57 -0
  210. package/dist/op/composites/workflow-audit-op.d.ts.map +1 -0
  211. package/dist/op/converge-rule.d.ts +12 -10
  212. package/dist/op/converge-rule.d.ts.map +1 -1
  213. package/dist/op/cron.d.ts +51 -0
  214. package/dist/op/cron.d.ts.map +1 -0
  215. package/dist/op/discover.d.ts +9 -0
  216. package/dist/op/discover.d.ts.map +1 -1
  217. package/dist/op/duration.d.ts +11 -0
  218. package/dist/op/duration.d.ts.map +1 -0
  219. package/dist/op/emulator-lifecycle.d.ts.map +1 -1
  220. package/dist/op/gate.d.ts +90 -0
  221. package/dist/op/gate.d.ts.map +1 -0
  222. package/dist/op/generate-pipeline.d.ts +9 -0
  223. package/dist/op/generate-pipeline.d.ts.map +1 -1
  224. package/dist/op/index.d.ts +23 -7
  225. package/dist/op/index.d.ts.map +1 -1
  226. package/dist/op/local-executor.d.ts +114 -28
  227. package/dist/op/local-executor.d.ts.map +1 -1
  228. package/dist/op/local-output.d.ts +11 -1
  229. package/dist/op/local-output.d.ts.map +1 -1
  230. package/dist/op/op-ir.d.ts +184 -0
  231. package/dist/op/op-ir.d.ts.map +1 -0
  232. package/dist/op/op-verb-class.d.ts +10 -2
  233. package/dist/op/op-verb-class.d.ts.map +1 -1
  234. package/dist/op/operator.d.ts +30 -5
  235. package/dist/op/operator.d.ts.map +1 -1
  236. package/dist/op/receipt-store.d.ts +1 -1
  237. package/dist/op/receipt-store.d.ts.map +1 -1
  238. package/dist/op/resource.d.ts +15 -1
  239. package/dist/op/resource.d.ts.map +1 -1
  240. package/dist/op/runtime.d.ts +200 -0
  241. package/dist/op/runtime.d.ts.map +1 -0
  242. package/dist/op/runtimes/local.d.ts +29 -0
  243. package/dist/op/runtimes/local.d.ts.map +1 -0
  244. package/dist/op/step-output-ref.d.ts +15 -13
  245. package/dist/op/step-output-ref.d.ts.map +1 -1
  246. package/dist/op/types.d.ts +79 -27
  247. package/dist/op/types.d.ts.map +1 -1
  248. package/dist/ownership.d.ts +1 -1
  249. package/dist/provenance.d.ts +21 -0
  250. package/dist/provenance.d.ts.map +1 -1
  251. package/dist/serializer-walker.d.ts.map +1 -1
  252. package/dist/stack-output.d.ts +5 -0
  253. package/dist/stack-output.d.ts.map +1 -1
  254. package/package.json +6 -1
  255. package/src/audit/catalog.test.ts +79 -3
  256. package/src/audit/catalog.ts +111 -13
  257. package/src/audit/core.test.ts +26 -0
  258. package/src/audit/core.ts +61 -17
  259. package/src/audit/discover.test.ts +39 -0
  260. package/src/audit/discover.ts +91 -15
  261. package/src/audit/lineage.ts +100 -0
  262. package/src/audit/prior-art.ts +153 -0
  263. package/src/audit/proof.test.ts +67 -0
  264. package/src/audit/proof.ts +70 -0
  265. package/src/audit/report-html.ts +9 -4
  266. package/src/audit/report-model.ts +16 -2
  267. package/src/audit/report.test.ts +33 -0
  268. package/src/audit/report.ts +5 -3
  269. package/src/audit/rules-doc.test.ts +34 -2
  270. package/src/audit/rules-doc.ts +82 -9
  271. package/src/audit/secrets.ts +15 -3
  272. package/src/audit/terraform-state.test.ts +144 -0
  273. package/src/audit/terraform-state.ts +131 -0
  274. package/src/build.ts +31 -1
  275. package/src/claimed-fields.test.ts +145 -0
  276. package/src/claimed-fields.ts +208 -0
  277. package/src/cli/build-params-cli.ts +2 -2
  278. package/src/cli/command-group.ts +14 -0
  279. package/src/cli/commands/__fixtures__/audit-terraform/infra/.terraform/providers/lock.txt +1 -0
  280. package/src/cli/commands/__fixtures__/audit-terraform/infra/main.tf +1 -0
  281. package/src/cli/commands/__fixtures__/audit-terraform/infra/modules/foo/main.tf +1 -0
  282. package/src/cli/commands/__fixtures__/audit-terraform/infra/variables.tf +3 -0
  283. package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +13 -4
  284. package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/docs-cli.ts +4 -0
  285. package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/package.ts +1 -0
  286. package/src/cli/commands/__fixtures__/init-lexicon-output/src/package-cli.ts +21 -0
  287. package/src/cli/commands/__snapshots__/init-lexicon.test.ts.snap +1 -0
  288. package/src/cli/commands/audit.test.ts +189 -11
  289. package/src/cli/commands/audit.ts +73 -27
  290. package/src/cli/commands/build.test.ts +292 -9
  291. package/src/cli/commands/build.ts +156 -24
  292. package/src/cli/commands/check-lexicon-docs.ts +1 -1
  293. package/src/cli/commands/check-lexicon-examples.test.ts +29 -1
  294. package/src/cli/commands/check-lexicon-examples.ts +42 -10
  295. package/src/cli/commands/import.ts +6 -0
  296. package/src/cli/commands/init-lexicon/templates/codegen.ts +9 -0
  297. package/src/cli/commands/init-lexicon/templates/project.ts +44 -4
  298. package/src/cli/commands/init-lexicon.test.ts +97 -2
  299. package/src/cli/commands/init-lexicon.ts +4 -2
  300. package/src/cli/commands/init.test.ts +35 -1
  301. package/src/cli/commands/init.ts +14 -3
  302. package/src/cli/commands/lint.test.ts +48 -0
  303. package/src/cli/commands/lint.ts +123 -0
  304. package/src/cli/commands/onboard.test.ts +75 -0
  305. package/src/cli/commands/onboard.ts +54 -23
  306. package/src/cli/handlers/build.test.ts +81 -1
  307. package/src/cli/handlers/build.ts +15 -1
  308. package/src/cli/handlers/graph.test.ts +3 -3
  309. package/src/cli/handlers/lifecycle.test.ts +195 -12
  310. package/src/cli/handlers/lifecycle.ts +123 -6
  311. package/src/cli/handlers/misc.ts +1 -1
  312. package/src/cli/handlers/operator.test.ts +183 -11
  313. package/src/cli/handlers/operator.ts +260 -55
  314. package/src/cli/handlers/run.test.ts +431 -1287
  315. package/src/cli/handlers/run.ts +365 -915
  316. package/src/cli/main.test.ts +23 -15
  317. package/src/cli/main.ts +88 -33
  318. package/src/cli/mcp/op-tools.ts +147 -88
  319. package/src/cli/mcp/resource-handlers.ts +10 -37
  320. package/src/cli/mcp/resources/context.ts +11 -12
  321. package/src/cli/mcp/server.test.ts +25 -27
  322. package/src/cli/mcp/server.ts +2 -2
  323. package/src/cli/registry.ts +26 -9
  324. package/src/codegen/docs.ts +1 -1
  325. package/src/codegen/generate-post-synth-barrel.test.ts +1 -1
  326. package/src/codegen/generate-post-synth-barrel.ts +1 -1
  327. package/src/components/README.md +3 -2
  328. package/src/components/auto-release.test.ts +4 -20
  329. package/src/components/auto-release.ts +17 -42
  330. package/src/components/capability.ts +4 -4
  331. package/src/components/cli-support.test.ts +10 -5
  332. package/src/components/cli-support.ts +52 -44
  333. package/src/components/component.schema.json +2 -2
  334. package/src/components/component.ts +3 -3
  335. package/src/components/driver-output.ts +14 -2
  336. package/src/components/driver.test.ts +92 -22
  337. package/src/components/driver.ts +193 -83
  338. package/src/components/index.ts +1 -6
  339. package/src/components/manifest-persistence.test.ts +2 -20
  340. package/src/components/manifest-persistence.ts +4 -24
  341. package/src/components/pilots/pilots-lint-clean.test.ts +11 -10
  342. package/src/components/run-progress.ts +6 -6
  343. package/src/components/verbs/run-agent.ts +11 -17
  344. package/src/components/verbs/verify.ts +2 -2
  345. package/src/deep-observation.test.ts +75 -0
  346. package/src/deep-observation.ts +48 -0
  347. package/src/discovery/collect.test.ts +3 -3
  348. package/src/discovery/files.ts +4 -4
  349. package/src/discovery/fold-import.ts +105 -2
  350. package/src/discovery/param-deps.test.ts +112 -1
  351. package/src/discovery/param-deps.ts +193 -0
  352. package/src/discovery/sandbox/bundle.ts +15 -1
  353. package/src/discovery/sandbox/config-wire.test.ts +2 -2
  354. package/src/discovery/sandbox/config-wire.ts +2 -2
  355. package/src/fold/fold.test.ts +56 -0
  356. package/src/fold/foldable-helpers.ts +81 -1
  357. package/src/fold-provenance-exclusion.test.ts +186 -0
  358. package/src/fold-provenance.test.ts +495 -0
  359. package/src/fold-provenance.ts +441 -0
  360. package/src/graph-ops.test.ts +2 -2
  361. package/src/graph-ops.ts +1 -1
  362. package/src/held-elsewhere.test.ts +102 -0
  363. package/src/held-elsewhere.ts +114 -0
  364. package/src/import/ir-utils.ts +11 -1
  365. package/src/import/parser.ts +35 -0
  366. package/src/index.ts +3 -0
  367. package/src/kubectl-context.ts +3 -3
  368. package/src/lexicon-config.test.ts +5 -5
  369. package/src/lexicon-config.ts +4 -4
  370. package/src/lexicon-plugin-helpers.ts +1 -1
  371. package/src/lexicon.ts +120 -14
  372. package/src/lifecycle/change-set.test.ts +49 -0
  373. package/src/lifecycle/change-set.ts +67 -0
  374. package/src/lifecycle/converge-ledger.ts +1 -1
  375. package/src/lifecycle/deep-diff.test.ts +267 -14
  376. package/src/lifecycle/deep-diff.ts +217 -14
  377. package/src/lifecycle/deep-observe.test.ts +3 -1
  378. package/src/lifecycle/deep-observe.ts +16 -6
  379. package/src/lifecycle/gate-ledger.test.ts +74 -2
  380. package/src/lifecycle/gate-ledger.ts +143 -36
  381. package/src/lifecycle/index.ts +1 -0
  382. package/src/lifecycle/release-ledger.ts +2 -2
  383. package/src/lifecycle/run-ledger.test.ts +268 -0
  384. package/src/lifecycle/run-ledger.ts +201 -0
  385. package/src/lifecycle/symptoms.ts +3 -3
  386. package/src/lint/config.test.ts +82 -1
  387. package/src/lint/config.ts +112 -3
  388. package/src/lint/policy.test.ts +1 -1
  389. package/src/lint/post-synth.test.ts +31 -0
  390. package/src/lint/post-synth.ts +54 -1
  391. package/src/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.ts +2 -2
  392. package/src/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.ts +1 -1
  393. package/src/lint/rules/comp/comp.test.ts +1 -1
  394. package/src/lint/rules/comp/comp004-gate-needs-durable-runtime.ts +74 -0
  395. package/src/lint/rules/comp/index.ts +3 -3
  396. package/src/lint/rules/op/index.ts +23 -0
  397. package/src/lint/rules/op/ops012-activity-contract.test.ts +161 -0
  398. package/src/lint/rules/op/ops012-activity-contract.ts +64 -0
  399. package/src/lint/rules/op/ops013-step-output-ref.test.ts +237 -0
  400. package/src/lint/rules/op/ops013-step-output-ref.ts +98 -0
  401. package/src/lint/rules/op/ops014-converge-rule-refusals.test.ts +263 -0
  402. package/src/lint/rules/op/ops014-converge-rule-refusals.ts +179 -0
  403. package/src/lint/rules/op/support.ts +11 -0
  404. package/src/lint/suppressions.test.ts +163 -0
  405. package/src/lint/suppressions.ts +204 -0
  406. package/src/live-endpoint.ts +1 -1
  407. package/src/op/activities/activity-contracts.ts +66 -0
  408. package/src/op/activities/apply.test.ts +567 -0
  409. package/src/op/activities/apply.ts +662 -0
  410. package/src/op/activities/build.ts +26 -0
  411. package/src/op/activities/converge.test.ts +330 -0
  412. package/src/op/activities/converge.ts +449 -0
  413. package/src/op/activities/env-teardown.test.ts +187 -0
  414. package/src/op/activities/env-teardown.ts +171 -0
  415. package/src/op/activities/guard-validate.test.ts +139 -0
  416. package/src/op/activities/guard-validate.ts +223 -0
  417. package/src/op/activities/http-check.test.ts +48 -0
  418. package/src/op/activities/http-check.ts +55 -0
  419. package/src/op/activities/index.ts +119 -0
  420. package/src/op/activities/lexicon-upgrade.test.ts +492 -0
  421. package/src/op/activities/lexicon-upgrade.ts +673 -0
  422. package/src/op/activities/lifecycle.ts +85 -0
  423. package/src/op/activities/pipeline-audit.test.ts +67 -0
  424. package/src/op/activities/pipeline-audit.ts +201 -0
  425. package/src/op/activities/policy.test.ts +19 -0
  426. package/src/op/activities/policy.ts +37 -0
  427. package/src/op/activities/reconcile.test.ts +81 -0
  428. package/src/op/activities/reconcile.ts +187 -0
  429. package/src/op/activities/shell.ts +26 -0
  430. package/src/op/activities/teardown.ts +22 -0
  431. package/src/op/activities/util.ts +6 -0
  432. package/src/op/activities/wait.ts +69 -0
  433. package/src/op/activities/workflow-audit.test.ts +90 -0
  434. package/src/op/activities/workflow-audit.ts +203 -0
  435. package/src/op/activity-contract-registry.test.ts +98 -0
  436. package/src/op/activity-contract-registry.ts +114 -0
  437. package/src/op/activity-contract.test.ts +1 -1
  438. package/src/op/activity-contract.ts +37 -33
  439. package/src/op/activity-failure.ts +34 -0
  440. package/src/op/activity-profiles.test.ts +56 -0
  441. package/src/op/activity-profiles.ts +116 -0
  442. package/src/op/activity-registry.test.ts +37 -28
  443. package/src/op/activity-registry.ts +27 -56
  444. package/src/op/activity-runtime.ts +3 -47
  445. package/src/op/builders-exports.test.ts +0 -49
  446. package/src/op/builders-typed.test.ts +164 -0
  447. package/src/op/builders.ts +123 -39
  448. package/src/op/composites/apply-op.ts +208 -0
  449. package/src/op/composites/composites.test.ts +366 -0
  450. package/src/op/composites/converge-op.test.ts +168 -0
  451. package/src/op/composites/converge-op.ts +214 -0
  452. package/src/op/composites/index.ts +26 -0
  453. package/src/op/composites/lexicon-upgrade-op.test.ts +68 -0
  454. package/src/op/composites/lexicon-upgrade-op.ts +134 -0
  455. package/src/op/composites/pipeline-audit-op.test.ts +25 -0
  456. package/src/op/composites/pipeline-audit-op.ts +78 -0
  457. package/src/op/composites/reconcile-op.test.ts +51 -0
  458. package/src/op/composites/reconcile-op.ts +107 -0
  459. package/src/op/composites/watch-op.ts +108 -0
  460. package/src/op/composites/workflow-audit-op.test.ts +25 -0
  461. package/src/op/composites/workflow-audit-op.ts +88 -0
  462. package/src/op/converge-rule.ts +12 -10
  463. package/src/op/cron.test.ts +128 -0
  464. package/src/op/cron.ts +149 -0
  465. package/src/op/discover-root.test.ts +105 -1
  466. package/src/op/discover.test.ts +6 -2
  467. package/src/op/discover.ts +84 -16
  468. package/src/op/duration.ts +21 -0
  469. package/src/op/effect-step.test.ts +26 -11
  470. package/src/op/emulator-lifecycle.ts +1 -2
  471. package/src/op/gate.ts +155 -0
  472. package/src/op/generate-pipeline.test.ts +65 -3
  473. package/src/op/generate-pipeline.ts +19 -2
  474. package/src/op/index.ts +39 -6
  475. package/src/op/local-executor.test.ts +163 -34
  476. package/src/op/local-executor.ts +370 -102
  477. package/src/op/local-output.test.ts +95 -11
  478. package/src/op/local-output.ts +33 -4
  479. package/src/op/op-ir.test.ts +281 -0
  480. package/src/op/op-ir.ts +417 -0
  481. package/src/op/op-verb-class.ts +19 -5
  482. package/src/op/op.test.ts +26 -5
  483. package/src/op/operator.test.ts +175 -6
  484. package/src/op/operator.ts +63 -16
  485. package/src/op/receipt-store.ts +1 -1
  486. package/src/op/resource.ts +20 -2
  487. package/src/op/runtime.ts +203 -0
  488. package/src/op/runtimes/local.test.ts +181 -0
  489. package/src/op/runtimes/local.ts +212 -0
  490. package/src/op/step-output-ref.ts +15 -13
  491. package/src/op/types.ts +84 -24
  492. package/src/ownership.ts +1 -1
  493. package/src/provenance.test.ts +6 -0
  494. package/src/provenance.ts +21 -1
  495. package/src/serializer-walker.test.ts +42 -0
  496. package/src/serializer-walker.ts +21 -2
  497. package/src/stack-output.ts +6 -1
  498. package/dist/cli/handlers/op-progress.d.ts +0 -90
  499. package/dist/cli/handlers/op-progress.d.ts.map +0 -1
  500. package/dist/cli/handlers/run-client.d.ts +0 -127
  501. package/dist/cli/handlers/run-client.d.ts.map +0 -1
  502. package/dist/cli/handlers/run-report.d.ts +0 -5
  503. package/dist/cli/handlers/run-report.d.ts.map +0 -1
  504. package/dist/components/temporal-codegen-loader.d.ts +0 -27
  505. package/dist/components/temporal-codegen-loader.d.ts.map +0 -1
  506. package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts +0 -37
  507. package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts.map +0 -1
  508. package/src/cli/handlers/op-progress.test.ts +0 -268
  509. package/src/cli/handlers/op-progress.ts +0 -248
  510. package/src/cli/handlers/run-client.test.ts +0 -82
  511. package/src/cli/handlers/run-client.ts +0 -219
  512. package/src/cli/handlers/run-report.test.ts +0 -62
  513. package/src/cli/handlers/run-report.ts +0 -122
  514. package/src/components/temporal-codegen-loader.ts +0 -41
  515. package/src/lint/rules/comp/comp004-gate-needs-temporal.ts +0 -66
@@ -14,11 +14,18 @@ import type { OwnershipMarker } from "../../ownership";
14
14
  import { resolveCliBuildParams } from "../build-params-cli";
15
15
  import type { Serializer, SerializerResult } from "../../serializer";
16
16
  import type { LexiconPlugin } from "../../lexicon";
17
- import { runPostSynthChecks } from "../../lint/post-synth";
17
+ import { runPostSynthChecks, type PostSynthDiagnostic } from "../../lint/post-synth";
18
+ import { loadActivityContracts } from "../../op/activity-contract-registry";
19
+ import { isOpEntity } from "../../op/resource";
20
+ import { serializeOpIR } from "../../op/op-ir";
21
+ import type { OpConfig } from "../../op/types";
18
22
  import { coreReceiptChecks } from "../../lint/receipt-checks";
19
23
  import { coreOutputChecks } from "../../lint/output-checks";
20
24
  import { coreKnowledgeChecks } from "../../lint/knowledge-checks";
21
- import { applyConfiguredSeverity } from "../../lint/config";
25
+ import { applyConfiguredSeverity, applyConfiguredPreset, resolvePresetIds } from "../../lint/config";
26
+ import { applyInlineSuppressions, type SuppressionMetaFinding } from "../../lint/suppressions";
27
+ import type { Declarable } from "../../declarable";
28
+ import { coreOpChecks } from "../../lint/rules/op";
22
29
  import { loadPolicyChecks } from "../../lint/policy";
23
30
  import { armSandboxPolicyExecution, runProjectPolicies } from "../../lint/policy-sandbox";
24
31
  import { sortedJsonReplacer } from "../../utils";
@@ -392,7 +399,46 @@ export async function buildCommand(options: BuildOptions): Promise<BuildResult>
392
399
  // rule id — so `lint.rules: { WAW019: "off" }` suppresses a post-synth
393
400
  // finding just as it suppresses a pre-synth one. A finding it suppresses is
394
401
  // counted, not dropped silently — see `suppressedPostSynthCount` below.
402
+ //
403
+ // chant #2111: every batch also goes through `applyInlineSuppressions`
404
+ // right after, so a `# chant-ignore` comment on an entity (terraform's HCL
405
+ // blocks today; any lexicon that attaches `suppressions` to its own
406
+ // entities tomorrow) suppresses identically regardless of which phase
407
+ // produced the diagnostic. Same counted-not-dropped contract, in its own
408
+ // `inlineSuppressedCount`, plus `suppressionMeta` for directives that are
409
+ // themselves worth a finding (expired, misplaced, denied by `ignorable: false`).
395
410
  let suppressedPostSynthCount = 0;
411
+ let inlineSuppressedCount = 0;
412
+ const suppressionMeta: SuppressionMetaFinding[] = [];
413
+ // A rule a `lint.presets` preset excludes (chant #2113) is a distinct
414
+ // reason a finding doesn't reach the errors/warnings lists. The preset
415
+ // decided the rule shouldn't run at all under this project's configured
416
+ // tier, not that `lint.rules` downgraded it to "off", so it gets its own
417
+ // counter and its own summary line rather than folding into the one above.
418
+ let suppressedPresetCount = 0;
419
+
420
+ /**
421
+ * Apply every suppression/filtering surface to one batch, in order:
422
+ * `lint.presets` (chant #2113, which check ids are enabled at all; a
423
+ * no-op when `presetIds` is undefined, the case for every call site below
424
+ * except the per-plugin loop, which is the only one with a lexicon a
425
+ * preset could apply to), then `lint.rules` severity overrides (chant
426
+ * #1138), then inline `# chant-ignore` comments (chant #2111).
427
+ */
428
+ const resolvePostSynth = (
429
+ diags: PostSynthDiagnostic[],
430
+ entities: Map<string, Declarable>,
431
+ presetIds?: Set<string>,
432
+ ): PostSynthDiagnostic[] => {
433
+ const { diagnostics: afterPreset, suppressed: presetSuppressed } = applyConfiguredPreset(diags, presetIds, config.lint?.rules);
434
+ suppressedPresetCount += presetSuppressed.length;
435
+ const { diagnostics: afterConfig, suppressed: configSuppressed } = applyConfiguredSeverity(afterPreset, config.lint?.rules);
436
+ suppressedPostSynthCount += configSuppressed.length;
437
+ const { diagnostics: active, suppressed: inlineSuppressed, meta } = applyInlineSuppressions(afterConfig, entities, config.lint?.rules);
438
+ inlineSuppressedCount += inlineSuppressed.length;
439
+ suppressionMeta.push(...meta);
440
+ return active;
441
+ };
396
442
 
397
443
  // Core-owned post-synth checks over effect receipts (#1833). Receipts are
398
444
  // recognized by marker, lexicon-independently, so this set runs over the
@@ -400,9 +446,7 @@ export async function buildCommand(options: BuildOptions): Promise<BuildResult>
400
446
  // Same severity-resolution funnel as every other post-synth finding.
401
447
  if (result.errors.length === 0) {
402
448
  const receiptDiags = runPostSynthChecks(coreReceiptChecks(), result, env);
403
- const { diagnostics: activeDiags, suppressed } = applyConfiguredSeverity(receiptDiags, config.lint?.rules);
404
- suppressedPostSynthCount += suppressed.length;
405
- for (const diag of activeDiags) {
449
+ for (const diag of resolvePostSynth(receiptDiags, result.entities)) {
406
450
  const prefix = diag.entity ? `[${diag.entity}] ` : "";
407
451
  const lexiconSuffix = diag.lexicon ? ` (${diag.lexicon})` : "";
408
452
  if (diag.severity === "error") {
@@ -419,9 +463,7 @@ export async function buildCommand(options: BuildOptions): Promise<BuildResult>
419
463
  // the FULL build result the same way the receipt checks above do.
420
464
  if (result.errors.length === 0) {
421
465
  const outputDiags = runPostSynthChecks(coreOutputChecks(), result, env);
422
- const { diagnostics: activeDiags, suppressed } = applyConfiguredSeverity(outputDiags, config.lint?.rules);
423
- suppressedPostSynthCount += suppressed.length;
424
- for (const diag of activeDiags) {
466
+ for (const diag of resolvePostSynth(outputDiags, result.entities)) {
425
467
  const prefix = diag.entity ? `[${diag.entity}] ` : "";
426
468
  const lexiconSuffix = diag.lexicon ? ` (${diag.lexicon})` : "";
427
469
  if (diag.severity === "error") {
@@ -440,7 +482,36 @@ export async function buildCommand(options: BuildOptions): Promise<BuildResult>
440
482
  if (result.errors.length === 0) {
441
483
  const bundle = await loadOkfBundle(resolveKnowledgeDir(config, configDir));
442
484
  const knowledgeDiags = runPostSynthChecks(coreKnowledgeChecks(bundle), result, env);
443
- const { diagnostics: activeDiags, suppressed } = applyConfiguredSeverity(knowledgeDiags, config.lint?.rules);
485
+ for (const diag of resolvePostSynth(knowledgeDiags, result.entities)) {
486
+ const prefix = diag.entity ? `[${diag.entity}] ` : "";
487
+ const lexiconSuffix = diag.lexicon ? ` (${diag.lexicon})` : "";
488
+ if (diag.severity === "error") {
489
+ errors.push(formatError({ message: `${prefix}${diag.message}${lexiconSuffix}` }));
490
+ } else {
491
+ warnings.push(formatWarning({ message: `${prefix}${diag.message}${lexiconSuffix}` }));
492
+ }
493
+ }
494
+ }
495
+
496
+ // Activity contracts across every loaded lexicon (chant #2101): core's own
497
+ // plus each lexicon's, by the same `@intentius/chant-lexicon-<name>/op/...`
498
+ // convention `loadActivities` resolves implementations with. OPS012/OPS013
499
+ // and a plugin's own checks merge this over their own tables, so a step
500
+ // calling a lexicon's activity is validated against that lexicon's contract
501
+ // instead of failing for the absence of one. Resolved once, for both check
502
+ // passes below.
503
+ const activityContracts =
504
+ result.errors.length === 0 ? await loadActivityContracts(options.plugins ?? []) : undefined;
505
+
506
+ // Core-owned post-synth checks over the Op model (#2122, epic #2114
507
+ // sub-issue 6) — OPS012/OPS013/OPS014, ported from a hosting lexicon's
508
+ // own TMP012/TMP013/TMP014. An Op is recognized by entity type
509
+ // (`OpResource`), not by which lexicon declared it, so this runs over the
510
+ // FULL build result regardless of which plugins loaded — same as the
511
+ // receipt/output/knowledge checks above.
512
+ if (result.errors.length === 0) {
513
+ const opDiags = runPostSynthChecks(coreOpChecks(), result, env, { activityContracts });
514
+ const { diagnostics: activeDiags, suppressed } = applyConfiguredSeverity(opDiags, config.lint?.rules);
444
515
  suppressedPostSynthCount += suppressed.length;
445
516
  for (const diag of activeDiags) {
446
517
  const prefix = diag.entity ? `[${diag.entity}] ` : "";
@@ -471,10 +542,16 @@ export async function buildCommand(options: BuildOptions): Promise<BuildResult>
471
542
  }
472
543
 
473
544
  const scopedResult = { ...result, outputs: scopedOutputs };
474
- const postDiags = runPostSynthChecks(checks, scopedResult, env);
475
- const { diagnostics: activeDiags, suppressed } = applyConfiguredSeverity(postDiags, config.lint?.rules);
476
- suppressedPostSynthCount += suppressed.length;
477
- for (const diag of activeDiags) {
545
+ const postDiags = runPostSynthChecks(checks, scopedResult, env, { activityContracts });
546
+ // `lint.presets` (chant #2113) filters WHICH check ids are reported at
547
+ // all, before `lint.rules`/inline suppression act on the reported
548
+ // ones. It's a no-op for a lexicon that ships no `lintPresets()` (the
549
+ // common case today), since `resolvePresetIds` returns `undefined`
550
+ // for one. This is the only `resolvePostSynth` call site with a
551
+ // lexicon a preset could apply to; every other call below passes no
552
+ // `presetIds` at all.
553
+ const presetIds = resolvePresetIds(plugin.lintPresets?.(), config.lint?.presets?.[plugin.name] ?? "recommended");
554
+ for (const diag of resolvePostSynth(postDiags, result.entities, presetIds)) {
478
555
  const prefix = diag.entity ? `[${diag.entity}] ` : "";
479
556
  const lexiconSuffix = diag.lexicon ? ` (${diag.lexicon})` : "";
480
557
  if (diag.severity === "error") {
@@ -511,9 +588,7 @@ export async function buildCommand(options: BuildOptions): Promise<BuildResult>
511
588
  env,
512
589
  preloaded: preloadedPolicyChecks,
513
590
  });
514
- const { diagnostics: activePolicyDiags, suppressed } = applyConfiguredSeverity(policyDiags, config.lint?.rules);
515
- suppressedPostSynthCount += suppressed.length;
516
- for (const diag of activePolicyDiags) {
591
+ for (const diag of resolvePostSynth(policyDiags, result.entities)) {
517
592
  const prefix = diag.entity ? `[${diag.entity}] ` : "";
518
593
  const where = diag.lexicon ? ` (${diag.lexicon})` : "";
519
594
  const msg = `[policy:${diag.checkId}] ${prefix}${diag.message}${where}`;
@@ -529,15 +604,45 @@ export async function buildCommand(options: BuildOptions): Promise<BuildResult>
529
604
  }),
530
605
  );
531
606
  }
607
+
608
+ if (suppressedPresetCount > 0) {
609
+ warnings.push(
610
+ formatWarning({
611
+ message: `${suppressedPresetCount} post-synth finding(s) not reported: excluded by the active lint.presets preset`,
612
+ }),
613
+ );
614
+ }
615
+
616
+ if (inlineSuppressedCount > 0) {
617
+ warnings.push(
618
+ formatWarning({
619
+ message: `${inlineSuppressedCount} post-synth finding(s) suppressed via inline chant-ignore comments`,
620
+ }),
621
+ );
622
+ }
623
+
624
+ // Directives that are themselves worth a finding (expired, misplaced, or
625
+ // naming a rule id configured `ignorable: false`) are reported once
626
+ // each, never silently (chant #2111).
627
+ for (const m of suppressionMeta) {
628
+ warnings.push(formatWarning({ message: `[${m.checkId}] ${m.file}:${m.line} ${m.message}` }));
629
+ }
532
630
  }
533
631
 
534
632
  // Empty-output guard: source files were discovered but no lexicon produced
535
633
  // any output. Almost always indicates broken imports resolving to undefined
536
634
  // (e.g. missing root re-exports from a lexicon) or modules that exported no
537
635
  // Declarables. Without this guard, chant writes "{}" and exits 0.
636
+ //
637
+ // An Op declaration is the honest exception (#2118): it belongs to no
638
+ // lexicon partition and its build output is the `op.json` written below,
639
+ // not a resource manifest, so an Ops-only project legitimately produces no
640
+ // serializer output and must not be reported as a broken import.
641
+ const declaredOps = [...result.entities.values()].filter(isOpEntity);
538
642
  if (
539
643
  result.sourceFileCount > 0 &&
540
644
  result.outputs.size === 0 &&
645
+ declaredOps.length === 0 &&
541
646
  result.errors.length === 0 &&
542
647
  errors.length === 0
543
648
  ) {
@@ -658,12 +763,12 @@ export async function buildCommand(options: BuildOptions): Promise<BuildResult>
658
763
  }
659
764
  }
660
765
 
661
- // Op worker artifacts (`ops/<name>/{workflow,worker,activities}.ts`) always
662
- // go to `<project>/dist/ops/` — the fixed location `chant run <op> --temporal`
663
- // reads (`join(projectPath, "dist", "ops", ...)`) — independent of `--output`,
664
- // which routes the primary resource manifest. Without this, a bare `chant build`
665
- // only printed them to stderr and `--output foo.yaml` scattered them next to
666
- // `foo.yaml`, so the durable-run worker was never where `run --temporal` looks.
766
+ // Anything a serializer emits under `ops/` always goes to
767
+ // `<project>/dist/ops/` — the fixed place an Op's build output is read
768
+ // from, alongside the `op.json` core writes below — independent of
769
+ // `--output`, which routes the primary resource manifest. Without this, a
770
+ // bare `chant build` only printed them to stderr and `--output foo.yaml`
771
+ // scattered them next to `foo.yaml`.
667
772
  const projectDist = resolve(options.path ?? ".", "dist");
668
773
  let opsWritten = 0;
669
774
  for (const [filename, entry] of [...additionalFiles]) {
@@ -677,13 +782,40 @@ export async function buildCommand(options: BuildOptions): Promise<BuildResult>
677
782
  } catch (err) {
678
783
  errors.push(
679
784
  formatError({
680
- message: `Failed to write Op worker file ${filename}: ${err instanceof Error ? err.message : String(err)}`,
785
+ message: `Failed to write Op output file ${filename}: ${err instanceof Error ? err.message : String(err)}`,
681
786
  }),
682
787
  );
683
788
  }
684
789
  }
685
790
  if (opsWritten > 0) {
686
- console.error(formatInfo(`Wrote ${opsWritten} Op worker file(s) under ${join(options.path ?? ".", "dist", "ops")}/`));
791
+ console.error(formatInfo(`Wrote ${opsWritten} Op output file(s) under ${join(options.path ?? ".", "dist", "ops")}/`));
792
+ }
793
+
794
+ // `dist/ops/<name>/op.json` — the Op IR (#1289), written here by core
795
+ // rather than emitted by a lexicon serializer (#2118). An Op declaration
796
+ // is core's own entity now (`Chant::Op`, lexicon `chant`) and is held out
797
+ // of `partitionByLexicon` entirely, so this is the one place its build
798
+ // output is produced: a deterministic, engine-neutral restatement of the
799
+ // step graph that anything can read without importing chant.
800
+ let irWritten = 0;
801
+ for (const entity of declaredOps) {
802
+ const config = (entity as unknown as { props?: OpConfig }).props;
803
+ if (!config?.name) continue;
804
+ try {
805
+ const targetPath = join(projectDist, "ops", config.name, "op.json");
806
+ mkdirSync(dirname(targetPath), { recursive: true });
807
+ writeFileSync(targetPath, serializeOpIR(config));
808
+ irWritten += 1;
809
+ } catch (err) {
810
+ errors.push(
811
+ formatError({
812
+ message: `Failed to write op.json for Op "${config.name}": ${err instanceof Error ? err.message : String(err)}`,
813
+ }),
814
+ );
815
+ }
816
+ }
817
+ if (irWritten > 0) {
818
+ console.error(formatInfo(`Wrote ${irWritten} op.json file(s) under ${join(options.path ?? ".", "dist", "ops")}/`));
687
819
  }
688
820
 
689
821
  if (options.output) {
@@ -4,7 +4,7 @@
4
4
  * The contract used to check documentation by counting files — "at least 1
5
5
  * .mdx page" at tier 1, "at least 8" at tier 2 — and never opened one. That
6
6
  * counts a page nothing links to exactly the same as a page a reader can
7
- * actually find, so azure, temporal, helm and github each accumulated
7
+ * actually find, so azure, helm and github each accumulated
8
8
  * hand-added pages that appear in no sidebar and are reachable only by typing
9
9
  * their URL. Azure's getting-started, resource reference and composites pages
10
10
  * were all invisible while its ≥8-page check passed comfortably — the count
@@ -119,7 +119,7 @@ export const plainBucket = new Bucket({
119
119
  const results = await checkExamplesBuild(dir);
120
120
  const insecure = results.find((r) => r.example === "insecure");
121
121
  expect(insecure?.ok).toBe(false);
122
- expect(insecure?.detail).toMatch(/post-synth error\(s\) from the lexicon's own checks/);
122
+ expect(insecure?.detail).toMatch(/post-synth error\(s\)/);
123
123
  expect(insecure?.detail).toMatch(/WAW042: \[plainBucket\]/);
124
124
  });
125
125
 
@@ -141,6 +141,34 @@ export const plainBucket = new Bucket({
141
141
  expect(results.find((r) => r.example === "suppressed")).toMatchObject({ ok: true });
142
142
  });
143
143
 
144
+ // #2101 — the third axis: core's own Op-model checks run over the example's
145
+ // result too, so an example carrying an Op has it validated here rather
146
+ // than only when a user builds the example themselves. The Op below
147
+ // references a step whose activity has no registered contract anywhere,
148
+ // which is exactly what OPS013 exists to refuse.
149
+ test("an example whose Op fails core's own OPS checks fails (#2101)", async () => {
150
+ writeLexiconDirWithExample(dir, "bad-op", {
151
+ "bucket.ts": cleanBucketSource,
152
+ "broken.op.ts": `import { Op, phase, activity, stepOutput } from "@intentius/chant/op";
153
+
154
+ export const brokenOp = Op({
155
+ name: "broken",
156
+ overview: "references a step nothing declares",
157
+ phases: [
158
+ phase("Run", [
159
+ activity("shellCmd", { cmd: stepOutput("nope", "value") }),
160
+ ]),
161
+ ],
162
+ });
163
+ `,
164
+ });
165
+
166
+ const results = await checkExamplesBuild(dir);
167
+ const badOp = results.find((r) => r.example === "bad-op");
168
+ expect(badOp?.ok).toBe(false);
169
+ expect(badOp?.detail).toMatch(/OPS013/);
170
+ });
171
+
144
172
  test("an empty src/ directory is skipped, not reported as a failure", async () => {
145
173
  writeLexiconDirWithExample(dir, "empty", {});
146
174
  const results = await checkExamplesBuild(dir);
@@ -23,6 +23,14 @@
23
23
  * diagnostic left at `error` severity fails the example. Warnings do not.
24
24
  * An example is what a user copies wholesale; it must not teach a pattern
25
25
  * the lexicon it demonstrates flags as an error.
26
+ *
27
+ * #2101 added the third axis: core's own Op-model checks (OPS012/OPS013/
28
+ * OPS014, `../../lint/rules/op/`) run over the same result, as `chant build`
29
+ * runs them, so an example carrying an Op has that Op validated here rather
30
+ * than only when a user builds the example themselves. They are given the
31
+ * activity contracts every loaded lexicon declares, resolved the same way
32
+ * `chant build` resolves them, so a step calling that lexicon's own activity
33
+ * validates against its own schemas.
26
34
  */
27
35
 
28
36
  import { existsSync, readdirSync } from "fs";
@@ -31,8 +39,11 @@ import { build, type BuildResult } from "../../build";
31
39
  import { findInfraFiles } from "../../discovery/files";
32
40
  import { detectLexicons } from "../../detectLexicon";
33
41
  import { loadChantConfig } from "../../config";
34
- import { loadPlugins } from "../plugins";
42
+ import { loadPlugins, collectBuildRootContributors } from "../plugins";
35
43
  import { runPostSynthChecks, type PostSynthDiagnostic } from "../../lint/post-synth";
44
+ import { coreOpChecks } from "../../lint/rules/op";
45
+ import { loadActivityContracts } from "../../op/activity-contract-registry";
46
+ import type { ActivityContract } from "../../op/activity-contract";
36
47
  import { applyConfiguredSeverity } from "../../lint/config";
37
48
  import type { LexiconPlugin } from "../../lexicon";
38
49
  import type { SerializerResult } from "../../serializer";
@@ -44,18 +55,31 @@ export interface ExampleBuildResult {
44
55
  }
45
56
 
46
57
  /**
47
- * Run each plugin's own post-synth checks against that plugin's output —
48
- * the same per-plugin scoping and `lint.rules` severity resolution
49
- * `cli/commands/build.ts` applies — and return what is left at `error`
50
- * severity. Project `lint.policies` are not run here: those are the
51
- * example author's organizational policy, not the lexicon's contract.
58
+ * Run core's Op-model checks over the whole result, then each plugin's own
59
+ * post-synth checks against that plugin's output — the same scoping and
60
+ * `lint.rules` severity resolution `cli/commands/build.ts` applies — and
61
+ * return what is left at `error` severity. Project `lint.policies` are not
62
+ * run here: those are the example author's organizational policy, not the
63
+ * lexicon's contract.
52
64
  */
53
65
  export function postSynthErrors(
54
66
  plugins: LexiconPlugin[],
55
67
  result: BuildResult,
56
68
  lintRules: Parameters<typeof applyConfiguredSeverity>[1],
69
+ activityContracts?: ReadonlyMap<string, ActivityContract>,
57
70
  ): PostSynthDiagnostic[] {
58
71
  const errors: PostSynthDiagnostic[] = [];
72
+
73
+ // Core's Op-model checks first (#2101). An Op is recognized by entity type,
74
+ // not by which lexicon declared it, so these run over the FULL result the
75
+ // way `chant build` runs them — unscoped, and regardless of which plugins
76
+ // loaded. Without this an example's Op reached output unvalidated, which is
77
+ // why the terraform, aws and render examples kept their Ops outside `src/`.
78
+ const opDiags = runPostSynthChecks(coreOpChecks(), result, undefined, { activityContracts });
79
+ for (const diag of applyConfiguredSeverity(opDiags, lintRules).diagnostics) {
80
+ if (diag.severity === "error") errors.push(diag);
81
+ }
82
+
59
83
  for (const plugin of plugins) {
60
84
  if (!plugin.postSynthChecks) continue;
61
85
  const checks = plugin.postSynthChecks();
@@ -66,7 +90,7 @@ export function postSynthErrors(
66
90
  const pluginOutput = result.outputs.get(outputKey);
67
91
  if (pluginOutput !== undefined) scopedOutputs.set(outputKey, pluginOutput);
68
92
 
69
- const diags = runPostSynthChecks(checks, { ...result, outputs: scopedOutputs });
93
+ const diags = runPostSynthChecks(checks, { ...result, outputs: scopedOutputs }, undefined, { activityContracts });
70
94
  const { diagnostics } = applyConfiguredSeverity(diags, lintRules);
71
95
  for (const diag of diagnostics) {
72
96
  if (diag.severity === "error") errors.push(diag);
@@ -129,7 +153,15 @@ export async function checkExamplesBuild(lexiconDir: string): Promise<ExampleBui
129
153
  }
130
154
 
131
155
  const plugins = await loadPlugins(lexiconNames);
132
- const result = await build(srcDir, plugins.map((p) => p.serializer));
156
+ // Bind each plugin's `buildRoots()` hook exactly as `chant build` does
157
+ // (#2083): a lexicon whose entities come from config-declared roots
158
+ // rather than typed source (k8s kustomize roots, terraform roots) has
159
+ // nothing to serialize otherwise, and its example would read as
160
+ // "produced no output" for a reason that is this harness's, not the
161
+ // example's.
162
+ const exampleDir = join(examplesDir, entry.name);
163
+ const buildRoots = collectBuildRootContributors(plugins, exampleConfig as Record<string, unknown>, exampleDir);
164
+ const result = await build(srcDir, plugins.map((p) => p.serializer), undefined, { buildRoots });
133
165
 
134
166
  const structuralErrors = result.errors.map((e) => e.message);
135
167
  const producedOutput = result.outputs.size > 0;
@@ -139,7 +171,7 @@ export async function checkExamplesBuild(lexiconDir: string): Promise<ExampleBui
139
171
  // already explains the failure, and partial output is not the output
140
172
  // the checks are meant to see.
141
173
  const postSynth = structurallyOk
142
- ? postSynthErrors(plugins, result, exampleConfig.lint?.rules)
174
+ ? postSynthErrors(plugins, result, exampleConfig.lint?.rules, await loadActivityContracts(plugins))
143
175
  : [];
144
176
  const ok = structurallyOk && postSynth.length === 0;
145
177
 
@@ -152,7 +184,7 @@ export async function checkExamplesBuild(lexiconDir: string): Promise<ExampleBui
152
184
  ? structuralErrors.join("; ")
153
185
  : !producedOutput
154
186
  ? "discovered source but produced no output"
155
- : `post-synth error(s) from the lexicon's own checks: ${postSynth.map(formatPostSynthError).join("; ")}`,
187
+ : `post-synth error(s): ${postSynth.map(formatPostSynthError).join("; ")}`,
156
188
  });
157
189
  } catch (err) {
158
190
  results.push({
@@ -313,6 +313,12 @@ function parseAndWrite(
313
313
  };
314
314
  }
315
315
 
316
+ // Sections the parser read but import cannot carry, named by the parser
317
+ // rather than dropped silently (#2069).
318
+ if (ir.warnings) {
319
+ warnings.push(...ir.warnings);
320
+ }
321
+
316
322
  const generator = plugin.templateGenerator!();
317
323
 
318
324
  // Check output directory
@@ -150,6 +150,7 @@ export async function packageLexicon(options?: { verbose?: boolean; force?: bool
150
150
  buildManifest: (genResult) => ({
151
151
  name: "${name}",
152
152
  version: "0.0.1",
153
+ chantVersion: ">=0.1.0",
153
154
  }),
154
155
  srcDir,
155
156
  collectSkills: () => new Map(),
@@ -161,6 +162,14 @@ export async function packageLexicon(options?: { verbose?: boolean; force?: bool
161
162
  `;
162
163
  }
163
164
 
165
+ export function generateCodegenDocsCliTs(): string {
166
+ return `#!/usr/bin/env tsx
167
+ import { generateDocs } from "./docs";
168
+
169
+ await generateDocs({ verbose: true });
170
+ `;
171
+ }
172
+
164
173
  export function generateCodegenDocsTs(name: string): string {
165
174
  return `import { docsPipeline, writeDocsSite } from "@intentius/chant/codegen/docs";
166
175
 
@@ -10,8 +10,16 @@ export function generatePackageJson(name: string, names: { packageName: string }
10
10
  private: true,
11
11
  files: ["src/", "dist/"],
12
12
  exports: {
13
- ".": "./src/index.ts",
14
- "./*": "./src/*",
13
+ ".": {
14
+ development: "./src/index.ts",
15
+ types: "./dist/index.d.ts",
16
+ default: "./src/index.ts",
17
+ },
18
+ "./*": {
19
+ development: "./src/*.ts",
20
+ types: "./dist/*.d.ts",
21
+ default: "./src/*.ts",
22
+ },
15
23
  "./manifest": "./dist/manifest.json",
16
24
  "./meta": "./dist/meta.json",
17
25
  "./types": "./dist/types/index.d.ts",
@@ -20,8 +28,9 @@ export function generatePackageJson(name: string, names: { packageName: string }
20
28
  generate: "npx tsx src/codegen/generate-cli.ts",
21
29
  validate: "npx tsx src/validate-cli.ts",
22
30
  docs: "npx tsx src/codegen/docs-cli.ts",
23
- build: "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
24
- prepack: "npm run generate && npm run validate && npm run build",
31
+ build: 'tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && find dist -type f \\( -name "*.js" -o -name "*.js.map" \\) -delete',
32
+ prepack: "npm run generate && npm run bundle && npm run validate && npm run build",
33
+ bundle: "tsx src/package-cli.ts",
25
34
  },
26
35
  devDependencies: {
27
36
  // `*` (not `workspace:*`) so a fresh lexicon `npm install`s under plain npm
@@ -211,3 +220,34 @@ import { validate } from "./validate";
211
220
  await validate();
212
221
  `;
213
222
  }
223
+
224
+ /**
225
+ * Thin entry point for `npm run bundle`, called from `prepack`. Writes
226
+ * `src/generated/` (via the generate pipeline) and `dist/` (via the package
227
+ * pipeline plus `writeBundleSpec`), so `dist/manifest.json` exists before
228
+ * `npm run validate` and `npm run build` run.
229
+ */
230
+ export function generatePackageCliTs(): string {
231
+ return `#!/usr/bin/env tsx
232
+ import { generate, writeGeneratedFiles } from "./codegen/generate";
233
+ import { packageLexicon } from "./codegen/package";
234
+ import { writeBundleSpec } from "@intentius/chant/codegen/package";
235
+ import { join, dirname } from "path";
236
+ import { fileURLToPath } from "url";
237
+
238
+ const srcDir = dirname(fileURLToPath(import.meta.url));
239
+
240
+ // 1. Generate src/generated/ files (writeGeneratedFiles resolves its own target)
241
+ const genResult = await generate({ verbose: true });
242
+ writeGeneratedFiles(genResult);
243
+
244
+ // 2. Run package pipeline and write dist/
245
+ const { spec, stats } = await packageLexicon({ verbose: true });
246
+
247
+ const distDir = join(dirname(srcDir), "dist");
248
+ writeBundleSpec(spec, distDir);
249
+
250
+ console.error(\`Packaged \${stats.resources} resources, \${stats.ruleCount} rules, \${stats.skillCount} skills\`);
251
+ console.error(\`dist/ written to \${distDir}\`);
252
+ `;
253
+ }