@intentius/chant 0.124.13 → 0.124.14

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 (907) hide show
  1. package/bin/chant +11 -0
  2. package/dist/agents/checks.js +326 -0
  3. package/dist/agents/discover.js +885 -0
  4. package/dist/agents/importer.js +17 -0
  5. package/dist/agents/index.js +12 -0
  6. package/dist/agents/types.js +19 -0
  7. package/dist/apply.js +151 -0
  8. package/dist/attrref.js +70 -0
  9. package/dist/audit/catalog.js +350 -0
  10. package/dist/audit/core.js +252 -0
  11. package/dist/audit/discover.js +633 -0
  12. package/dist/audit/fetch.js +666 -0
  13. package/dist/audit/lineage.js +91 -0
  14. package/dist/audit/nginx.js +366 -0
  15. package/dist/audit/prior-art.js +132 -0
  16. package/dist/audit/proof.js +321 -0
  17. package/dist/audit/report-html.js +194 -0
  18. package/dist/audit/report-model.js +198 -0
  19. package/dist/audit/report.js +102 -0
  20. package/dist/audit/rules-doc.js +144 -0
  21. package/dist/audit/secrets.js +405 -0
  22. package/dist/audit/terraform-state.js +140 -0
  23. package/dist/audit/wrangler.js +262 -0
  24. package/dist/behaviour-delta.js +401 -0
  25. package/dist/behaviour-engine.js +357 -0
  26. package/dist/behaviour-graph.js +83 -0
  27. package/dist/behaviour-http.js +188 -0
  28. package/dist/behaviour-kinds.js +172 -0
  29. package/dist/behaviour-overlay.js +50 -0
  30. package/dist/behaviour-predict.js +188 -0
  31. package/dist/behaviour-request.js +194 -0
  32. package/dist/behaviour.js +1325 -0
  33. package/dist/build-params.js +108 -0
  34. package/dist/build.js +668 -0
  35. package/dist/builder.js +44 -0
  36. package/dist/cdk/advise.js +30 -0
  37. package/dist/cdk/assembly.js +122 -0
  38. package/dist/cdk/graph.js +444 -0
  39. package/dist/cdk/tier-map.js +64 -0
  40. package/dist/cdk/types.js +24 -0
  41. package/dist/change-set.js +312 -0
  42. package/dist/child-project.js +21 -0
  43. package/dist/claimed-fields.js +135 -0
  44. package/dist/cli/build-options.js +70 -0
  45. package/dist/cli/build-params-cli.js +139 -0
  46. package/dist/cli/command-group.js +123 -0
  47. package/dist/cli/commands/audit-agents.js +326 -0
  48. package/dist/cli/commands/audit.js +571 -0
  49. package/dist/cli/commands/build.js +920 -0
  50. package/dist/cli/commands/carve-apply.js +153 -0
  51. package/dist/cli/commands/carve-bridge.js +201 -0
  52. package/dist/cli/commands/carve-emit.js +332 -0
  53. package/dist/cli/commands/carve-status.js +119 -0
  54. package/dist/cli/commands/carve.js +204 -0
  55. package/dist/cli/commands/check-lexicon-docs.js +79 -0
  56. package/dist/cli/commands/check-lexicon-examples.js +177 -0
  57. package/dist/cli/commands/check-lexicon-intrinsics.js +291 -0
  58. package/dist/cli/commands/check-lexicon-mcp.js +82 -0
  59. package/dist/cli/commands/check-lexicon-plugin.d.ts.map +1 -1
  60. package/dist/cli/commands/check-lexicon-plugin.js +104 -0
  61. package/dist/cli/commands/check-lexicon.js +766 -0
  62. package/dist/cli/commands/describe.js +85 -0
  63. package/dist/cli/commands/diff.js +175 -0
  64. package/dist/cli/commands/doctor.js +350 -0
  65. package/dist/cli/commands/import-agents.js +155 -0
  66. package/dist/cli/commands/import.js +670 -0
  67. package/dist/cli/commands/init-lexicon/templates/codegen.js +194 -0
  68. package/dist/cli/commands/init-lexicon/templates/docs.js +100 -0
  69. package/dist/cli/commands/init-lexicon/templates/examples.js +29 -0
  70. package/dist/cli/commands/init-lexicon/templates/lint.js +34 -0
  71. package/dist/cli/commands/init-lexicon/templates/lsp.js +37 -0
  72. package/dist/cli/commands/init-lexicon/templates/plugin.js +108 -0
  73. package/dist/cli/commands/init-lexicon/templates/project.js +240 -0
  74. package/dist/cli/commands/init-lexicon/templates/spec.js +56 -0
  75. package/dist/cli/commands/init-lexicon/templates/tests.js +66 -0
  76. package/dist/cli/commands/init-lexicon.js +172 -0
  77. package/dist/cli/commands/init.js +381 -0
  78. package/dist/cli/commands/lexicon-rolling-upgrade.js +145 -0
  79. package/dist/cli/commands/lexicon-surface-diff.js +145 -0
  80. package/dist/cli/commands/licenses.js +125 -0
  81. package/dist/cli/commands/lint.d.ts.map +1 -1
  82. package/dist/cli/commands/lint.js +948 -0
  83. package/dist/cli/commands/list.js +63 -0
  84. package/dist/cli/commands/migrate.d.ts.map +1 -1
  85. package/dist/cli/commands/migrate.js +423 -0
  86. package/dist/cli/commands/onboard.js +403 -0
  87. package/dist/cli/commands/pinned-upgrade.js +191 -0
  88. package/dist/cli/commands/update.js +194 -0
  89. package/dist/cli/commands/vendor.js +217 -0
  90. package/dist/cli/conflict-check.js +104 -0
  91. package/dist/cli/debug.js +8 -0
  92. package/dist/cli/format.js +104 -0
  93. package/dist/cli/handlers/build.js +267 -0
  94. package/dist/cli/handlers/carve-apply.js +30 -0
  95. package/dist/cli/handlers/carve-bridge.js +28 -0
  96. package/dist/cli/handlers/carve-emit.js +50 -0
  97. package/dist/cli/handlers/carve-status.js +26 -0
  98. package/dist/cli/handlers/carve.js +40 -0
  99. package/dist/cli/handlers/change-set.js +46 -0
  100. package/dist/cli/handlers/components.js +730 -0
  101. package/dist/cli/handlers/dev.js +113 -0
  102. package/dist/cli/handlers/emulator.js +233 -0
  103. package/dist/cli/handlers/explain.js +54 -0
  104. package/dist/cli/handlers/fan-out.js +422 -0
  105. package/dist/cli/handlers/gate-resume.js +275 -0
  106. package/dist/cli/handlers/generate.js +84 -0
  107. package/dist/cli/handlers/graph.js +969 -0
  108. package/dist/cli/handlers/init.js +102 -0
  109. package/dist/cli/handlers/lifecycle.js +1727 -0
  110. package/dist/cli/handlers/lint.js +62 -0
  111. package/dist/cli/handlers/migrate.js +48 -0
  112. package/dist/cli/handlers/misc.js +391 -0
  113. package/dist/cli/handlers/operator.js +1162 -0
  114. package/dist/cli/handlers/override-approve.js +102 -0
  115. package/dist/cli/handlers/pr.js +503 -0
  116. package/dist/cli/handlers/promote.js +342 -0
  117. package/dist/cli/handlers/run-generate.js +206 -0
  118. package/dist/cli/handlers/run-wave.js +66 -0
  119. package/dist/cli/handlers/run.js +1191 -0
  120. package/dist/cli/handlers/scenario.js +325 -0
  121. package/dist/cli/handlers/search.js +924 -0
  122. package/dist/cli/handlers/serve.js +32 -0
  123. package/dist/cli/handlers/vendor.js +154 -0
  124. package/dist/cli/index.js +3 -0
  125. package/dist/cli/is-entry-point.js +23 -0
  126. package/dist/cli/lsp/capabilities.js +28 -0
  127. package/dist/cli/lsp/diagnostics.js +34 -0
  128. package/dist/cli/lsp/server.js +329 -0
  129. package/dist/cli/main.d.ts.map +1 -1
  130. package/dist/cli/main.js +2540 -0
  131. package/dist/cli/mcp/lifecycle-tools.js +80 -0
  132. package/dist/cli/mcp/op-tools.js +306 -0
  133. package/dist/cli/mcp/resource-handlers.js +258 -0
  134. package/dist/cli/mcp/resources/context.js +85 -0
  135. package/dist/cli/mcp/server.js +353 -0
  136. package/dist/cli/mcp/tools/build.js +111 -0
  137. package/dist/cli/mcp/tools/composites.js +95 -0
  138. package/dist/cli/mcp/tools/explain.js +166 -0
  139. package/dist/cli/mcp/tools/import.js +49 -0
  140. package/dist/cli/mcp/tools/lint.js +41 -0
  141. package/dist/cli/mcp/tools/scaffold.js +111 -0
  142. package/dist/cli/mcp/tools/search.js +112 -0
  143. package/dist/cli/mcp/types.js +1 -0
  144. package/dist/cli/mcp/workspace-plugins.js +91 -0
  145. package/dist/cli/mcp/workspace-tools.d.ts +1 -1
  146. package/dist/cli/mcp/workspace-tools.js +564 -0
  147. package/dist/cli/mcp-config.js +70 -0
  148. package/dist/cli/plugins.js +313 -0
  149. package/dist/cli/registry.js +23 -0
  150. package/dist/cli/reporters/stylish.js +329 -0
  151. package/dist/cli/version.js +15 -0
  152. package/dist/cli/watch.js +79 -0
  153. package/dist/codegen/bound-property-types.js +82 -0
  154. package/dist/codegen/coverage.js +119 -0
  155. package/dist/codegen/docs-file-markers.js +60 -0
  156. package/dist/codegen/docs-pages.js +115 -0
  157. package/dist/codegen/docs-rule-scanning.js +164 -0
  158. package/dist/codegen/docs-rules.js +76 -0
  159. package/dist/codegen/docs-sections.js +117 -0
  160. package/dist/codegen/docs-sidebar.js +65 -0
  161. package/dist/codegen/docs-types.js +4 -0
  162. package/dist/codegen/docs.js +356 -0
  163. package/dist/codegen/fetch.js +340 -0
  164. package/dist/codegen/generate-post-synth-barrel.js +63 -0
  165. package/dist/codegen/generate-registry.js +71 -0
  166. package/dist/codegen/generate-runtime-index.js +56 -0
  167. package/dist/codegen/generate-typescript.js +119 -0
  168. package/dist/codegen/generate.js +115 -0
  169. package/dist/codegen/json-patch.js +141 -0
  170. package/dist/codegen/json-schema-to-ts.js +344 -0
  171. package/dist/codegen/json-schema.js +246 -0
  172. package/dist/codegen/lexicon-regen.js +412 -0
  173. package/dist/codegen/naming.js +217 -0
  174. package/dist/codegen/okf-lexicon.js +245 -0
  175. package/dist/codegen/package.js +150 -0
  176. package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
  177. package/dist/codegen/pinned-upgrade.js +494 -0
  178. package/dist/codegen/registry.js +60 -0
  179. package/dist/codegen/rehype-base-url.mjs +68 -0
  180. package/dist/codegen/rolling-upgrade.js +217 -0
  181. package/dist/codegen/surface-snapshot.js +537 -0
  182. package/dist/codegen/testdata/postgres-tags.json +242 -0
  183. package/dist/codegen/topo-sort.js +36 -0
  184. package/dist/codegen/typecheck.js +115 -0
  185. package/dist/codegen/validate.js +200 -0
  186. package/dist/codegen/version-bump.js +35 -0
  187. package/dist/components/auto-release.js +143 -0
  188. package/dist/components/builders.js +47 -0
  189. package/dist/components/capability-plugin-loader.js +175 -0
  190. package/dist/components/capability-plugin-schema.js +46 -0
  191. package/dist/components/capability-plugin.js +99 -0
  192. package/dist/components/capability.js +60 -0
  193. package/dist/components/changed-files.js +72 -0
  194. package/dist/components/cli-support.js +427 -0
  195. package/dist/components/component.js +120 -0
  196. package/dist/components/component.schema.json +271 -0
  197. package/dist/components/config-defaults.js +130 -0
  198. package/dist/components/deploy-units.js +60 -0
  199. package/dist/components/discover.d.ts.map +1 -1
  200. package/dist/components/discover.js +189 -0
  201. package/dist/components/driver-output.js +86 -0
  202. package/dist/components/driver.js +728 -0
  203. package/dist/components/fan-out-output.js +165 -0
  204. package/dist/components/fan-out-record.js +94 -0
  205. package/dist/components/fan-out-run.js +373 -0
  206. package/dist/components/fan-out-support.js +60 -0
  207. package/dist/components/fan-out.js +273 -0
  208. package/dist/components/gate-plan.js +41 -0
  209. package/dist/components/gated-wave-pipeline.js +46 -0
  210. package/dist/components/index.js +24 -0
  211. package/dist/components/layers.js +28 -0
  212. package/dist/components/manifest-persistence.js +108 -0
  213. package/dist/components/pilots/alb-ecs.pilot.js +59 -0
  214. package/dist/components/pilots/dynamodb.pilot.js +51 -0
  215. package/dist/components/pilots/jar-emr.pilot.js +65 -0
  216. package/dist/components/pilots/lambda.pilot.js +52 -0
  217. package/dist/components/pilots/neo4j-fanout.pilot.js +68 -0
  218. package/dist/components/pilots/project.js +12 -0
  219. package/dist/components/pr-pipeline.js +134 -0
  220. package/dist/components/pr-run.js +363 -0
  221. package/dist/components/presets/ecs-fargate.js +72 -0
  222. package/dist/components/presets/index.js +28 -0
  223. package/dist/components/presets/lambda.js +34 -0
  224. package/dist/components/presets/single-host-compose.js +41 -0
  225. package/dist/components/promote.js +549 -0
  226. package/dist/components/registry.js +34 -0
  227. package/dist/components/run-progress.js +33 -0
  228. package/dist/components/sandbox/driver.d.ts.map +1 -1
  229. package/dist/components/sandbox/driver.js +93 -0
  230. package/dist/components/sandbox/run.js +115 -0
  231. package/dist/components/starter-plugin.js +104 -0
  232. package/dist/components/verbs/__tests__/mock-cloud-executor.js +68 -0
  233. package/dist/components/verbs/__tests__/mock-process-runner.js +45 -0
  234. package/dist/components/verbs/__tests__/mock-sbom-generator.js +56 -0
  235. package/dist/components/verbs/bom-writer.js +287 -0
  236. package/dist/components/verbs/build-archive.js +188 -0
  237. package/dist/components/verbs/build.js +142 -0
  238. package/dist/components/verbs/cloud-executor.js +110 -0
  239. package/dist/components/verbs/component-bom.js +125 -0
  240. package/dist/components/verbs/ensure-secret.js +50 -0
  241. package/dist/components/verbs/index.js +61 -0
  242. package/dist/components/verbs/license-policy.js +75 -0
  243. package/dist/components/verbs/lockfile-sbom-generator.js +191 -0
  244. package/dist/components/verbs/process-runner.js +78 -0
  245. package/dist/components/verbs/r2-sync.js +93 -0
  246. package/dist/components/verbs/reproducibility.js +62 -0
  247. package/dist/components/verbs/run-agent.js +577 -0
  248. package/dist/components/verbs/sbom-generator.js +119 -0
  249. package/dist/components/verbs/sbom.js +97 -0
  250. package/dist/components/verbs/shell.js +32 -0
  251. package/dist/components/verbs/sign.js +221 -0
  252. package/dist/components/verbs/stub.js +28 -0
  253. package/dist/components/verbs/tool-sbom-generator.js +154 -0
  254. package/dist/components/verbs/verify.js +112 -0
  255. package/dist/components/verbs/vex.js +131 -0
  256. package/dist/components/verbs/vuln-gate.js +152 -0
  257. package/dist/components/verbs/vuln-scan.js +288 -0
  258. package/dist/components/verbs/wait-verify.js +106 -0
  259. package/dist/components/verbs/wrangler.js +179 -0
  260. package/dist/components/wave-plan.js +102 -0
  261. package/dist/composite.js +305 -0
  262. package/dist/config-import.d.ts.map +1 -1
  263. package/dist/config-import.js +22 -0
  264. package/dist/config-sandbox.js +122 -0
  265. package/dist/config-static.js +206 -0
  266. package/dist/config.js +605 -0
  267. package/dist/content-digest.js +23 -0
  268. package/dist/declarable.js +114 -0
  269. package/dist/deep-observation.js +437 -0
  270. package/dist/detectLexicon.js +54 -0
  271. package/dist/discovery/cache.js +70 -0
  272. package/dist/discovery/collect.js +208 -0
  273. package/dist/discovery/cycles.js +95 -0
  274. package/dist/discovery/entity-wire-codec.js +391 -0
  275. package/dist/discovery/entity-wire.js +42 -0
  276. package/dist/discovery/files.js +121 -0
  277. package/dist/discovery/fold-import.d.ts.map +1 -1
  278. package/dist/discovery/fold-import.js +4178 -0
  279. package/dist/discovery/fold-rank.js +292 -0
  280. package/dist/discovery/graph.js +115 -0
  281. package/dist/discovery/import.d.ts.map +1 -1
  282. package/dist/discovery/import.js +65 -0
  283. package/dist/discovery/index.js +333 -0
  284. package/dist/discovery/param-deps.js +487 -0
  285. package/dist/discovery/resolve.js +39 -0
  286. package/dist/discovery/sandbox/bundle.js +214 -0
  287. package/dist/discovery/sandbox/child-errors.js +26 -0
  288. package/dist/discovery/sandbox/config-run.js +100 -0
  289. package/dist/discovery/sandbox/config-wire.js +183 -0
  290. package/dist/discovery/sandbox/driver.d.ts.map +1 -1
  291. package/dist/discovery/sandbox/driver.js +333 -0
  292. package/dist/discovery/sandbox/fork.js +229 -0
  293. package/dist/discovery/sandbox/policy-run.js +142 -0
  294. package/dist/discovery/sandbox/policy-wire.js +152 -0
  295. package/dist/discovery/sandbox/run.js +77 -0
  296. package/dist/discovery/specifier-resolve.js +320 -0
  297. package/dist/discovery/walk.js +284 -0
  298. package/dist/effect-receipt.js +340 -0
  299. package/dist/env.js +55 -0
  300. package/dist/errors.js +62 -0
  301. package/dist/fold/fold.js +1434 -0
  302. package/dist/fold/foldable-helpers.js +229 -0
  303. package/dist/fold/subset.js +696 -0
  304. package/dist/fold-provenance.js +414 -0
  305. package/dist/gate-decision.js +260 -0
  306. package/dist/gate-resume-run.js +154 -0
  307. package/dist/gated-waves.js +165 -0
  308. package/dist/governance.js +43 -0
  309. package/dist/graph-declared.js +45 -0
  310. package/dist/graph-detail.js +207 -0
  311. package/dist/graph-dot.js +54 -0
  312. package/dist/graph-effective.js +107 -0
  313. package/dist/graph-ir.js +623 -0
  314. package/dist/graph-layout.js +184 -0
  315. package/dist/graph-lens.js +105 -0
  316. package/dist/graph-mermaid.js +83 -0
  317. package/dist/graph-ops.js +39 -0
  318. package/dist/graph-refs.js +156 -0
  319. package/dist/held-elsewhere.js +87 -0
  320. package/dist/identity.js +251 -0
  321. package/dist/import/base-parser.js +34 -0
  322. package/dist/import/embedded.js +255 -0
  323. package/dist/import/generator.js +1 -0
  324. package/dist/import/ir-utils.js +85 -0
  325. package/dist/import/parser-options.js +45 -0
  326. package/dist/import/parser.js +1 -0
  327. package/dist/index.js +118 -0
  328. package/dist/intrinsic-interpolation.js +73 -0
  329. package/dist/intrinsic.js +31 -0
  330. package/dist/join-key.js +35 -0
  331. package/dist/kubectl-context.js +150 -0
  332. package/dist/lexicon-config.js +58 -0
  333. package/dist/lexicon-integrity.js +47 -0
  334. package/dist/lexicon-manifest.js +70 -0
  335. package/dist/lexicon-module.d.ts.map +1 -1
  336. package/dist/lexicon-module.js +241 -0
  337. package/dist/lexicon-output.js +218 -0
  338. package/dist/lexicon-plugin-helpers.js +104 -0
  339. package/dist/lexicon-schema.js +136 -0
  340. package/dist/lexicon.js +130 -0
  341. package/dist/lifecycle/affected.js +224 -0
  342. package/dist/lifecycle/assert-live.js +110 -0
  343. package/dist/lifecycle/build-ledger-store.js +160 -0
  344. package/dist/lifecycle/build-ledger.js +155 -0
  345. package/dist/lifecycle/change-set.js +356 -0
  346. package/dist/lifecycle/converge-ledger.js +161 -0
  347. package/dist/lifecycle/deep-diff.js +233 -0
  348. package/dist/lifecycle/deep-observe.js +147 -0
  349. package/dist/lifecycle/digest.js +143 -0
  350. package/dist/lifecycle/disruption.js +135 -0
  351. package/dist/lifecycle/gate-applied.js +113 -0
  352. package/dist/lifecycle/gate-audit.js +341 -0
  353. package/dist/lifecycle/gate-ledger-select.js +89 -0
  354. package/dist/lifecycle/gate-ledger.js +193 -0
  355. package/dist/lifecycle/gate-origin.js +117 -0
  356. package/dist/lifecycle/gate-pending.js +58 -0
  357. package/dist/lifecycle/git.js +1182 -0
  358. package/dist/lifecycle/identity.js +58 -0
  359. package/dist/lifecycle/index.js +26 -0
  360. package/dist/lifecycle/lease.js +283 -0
  361. package/dist/lifecycle/ledger-port.js +1 -0
  362. package/dist/lifecycle/legacy-digest.js +91 -0
  363. package/dist/lifecycle/live-diff.js +274 -0
  364. package/dist/lifecycle/local-note.js +15 -0
  365. package/dist/lifecycle/member-ledger.js +122 -0
  366. package/dist/lifecycle/observation-baseline.js +155 -0
  367. package/dist/lifecycle/observe.js +375 -0
  368. package/dist/lifecycle/oras-referrer-lookup.js +82 -0
  369. package/dist/lifecycle/override-ledger.js +54 -0
  370. package/dist/lifecycle/plan-digest.js +110 -0
  371. package/dist/lifecycle/plan-ledger.js +129 -0
  372. package/dist/lifecycle/receipt-plan.js +192 -0
  373. package/dist/lifecycle/release-ledger.js +155 -0
  374. package/dist/lifecycle/release-read.js +64 -0
  375. package/dist/lifecycle/replay.js +193 -0
  376. package/dist/lifecycle/rollback.js +102 -0
  377. package/dist/lifecycle/run-ledger.js +183 -0
  378. package/dist/lifecycle/scenario-eval.js +204 -0
  379. package/dist/lifecycle/scenario.js +214 -0
  380. package/dist/lifecycle/snapshot.js +239 -0
  381. package/dist/lifecycle/status.js +447 -0
  382. package/dist/lifecycle/symptoms.js +117 -0
  383. package/dist/lifecycle/teardown.js +255 -0
  384. package/dist/lifecycle/types.js +1 -0
  385. package/dist/lifecycle/unobserved-gate.js +33 -0
  386. package/dist/lifecycle/wave-plans.js +68 -0
  387. package/dist/lifecycle/work-item-id.js +36 -0
  388. package/dist/lifecycle/work-lease.js +393 -0
  389. package/dist/lint/component-checks.js +87 -0
  390. package/dist/lint/config.js +483 -0
  391. package/dist/lint/declarative.js +122 -0
  392. package/dist/lint/discover.d.ts.map +1 -1
  393. package/dist/lint/discover.js +138 -0
  394. package/dist/lint/engine.js +246 -0
  395. package/dist/lint/knowledge-checks.js +64 -0
  396. package/dist/lint/named-checks.js +22 -0
  397. package/dist/lint/output-checks.js +87 -0
  398. package/dist/lint/output-docs.js +163 -0
  399. package/dist/lint/parser.js +33 -0
  400. package/dist/lint/pipeline-change-gate.js +70 -0
  401. package/dist/lint/policy-import.d.ts +1 -1
  402. package/dist/lint/policy-import.d.ts.map +1 -1
  403. package/dist/lint/policy-import.js +62 -0
  404. package/dist/lint/policy-sandbox.js +86 -0
  405. package/dist/lint/policy.js +122 -0
  406. package/dist/lint/post-synth.js +87 -0
  407. package/dist/lint/presets/relaxed.json +26 -0
  408. package/dist/lint/presets/strict.json +24 -24
  409. package/dist/lint/receipt-checks.js +83 -0
  410. package/dist/lint/rule-loader.d.ts.map +1 -1
  411. package/dist/lint/rule-loader.js +89 -0
  412. package/dist/lint/rule-registry.js +86 -0
  413. package/dist/lint/rule.js +1 -0
  414. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.js +7 -0
  415. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.js +7 -0
  416. package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.js +9 -0
  417. package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.js +11 -0
  418. package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.js +9 -0
  419. package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.js +25 -0
  420. package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.js +8 -0
  421. package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.js +21 -0
  422. package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.js +8 -0
  423. package/dist/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.js +24 -0
  424. package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.js +17 -0
  425. package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.js +8 -0
  426. package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.js +18 -0
  427. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.js +20 -0
  428. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.js +8 -0
  429. package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.js +12 -0
  430. package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.js +16 -0
  431. package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.js +8 -0
  432. package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.js +12 -0
  433. package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.js +11 -0
  434. package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.js +11 -0
  435. package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.js +10 -0
  436. package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.js +16 -0
  437. package/dist/lint/rules/comp/comp001-publishes-never-applies.js +69 -0
  438. package/dist/lint/rules/comp/comp002-dangling-wiring-ref.js +84 -0
  439. package/dist/lint/rules/comp/comp003-mutating-no-rollback.js +103 -0
  440. package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.js +70 -0
  441. package/dist/lint/rules/comp/comp005-capability-kind-is-noun.js +109 -0
  442. package/dist/lint/rules/comp/comp006-shell-needs-reason.js +49 -0
  443. package/dist/lint/rules/comp/comp007-composition-sprawl.js +64 -0
  444. package/dist/lint/rules/comp/index.js +33 -0
  445. package/dist/lint/rules/comp/support.js +129 -0
  446. package/dist/lint/rules/composite-scope.js +51 -0
  447. package/dist/lint/rules/cor017-composite-name-match.js +93 -0
  448. package/dist/lint/rules/cor018-composite-prefer-lexicon-type.js +136 -0
  449. package/dist/lint/rules/cor021-env-literal-name.js +100 -0
  450. package/dist/lint/rules/cor022-receipt-leaf.js +118 -0
  451. package/dist/lint/rules/cor024-receipt-secret-pointer.js +199 -0
  452. package/dist/lint/rules/declarable-naming-convention.js +62 -0
  453. package/dist/lint/rules/evl001-non-literal-expression.js +66 -0
  454. package/dist/lint/rules/evl002-control-flow-resource.js +69 -0
  455. package/dist/lint/rules/evl003-dynamic-property-access.js +44 -0
  456. package/dist/lint/rules/evl004-spread-non-const.js +94 -0
  457. package/dist/lint/rules/evl005-resource-block-body.js +41 -0
  458. package/dist/lint/rules/evl007-invalid-siblings.js +105 -0
  459. package/dist/lint/rules/evl009-composite-no-constant.js +158 -0
  460. package/dist/lint/rules/evl010-composite-no-transform.js +59 -0
  461. package/dist/lint/rules/evl011-symbolic-in-template.js +106 -0
  462. package/dist/lint/rules/export-required.js +115 -0
  463. package/dist/lint/rules/file-declarable-limit.js +88 -0
  464. package/dist/lint/rules/flat-declarations.js +62 -0
  465. package/dist/lint/rules/index.js +90 -0
  466. package/dist/lint/rules/no-cyclic-declarable-ref.js +138 -0
  467. package/dist/lint/rules/no-redundant-type-import.js +76 -0
  468. package/dist/lint/rules/no-redundant-value-cast.js +41 -0
  469. package/dist/lint/rules/no-string-ref.js +59 -0
  470. package/dist/lint/rules/no-unused-declarable-import.js +75 -0
  471. package/dist/lint/rules/no-unused-declarable.js +142 -0
  472. package/dist/lint/rules/op/index.js +28 -0
  473. package/dist/lint/rules/op/ops012-activity-contract.js +54 -0
  474. package/dist/lint/rules/op/ops013-step-output-ref.js +88 -0
  475. package/dist/lint/rules/op/ops014-converge-rule-refusals.js +114 -0
  476. package/dist/lint/rules/op/ops015-gate-approval.js +45 -0
  477. package/dist/lint/rules/op/support.js +11 -0
  478. package/dist/lint/rules/op/sys010-key-over-plain-http.js +100 -0
  479. package/dist/lint/rules/property-kind.js +56 -0
  480. package/dist/lint/rules/single-concern-file.js +71 -0
  481. package/dist/lint/rules/sys001-no-literal-key.js +60 -0
  482. package/dist/lint/selectors.js +168 -0
  483. package/dist/lint/suppressions.js +129 -0
  484. package/dist/lint/typescript.js +17 -0
  485. package/dist/live-endpoint.js +113 -0
  486. package/dist/live-read-session.js +76 -0
  487. package/dist/lsp/lexicon-providers.js +163 -0
  488. package/dist/lsp/types.js +5 -0
  489. package/dist/managed-fields.js +293 -0
  490. package/dist/mcp/types.js +4 -0
  491. package/dist/notify-verify.js +0 -1
  492. package/dist/notify.js +0 -1
  493. package/dist/notify.schema.json +72 -0
  494. package/dist/observation.js +266 -0
  495. package/dist/okf-read.js +134 -0
  496. package/dist/okf.js +275 -0
  497. package/dist/op/__fixtures__/decide-stub-backend.js +125 -0
  498. package/dist/op/activities/activity-contracts.js +313 -0
  499. package/dist/op/activities/apply.js +582 -0
  500. package/dist/op/activities/build.js +18 -0
  501. package/dist/op/activities/change-coverage.js +40 -0
  502. package/dist/op/activities/change-set.js +64 -0
  503. package/dist/op/activities/converge.js +492 -0
  504. package/dist/op/activities/decide.js +211 -0
  505. package/dist/op/activities/env-teardown.js +110 -0
  506. package/dist/op/activities/factory.js +591 -0
  507. package/dist/op/activities/forge-pull-request.js +82 -0
  508. package/dist/op/activities/gh-host.js +78 -0
  509. package/dist/op/activities/guard-validate.js +165 -0
  510. package/dist/op/activities/http-check.js +40 -0
  511. package/dist/op/activities/index.js +59 -0
  512. package/dist/op/activities/lexicon-upgrade.js +629 -0
  513. package/dist/op/activities/lifecycle.js +109 -0
  514. package/dist/op/activities/pipeline-audit.js +147 -0
  515. package/dist/op/activities/policy.js +26 -0
  516. package/dist/op/activities/predict-behaviour.js +341 -0
  517. package/dist/op/activities/propose-upgrade.js +165 -0
  518. package/dist/op/activities/reconcile.js +997 -0
  519. package/dist/op/activities/shell.js +118 -0
  520. package/dist/op/activities/source-release.js +97 -0
  521. package/dist/op/activities/source-rollback.js +165 -0
  522. package/dist/op/activities/teardown.js +17 -0
  523. package/dist/op/activities/util.js +6 -0
  524. package/dist/op/activities/wait.js +51 -0
  525. package/dist/op/activities/work-evidence.js +35 -0
  526. package/dist/op/activities/workflow-audit.js +133 -0
  527. package/dist/op/activity-contract-registry.js +106 -0
  528. package/dist/op/activity-contract.js +232 -0
  529. package/dist/op/activity-failure.js +31 -0
  530. package/dist/op/activity-profiles.js +129 -0
  531. package/dist/op/activity-registry.js +105 -0
  532. package/dist/op/activity-runtime.js +28 -0
  533. package/dist/op/builders.js +801 -0
  534. package/dist/op/change-signal.js +118 -0
  535. package/dist/op/composites/apply-op.js +151 -0
  536. package/dist/op/composites/behaviour-op.js +65 -0
  537. package/dist/op/composites/converge-op.js +141 -0
  538. package/dist/op/composites/index.js +19 -0
  539. package/dist/op/composites/lexicon-upgrade-op.js +107 -0
  540. package/dist/op/composites/pipeline-audit-op.js +50 -0
  541. package/dist/op/composites/reconcile-op.js +84 -0
  542. package/dist/op/composites/watch-op.js +69 -0
  543. package/dist/op/composites/workflow-audit-op.js +57 -0
  544. package/dist/op/converge-rule.js +205 -0
  545. package/dist/op/cron.js +146 -0
  546. package/dist/op/decide-backend.js +181 -0
  547. package/dist/op/decide-config.js +68 -0
  548. package/dist/op/decide-read-inputs.js +141 -0
  549. package/dist/op/discover.d.ts.map +1 -1
  550. package/dist/op/discover.js +213 -0
  551. package/dist/op/duration.js +21 -0
  552. package/dist/op/emulator-freshness.js +80 -0
  553. package/dist/op/emulator-lifecycle.js +269 -0
  554. package/dist/op/factory.js +83 -0
  555. package/dist/op/gate-approval.js +172 -0
  556. package/dist/op/gate-name.js +86 -0
  557. package/dist/op/gate-plan-context.js +167 -0
  558. package/dist/op/gate-point-run.js +67 -0
  559. package/dist/op/gate-point.js +111 -0
  560. package/dist/op/gate-resume-plan.js +155 -0
  561. package/dist/op/gate-resume.js +31 -0
  562. package/dist/op/gate-review.js +290 -0
  563. package/dist/op/gate-run-locator.js +85 -0
  564. package/dist/op/gate-summary.js +100 -0
  565. package/dist/op/gate-wait.js +56 -0
  566. package/dist/op/gate.js +449 -0
  567. package/dist/op/generate-pipeline.js +124 -0
  568. package/dist/op/index.js +51 -0
  569. package/dist/op/lifecycle-receipt-store.js +45 -0
  570. package/dist/op/local-executor.js +1164 -0
  571. package/dist/op/local-output.js +140 -0
  572. package/dist/op/op-ir.js +317 -0
  573. package/dist/op/op-verb-class.js +131 -0
  574. package/dist/op/op-waves-notify.js +136 -0
  575. package/dist/op/op-waves-run.js +1657 -0
  576. package/dist/op/op-waves.js +409 -0
  577. package/dist/op/operator.js +743 -0
  578. package/dist/op/receipt-store.js +94 -0
  579. package/dist/op/resource.js +23 -0
  580. package/dist/op/run-context.js +28 -0
  581. package/dist/op/run-live.js +256 -0
  582. package/dist/op/runtime.js +21 -0
  583. package/dist/op/runtimes/local.js +195 -0
  584. package/dist/op/source-archive.js +131 -0
  585. package/dist/op/step-output-ref.js +397 -0
  586. package/dist/op/steward-beside.js +169 -0
  587. package/dist/op/steward-points.js +138 -0
  588. package/dist/op/steward-turn.js +59 -0
  589. package/dist/op/steward.js +317 -0
  590. package/dist/op/types.js +25 -0
  591. package/dist/op/work-lease-decl.js +81 -0
  592. package/dist/op/work-lease-run.js +393 -0
  593. package/dist/override-gate.js +284 -0
  594. package/dist/owner-chain.js +74 -0
  595. package/dist/ownership.js +92 -0
  596. package/dist/params.js +61 -0
  597. package/dist/plan-summary.js +711 -0
  598. package/dist/point-decision.js +211 -0
  599. package/dist/pr-forge.js +810 -0
  600. package/dist/pr-loop.js +203 -0
  601. package/dist/project-codegen.js +191 -0
  602. package/dist/project-root.js +74 -0
  603. package/dist/project-validation.js +50 -0
  604. package/dist/provenance.js +157 -0
  605. package/dist/pseudo-parameter.js +40 -0
  606. package/dist/reconcile.js +450 -0
  607. package/dist/resource-attributes.js +33 -0
  608. package/dist/runtime-adapter.js +77 -0
  609. package/dist/runtime.js +66 -0
  610. package/dist/secret-materialization.js +153 -0
  611. package/dist/secret-provenance.js +250 -0
  612. package/dist/serializer-walker.js +112 -0
  613. package/dist/serializer.js +1 -0
  614. package/dist/sort.js +45 -0
  615. package/dist/stack-output.js +115 -0
  616. package/dist/telemetry-attribution.js +149 -0
  617. package/dist/terraform/__fixtures__/build-graph.js +63 -0
  618. package/dist/terraform/adopt-state.js +40 -0
  619. package/dist/terraform/aws-resources.js +384 -0
  620. package/dist/terraform/bridge.js +204 -0
  621. package/dist/terraform/carve-provider.js +155 -0
  622. package/dist/terraform/carve.js +138 -0
  623. package/dist/terraform/data-source-shape.js +57 -0
  624. package/dist/terraform/emit-source.js +36 -0
  625. package/dist/terraform/excise.js +123 -0
  626. package/dist/terraform/graduate.js +128 -0
  627. package/dist/terraform/graph.js +435 -0
  628. package/dist/terraform/hcl2json.js +60 -0
  629. package/dist/terraform/manifest.js +149 -0
  630. package/dist/terraform/parse.js +81 -0
  631. package/dist/terraform/providers/aws.js +146 -0
  632. package/dist/terraform/providers/gcp.js +294 -0
  633. package/dist/terraform/providers/index.js +17 -0
  634. package/dist/terraform/providers/kubernetes.js +253 -0
  635. package/dist/terraform/score.js +151 -0
  636. package/dist/terraform/state.js +67 -0
  637. package/dist/terraform/tier-map.js +74 -0
  638. package/dist/terraform/types.js +13 -0
  639. package/dist/terraform/unified-diff.js +132 -0
  640. package/dist/testing.js +295 -0
  641. package/dist/toml-emit.js +153 -0
  642. package/dist/toml-parse.js +355 -0
  643. package/dist/toml-utils.js +60 -0
  644. package/dist/toml.js +428 -0
  645. package/dist/ts-loader.d.ts +46 -0
  646. package/dist/ts-loader.d.ts.map +1 -0
  647. package/dist/ts-loader.js +103 -0
  648. package/dist/types.js +1 -0
  649. package/dist/utils.js +61 -0
  650. package/dist/validation.js +20 -0
  651. package/dist/vendor/js-yaml-load.js +1662 -0
  652. package/dist/workspace/__fixtures__/contract-repo.js +103 -0
  653. package/dist/workspace/__fixtures__/decide-workspace.js +112 -0
  654. package/dist/workspace/__fixtures__/sessions.js +91 -0
  655. package/dist/workspace/__fixtures__/two-member-workspace.js +34 -0
  656. package/dist/workspace/agent-cli.js +99 -0
  657. package/dist/workspace/agent.schema.json +390 -0
  658. package/dist/workspace/answers-ledger.js +89 -0
  659. package/dist/workspace/box-cli.js +142 -0
  660. package/dist/workspace/box-factory-write.js +196 -0
  661. package/dist/workspace/box-factory-write.schema.json +342 -0
  662. package/dist/workspace/box-factory.js +88 -0
  663. package/dist/workspace/box-intent.js +126 -0
  664. package/dist/workspace/box-isolation.js +169 -0
  665. package/dist/workspace/box-listing-write.schema.json +204 -0
  666. package/dist/workspace/box-listing.js +298 -0
  667. package/dist/workspace/box-publish.js +352 -0
  668. package/dist/workspace/box-publish.schema.json +498 -0
  669. package/dist/workspace/box-services.js +39 -0
  670. package/dist/workspace/broker-protocol.js +359 -0
  671. package/dist/workspace/broker-protocol.schema.json +228 -0
  672. package/dist/workspace/change-set.schema.json +460 -0
  673. package/dist/workspace/changes-cli.js +56 -0
  674. package/dist/workspace/changes.js +446 -0
  675. package/dist/workspace/changes.schema.json +642 -0
  676. package/dist/workspace/chant-migrations/chud-lexicon-exit-fly-site.js +198 -0
  677. package/dist/workspace/chant-migrations/chud-lexicon-exit-live-names.js +155 -0
  678. package/dist/workspace/chant-migrations/chud-lexicon-exit-rollback.js +214 -0
  679. package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.js +180 -0
  680. package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-policy.js +99 -0
  681. package/dist/workspace/chant-migrations/chud-lexicon-exit.js +847 -0
  682. package/dist/workspace/chant-migrations.js +113 -0
  683. package/dist/workspace/check.schema.json +433 -0
  684. package/dist/workspace/checks/box-isolation.js +62 -0
  685. package/dist/workspace/checks/boxes.js +491 -0
  686. package/dist/workspace/checks/diagrams.js +104 -0
  687. package/dist/workspace/checks/generated.js +419 -0
  688. package/dist/workspace/checks/ledgers.js +212 -0
  689. package/dist/workspace/checks/links.js +191 -0
  690. package/dist/workspace/checks/live.js +100 -0
  691. package/dist/workspace/checks/pipelines.js +188 -0
  692. package/dist/workspace/checks/records.js +169 -0
  693. package/dist/workspace/checks.js +426 -0
  694. package/dist/workspace/ci-green-cli.js +125 -0
  695. package/dist/workspace/ci-green-forge.js +83 -0
  696. package/dist/workspace/ci-green-workflow.js +199 -0
  697. package/dist/workspace/ci-green.js +325 -0
  698. package/dist/workspace/ci-last-green.schema.json +158 -0
  699. package/dist/workspace/compose-graph.js +235 -0
  700. package/dist/workspace/compose-reports.js +146 -0
  701. package/dist/workspace/composites.js +264 -0
  702. package/dist/workspace/composites.schema.json +617 -0
  703. package/dist/workspace/conformance/__fixture__/app/package.json +7 -0
  704. package/dist/workspace/conformance/__fixture__/app/src/server.mjs +29 -0
  705. package/dist/workspace/conformance/__fixture__/decisions/decision.kind.mjs +54 -0
  706. package/dist/workspace/conformance/__fixture__/decisions/decision.schema.json +512 -0
  707. package/dist/workspace/conformance/__fixture__/decisions/fix-001-how-the-app-is-deployed.md +40 -0
  708. package/dist/workspace/conformance/__fixture__/delivery/chant.config.ts +7 -0
  709. package/dist/workspace/conformance/__fixture__/delivery/lexicon/index.ts +26 -0
  710. package/dist/workspace/conformance/__fixture__/delivery/package.json +7 -0
  711. package/dist/workspace/conformance/__fixture__/delivery/src/app.component.ts +14 -0
  712. package/dist/workspace/conformance/__fixture__/delivery/src/app.ts +4 -0
  713. package/dist/workspace/conformance/__fixtures__/reference-broker.js +205 -0
  714. package/dist/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +32 -0
  715. package/dist/workspace/conformance/__writer_fixture__/answers/answer.schema.json +135 -0
  716. package/dist/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
  717. package/dist/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
  718. package/dist/workspace/conformance/__writer_fixture__/decisions/points.json +228 -0
  719. package/dist/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
  720. package/dist/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
  721. package/dist/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +54 -0
  722. package/dist/workspace/conformance/__writer_fixture__/sessions/session.schema.json +289 -0
  723. package/dist/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
  724. package/dist/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
  725. package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +603 -0
  726. package/dist/workspace/conformance/broker.js +736 -0
  727. package/dist/workspace/conformance/index.js +673 -0
  728. package/dist/workspace/conformance/vitest.js +108 -0
  729. package/dist/workspace/conformance/writer.js +1080 -0
  730. package/dist/workspace/decide.js +879 -0
  731. package/dist/workspace/decision-points.schema.json +135 -135
  732. package/dist/workspace/declaration-write-cli.js +74 -0
  733. package/dist/workspace/declaration-write.js +238 -0
  734. package/dist/workspace/declaration.js +938 -0
  735. package/dist/workspace/declaration.schema.json +1413 -1413
  736. package/dist/workspace/declared-kinds.js +106 -0
  737. package/dist/workspace/environments.js +164 -0
  738. package/dist/workspace/evidence.schema.json +279 -0
  739. package/dist/workspace/export-cli.js +185 -0
  740. package/dist/workspace/export.js +499 -0
  741. package/dist/workspace/factory-rules.js +175 -0
  742. package/dist/workspace/generated-files.js +92 -0
  743. package/dist/workspace/glob.js +45 -0
  744. package/dist/workspace/graph-cache.js +352 -0
  745. package/dist/workspace/graph-cli.js +348 -0
  746. package/dist/workspace/graph.schema.json +1338 -0
  747. package/dist/workspace/identity-gate-rule.js +75 -0
  748. package/dist/workspace/identity.js +126 -0
  749. package/dist/workspace/import.js +283 -0
  750. package/dist/workspace/init.js +620 -0
  751. package/dist/workspace/intent-cli.js +263 -0
  752. package/dist/workspace/intent-joins.js +201 -0
  753. package/dist/workspace/intent-record.js +352 -0
  754. package/dist/workspace/intent-record.schema.json +864 -0
  755. package/dist/workspace/intent.js +1582 -0
  756. package/dist/workspace/intent.schema.json +2420 -0
  757. package/dist/workspace/json-edit.js +221 -0
  758. package/dist/workspace/jsonc.js +235 -0
  759. package/dist/workspace/kind-readers.js +103 -0
  760. package/dist/workspace/kinds.js +587 -0
  761. package/dist/workspace/lexicon-symbols.js +112 -0
  762. package/dist/workspace/lineage-adopt-cli.js +102 -0
  763. package/dist/workspace/lineage-adopt.js +360 -0
  764. package/dist/workspace/lineage-check.js +282 -0
  765. package/dist/workspace/lineage-cli.js +121 -0
  766. package/dist/workspace/lineage-hash-index.js +284 -0
  767. package/dist/workspace/lineage-init.js +507 -0
  768. package/dist/workspace/lineage-lock.js +387 -0
  769. package/dist/workspace/lineage-merge.js +45 -0
  770. package/dist/workspace/lineage-migrations.d.ts.map +1 -1
  771. package/dist/workspace/lineage-migrations.js +329 -0
  772. package/dist/workspace/lineage-provenance.js +36 -0
  773. package/dist/workspace/lineage-update.js +138 -0
  774. package/dist/workspace/lineage-upgrade-cli.js +131 -0
  775. package/dist/workspace/lineage-upgrade.js +889 -0
  776. package/dist/workspace/lineage-vendor.js +171 -0
  777. package/dist/workspace/lineage-version.js +128 -0
  778. package/dist/workspace/lineage-versions.js +275 -0
  779. package/dist/workspace/links.js +330 -0
  780. package/dist/workspace/ls-generated.js +95 -0
  781. package/dist/workspace/ls.js +277 -0
  782. package/dist/workspace/ls.schema.json +333 -0
  783. package/dist/workspace/member-commands.js +508 -0
  784. package/dist/workspace/member-handles.js +216 -0
  785. package/dist/workspace/member-pipeline.js +258 -0
  786. package/dist/workspace/member-run.js +117 -0
  787. package/dist/workspace/member-write.schema.json +193 -0
  788. package/dist/workspace/nested-graph.js +156 -0
  789. package/dist/workspace/nesting.js +38 -0
  790. package/dist/workspace/patch.js +301 -0
  791. package/dist/workspace/patch.schema.json +321 -0
  792. package/dist/workspace/pin-cli.js +55 -0
  793. package/dist/workspace/pin-integrity.js +100 -0
  794. package/dist/workspace/plan-summary.schema.json +155 -0
  795. package/dist/workspace/point-answer.schema.json +129 -129
  796. package/dist/workspace/points-cli.js +291 -0
  797. package/dist/workspace/points-write.schema.json +660 -0
  798. package/dist/workspace/points.js +521 -0
  799. package/dist/workspace/points.schema.json +916 -0
  800. package/dist/workspace/pr-report.schema.json +108 -0
  801. package/dist/workspace/principal-classes.js +245 -0
  802. package/dist/workspace/reason-codes.js +326 -0
  803. package/dist/workspace/record-assets.js +151 -0
  804. package/dist/workspace/record-decided.js +105 -0
  805. package/dist/workspace/record-sessions.js +96 -0
  806. package/dist/workspace/record-source.js +114 -0
  807. package/dist/workspace/records-amend.schema.json +284 -0
  808. package/dist/workspace/records-checkout.js +76 -0
  809. package/dist/workspace/records-cli.js +707 -0
  810. package/dist/workspace/records-close.js +116 -0
  811. package/dist/workspace/records-close.schema.json +278 -0
  812. package/dist/workspace/records-new.schema.json +202 -0
  813. package/dist/workspace/records-review.schema.json +367 -0
  814. package/dist/workspace/records-since.js +317 -0
  815. package/dist/workspace/records-since.schema.json +218 -0
  816. package/dist/workspace/records-write.js +1229 -0
  817. package/dist/workspace/records.js +1345 -0
  818. package/dist/workspace/records.schema.json +604 -0
  819. package/dist/workspace/reference-kinds/app/package.json +10 -0
  820. package/dist/workspace/reference-kinds/app/workspace-kinds.json +45 -0
  821. package/dist/workspace/returns.js +303 -0
  822. package/dist/workspace/root-refusal.js +75 -0
  823. package/dist/workspace/run-statement.schema.json +622 -0
  824. package/dist/workspace/runs-cli.js +584 -0
  825. package/dist/workspace/runs-write.schema.json +994 -0
  826. package/dist/workspace/runs.js +708 -0
  827. package/dist/workspace/runs.schema.json +1257 -0
  828. package/dist/workspace/runtimes.js +76 -0
  829. package/dist/workspace/session-kinds.js +83 -0
  830. package/dist/workspace/signers.schema.json +206 -0
  831. package/dist/workspace/source-block.js +125 -0
  832. package/dist/workspace/squash.js +177 -0
  833. package/dist/workspace/status-gates.js +162 -0
  834. package/dist/workspace/status-stewards.js +330 -0
  835. package/dist/workspace/status.js +514 -0
  836. package/dist/workspace/status.schema.json +998 -0
  837. package/dist/workspace/steward-index.js +191 -0
  838. package/dist/workspace/symbols.js +188 -0
  839. package/dist/workspace/template-manifest.js +227 -0
  840. package/dist/workspace/template-pins.js +115 -0
  841. package/dist/workspace/trailer-joins.js +65 -0
  842. package/dist/workspace/trailers.js +111 -0
  843. package/dist/workspace/tree.js +136 -0
  844. package/dist/workspace/trust/attestor.js +63 -0
  845. package/dist/workspace/trust/dsse.js +108 -0
  846. package/dist/workspace/trust/evidence-cli.js +175 -0
  847. package/dist/workspace/trust/evidence.js +161 -0
  848. package/dist/workspace/trust/gate-seal.js +226 -0
  849. package/dist/workspace/trust/policy.js +190 -0
  850. package/dist/workspace/trust/provenance.js +180 -0
  851. package/dist/workspace/trust/rotation.js +298 -0
  852. package/dist/workspace/trust/run-commits.js +101 -0
  853. package/dist/workspace/trust/run-statement.js +182 -0
  854. package/dist/workspace/trust/seal.js +272 -0
  855. package/dist/workspace/trust/signers-cli.js +152 -0
  856. package/dist/workspace/trust/ssh-commit.js +178 -0
  857. package/dist/workspace/trust/test-repo.js +118 -0
  858. package/dist/workspace/trust/trust-files.js +193 -0
  859. package/dist/workspace/trust/verify-cli.js +63 -0
  860. package/dist/workspace/trust/verify.js +192 -0
  861. package/dist/workspace/which-chant.js +141 -0
  862. package/dist/workspace/wip-cli.js +95 -0
  863. package/dist/workspace/wip-write.schema.json +504 -0
  864. package/dist/workspace/wip.js +631 -0
  865. package/dist/workspace/wip.schema.json +334 -0
  866. package/dist/workspace/work-cli.js +448 -0
  867. package/dist/workspace/work-evidence.js +122 -0
  868. package/dist/workspace/work-evidence.schema.json +222 -0
  869. package/dist/workspace/work-history.schema.json +421 -0
  870. package/dist/workspace/work-lease.schema.json +246 -0
  871. package/dist/workspace/work-size.js +77 -0
  872. package/dist/workspace/work.js +283 -0
  873. package/dist/workspace/workspace-kinds.schema.json +259 -259
  874. package/dist/workspace/workspace-principals.schema.json +53 -53
  875. package/dist/workspace/write-lock-cli.js +105 -0
  876. package/dist/workspace/write-lock.js +424 -0
  877. package/dist/workspace/write-lock.schema.json +172 -0
  878. package/dist/workspace/write-scope.js +484 -0
  879. package/dist/yaml.js +459 -0
  880. package/package.json +2 -2
  881. package/src/cli/commands/check-lexicon-plugin.ts +2 -0
  882. package/src/cli/commands/lint.ts +3 -0
  883. package/src/cli/commands/migrate.ts +2 -0
  884. package/src/cli/compiled-cli.e2e.test.ts +165 -0
  885. package/src/cli/main.ts +121 -27
  886. package/src/cli/mcp/workspace-tools.ts +1 -1
  887. package/src/codegen/pinned-upgrade.ts +2 -0
  888. package/src/components/discover.ts +2 -0
  889. package/src/components/sandbox/driver.ts +3 -1
  890. package/src/config-import.ts +3 -0
  891. package/src/discovery/fold-import.ts +23 -14
  892. package/src/discovery/import.ts +2 -0
  893. package/src/discovery/sandbox/driver.ts +3 -1
  894. package/src/lexicon-module.ts +3 -0
  895. package/src/lint/config.ts +1 -1
  896. package/src/lint/discover.ts +28 -8
  897. package/src/lint/policy-import.ts +4 -1
  898. package/src/lint/rule-loader.ts +2 -0
  899. package/src/op/discover.ts +3 -0
  900. package/src/ts-loader.test.ts +23 -0
  901. package/src/ts-loader.ts +122 -0
  902. package/src/workspace/chant-migrations/chud-lexicon-exit.ts +1 -1
  903. package/src/workspace/declaration.ts +1 -1
  904. package/src/workspace/kinds.ts +1 -1
  905. package/src/workspace/lineage-migrations.ts +2 -0
  906. package/src/workspace/points.ts +1 -1
  907. package/src/workspace/principal-classes.ts +1 -1
@@ -0,0 +1,1191 @@
1
+ import { lexiconNames } from "../../lexicon-module.js";
2
+ import { resolve, dirname, basename } from "node:path";
3
+ import { writeFileSync, mkdirSync, readFileSync } from "node:fs";
4
+ import { loadChantConfig, resolveAutoReleaseDisabled, InvalidChantConfigError } from "../../config.js";
5
+ import { discoverOps, discoverStewards } from "../../op/discover.js";
6
+ import { stewardWorkHolder } from "../../op/work-lease-run.js";
7
+ import { DRIFT_EXIT_CODE } from "../../op/types.js";
8
+ import { findPolicyGateStep, OpRunFailure } from "../../op/local-executor.js";
9
+ import { approveCommand, describeGateMismatch, gateIsSealed } from "../../op/gate.js";
10
+ import { summaryLedgerPrefix, writeGatedRunSummary } from "../../op/gate-summary.js";
11
+ import { createLocalOpRuntime } from "../../op/runtimes/local.js";
12
+ import { pointAnswerCommand, renderHuman, renderJson } from "../../op/local-output.js";
13
+ import { loadPlugins } from "../plugins.js";
14
+ import { recordGateApproval } from "./operator.js";
15
+ import { formatError, formatWarning, formatSuccess, formatBold, formatInfo } from "../format.js";
16
+ import { resolveCliBuildParams, parseParamFlags } from "../build-params-cli.js";
17
+ import { stewardBesideFor, stewardFormFor, stewardTurnLeaseName, DEFAULT_STEWARD_ENV } from "../../op/steward.js";
18
+ import { holdBesideLease } from "../../op/steward-beside.js";
19
+ import { acquireStewardTurn, STEWARD_TURN_WAIT_MS } from "../../op/operator.js";
20
+ import { releaseLease, currentHolderId } from "../../lifecycle/lease.js";
21
+ import { StaleLockError } from "../../lifecycle/git.js";
22
+ import { LIFECYCLE_LOCAL_NOTE, isLifecycleLocalNote } from "../../lifecycle/local-note.js";
23
+ import { renderDriverHuman, renderDriverJson } from "../../components/driver-output.js";
24
+ import { ndjsonProgressSink } from "../../components/run-progress.js";
25
+ import { maybeRecordAutoRelease } from "../../components/auto-release.js";
26
+ import { maybePersistBuildManifest } from "../../components/manifest-persistence.js";
27
+ import { runOpGenerate } from "./run-generate.js";
28
+ /**
29
+ * The exit code a run that stopped at an unapproved gate uses (#2119).
30
+ * Deliberately not 1: a gate is a standing fact waiting on a human, and a CI
31
+ * job that treats it as a failure would page someone for a decision nobody has
32
+ * made yet.
33
+ */
34
+ export const GATED_EXIT_CODE = 3;
35
+ /**
36
+ * The exit code this invocation gives a gated run — {@link GATED_EXIT_CODE}
37
+ * unless `--gated-exit <code>` asked for another one (#2243).
38
+ *
39
+ * The mapping lives here rather than in a shell wrapper in every generated
40
+ * pipeline, so one rule covers every forge: GitHub Actions has no neutral
41
+ * conclusion for a `run:` step, so a push-to-main apply that stops at its gate
42
+ * paints the branch red on every merge until someone approves. `--gated-exit
43
+ * 0` is how the job that knows a pending approval is not a failure says so.
44
+ *
45
+ * Only the gated outcome is remapped. A failed run still returns 1, so the
46
+ * flag can never hide a broken apply. Returns `undefined` after printing the
47
+ * refusal when the value is not a process exit status.
48
+ */
49
+ function resolveGatedExitCode(ctx) {
50
+ const raw = ctx.args.gatedExit;
51
+ if (raw === undefined)
52
+ return GATED_EXIT_CODE;
53
+ if (!Number.isInteger(raw) || raw < 0 || raw > 255) {
54
+ console.error(formatError({
55
+ message: "--gated-exit expects a whole number from 0 to 255",
56
+ hint: `Got ${Number.isNaN(raw) ? "a non-numeric value" : String(raw)}. ` +
57
+ `Pass --gated-exit 0 to make a run that stopped at a gate a success for CI; ` +
58
+ `omit the flag for the default ${GATED_EXIT_CODE}.`,
59
+ }));
60
+ return undefined;
61
+ }
62
+ return raw;
63
+ }
64
+ /**
65
+ * Whether a settled run's records carry a true `Drift` outcome (#3675) — the
66
+ * one `lifecycleDiff` surfaces through `outcomeAttribute` on a WatchOp,
67
+ * ApplyOp, ReconcileOp or ConvergeOp step.
68
+ */
69
+ export function runFoundDrift(records) {
70
+ for (const record of records ?? []) {
71
+ const outcomes = record.outcomes ?? (record.outcome ? [record.outcome] : []);
72
+ if (outcomes.some((o) => o.name === "Drift" && o.value === true))
73
+ return true;
74
+ }
75
+ return false;
76
+ }
77
+ /**
78
+ * The exit code for a completed run (#3675): 0, or {@link DRIFT_EXIT_CODE}
79
+ * when the run found drift and either `--fail-on-drift` or the Op's own
80
+ * `failOn: "drift"` asked for drift to fail the job. Says why on stderr when
81
+ * it remaps, since every step in the run succeeded.
82
+ */
83
+ export function completedRunExitCode(opName, config, failOnDriftFlag, records) {
84
+ if (!(failOnDriftFlag || config.failOn === "drift"))
85
+ return 0;
86
+ if (!runFoundDrift(records))
87
+ return 0;
88
+ const why = failOnDriftFlag ? "--fail-on-drift" : `the Op declares failOn: "drift"`;
89
+ console.error(formatWarning({
90
+ message: `Op "${opName}" found drift; exiting ${DRIFT_EXIT_CODE} because ${why}`,
91
+ }));
92
+ return DRIFT_EXIT_CODE;
93
+ }
94
+ /**
95
+ * What a gated run leaves behind for CI, beyond the stderr block the renderers
96
+ * already print (#2243): the same gate, approve command and ledger path
97
+ * appended to whatever file `GITHUB_STEP_SUMMARY` names, so the run page says
98
+ * what is pending without anyone opening the log.
99
+ *
100
+ * Also says on stderr that the exit code was remapped, when it was. A job that
101
+ * passes `--gated-exit 0` reports success, and the one line that explains why
102
+ * a zero-exit run applied nothing belongs next to the gate itself.
103
+ */
104
+ async function reportGatedRun(summary, exitCode) {
105
+ writeGatedRunSummary({ ...summary, sealed: await gateIsSealed(summary.gate) });
106
+ if (exitCode !== GATED_EXIT_CODE) {
107
+ console.error(formatInfo(`gated: exiting ${exitCode} because --gated-exit asked for it. Nothing after the gate ran.`));
108
+ }
109
+ }
110
+ /**
111
+ * `run list/status/log/cancel --components` reported a component's *durable*
112
+ * run state — a run that outlives the CLI process and can be queried, signalled
113
+ * or cancelled afterwards (#589). #2116 removed the runtime that provided it.
114
+ * The local driver runs a component to completion inside this process, so there
115
+ * is no separate run left to ask about once the command returns.
116
+ *
117
+ * Returns 1; the caller returns it straight back.
118
+ */
119
+ function refuseDurableComponentSubcommand(what, hint) {
120
+ console.error(formatError({
121
+ message: `\`${what}\` read a component's durable run state, which #2116 removed`,
122
+ hint,
123
+ }));
124
+ return 1;
125
+ }
126
+ // ── The runtime seam (#2121) ────────────────────────────────────────────────
127
+ /**
128
+ * Resolve the one runtime this invocation talks to.
129
+ *
130
+ * `--on <name>` picks the named lexicon's `opRuntime` (`../../lexicon.ts`).
131
+ * Without it, `run.on` in `chant.config.ts` does (#2523), and without either,
132
+ * core's built-in `local` provider runs the Op in this process. `local`, from
133
+ * either place, names the built-in provider. Every `chant run` subcommand goes
134
+ * through whichever comes back, so there is one dispatch path rather than a
135
+ * branch per runtime.
136
+ *
137
+ * A lexicon already loaded into the command context wins the lookup — that is
138
+ * how a test hands in a stub, and how a command that loaded plugins for its
139
+ * own reasons avoids loading them twice. Otherwise the project's configured
140
+ * lexicons are loaded on demand: `chant run` is not a `requiresPlugins`
141
+ * command, and a plain local run must not start paying for plugin resolution.
142
+ *
143
+ * Returns `undefined` after printing an actionable error — an unconfigured
144
+ * name is answered with the configured list, a configured lexicon that hosts
145
+ * nothing is named outright. A `run.on` default gets the same messages as
146
+ * `--on`, labelled `run.on` and the config file instead of `--on`.
147
+ */
148
+ async function resolveOpRuntime(ctx) {
149
+ const choice = await chooseOpRuntime(ctx);
150
+ if (!choice)
151
+ return undefined;
152
+ const { on, source, configured } = choice;
153
+ if (!on || on === "local")
154
+ return createLocalOpRuntime({ projectPath: resolve(".") });
155
+ // How the error names the choice, and how to get the built-in runtime back.
156
+ const label = source === "flag" ? `--on ${on}` : `run.on "${on}" in ${choice.configFile}`;
157
+ const fallback = source === "flag"
158
+ ? "Omit --on to run on the built-in local runtime."
159
+ : `Fix \`run.on\` in ${choice.configFile}, or pass --on local to run on the built-in local runtime.`;
160
+ let plugin = ctx.plugins.find((p) => p.name === on);
161
+ if (!plugin && configured.includes(on)) {
162
+ plugin = (await loadPlugins([on]).catch(() => []))[0];
163
+ }
164
+ if (!plugin) {
165
+ const known = [...new Set([...ctx.plugins.map((p) => p.name), ...configured])];
166
+ console.error(formatError({
167
+ message: `${label}: "${on}" is not a configured lexicon`,
168
+ hint: known.length > 0
169
+ ? `Configured lexicons: ${known.join(", ")}. ${fallback}`
170
+ : `chant.config.ts configures no lexicons. ${fallback}`,
171
+ }));
172
+ return undefined;
173
+ }
174
+ if (!plugin.opRuntime) {
175
+ console.error(formatError({
176
+ message: `${label}: lexicon "${on}" does not host Op runs`,
177
+ hint: `It declares no opRuntime. ${fallback}`,
178
+ }));
179
+ return undefined;
180
+ }
181
+ return plugin.opRuntime;
182
+ }
183
+ /**
184
+ * The runtime name `--on`, then `run.on` in `chant.config.ts` (#2523), then
185
+ * the built-in default pick, without loading any lexicon.
186
+ *
187
+ * Reads the configured list straight from `chant.config.ts` rather than
188
+ * through `resolveProjectLexicons`: `--on` names a *configured* lexicon, and
189
+ * that helper's fallback is a source scan of the whole project, which is a
190
+ * long wait to be told a name is wrong.
191
+ *
192
+ * A config that fails to load leaves the flag's choice alone, as before. With
193
+ * no flag, a config whose `run` block is invalid is refused (printed, then
194
+ * `undefined`): running the Op locally would hide that the project asked for
195
+ * another runtime. Any other load failure falls back to the built-in runtime,
196
+ * which is what a project with no `run.on` got before. `quiet` skips printing
197
+ * that refusal, for a caller that only peeks at the choice and leaves the
198
+ * reporting to {@link resolveOpRuntime}.
199
+ */
200
+ async function chooseOpRuntime(ctx, quiet = false) {
201
+ const flag = ctx.args.on;
202
+ if (flag === "local")
203
+ return { on: "local", source: "flag", configured: [], configFile: "chant.config.ts" };
204
+ let configured = [];
205
+ let configuredOn;
206
+ let configFile = "chant.config.ts";
207
+ try {
208
+ const { config, configPath } = await loadChantConfig(resolve("."));
209
+ configured = lexiconNames(config.lexicons ?? []);
210
+ configuredOn = config.run?.on;
211
+ if (configPath)
212
+ configFile = basename(configPath);
213
+ }
214
+ catch (err) {
215
+ if (!flag && err instanceof InvalidChantConfigError && err.key === "run") {
216
+ if (quiet)
217
+ return undefined;
218
+ console.error(formatError({
219
+ message: err.message,
220
+ hint: "`run.on` names the runtime that hosts this project's Op runs: a configured lexicon with an opRuntime, or \"local\". Fix it, or pass --on to pick the runtime for this run.",
221
+ }));
222
+ return undefined;
223
+ }
224
+ // No/unreadable chant.config.ts: an `--on` error says so by listing nothing.
225
+ }
226
+ if (flag)
227
+ return { on: flag, source: "flag", configured, configFile };
228
+ if (configuredOn)
229
+ return { on: configuredOn, source: "config", configured, configFile };
230
+ return { on: undefined, source: "default", configured, configFile };
231
+ }
232
+ /** An ISO-8601 instant trimmed to what a table cell has room for. */
233
+ function shortInstant(iso) {
234
+ return iso ? iso.slice(0, 19).replace("T", " ") : "—";
235
+ }
236
+ /** Print what a runtime reports for a settled or in-flight run. */
237
+ function renderRuntimeStatus(label, name, runtime, status) {
238
+ console.log(formatBold(`${label}: ${name}`));
239
+ console.log(` Runtime : ${runtime}`);
240
+ console.log(` Run ID : ${status.runId}`);
241
+ console.log(` State : ${status.state}`);
242
+ console.log(` Started : ${shortInstant(status.startedAt)}`);
243
+ if (status.endedAt)
244
+ console.log(` Ended : ${shortInstant(status.endedAt)}`);
245
+ if (status.records) {
246
+ const settled = status.records.filter((r) => r.status !== "skipped").length;
247
+ console.log(` Steps : ${settled}/${status.records.length} settled`);
248
+ }
249
+ if (status.gate) {
250
+ console.log(` Gate : ${status.gate.name} (pending since ${status.gate.since})`);
251
+ }
252
+ if (status.error)
253
+ console.log(` Error : ${status.error}`);
254
+ }
255
+ // ── chant run list ──────────────────────────────────���─────────────────────────
256
+ export async function runOpList(ctx) {
257
+ if (ctx.args.components)
258
+ return runComponentsList();
259
+ return runOpListOnRuntime(ctx);
260
+ }
261
+ /**
262
+ * `chant run list` on the resolved runtime (#2121) — discover every Op, ask
263
+ * the runtime what it knows about each, print one row per Op. The runtime
264
+ * answers for all of them in one call (`list`), so a hosted runtime can do it
265
+ * in one round trip instead of N.
266
+ *
267
+ * An Op the runtime has no run for prints with no state annotation.
268
+ */
269
+ async function runOpListOnRuntime(ctx) {
270
+ const runtime = await resolveOpRuntime(ctx);
271
+ if (!runtime)
272
+ return 1;
273
+ const { ops, errors } = await discoverOps();
274
+ for (const err of errors)
275
+ console.error(formatError({ message: err }));
276
+ if (ops.size === 0) {
277
+ console.error(formatWarning({ message: "No Op definitions found (*.op.ts)" }));
278
+ return 0;
279
+ }
280
+ let states;
281
+ try {
282
+ states = await runtime.list([...ops.values()].map((d) => d.config));
283
+ }
284
+ catch (err) {
285
+ console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
286
+ return 1;
287
+ }
288
+ console.log("NAME".padEnd(26) +
289
+ "PHASES".padEnd(8) +
290
+ "DEPENDS".padEnd(20) +
291
+ "OVERVIEW");
292
+ for (const [name, { config }] of ops) {
293
+ const phases = String(config.phases.length);
294
+ const deps = config.depends?.join(",") ?? "—";
295
+ const overview = config.overview.length > 36
296
+ ? config.overview.slice(0, 33) + "..."
297
+ : config.overview;
298
+ const state = states.get(name)?.state;
299
+ console.log((name + (state ? ` [${state}]` : "")).padEnd(26) +
300
+ phases.padEnd(8) +
301
+ deps.padEnd(20) +
302
+ overview);
303
+ }
304
+ return 0;
305
+ }
306
+ /**
307
+ * `chant run list --components` (#599) listed discovered components annotated
308
+ * with each one's durable run status. Discovery alone is what `chant list
309
+ * --components` already prints, so with the status column gone (#2116) this
310
+ * subcommand has nothing of its own left to say.
311
+ */
312
+ function runComponentsList() {
313
+ return Promise.resolve(refuseDurableComponentSubcommand("chant run list --components", "Run `chant list --components` to see discovered components."));
314
+ }
315
+ // ── chant run status <name> ───────────────────────────────────────────────────
316
+ export async function runOpStatus(ctx) {
317
+ const name = ctx.args.extraPositional;
318
+ if (!name) {
319
+ const label = ctx.args.components ? "Component" : "Op";
320
+ console.error(formatError({ message: `${label} name is required: chant run status <name>` }));
321
+ return 1;
322
+ }
323
+ if (ctx.args.components) {
324
+ return refuseDurableComponentSubcommand("chant run status --components", "Run `chant components status` for a component's release and build state.");
325
+ }
326
+ return runOpStatusOnRuntime(ctx, name);
327
+ }
328
+ /**
329
+ * `chant run status <name>` on the resolved runtime (#2121). A runtime with
330
+ * no record of the Op is not an error: it prints one line saying so and exits
331
+ * 0, because "this runtime has never run it" is a true answer to the question.
332
+ */
333
+ async function runOpStatusOnRuntime(ctx, name) {
334
+ const runtime = await resolveOpRuntime(ctx);
335
+ if (!runtime)
336
+ return 1;
337
+ let status;
338
+ try {
339
+ status = await runtime.status(name);
340
+ }
341
+ catch (err) {
342
+ console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
343
+ return 1;
344
+ }
345
+ if (!status) {
346
+ console.error(formatInfo(`No run of Op "${name}" is recorded on the "${runtime.name}" runtime.`));
347
+ return 0;
348
+ }
349
+ renderRuntimeStatus("Op", name, runtime.name, status);
350
+ return 0;
351
+ }
352
+ // ── chant run log <name> ──────────────────────────────────────────────────────
353
+ export async function runOpLog(ctx) {
354
+ const name = ctx.args.extraPositional;
355
+ if (!name) {
356
+ const label = ctx.args.components ? "Component" : "Op";
357
+ console.error(formatError({ message: `${label} name is required: chant run log <name>` }));
358
+ return 1;
359
+ }
360
+ if (ctx.args.components) {
361
+ return refuseDurableComponentSubcommand("chant run log --components", "Run `chant components status` for a component's recorded releases.");
362
+ }
363
+ return runOpLogOnRuntime(ctx, name);
364
+ }
365
+ /**
366
+ * `chant run log <name>` on the resolved runtime (#2121) — the runtime's own
367
+ * run history, newest first, `--limit <n>` rows at most.
368
+ */
369
+ async function runOpLogOnRuntime(ctx, name) {
370
+ const runtime = await resolveOpRuntime(ctx);
371
+ if (!runtime)
372
+ return 1;
373
+ let records;
374
+ try {
375
+ records = await runtime.log(name, ctx.args.limit === undefined ? undefined : { limit: ctx.args.limit });
376
+ }
377
+ catch (err) {
378
+ console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
379
+ return 1;
380
+ }
381
+ if (records.length === 0) {
382
+ console.error(formatInfo(`No run of Op "${name}" is recorded on the "${runtime.name}" runtime.`));
383
+ return 0;
384
+ }
385
+ console.log("RUN-ID".padEnd(38) +
386
+ "STATUS".padEnd(10) +
387
+ "STARTED".padEnd(26) +
388
+ "ENDED");
389
+ for (const record of records) {
390
+ console.log(record.id.padEnd(38) +
391
+ record.status.padEnd(10) +
392
+ shortInstant(record.started).padEnd(26) +
393
+ shortInstant(record.ended));
394
+ }
395
+ return 0;
396
+ }
397
+ // ── chant run approve <op> <gate> ────────────────────────────────────────────
398
+ /**
399
+ * `chant run approve <op> <gate> [--approver] [--url] [--note]` (#2121) — the
400
+ * rename of `chant run signal`, and a different act.
401
+ *
402
+ * A gate resolution is a fact, not a message: the ledger write is the whole
403
+ * of it, and it is the same write `chant approve` performs
404
+ * (`recordGateApproval`, ./operator.ts), so a resolution recorded here reads
405
+ * back identically. The runtime is told afterwards, through its optional
406
+ * `resolveGate`, purely so a runtime that parks a run mid-flight can wake it
407
+ * now rather than on its next tick. A runtime without that method is not a
408
+ * failure — the fact is recorded either way, and the next run re-reads it.
409
+ */
410
+ export async function runOpApprove(ctx) {
411
+ const opName = ctx.args.extraPositional;
412
+ const gate = ctx.args.extraPositional2;
413
+ if (!opName || !gate) {
414
+ console.error(formatError({ message: "Usage: chant run approve <op> <gate>" }));
415
+ return 1;
416
+ }
417
+ const runtime = await resolveOpRuntime(ctx);
418
+ if (!runtime)
419
+ return 1;
420
+ const outcome = await recordGateApproval(opName, gate, {
421
+ actor: ctx.args.approver ?? ctx.args.actor,
422
+ note: ctx.args.note,
423
+ url: ctx.args.url,
424
+ plan: ctx.args.plan,
425
+ ...(ctx.args.sign !== undefined ? { sign: ctx.args.sign } : {}),
426
+ ...(ctx.args.relayedBy !== undefined ? { relayedBy: ctx.args.relayedBy } : {}),
427
+ });
428
+ if (!outcome.ok)
429
+ return 1;
430
+ if (!runtime.resolveGate) {
431
+ console.error(formatInfo(`The "${runtime.name}" runtime reads the resolution when the op next runs — re-run \`chant run ${opName}\`.`));
432
+ return 0;
433
+ }
434
+ try {
435
+ // `--env` on the approve line names the environment the woken run runs
436
+ // in (#3539); without it the runtime keeps the gated run's.
437
+ if (ctx.args.env !== undefined)
438
+ await runtime.resolveGate(opName, gate, outcome.record, { env: ctx.args.env });
439
+ else
440
+ await runtime.resolveGate(opName, gate, outcome.record);
441
+ }
442
+ catch (err) {
443
+ console.error(formatWarning({
444
+ message: `The resolution is recorded, but the "${runtime.name}" runtime could not be woken: ` +
445
+ (err instanceof Error ? err.message : String(err)),
446
+ hint: `Re-run \`chant run ${opName} --on ${runtime.name}\` once the runtime is reachable.`,
447
+ }));
448
+ return 1;
449
+ }
450
+ console.error(formatSuccess(`Runtime "${runtime.name}" was notified of the resolution.`));
451
+ return 0;
452
+ }
453
+ /**
454
+ * `chant run signal` was renamed `chant run approve` (#2121). Registered so
455
+ * the old spelling says where the verb went instead of being read as an Op
456
+ * named "signal".
457
+ */
458
+ export function runOpSignalRenamed(ctx) {
459
+ const opName = ctx.args.extraPositional ?? "<op>";
460
+ const gate = ctx.args.extraPositional2 ?? "<gate>";
461
+ console.error(formatError({
462
+ message: "`chant run signal` is now `chant run approve`",
463
+ hint: `A gate is resolved by recording the fact, not by sending a message: chant run approve ${opName} ${gate}`,
464
+ }));
465
+ return Promise.resolve(1);
466
+ }
467
+ // ── chant run cancel <name> ───────────────────────────────────────────────────
468
+ /** `chant run cancel <name>` — asks the resolved runtime (#2121) to stop the Op's active run. */
469
+ export async function runOpCancel(ctx) {
470
+ const name = ctx.args.extraPositional;
471
+ if (!name) {
472
+ console.error(formatError({ message: "Op name is required: chant run cancel <name>" }));
473
+ return 1;
474
+ }
475
+ if (!ctx.args.force) {
476
+ console.error(formatWarning({
477
+ message: `Cancelling "${name}" will stop the active run`,
478
+ hint: "Use --force to confirm cancellation",
479
+ }));
480
+ return 1;
481
+ }
482
+ if (ctx.args.components) {
483
+ return refuseDurableComponentSubcommand("chant run cancel --components", "A component run lives and dies with the `chant run --components` process — interrupt that instead.");
484
+ }
485
+ return runOpCancelOnRuntime(ctx, name);
486
+ }
487
+ /**
488
+ * `chant run cancel <name>` on the resolved runtime (#2121). `--force` is
489
+ * already checked by the caller, so a runtime only ever sees a confirmed
490
+ * request; a runtime with nothing to cancel says so in its own words and the
491
+ * command exits non-zero.
492
+ */
493
+ async function runOpCancelOnRuntime(ctx, name) {
494
+ const runtime = await resolveOpRuntime(ctx);
495
+ if (!runtime)
496
+ return 1;
497
+ try {
498
+ await runtime.cancel(name, { force: true });
499
+ }
500
+ catch (err) {
501
+ console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
502
+ return 1;
503
+ }
504
+ console.error(formatSuccess(`Cancellation requested for Op "${name}" on the "${runtime.name}" runtime`));
505
+ return 0;
506
+ }
507
+ // ── chant run <name> — main command ───────────────────────────────────────────
508
+ /**
509
+ * `chant run <name>` dispatcher.
510
+ *
511
+ * Every run goes through the runtime resolved by `--on` (#2121); without it,
512
+ * core's built-in local provider runs the Op in this process, where a `gate`
513
+ * is decided against the gate ledger and ends the run pending approval
514
+ * (#2119), exit code 3.
515
+ *
516
+ * `chant run --components <name|all>` (#585) is a separate target: discovered
517
+ * `Component` declarations dispatched through the interpret driver
518
+ * (`../../components/driver.ts`) rather than a `*.op.ts` Op. Checked first,
519
+ * mirroring `runGraph`'s `if (ctx.args.components) return
520
+ * runComponentGraph(ctx)` branch (../handlers/graph.ts).
521
+ *
522
+ * chant #1116 — `--report` with `--components` is checked and hard-errored
523
+ * before that dispatch, and #2116 retired `--report` on the Op path too: it
524
+ * rendered a past durable run's workflow history, which no runtime keeps any
525
+ * more. Both refuse rather than falling through to a real dispatch — the
526
+ * component case was observed live reaching an actual cloud shell-out.
527
+ */
528
+ /**
529
+ * Pre-flight for `chant run <op> --sandbox` on an Op containing a `policyGate`
530
+ * step (chant #2003). `--sandbox` is a global flag, and `../main.ts` arms the
531
+ * process-wide policy latch off it for every command — so the gate's
532
+ * `loadPolicyChecks` refuses mid-run with a message addressed to a chant
533
+ * maintainer ("This is a chant bug"), which is not an answer a user can act
534
+ * on. Refuse here instead, before anything runs, naming the combination and
535
+ * what to do about it.
536
+ *
537
+ * Keyed on the flag rather than on whether the project declares
538
+ * `lint.policies`: the flag is what arms the latch, and a gate that builds the
539
+ * project in this process is a divergence from what `--sandbox` promises
540
+ * whether or not a policy module happens to be declared. Returns true when the
541
+ * caller should stop.
542
+ */
543
+ function refusesPolicyGateUnderSandbox(ctx, config, opName) {
544
+ if (!ctx.args.sandbox)
545
+ return false;
546
+ if (!findPolicyGateStep(config))
547
+ return false;
548
+ console.error(formatError({
549
+ message: `Op "${opName}" has a policyGate step, which cannot run under --sandbox: the gate builds this project and imports its lint.policies in the chant process, which --sandbox forbids.`,
550
+ hint: "Re-run without --sandbox, or drop the policyGate step from this Op. Running the gate itself inside the sandbox boundary is tracked on chant#1157.",
551
+ }));
552
+ return true;
553
+ }
554
+ /**
555
+ * `chant run <op>` for an Op a declared steward lists is one of that
556
+ * steward's turns, not a run beside it (#2750, follow-up to #2731).
557
+ *
558
+ * On fountain, the run belongs on the steward's thread: without `--on
559
+ * fountain` this refuses outright, naming the command that posts it there
560
+ * instead (the fountain runtime's own turn already refuses a busy teammate,
561
+ * unretried — see chant-fountain-ops).
562
+ *
563
+ * In the local form, the run takes the steward's turn lease
564
+ * (`../../op/operator.ts`'s `acquireStewardTurn`) — the same lease a round's
565
+ * scheduled tick holds for the length of its own run. Held already, this
566
+ * waits up to {@link STEWARD_TURN_WAIT_MS} (long enough to ride out a race
567
+ * with a turn that's just ending) and then refuses, naming the steward and
568
+ * its holder. It never queues past that: a round's own leases skip and
569
+ * report rather than wait (`../../op/operator.ts`'s module doc), and a
570
+ * foreground CLI blocked with no visibility for however long a scheduled
571
+ * turn takes would be a worse answer than a clear refusal with a retry in
572
+ * hand. Ctrl-C already means "abort my own run" here; it must not also mean
573
+ * "give up waiting for someone else's turn".
574
+ *
575
+ * An Op the steward runs beside its turns (#2861) takes the Op's own lease
576
+ * instead, renewed for as long as the run lasts, and never the turn: the run
577
+ * is one at a time with the runs the operator starts of it, and holds none
578
+ * of the steward's other Ops up. Held already, it refuses at once, naming
579
+ * the holder.
580
+ *
581
+ * `undefined` (via the caller checking `owner`) when no steward lists this
582
+ * op — the ordinary, untouched path.
583
+ */
584
+ async function stewardTurnGate(opName, ctx) {
585
+ const { stewards } = await discoverStewards().catch(() => ({ stewards: new Map() }));
586
+ let owner;
587
+ for (const { declaration } of stewards.values()) {
588
+ if (declaration.ops.some((op) => op.name === opName)) {
589
+ owner = declaration;
590
+ break;
591
+ }
592
+ }
593
+ if (!owner)
594
+ return undefined;
595
+ const env = ctx.args.env ?? DEFAULT_STEWARD_ENV;
596
+ const form = stewardFormFor(owner, env);
597
+ if (form === "fountain") {
598
+ // `run.on: "fountain"` asks for the steward's thread as much as the flag
599
+ // does (#2523).
600
+ if ((await chooseOpRuntime(ctx, true))?.on === "fountain")
601
+ return { ok: true };
602
+ return {
603
+ ok: false,
604
+ message: `Op "${opName}" is one of steward "${owner.name}"'s Ops, which runs on fountain in environment "${env}"`,
605
+ hint: `Run \`chant run ${opName} --on fountain\` so it posts to "${owner.name}"'s thread. ` +
606
+ `A plain \`chant run ${opName}\` would run it outside that thread, beside the steward instead of one of its turns.`,
607
+ };
608
+ }
609
+ if (stewardBesideFor(owner, opName))
610
+ return besideLeaseGate(opName, owner.name, ctx);
611
+ const holder = currentHolderId();
612
+ let turn;
613
+ try {
614
+ turn = await acquireStewardTurn(owner.name, holder, { waitMs: STEWARD_TURN_WAIT_MS });
615
+ }
616
+ catch (err) {
617
+ // Not turn contention — the acquire attempt itself failed (most likely a
618
+ // StaleLockError, a `.lock` left behind by a killed operator process).
619
+ // Report it as a refusal rather than letting it propagate uncaught out
620
+ // of `runOpOnRuntime`, before that function's own try/catch even starts.
621
+ return {
622
+ ok: false,
623
+ message: `Op "${opName}" is one of steward "${owner.name}"'s turns, and its lease could not be read`,
624
+ hint: `${err instanceof StaleLockError ? err.message : err instanceof Error ? err.message : String(err)} ` +
625
+ `This can happen when an operator process was killed mid-write; check refs/chant/lease/_turns/${owner.name} for a stale lock.`,
626
+ };
627
+ }
628
+ if (!turn.acquired) {
629
+ const heldBy = turn.heldBy?.holder;
630
+ return {
631
+ ok: false,
632
+ message: `Op "${opName}" is one of steward "${owner.name}"'s turns, and a turn is in progress` +
633
+ (heldBy ? ` (held by ${heldBy})` : ""),
634
+ hint: `Wait for the turn to finish and re-run \`chant run ${opName}\`, or check \`chant operator status --steward ${owner.name}\`. ` +
635
+ `If it looks stuck, stop the operator process holding it (Ctrl-C, or kill it) — its lease also expires on its own.`,
636
+ };
637
+ }
638
+ const lease = turn.lease;
639
+ const stewardName = owner.name;
640
+ return { ok: true, release: async () => { await releaseLease(stewardTurnLeaseName(stewardName), holder, lease.token).catch(() => false); } };
641
+ }
642
+ /**
643
+ * The lease a `chant run` of an Op beside a steward's turns holds (#2861):
644
+ * the Op's own, as `--holder` (the operator passes `<steward>/<op>@<its
645
+ * holder>`) or this process.
646
+ */
647
+ async function besideLeaseGate(opName, steward, ctx) {
648
+ const holder = ctx.args.holder ?? currentHolderId();
649
+ let held;
650
+ try {
651
+ held = await holdBesideLease(opName, holder);
652
+ }
653
+ catch (err) {
654
+ return {
655
+ ok: false,
656
+ message: `Op "${opName}" runs beside steward "${steward}"'s turns, and its lease could not be read`,
657
+ hint: `${err instanceof StaleLockError ? err.message : err instanceof Error ? err.message : String(err)} ` +
658
+ `This can happen when a process was killed mid-write; check refs/chant/lease/${opName} for a stale lock.`,
659
+ };
660
+ }
661
+ if (!held.acquired) {
662
+ return {
663
+ ok: false,
664
+ message: `Op "${opName}" runs beside steward "${steward}"'s turns, one run at a time, and a run of it is in progress` +
665
+ (held.heldBy ? ` (held by ${held.heldBy})` : ""),
666
+ hint: `Wait for that run to end and re-run \`chant run ${opName}\`; \`chant workspace status --json\` lists it under the steward. Its lease expires on its own if the process holding it died.`,
667
+ };
668
+ }
669
+ return { ok: true, release: held.release };
670
+ }
671
+ export async function runOp(ctx) {
672
+ if (ctx.args.generate) {
673
+ if (ctx.args.components) {
674
+ console.error(formatError({
675
+ message: "`chant run --components --generate` is not a command",
676
+ hint: "Generate a component pipeline with `chant build --components --generate <lexicon>`, or Op pipelines with `chant run --generate <provider>`.",
677
+ }));
678
+ return 1;
679
+ }
680
+ return runOpGenerate(ctx);
681
+ }
682
+ if (ctx.args.components && ctx.args.report) {
683
+ console.error(formatError({
684
+ message: "--report is not supported with --components",
685
+ hint: "No preview/dry-run mode exists yet for the component driver (see chant#1116). Omit --report.",
686
+ }));
687
+ return 1;
688
+ }
689
+ if (ctx.args.components)
690
+ return runOpComponents(ctx);
691
+ if (ctx.args.report) {
692
+ console.error(formatError({
693
+ message: "`chant run --report` rendered a past durable run, which #2116 removed",
694
+ hint: "Run `chant run log <op>` for the runtime's own run history.",
695
+ }));
696
+ return 1;
697
+ }
698
+ return runOpOnRuntime(ctx);
699
+ }
700
+ // ── Auto-release recording post-run (#597) ──────────────────────────────────
701
+ /**
702
+ * After a successful `chant run --components` (local executor), auto-emit
703
+ * one release record per successfully deployed component that published a
704
+ * digest-bearing artifact — reusing `maybeRecordAutoRelease`
705
+ * (../../components/auto-release.ts), which itself reuses
706
+ * `../../lifecycle/release-ledger.ts`'s `appendReleaseRecord` verbatim. Never
707
+ * called on a failed run: both call sites below only reach this after
708
+ * confirming `result.success`/`componentResult.ok`, so a failed deploy writes
709
+ * nothing, by construction.
710
+ *
711
+ * Also persists the component's accumulated `BuildArchiveManifest`, when its
712
+ * composition produced one, to the durable build-manifest store (#609,
713
+ * ../../components/manifest-persistence.ts, ../../lifecycle/build-ledger-
714
+ * store.ts) — the missing piece that lets `chant components status`'s
715
+ * `componentBom`/`build.reproducibility` resolve to a real manifest instead
716
+ * of always reporting `null`. Same `disabled` opt-out flag as the release
717
+ * record: both are "durably record this successful deploy" side effects, so
718
+ * `--no-release-record`/`release.autoRecord: false` gates persistence too
719
+ * rather than needing a second, easy-to-forget knob (see
720
+ * `ManifestPersistOptions.disabled`'s doc).
721
+ *
722
+ * Best-effort and silent on the happy path: a skip (opted out, no digest/
723
+ * manifest, no actor) is unremarkable and not printed; only an actual write
724
+ * failure (`reason: "error"`) is surfaced, as a warning — never a nonzero
725
+ * exit, since the deploy itself already succeeded and a ledger-write hiccup
726
+ * must not retroactively fail it.
727
+ *
728
+ * Exported for `chant components fan-out` (#2420), which applies components
729
+ * through a different runner and would otherwise leave no trace in the release
730
+ * ledger for work `chant run --components` records. Each result is filtered on
731
+ * its own `ok`, so a fan-out that partly succeeded records exactly the
732
+ * components that did.
733
+ *
734
+ * Returns the records it wrote, for `--digest-file` (#2602).
735
+ */
736
+ export async function recordAutoReleasesForRun(results, env, runId, disabled) {
737
+ const recorded = [];
738
+ for (const componentResult of results) {
739
+ if (!componentResult.ok)
740
+ continue;
741
+ const outcome = await maybeRecordAutoRelease({
742
+ component: componentResult.component,
743
+ env,
744
+ success: true,
745
+ records: componentResult.records,
746
+ runId,
747
+ // A local-executor id resolves nowhere — say so in a field (#2045).
748
+ runOrigin: { forge: "local" },
749
+ }, { disabled });
750
+ if (!outcome.recorded && outcome.reason === "error") {
751
+ console.error(formatWarning({
752
+ message: `release record for "${componentResult.component}"@${env} was not recorded: ${outcome.error}`,
753
+ }));
754
+ }
755
+ else if (outcome.recorded) {
756
+ recorded.push(outcome.record);
757
+ console.error(formatInfo(`Recorded release: ${formatBold(componentResult.component)}@${env} -> ${outcome.record.digest} (commit ${outcome.commit.slice(0, 7)})`));
758
+ }
759
+ const manifestOutcome = await maybePersistBuildManifest({ success: true, records: componentResult.records }, { disabled });
760
+ if (!manifestOutcome.persisted && manifestOutcome.reason === "error") {
761
+ console.error(formatWarning({
762
+ message: `build manifest for "${componentResult.component}"@${env} was not persisted: ${manifestOutcome.error}`,
763
+ }));
764
+ }
765
+ else if (manifestOutcome.persisted) {
766
+ console.error(formatInfo(`Persisted build manifest: ${formatBold(componentResult.component)} -> ${manifestOutcome.manifestDigest} (commit ${manifestOutcome.commit.slice(0, 7)})`));
767
+ }
768
+ }
769
+ return recorded;
770
+ }
771
+ // ── chant run --components <name|all> ────────────────────────────────────────
772
+ /**
773
+ * `chant run --components <name|all> [--env <env>]` (#585) — the interpret
774
+ * driver's CLI entrypoint, and since #2116 the only component run path there
775
+ * is. `args.path` is the component name (or `all`), matching `chant run
776
+ * <name>`'s Op-dispatch convention exactly (`args.path` is the Op name there
777
+ * too) rather than a project directory — components are always discovered from
778
+ * the current working directory, the same way Op discovery (`discoverOps()`)
779
+ * never takes a project-path argument either.
780
+ *
781
+ * The selector resolves through the runtime's `runComponents` and runs on the
782
+ * local in-process driver; a `gate` is decided against the gate ledger when
783
+ * the driver reaches it (#2119), and one nobody has approved ends the run with
784
+ * exit code 3 and the `chant approve` line, exactly as `chant run <op>` does.
785
+ *
786
+ * On a successful run, auto-emits one release-ledger record per component
787
+ * that published a digest (#597, `recordAutoReleasesForRun` above) — a
788
+ * *post-run* CLI step, not a change to the driver itself (`../../components/
789
+ * driver.ts` stays capability-agnostic and knows nothing about the ledger).
790
+ * Opt out with `--no-release-record` or `chant.config.ts`'s
791
+ * `release.autoRecord: false`; the default is ON. A failed run never reaches
792
+ * this step, so it writes nothing.
793
+ *
794
+ * chant #1108 — resolves this invocation's declared build-time parameters
795
+ * (`chant.config.ts`'s `buildParams`, against `--param`/`--params-file`/a
796
+ * declared `env` mapping) the exact same way `chant build` does
797
+ * (`resolveCliBuildParams`, shared with `buildCommand`), BEFORE anything
798
+ * discovers/imports a `*.component.ts` file.
799
+ * Before this, `params.*` (`@intentius/chant/params`) was always `{}` under
800
+ * this command, no matter what a component's `chant.config.ts` declared or a
801
+ * CI job's environment supplied — see chant #1108. `chant.config.ts` is
802
+ * loaded once here (with the same defensive fallback the post-run
803
+ * auto-release check below used to apply itself) and reused for that check,
804
+ * rather than loaded a second time.
805
+ */
806
+ export async function runOpComponents(ctx) {
807
+ const selector = ctx.args.path;
808
+ if (!selector || selector === ".") {
809
+ console.error(formatError({
810
+ message: "Component name is required: chant run --components <name|all>",
811
+ hint: "Run `chant list --components` to see available components.",
812
+ }));
813
+ return 1;
814
+ }
815
+ const gatedExit = resolveGatedExitCode(ctx);
816
+ if (gatedExit === undefined)
817
+ return 1;
818
+ const projectPath = resolve(".");
819
+ const { config } = await loadChantConfig(projectPath).catch(() => ({ config: {} }));
820
+ const paramsResolution = resolveCliBuildParams(config.buildParams, {
821
+ cli: parseParamFlags(ctx.args.param),
822
+ paramsFile: ctx.args.paramsFile,
823
+ verbose: ctx.args.verbose,
824
+ });
825
+ if (!paramsResolution.success) {
826
+ for (const message of paramsResolution.errors)
827
+ console.error(message);
828
+ return 1;
829
+ }
830
+ const runtime = await resolveOpRuntime(ctx);
831
+ if (!runtime)
832
+ return 1;
833
+ if (!runtime.runComponents) {
834
+ console.error(formatError({
835
+ message: `--components is not supported on the "${runtime.name}" runtime`,
836
+ hint: "Omit --on to run components on the built-in local runtime.",
837
+ }));
838
+ return 1;
839
+ }
840
+ const env = ctx.args.env ?? "local";
841
+ // Seed cross-component/cross-stack outputs from upstream jobs' dumped files
842
+ // (`--seed-outputs`), so a single-component run resolves references to a
843
+ // component that ran in an earlier CI job.
844
+ const seededOutputs = {};
845
+ for (const file of ctx.args.seedOutputs ?? []) {
846
+ try {
847
+ Object.assign(seededOutputs, JSON.parse(readFileSync(resolve(file), "utf8")));
848
+ }
849
+ catch (err) {
850
+ console.error(formatError({
851
+ message: `--seed-outputs: could not read "${file}": ${err instanceof Error ? err.message : String(err)}`,
852
+ }));
853
+ return 1;
854
+ }
855
+ }
856
+ // `--progress-json` (#M3, behold roadmap): stream one NDJSON RunProgressEvent
857
+ // per line to stdout while the run executes, so a consumer (e.g. behold) can
858
+ // render live wave/component/phase/step progress instead of tailing raw
859
+ // logs. Purely additive: when the flag is absent, `onProgress` stays
860
+ // `undefined` and every `onProgress?.(...)` call in the driver is a no-op —
861
+ // behavior is byte-for-byte unchanged from before this flag existed.
862
+ const onProgress = ctx.args.progressJson ? ndjsonProgressSink() : undefined;
863
+ const result = await runtime.runComponents(projectPath, selector, {
864
+ env: ctx.args.env,
865
+ componentOutputs: seededOutputs,
866
+ onProgress,
867
+ sandbox: ctx.args.sandbox,
868
+ buildParams: paramsResolution.provenance,
869
+ });
870
+ // Dump the accumulated outputs for a downstream job to seed from. Written
871
+ // even on failure (partial outputs) so a resumed run still has what completed.
872
+ if (ctx.args.dumpOutputs && result.run) {
873
+ const dumpPath = resolve(ctx.args.dumpOutputs);
874
+ mkdirSync(dirname(dumpPath), { recursive: true });
875
+ writeFileSync(dumpPath, JSON.stringify(result.run.componentOutputs, null, 2));
876
+ }
877
+ if (!result.success && !result.run && !result.gated) {
878
+ console.error(formatError({ message: result.error ?? "Failed to run component(s)" }));
879
+ return 1;
880
+ }
881
+ if (result.run) {
882
+ if (ctx.args.json)
883
+ renderDriverJson(result.run);
884
+ else
885
+ renderDriverHuman(result.run);
886
+ }
887
+ // Gated (#2119): the same fact-and-stop the Op path takes, and the same
888
+ // exit code. Nothing to release — the component stopped short of finishing.
889
+ if (result.gated) {
890
+ const { gate } = result.gated;
891
+ console.error(formatWarning({
892
+ message: `component "${result.gated.component}" is gated on "${gate.gate}" — pending approval`,
893
+ }));
894
+ // #2574: an approval stands, but for another plan or for none. Say so,
895
+ // with the command that replaces it.
896
+ const sealed = await gateIsSealed(gate.gate);
897
+ if (result.gated.mismatch) {
898
+ console.error(formatWarning({ message: describeGateMismatch(gate.op, gate.gate, result.gated.mismatch, sealed) }));
899
+ }
900
+ console.error(formatInfo(`approve : ${approveCommand(gate.op, gate.gate, gate.environment, undefined, sealed)}`));
901
+ if (gate.url)
902
+ console.error(formatInfo(`approve at: ${gate.url}`));
903
+ console.error(formatInfo(`expires : ${gate.expiresAt}`));
904
+ // #2310: this run's own append reached only the local chant/lifecycle
905
+ // branch. The gate is still right to stand, but an operator elsewhere
906
+ // cannot see the pending fact to approve it, and nothing else here says
907
+ // why not.
908
+ if (result.gated.pushed === false && isLifecycleLocalNote(result.gated.pushWarning)) {
909
+ console.error(formatInfo(LIFECYCLE_LOCAL_NOTE));
910
+ }
911
+ else if (result.gated.pushed === false) {
912
+ console.error(formatWarning({
913
+ message: `the pending fact was not pushed to the remote: ${result.gated.pushWarning ?? "recorded locally only"}`,
914
+ hint: "an operator working from a clone of the remote cannot approve it until it does",
915
+ }));
916
+ }
917
+ await reportGatedRun({
918
+ op: gate.op,
919
+ gate: gate.gate,
920
+ ...(gate.description ? { description: gate.description } : {}),
921
+ expiresAt: gate.expiresAt,
922
+ ...(gate.url ? { url: gate.url } : {}),
923
+ ...(result.gated.pushed === false ? { pushed: false, pushWarning: result.gated.pushWarning } : {}),
924
+ ...(gate.planDigest ? { planDigest: gate.planDigest } : {}),
925
+ ...(await summaryLedgerPrefix()),
926
+ ...(gate.environment ? { environment: gate.environment } : {}),
927
+ }, gatedExit);
928
+ return gatedExit;
929
+ }
930
+ if (result.success && result.run) {
931
+ const disabled = resolveAutoReleaseDisabled(config, ctx.args.noReleaseRecord);
932
+ const recorded = await recordAutoReleasesForRun(result.run.results, env, `local-${Date.now()}`, disabled);
933
+ // `--digest-file` (#2602): the releases this run recorded, one
934
+ // `<component>=<digest>` line each, the form `chant components promote
935
+ // --digest` takes. A generated promote job reads it to promote exactly
936
+ // what this job built, not whatever is latest in the environment.
937
+ if (ctx.args.digestFile) {
938
+ const digestPath = resolve(ctx.args.digestFile);
939
+ mkdirSync(dirname(digestPath), { recursive: true });
940
+ writeFileSync(digestPath, recorded.map((r) => `${r.component}=${r.digest}\n`).join(""));
941
+ }
942
+ }
943
+ return result.success ? 0 : 1;
944
+ }
945
+ /**
946
+ * `chant run <name>` on the resolved runtime (#2121) — the built-in `local`
947
+ * provider by default, a lexicon's `opRuntime` under `--on <name>`.
948
+ *
949
+ * This function knows nothing about how a run happens. It discovers the Op,
950
+ * runs the CLI-level pre-flights that are about flags rather than execution
951
+ * (`--sandbox` over a `policyGate` step, #2003), hands the config to the
952
+ * runtime, and renders whatever comes back. On the local runtime that is the
953
+ * executor's own `OpRunResult`, so `--json` and the human render are exactly
954
+ * what they were before the seam existed; a runtime that reports only a state
955
+ * gets the terser render instead.
956
+ */
957
+ export async function runOpOnRuntime(ctx) {
958
+ const opName = ctx.args.path;
959
+ if (!opName || opName === ".") {
960
+ console.error(formatError({
961
+ message: "Op name is required: chant run <name>",
962
+ hint: "Run `chant run list` to see available Ops",
963
+ }));
964
+ return 1;
965
+ }
966
+ const gatedExit = resolveGatedExitCode(ctx);
967
+ if (gatedExit === undefined)
968
+ return 1;
969
+ const { ops, errors } = await discoverOps();
970
+ for (const err of errors)
971
+ console.error(formatWarning({ message: err }));
972
+ const discovered = ops.get(opName);
973
+ if (!discovered) {
974
+ const names = [...ops.keys()];
975
+ console.error(formatError({
976
+ message: `Op "${opName}" not found`,
977
+ hint: names.length > 0
978
+ ? `Available: ${names.join(", ")}`
979
+ : "No *.op.ts files found — create one",
980
+ }));
981
+ return 1;
982
+ }
983
+ const { config } = discovered;
984
+ // Pre-flight: --sandbox cannot cover a policyGate step (#2003).
985
+ if (refusesPolicyGateUnderSandbox(ctx, config, opName))
986
+ return 1;
987
+ // A hand run of an Op a declared steward lists is one of that steward's
988
+ // turns, not a run beside it (#2750). `undefined` when no steward lists
989
+ // this op at all — the ordinary path.
990
+ const stewardGate = await stewardTurnGate(opName, ctx);
991
+ if (stewardGate && !stewardGate.ok) {
992
+ console.error(formatError({ message: stewardGate.message, hint: stewardGate.hint }));
993
+ return 1;
994
+ }
995
+ const runtime = await resolveOpRuntime(ctx);
996
+ if (!runtime) {
997
+ await stewardGate?.release?.();
998
+ return 1;
999
+ }
1000
+ // The work lease (#2748). `--work` names the item an Op with a work lease
1001
+ // runs under; it is taken where the run executes, which for a hosted
1002
+ // runtime that carries it (fountain, #3555) is not this process.
1003
+ const work = await resolveRunWork(ctx, config, runtime);
1004
+ if (work === null) {
1005
+ await stewardGate?.release?.();
1006
+ return 1;
1007
+ }
1008
+ // `--progress-json` streams one NDJSON StepRecord per settled step, fed by
1009
+ // whatever the runtime reports through `progress`.
1010
+ const progress = ctx.args.progressJson ? ndjsonProgressSink() : undefined;
1011
+ // Ctrl-C, or a SIGTERM (the signal a steward's operator sends this process
1012
+ // when it runs beside the steward's turns and the operator itself stops,
1013
+ // and what a plain `kill <pid>` sends with no signal named), aborts
1014
+ // in-flight activities (kills their child processes) instead of orphaning
1015
+ // them. `process.on`, not `.once` (chant#2872's shape, here too): a second
1016
+ // signal arriving before the `finally` below has released this run's lease
1017
+ // (`stewardGate`, for a beside run) must not fall through to Node's default
1018
+ // disposition and skip that release. `stopping` makes a repeat a no-op; the
1019
+ // listeners are removed only after the release, at the very end of
1020
+ // `finally`, not before it.
1021
+ const controller = new AbortController();
1022
+ let stopping = false;
1023
+ const onSigint = () => {
1024
+ if (stopping)
1025
+ return;
1026
+ stopping = true;
1027
+ console.error(formatWarning({ message: "interrupted — stopping Op" }));
1028
+ controller.abort();
1029
+ };
1030
+ process.on("SIGINT", onSigint);
1031
+ process.on("SIGTERM", onSigint);
1032
+ try {
1033
+ // `--param name=value` reaches the runtime (#3539). The local runtime
1034
+ // has no use for it; fountain reads `agent` to pick the steward and posts
1035
+ // the rest on the command line it hands the sandbox.
1036
+ const params = parseParamFlags(ctx.args.param);
1037
+ const handle = await runtime.start(config, {
1038
+ env: ctx.args.env,
1039
+ ...(params ? { params } : {}),
1040
+ ...(ctx.args.profile !== undefined ? { profile: ctx.args.profile } : {}),
1041
+ progress,
1042
+ signal: controller.signal,
1043
+ ...(work ? { work } : {}),
1044
+ });
1045
+ const status = await handle.result();
1046
+ if (status.result) {
1047
+ // The executor's own render already prints a gate, its approve line
1048
+ // and its expiry (#2119).
1049
+ const sealed = status.result.gate ? await gateIsSealed(status.result.gate.gate) : false;
1050
+ if (ctx.args.json)
1051
+ renderJson(status.result, undefined, sealed);
1052
+ else
1053
+ renderHuman(status.result, undefined, sealed);
1054
+ }
1055
+ else {
1056
+ renderRuntimeStatus("Op", opName, runtime.name, status);
1057
+ if (status.state === "gated" && status.gate) {
1058
+ console.error(formatWarning({
1059
+ message: `Op "${opName}" is waiting on gate "${status.gate.name}"`,
1060
+ hint: `Record the resolution with: ${approveCommand(opName, status.gate.name, undefined, undefined, await gateIsSealed(status.gate.name))}`,
1061
+ }));
1062
+ }
1063
+ }
1064
+ // Exit 3 for a gated run (#2119) — a distinct code so CI can tell
1065
+ // "waiting on a human" from a broken op, and retry the one but not the
1066
+ // other. `--gated-exit <code>` remaps that one outcome and nothing else
1067
+ // (#2243).
1068
+ if (status.state === "gated") {
1069
+ // The local runtime carries the whole pending fact on its result; a
1070
+ // runtime that reports only a state carries the gate's name alone.
1071
+ const pending = status.result?.gate;
1072
+ const gate = pending?.gate ?? status.gate?.name;
1073
+ if (gate) {
1074
+ await reportGatedRun({
1075
+ op: opName,
1076
+ gate,
1077
+ ...(pending?.description ? { description: pending.description } : {}),
1078
+ ...(pending?.expiresAt ? { expiresAt: pending.expiresAt } : {}),
1079
+ ...(pending?.url ? { url: pending.url } : {}),
1080
+ // #2310: the local runtime knows whether this run's own append
1081
+ // reached the remote; a runtime that reports only a state does not.
1082
+ ...(status.result?.gatePushed === false
1083
+ ? { pushed: false, pushWarning: status.result.gatePushWarning }
1084
+ : {}),
1085
+ ...(pending?.planDigest ? { planDigest: pending.planDigest } : {}),
1086
+ ...(await summaryLedgerPrefix()),
1087
+ }, gatedExit);
1088
+ }
1089
+ return gatedExit;
1090
+ }
1091
+ // A run waiting on an open decision point (#2749) is waiting on a person,
1092
+ // like a gated one, and exits with the same code. Its answer comes through
1093
+ // hud or `points answer`, never a `chant approve`.
1094
+ if (status.state === "waiting") {
1095
+ if (!status.result && status.point) {
1096
+ console.error(formatWarning({
1097
+ message: `Op "${opName}" is waiting on decision point "${status.point.point}" (${status.point.id})`,
1098
+ hint: `A person answers it with: ${pointAnswerCommand(status.point.id)}`,
1099
+ }));
1100
+ }
1101
+ return gatedExit;
1102
+ }
1103
+ if (status.state !== "completed")
1104
+ return 1;
1105
+ // A completed run that found drift exits 2 when asked to (#3675), so a
1106
+ // scheduled drift job turns red without a script that reads the ledger.
1107
+ return completedRunExitCode(opName, config, ctx.args.failOnDrift, status.result?.records ?? status.records);
1108
+ }
1109
+ catch (err) {
1110
+ if (err instanceof OpRunFailure) {
1111
+ const sealed = err.result.gate ? await gateIsSealed(err.result.gate.gate) : false;
1112
+ if (ctx.args.json)
1113
+ renderJson(err.result, undefined, sealed);
1114
+ else
1115
+ renderHuman(err.result, undefined, sealed);
1116
+ return 1;
1117
+ }
1118
+ console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
1119
+ return 1;
1120
+ }
1121
+ finally {
1122
+ // The turn is over, win or lose — free it so the steward's next round,
1123
+ // or the next hand run, doesn't wait out this run's own TTL (#2750). The
1124
+ // listeners stay registered until after this release (chant#2872): it is
1125
+ // itself async, and removing them first would let a repeat signal in
1126
+ // that window fall through to Node's default disposition and skip it.
1127
+ await stewardGate?.release?.();
1128
+ process.removeListener("SIGINT", onSigint);
1129
+ process.removeListener("SIGTERM", onSigint);
1130
+ }
1131
+ }
1132
+ /**
1133
+ * The work item and holder a `chant run` passes to the runtime (#2748), or
1134
+ * `null` after printing why the run is refused. The holder is `--holder`, or,
1135
+ * for an Op a steward lists, `<steward>/<op>@<process>` so `workspace status`
1136
+ * shows the lease beside the steward's Ops, or this process's id.
1137
+ *
1138
+ * A non-local runtime takes `--work` only when it declares `carriesWork`
1139
+ * (#3555), and then gets just what the caller named: the holder is chosen
1140
+ * where the run executes, not after this process.
1141
+ */
1142
+ async function resolveRunWork(ctx, config, provider) {
1143
+ const runtime = provider.name;
1144
+ const item = ctx.args.work;
1145
+ if (!config.workLease) {
1146
+ if (item === undefined)
1147
+ return undefined;
1148
+ console.error(formatError({
1149
+ message: `--work ${item}: Op "${config.name}" declares no work lease`,
1150
+ hint: "Declare workLease on the Op to run it under a work item's lease.",
1151
+ }));
1152
+ return null;
1153
+ }
1154
+ if (runtime !== "local" && provider.carriesWork !== true && (item !== undefined || ctx.args.holder !== undefined)) {
1155
+ console.error(formatError({
1156
+ message: `--work and --holder run on the local runtime; "${runtime}" takes the work lease where it executes the run`,
1157
+ hint: "Omit --on, or name the item in the Op's workLease.",
1158
+ }));
1159
+ return null;
1160
+ }
1161
+ if (runtime !== "local" && provider.carriesWork === true) {
1162
+ const holderArg = ctx.args.holder;
1163
+ if (item === undefined && holderArg === undefined)
1164
+ return undefined;
1165
+ return { ...(item !== undefined ? { item } : {}), ...(holderArg !== undefined ? { holder: holderArg } : {}) };
1166
+ }
1167
+ let holder = ctx.args.holder;
1168
+ if (holder === undefined) {
1169
+ try {
1170
+ const { stewards } = await discoverStewards();
1171
+ for (const { declaration } of stewards.values()) {
1172
+ if (declaration.ops.some((op) => op.name === config.name)) {
1173
+ holder = stewardWorkHolder(declaration.name, config.name);
1174
+ break;
1175
+ }
1176
+ }
1177
+ }
1178
+ catch {
1179
+ // No steward can be read: the run holds the lease as this process.
1180
+ }
1181
+ }
1182
+ return { ...(item !== undefined ? { item } : {}), ...(holder !== undefined ? { holder } : {}) };
1183
+ }
1184
+ // ── fallback ────────────────────────────────────────────────────────────────���─
1185
+ export function runOpUnknown(ctx) {
1186
+ console.error(formatError({
1187
+ message: `Unknown run subcommand: ${ctx.args.extraPositional ?? ctx.args.path}`,
1188
+ hint: "Available: chant run <name>, run list, run status, run approve, run cancel, run log",
1189
+ }));
1190
+ return Promise.resolve(1);
1191
+ }