@intentius/chant 0.124.13 → 0.124.15

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 (991) 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.d.ts +6 -0
  35. package/dist/build.d.ts.map +1 -1
  36. package/dist/build.js +669 -0
  37. package/dist/builder.js +44 -0
  38. package/dist/cdk/advise.js +30 -0
  39. package/dist/cdk/assembly.js +122 -0
  40. package/dist/cdk/graph.js +444 -0
  41. package/dist/cdk/tier-map.js +64 -0
  42. package/dist/cdk/types.js +24 -0
  43. package/dist/change-set.d.ts +24 -2
  44. package/dist/change-set.d.ts.map +1 -1
  45. package/dist/change-set.js +361 -0
  46. package/dist/child-project.js +21 -0
  47. package/dist/ci-jobs.d.ts +227 -0
  48. package/dist/ci-jobs.d.ts.map +1 -0
  49. package/dist/ci-jobs.js +448 -0
  50. package/dist/claimed-fields.js +135 -0
  51. package/dist/cli/build-options.js +70 -0
  52. package/dist/cli/build-params-cli.js +139 -0
  53. package/dist/cli/command-group.js +123 -0
  54. package/dist/cli/commands/audit-agents.js +326 -0
  55. package/dist/cli/commands/audit.js +571 -0
  56. package/dist/cli/commands/build.js +920 -0
  57. package/dist/cli/commands/carve-apply.js +153 -0
  58. package/dist/cli/commands/carve-bridge.js +201 -0
  59. package/dist/cli/commands/carve-emit.js +332 -0
  60. package/dist/cli/commands/carve-status.js +119 -0
  61. package/dist/cli/commands/carve.js +204 -0
  62. package/dist/cli/commands/check-lexicon-docs.js +79 -0
  63. package/dist/cli/commands/check-lexicon-examples.js +177 -0
  64. package/dist/cli/commands/check-lexicon-intrinsics.js +291 -0
  65. package/dist/cli/commands/check-lexicon-mcp.js +82 -0
  66. package/dist/cli/commands/check-lexicon-plugin.d.ts.map +1 -1
  67. package/dist/cli/commands/check-lexicon-plugin.js +104 -0
  68. package/dist/cli/commands/check-lexicon.js +766 -0
  69. package/dist/cli/commands/describe.js +85 -0
  70. package/dist/cli/commands/diff.js +175 -0
  71. package/dist/cli/commands/doctor.js +350 -0
  72. package/dist/cli/commands/import-agents.js +155 -0
  73. package/dist/cli/commands/import.js +670 -0
  74. package/dist/cli/commands/init-lexicon/templates/codegen.js +194 -0
  75. package/dist/cli/commands/init-lexicon/templates/docs.js +100 -0
  76. package/dist/cli/commands/init-lexicon/templates/examples.js +29 -0
  77. package/dist/cli/commands/init-lexicon/templates/lint.js +34 -0
  78. package/dist/cli/commands/init-lexicon/templates/lsp.js +37 -0
  79. package/dist/cli/commands/init-lexicon/templates/plugin.js +108 -0
  80. package/dist/cli/commands/init-lexicon/templates/project.js +240 -0
  81. package/dist/cli/commands/init-lexicon/templates/spec.js +56 -0
  82. package/dist/cli/commands/init-lexicon/templates/tests.js +66 -0
  83. package/dist/cli/commands/init-lexicon.js +172 -0
  84. package/dist/cli/commands/init.js +381 -0
  85. package/dist/cli/commands/lexicon-rolling-upgrade.js +145 -0
  86. package/dist/cli/commands/lexicon-surface-diff.js +145 -0
  87. package/dist/cli/commands/licenses.js +125 -0
  88. package/dist/cli/commands/lint.d.ts.map +1 -1
  89. package/dist/cli/commands/lint.js +948 -0
  90. package/dist/cli/commands/list.js +63 -0
  91. package/dist/cli/commands/migrate.d.ts.map +1 -1
  92. package/dist/cli/commands/migrate.js +423 -0
  93. package/dist/cli/commands/onboard.js +403 -0
  94. package/dist/cli/commands/pinned-upgrade.js +191 -0
  95. package/dist/cli/commands/update.js +194 -0
  96. package/dist/cli/commands/vendor.js +217 -0
  97. package/dist/cli/conflict-check.js +104 -0
  98. package/dist/cli/debug.js +8 -0
  99. package/dist/cli/format.js +104 -0
  100. package/dist/cli/handlers/build.js +267 -0
  101. package/dist/cli/handlers/carve-apply.js +30 -0
  102. package/dist/cli/handlers/carve-bridge.js +28 -0
  103. package/dist/cli/handlers/carve-emit.js +50 -0
  104. package/dist/cli/handlers/carve-status.js +26 -0
  105. package/dist/cli/handlers/carve.js +40 -0
  106. package/dist/cli/handlers/change-set.js +46 -0
  107. package/dist/cli/handlers/components.js +730 -0
  108. package/dist/cli/handlers/dev.js +113 -0
  109. package/dist/cli/handlers/emulator.js +233 -0
  110. package/dist/cli/handlers/explain.js +54 -0
  111. package/dist/cli/handlers/fan-out.js +422 -0
  112. package/dist/cli/handlers/gate-resume.js +275 -0
  113. package/dist/cli/handlers/generate.js +84 -0
  114. package/dist/cli/handlers/graph.js +969 -0
  115. package/dist/cli/handlers/init.js +102 -0
  116. package/dist/cli/handlers/lifecycle.js +1727 -0
  117. package/dist/cli/handlers/lint.js +62 -0
  118. package/dist/cli/handlers/migrate.js +48 -0
  119. package/dist/cli/handlers/misc.js +391 -0
  120. package/dist/cli/handlers/operator.js +1162 -0
  121. package/dist/cli/handlers/override-approve.js +102 -0
  122. package/dist/cli/handlers/pr.js +503 -0
  123. package/dist/cli/handlers/promote.js +342 -0
  124. package/dist/cli/handlers/run-generate.js +206 -0
  125. package/dist/cli/handlers/run-wave.js +66 -0
  126. package/dist/cli/handlers/run.js +1191 -0
  127. package/dist/cli/handlers/scenario.js +325 -0
  128. package/dist/cli/handlers/search.js +924 -0
  129. package/dist/cli/handlers/serve.js +32 -0
  130. package/dist/cli/handlers/vendor.js +154 -0
  131. package/dist/cli/index.js +3 -0
  132. package/dist/cli/is-entry-point.js +23 -0
  133. package/dist/cli/lsp/capabilities.js +28 -0
  134. package/dist/cli/lsp/diagnostics.js +34 -0
  135. package/dist/cli/lsp/server.js +329 -0
  136. package/dist/cli/main.d.ts.map +1 -1
  137. package/dist/cli/main.js +2540 -0
  138. package/dist/cli/mcp/lifecycle-tools.js +80 -0
  139. package/dist/cli/mcp/op-tools.js +306 -0
  140. package/dist/cli/mcp/resource-handlers.js +258 -0
  141. package/dist/cli/mcp/resources/context.js +85 -0
  142. package/dist/cli/mcp/server.js +353 -0
  143. package/dist/cli/mcp/tools/build.js +111 -0
  144. package/dist/cli/mcp/tools/composites.js +95 -0
  145. package/dist/cli/mcp/tools/explain.js +166 -0
  146. package/dist/cli/mcp/tools/import.js +49 -0
  147. package/dist/cli/mcp/tools/lint.js +41 -0
  148. package/dist/cli/mcp/tools/scaffold.js +111 -0
  149. package/dist/cli/mcp/tools/search.js +112 -0
  150. package/dist/cli/mcp/types.js +1 -0
  151. package/dist/cli/mcp/workspace-plugins.js +91 -0
  152. package/dist/cli/mcp/workspace-tools.d.ts +1 -1
  153. package/dist/cli/mcp/workspace-tools.js +564 -0
  154. package/dist/cli/mcp-config.js +70 -0
  155. package/dist/cli/plugins.js +313 -0
  156. package/dist/cli/registry.js +23 -0
  157. package/dist/cli/reporters/stylish.js +329 -0
  158. package/dist/cli/version.js +15 -0
  159. package/dist/cli/watch.js +79 -0
  160. package/dist/codegen/bound-property-types.js +82 -0
  161. package/dist/codegen/coverage.js +119 -0
  162. package/dist/codegen/docs-file-markers.js +60 -0
  163. package/dist/codegen/docs-pages.js +115 -0
  164. package/dist/codegen/docs-rule-scanning.js +164 -0
  165. package/dist/codegen/docs-rules.js +76 -0
  166. package/dist/codegen/docs-sections.js +117 -0
  167. package/dist/codegen/docs-sidebar.js +65 -0
  168. package/dist/codegen/docs-types.js +4 -0
  169. package/dist/codegen/docs.js +356 -0
  170. package/dist/codegen/fetch.js +340 -0
  171. package/dist/codegen/generate-post-synth-barrel.js +63 -0
  172. package/dist/codegen/generate-registry.js +71 -0
  173. package/dist/codegen/generate-runtime-index.js +56 -0
  174. package/dist/codegen/generate-typescript.js +119 -0
  175. package/dist/codegen/generate.js +115 -0
  176. package/dist/codegen/json-patch.js +141 -0
  177. package/dist/codegen/json-schema-to-ts.js +344 -0
  178. package/dist/codegen/json-schema.js +246 -0
  179. package/dist/codegen/lexicon-regen.js +412 -0
  180. package/dist/codegen/naming.js +217 -0
  181. package/dist/codegen/okf-lexicon.js +245 -0
  182. package/dist/codegen/package.js +150 -0
  183. package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
  184. package/dist/codegen/pinned-upgrade.js +494 -0
  185. package/dist/codegen/registry.js +60 -0
  186. package/dist/codegen/rehype-base-url.mjs +68 -0
  187. package/dist/codegen/rolling-upgrade.js +217 -0
  188. package/dist/codegen/surface-snapshot.js +537 -0
  189. package/dist/codegen/testdata/postgres-tags.json +242 -0
  190. package/dist/codegen/topo-sort.js +36 -0
  191. package/dist/codegen/typecheck.js +115 -0
  192. package/dist/codegen/validate.js +200 -0
  193. package/dist/codegen/version-bump.js +35 -0
  194. package/dist/components/auto-release.js +143 -0
  195. package/dist/components/builders.js +47 -0
  196. package/dist/components/capability-plugin-loader.js +175 -0
  197. package/dist/components/capability-plugin-schema.js +46 -0
  198. package/dist/components/capability-plugin.js +99 -0
  199. package/dist/components/capability.js +60 -0
  200. package/dist/components/changed-files.js +72 -0
  201. package/dist/components/cli-support.js +427 -0
  202. package/dist/components/component.js +120 -0
  203. package/dist/components/component.schema.json +271 -0
  204. package/dist/components/config-defaults.js +130 -0
  205. package/dist/components/deploy-units.js +60 -0
  206. package/dist/components/discover.d.ts.map +1 -1
  207. package/dist/components/discover.js +189 -0
  208. package/dist/components/driver-output.js +86 -0
  209. package/dist/components/driver.js +728 -0
  210. package/dist/components/fan-out-output.js +165 -0
  211. package/dist/components/fan-out-record.js +94 -0
  212. package/dist/components/fan-out-run.js +373 -0
  213. package/dist/components/fan-out-support.js +60 -0
  214. package/dist/components/fan-out.js +273 -0
  215. package/dist/components/gate-plan.js +41 -0
  216. package/dist/components/gated-wave-pipeline.js +46 -0
  217. package/dist/components/index.js +24 -0
  218. package/dist/components/layers.js +28 -0
  219. package/dist/components/manifest-persistence.js +108 -0
  220. package/dist/components/pilots/alb-ecs.pilot.js +59 -0
  221. package/dist/components/pilots/dynamodb.pilot.js +51 -0
  222. package/dist/components/pilots/jar-emr.pilot.js +65 -0
  223. package/dist/components/pilots/lambda.pilot.js +52 -0
  224. package/dist/components/pilots/neo4j-fanout.pilot.js +68 -0
  225. package/dist/components/pilots/project.js +12 -0
  226. package/dist/components/pr-pipeline.d.ts.map +1 -1
  227. package/dist/components/pr-pipeline.js +135 -0
  228. package/dist/components/pr-run.js +363 -0
  229. package/dist/components/presets/ecs-fargate.js +72 -0
  230. package/dist/components/presets/index.js +28 -0
  231. package/dist/components/presets/lambda.js +34 -0
  232. package/dist/components/presets/single-host-compose.js +41 -0
  233. package/dist/components/promote.js +549 -0
  234. package/dist/components/registry.js +34 -0
  235. package/dist/components/run-progress.js +33 -0
  236. package/dist/components/sandbox/driver.d.ts.map +1 -1
  237. package/dist/components/sandbox/driver.js +93 -0
  238. package/dist/components/sandbox/run.js +115 -0
  239. package/dist/components/starter-plugin.js +104 -0
  240. package/dist/components/verbs/__tests__/mock-cloud-executor.js +68 -0
  241. package/dist/components/verbs/__tests__/mock-process-runner.js +45 -0
  242. package/dist/components/verbs/__tests__/mock-sbom-generator.js +56 -0
  243. package/dist/components/verbs/bom-writer.js +287 -0
  244. package/dist/components/verbs/build-archive.js +188 -0
  245. package/dist/components/verbs/build.js +142 -0
  246. package/dist/components/verbs/cloud-executor.js +110 -0
  247. package/dist/components/verbs/component-bom.js +125 -0
  248. package/dist/components/verbs/ensure-secret.js +50 -0
  249. package/dist/components/verbs/index.js +61 -0
  250. package/dist/components/verbs/license-policy.js +75 -0
  251. package/dist/components/verbs/lockfile-sbom-generator.js +191 -0
  252. package/dist/components/verbs/process-runner.js +78 -0
  253. package/dist/components/verbs/r2-sync.js +93 -0
  254. package/dist/components/verbs/reproducibility.js +62 -0
  255. package/dist/components/verbs/run-agent.js +577 -0
  256. package/dist/components/verbs/sbom-generator.js +119 -0
  257. package/dist/components/verbs/sbom.js +97 -0
  258. package/dist/components/verbs/shell.js +32 -0
  259. package/dist/components/verbs/sign.js +221 -0
  260. package/dist/components/verbs/stub.js +28 -0
  261. package/dist/components/verbs/tool-sbom-generator.js +154 -0
  262. package/dist/components/verbs/verify.js +112 -0
  263. package/dist/components/verbs/vex.js +131 -0
  264. package/dist/components/verbs/vuln-gate.js +152 -0
  265. package/dist/components/verbs/vuln-scan.js +288 -0
  266. package/dist/components/verbs/wait-verify.js +106 -0
  267. package/dist/components/verbs/wrangler.js +179 -0
  268. package/dist/components/wave-plan.js +102 -0
  269. package/dist/composite.d.ts +10 -2
  270. package/dist/composite.d.ts.map +1 -1
  271. package/dist/composite.js +313 -0
  272. package/dist/config-import.d.ts.map +1 -1
  273. package/dist/config-import.js +22 -0
  274. package/dist/config-sandbox.js +122 -0
  275. package/dist/config-static.js +206 -0
  276. package/dist/config.js +605 -0
  277. package/dist/content-digest.js +23 -0
  278. package/dist/declarable.js +114 -0
  279. package/dist/deep-observation.js +437 -0
  280. package/dist/detectLexicon.js +54 -0
  281. package/dist/discovery/cache.js +70 -0
  282. package/dist/discovery/collect.d.ts +2 -1
  283. package/dist/discovery/collect.d.ts.map +1 -1
  284. package/dist/discovery/collect.js +223 -0
  285. package/dist/discovery/cycles.js +95 -0
  286. package/dist/discovery/entity-wire-codec.js +391 -0
  287. package/dist/discovery/entity-wire.js +42 -0
  288. package/dist/discovery/files.js +121 -0
  289. package/dist/discovery/fold-import.d.ts.map +1 -1
  290. package/dist/discovery/fold-import.js +4073 -0
  291. package/dist/discovery/fold-rank.js +292 -0
  292. package/dist/discovery/graph.js +115 -0
  293. package/dist/discovery/host-composite.d.ts +35 -0
  294. package/dist/discovery/host-composite.d.ts.map +1 -0
  295. package/dist/discovery/host-composite.js +93 -0
  296. package/dist/discovery/import.d.ts.map +1 -1
  297. package/dist/discovery/import.js +65 -0
  298. package/dist/discovery/index.d.ts +9 -0
  299. package/dist/discovery/index.d.ts.map +1 -1
  300. package/dist/discovery/index.js +333 -0
  301. package/dist/discovery/param-deps.js +487 -0
  302. package/dist/discovery/resolve.js +39 -0
  303. package/dist/discovery/sandbox/bundle.js +214 -0
  304. package/dist/discovery/sandbox/child-errors.js +26 -0
  305. package/dist/discovery/sandbox/config-run.js +100 -0
  306. package/dist/discovery/sandbox/config-wire.js +183 -0
  307. package/dist/discovery/sandbox/driver.d.ts.map +1 -1
  308. package/dist/discovery/sandbox/driver.js +333 -0
  309. package/dist/discovery/sandbox/fork.js +229 -0
  310. package/dist/discovery/sandbox/policy-run.js +142 -0
  311. package/dist/discovery/sandbox/policy-wire.js +152 -0
  312. package/dist/discovery/sandbox/run.js +77 -0
  313. package/dist/discovery/specifier-resolve.js +320 -0
  314. package/dist/discovery/walk.js +284 -0
  315. package/dist/effect-receipt.js +340 -0
  316. package/dist/env.js +55 -0
  317. package/dist/errors.js +62 -0
  318. package/dist/fold/fold.js +1434 -0
  319. package/dist/fold/foldable-helpers.js +229 -0
  320. package/dist/fold/subset.js +696 -0
  321. package/dist/fold-provenance.js +414 -0
  322. package/dist/gate-decision.d.ts +20 -9
  323. package/dist/gate-decision.d.ts.map +1 -1
  324. package/dist/gate-decision.js +313 -0
  325. package/dist/gate-resume-run.js +154 -0
  326. package/dist/gated-waves.js +165 -0
  327. package/dist/governance.js +43 -0
  328. package/dist/graph-declared.js +45 -0
  329. package/dist/graph-detail.js +207 -0
  330. package/dist/graph-dot.js +54 -0
  331. package/dist/graph-effective.js +107 -0
  332. package/dist/graph-ir.js +623 -0
  333. package/dist/graph-layout.js +184 -0
  334. package/dist/graph-lens.js +105 -0
  335. package/dist/graph-mermaid.js +83 -0
  336. package/dist/graph-ops.js +39 -0
  337. package/dist/graph-refs.js +156 -0
  338. package/dist/held-elsewhere.js +87 -0
  339. package/dist/identity.js +251 -0
  340. package/dist/import/base-parser.js +34 -0
  341. package/dist/import/embedded.js +255 -0
  342. package/dist/import/generator.js +1 -0
  343. package/dist/import/ir-utils.js +85 -0
  344. package/dist/import/parser-options.js +45 -0
  345. package/dist/import/parser.js +1 -0
  346. package/dist/index.js +118 -0
  347. package/dist/intrinsic-interpolation.js +73 -0
  348. package/dist/intrinsic.js +31 -0
  349. package/dist/join-key.js +35 -0
  350. package/dist/kubectl-context.js +150 -0
  351. package/dist/lexicon-config.js +58 -0
  352. package/dist/lexicon-integrity.js +47 -0
  353. package/dist/lexicon-manifest.js +70 -0
  354. package/dist/lexicon-module.d.ts.map +1 -1
  355. package/dist/lexicon-module.js +241 -0
  356. package/dist/lexicon-output.js +218 -0
  357. package/dist/lexicon-plugin-helpers.js +104 -0
  358. package/dist/lexicon-schema.js +136 -0
  359. package/dist/lexicon.js +130 -0
  360. package/dist/lifecycle/affected.js +224 -0
  361. package/dist/lifecycle/assert-live.js +110 -0
  362. package/dist/lifecycle/build-ledger-store.js +160 -0
  363. package/dist/lifecycle/build-ledger.js +155 -0
  364. package/dist/lifecycle/change-set.js +356 -0
  365. package/dist/lifecycle/converge-ledger.js +161 -0
  366. package/dist/lifecycle/deep-diff.js +233 -0
  367. package/dist/lifecycle/deep-observe.js +147 -0
  368. package/dist/lifecycle/digest.js +143 -0
  369. package/dist/lifecycle/disruption.js +135 -0
  370. package/dist/lifecycle/gate-applied.js +113 -0
  371. package/dist/lifecycle/gate-audit.d.ts +69 -2
  372. package/dist/lifecycle/gate-audit.d.ts.map +1 -1
  373. package/dist/lifecycle/gate-audit.js +415 -0
  374. package/dist/lifecycle/gate-ledger-select.js +89 -0
  375. package/dist/lifecycle/gate-ledger.d.ts +24 -0
  376. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  377. package/dist/lifecycle/gate-ledger.js +201 -0
  378. package/dist/lifecycle/gate-origin.js +117 -0
  379. package/dist/lifecycle/gate-pending.js +58 -0
  380. package/dist/lifecycle/git.js +1182 -0
  381. package/dist/lifecycle/identity.js +58 -0
  382. package/dist/lifecycle/index.js +26 -0
  383. package/dist/lifecycle/lease.js +283 -0
  384. package/dist/lifecycle/ledger-port.js +1 -0
  385. package/dist/lifecycle/legacy-digest.js +91 -0
  386. package/dist/lifecycle/live-diff.js +274 -0
  387. package/dist/lifecycle/local-note.js +15 -0
  388. package/dist/lifecycle/member-ledger.js +122 -0
  389. package/dist/lifecycle/observation-baseline.js +155 -0
  390. package/dist/lifecycle/observe.js +375 -0
  391. package/dist/lifecycle/oras-referrer-lookup.js +82 -0
  392. package/dist/lifecycle/override-ledger.js +54 -0
  393. package/dist/lifecycle/plan-digest.js +110 -0
  394. package/dist/lifecycle/plan-ledger.js +129 -0
  395. package/dist/lifecycle/receipt-plan.js +192 -0
  396. package/dist/lifecycle/release-ledger.js +155 -0
  397. package/dist/lifecycle/release-read.js +64 -0
  398. package/dist/lifecycle/replay.js +193 -0
  399. package/dist/lifecycle/rollback.js +102 -0
  400. package/dist/lifecycle/run-ledger.js +183 -0
  401. package/dist/lifecycle/scenario-eval.js +204 -0
  402. package/dist/lifecycle/scenario.js +214 -0
  403. package/dist/lifecycle/snapshot.js +239 -0
  404. package/dist/lifecycle/status.js +447 -0
  405. package/dist/lifecycle/symptoms.js +117 -0
  406. package/dist/lifecycle/teardown.js +255 -0
  407. package/dist/lifecycle/types.js +1 -0
  408. package/dist/lifecycle/unobserved-gate.js +33 -0
  409. package/dist/lifecycle/wave-plans.js +68 -0
  410. package/dist/lifecycle/work-item-id.js +36 -0
  411. package/dist/lifecycle/work-lease.js +393 -0
  412. package/dist/lint/component-checks.js +87 -0
  413. package/dist/lint/config.js +483 -0
  414. package/dist/lint/declarative.js +122 -0
  415. package/dist/lint/discover.d.ts.map +1 -1
  416. package/dist/lint/discover.js +138 -0
  417. package/dist/lint/engine.js +246 -0
  418. package/dist/lint/knowledge-checks.js +64 -0
  419. package/dist/lint/named-checks.js +22 -0
  420. package/dist/lint/output-checks.js +87 -0
  421. package/dist/lint/output-docs.js +163 -0
  422. package/dist/lint/parser.js +33 -0
  423. package/dist/lint/pipeline-change-gate.js +70 -0
  424. package/dist/lint/policy-import.d.ts +1 -1
  425. package/dist/lint/policy-import.d.ts.map +1 -1
  426. package/dist/lint/policy-import.js +62 -0
  427. package/dist/lint/policy-sandbox.js +86 -0
  428. package/dist/lint/policy.js +122 -0
  429. package/dist/lint/post-synth.js +87 -0
  430. package/dist/lint/presets/relaxed.json +26 -0
  431. package/dist/lint/presets/strict.json +24 -24
  432. package/dist/lint/receipt-checks.js +83 -0
  433. package/dist/lint/rule-loader.d.ts.map +1 -1
  434. package/dist/lint/rule-loader.js +89 -0
  435. package/dist/lint/rule-registry.js +86 -0
  436. package/dist/lint/rule.js +1 -0
  437. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.js +7 -0
  438. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.js +7 -0
  439. package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.js +9 -0
  440. package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.js +11 -0
  441. package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.js +9 -0
  442. package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.js +25 -0
  443. package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.js +8 -0
  444. package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.js +21 -0
  445. package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.js +8 -0
  446. package/dist/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.js +24 -0
  447. package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.js +17 -0
  448. package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.js +8 -0
  449. package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.js +18 -0
  450. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.js +20 -0
  451. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.js +8 -0
  452. package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.js +12 -0
  453. package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.js +16 -0
  454. package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.js +8 -0
  455. package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.js +12 -0
  456. package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.js +11 -0
  457. package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.js +11 -0
  458. package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.js +10 -0
  459. package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.js +16 -0
  460. package/dist/lint/rules/comp/comp001-publishes-never-applies.js +69 -0
  461. package/dist/lint/rules/comp/comp002-dangling-wiring-ref.js +84 -0
  462. package/dist/lint/rules/comp/comp003-mutating-no-rollback.js +103 -0
  463. package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.js +70 -0
  464. package/dist/lint/rules/comp/comp005-capability-kind-is-noun.js +109 -0
  465. package/dist/lint/rules/comp/comp006-shell-needs-reason.js +49 -0
  466. package/dist/lint/rules/comp/comp007-composition-sprawl.js +64 -0
  467. package/dist/lint/rules/comp/index.js +33 -0
  468. package/dist/lint/rules/comp/support.js +129 -0
  469. package/dist/lint/rules/composite-scope.js +51 -0
  470. package/dist/lint/rules/cor017-composite-name-match.js +93 -0
  471. package/dist/lint/rules/cor018-composite-prefer-lexicon-type.js +136 -0
  472. package/dist/lint/rules/cor021-env-literal-name.js +100 -0
  473. package/dist/lint/rules/cor022-receipt-leaf.js +118 -0
  474. package/dist/lint/rules/cor024-receipt-secret-pointer.js +199 -0
  475. package/dist/lint/rules/declarable-naming-convention.js +62 -0
  476. package/dist/lint/rules/evl001-non-literal-expression.js +66 -0
  477. package/dist/lint/rules/evl002-control-flow-resource.js +69 -0
  478. package/dist/lint/rules/evl003-dynamic-property-access.js +44 -0
  479. package/dist/lint/rules/evl004-spread-non-const.js +94 -0
  480. package/dist/lint/rules/evl005-resource-block-body.js +41 -0
  481. package/dist/lint/rules/evl007-invalid-siblings.js +105 -0
  482. package/dist/lint/rules/evl009-composite-no-constant.js +158 -0
  483. package/dist/lint/rules/evl010-composite-no-transform.js +59 -0
  484. package/dist/lint/rules/evl011-symbolic-in-template.js +106 -0
  485. package/dist/lint/rules/export-required.js +115 -0
  486. package/dist/lint/rules/file-declarable-limit.js +88 -0
  487. package/dist/lint/rules/flat-declarations.js +62 -0
  488. package/dist/lint/rules/index.js +90 -0
  489. package/dist/lint/rules/no-cyclic-declarable-ref.js +138 -0
  490. package/dist/lint/rules/no-redundant-type-import.js +76 -0
  491. package/dist/lint/rules/no-redundant-value-cast.js +41 -0
  492. package/dist/lint/rules/no-string-ref.js +59 -0
  493. package/dist/lint/rules/no-unused-declarable-import.js +75 -0
  494. package/dist/lint/rules/no-unused-declarable.js +142 -0
  495. package/dist/lint/rules/op/index.js +28 -0
  496. package/dist/lint/rules/op/ops012-activity-contract.js +54 -0
  497. package/dist/lint/rules/op/ops013-step-output-ref.js +88 -0
  498. package/dist/lint/rules/op/ops014-converge-rule-refusals.js +114 -0
  499. package/dist/lint/rules/op/ops015-gate-approval.js +45 -0
  500. package/dist/lint/rules/op/support.js +11 -0
  501. package/dist/lint/rules/op/sys010-key-over-plain-http.js +100 -0
  502. package/dist/lint/rules/property-kind.js +56 -0
  503. package/dist/lint/rules/single-concern-file.js +71 -0
  504. package/dist/lint/rules/sys001-no-literal-key.js +60 -0
  505. package/dist/lint/selectors.js +168 -0
  506. package/dist/lint/suppressions.js +129 -0
  507. package/dist/lint/typescript.js +17 -0
  508. package/dist/live-endpoint.js +113 -0
  509. package/dist/live-read-session.js +76 -0
  510. package/dist/lsp/lexicon-providers.js +163 -0
  511. package/dist/lsp/types.js +5 -0
  512. package/dist/managed-fields.js +293 -0
  513. package/dist/mcp/types.js +4 -0
  514. package/dist/notify-verify.js +0 -1
  515. package/dist/notify.js +0 -1
  516. package/dist/notify.schema.json +72 -0
  517. package/dist/observation.js +266 -0
  518. package/dist/okf-read.js +134 -0
  519. package/dist/okf.js +275 -0
  520. package/dist/op/__fixtures__/decide-stub-backend.js +125 -0
  521. package/dist/op/activities/activity-contracts.d.ts +1 -1
  522. package/dist/op/activities/activity-contracts.js +313 -0
  523. package/dist/op/activities/apply.js +582 -0
  524. package/dist/op/activities/build.js +18 -0
  525. package/dist/op/activities/change-coverage.js +40 -0
  526. package/dist/op/activities/change-set.d.ts +8 -3
  527. package/dist/op/activities/change-set.d.ts.map +1 -1
  528. package/dist/op/activities/change-set.js +67 -0
  529. package/dist/op/activities/converge.js +492 -0
  530. package/dist/op/activities/decide.js +211 -0
  531. package/dist/op/activities/env-teardown.js +110 -0
  532. package/dist/op/activities/factory.js +591 -0
  533. package/dist/op/activities/forge-pull-request.js +82 -0
  534. package/dist/op/activities/gh-host.js +78 -0
  535. package/dist/op/activities/guard-validate.js +165 -0
  536. package/dist/op/activities/http-check.js +40 -0
  537. package/dist/op/activities/index.js +59 -0
  538. package/dist/op/activities/lexicon-upgrade.js +629 -0
  539. package/dist/op/activities/lifecycle.js +109 -0
  540. package/dist/op/activities/pipeline-audit.js +147 -0
  541. package/dist/op/activities/policy.js +26 -0
  542. package/dist/op/activities/predict-behaviour.js +341 -0
  543. package/dist/op/activities/propose-upgrade.js +165 -0
  544. package/dist/op/activities/reconcile.d.ts +28 -16
  545. package/dist/op/activities/reconcile.d.ts.map +1 -1
  546. package/dist/op/activities/reconcile.js +1011 -0
  547. package/dist/op/activities/shell.js +118 -0
  548. package/dist/op/activities/source-release.js +97 -0
  549. package/dist/op/activities/source-rollback.js +165 -0
  550. package/dist/op/activities/teardown.js +17 -0
  551. package/dist/op/activities/util.js +6 -0
  552. package/dist/op/activities/wait.js +51 -0
  553. package/dist/op/activities/work-evidence.js +35 -0
  554. package/dist/op/activities/workflow-audit.js +133 -0
  555. package/dist/op/activity-contract-registry.js +106 -0
  556. package/dist/op/activity-contract.js +232 -0
  557. package/dist/op/activity-failure.js +31 -0
  558. package/dist/op/activity-profiles.js +129 -0
  559. package/dist/op/activity-registry.js +105 -0
  560. package/dist/op/activity-runtime.js +28 -0
  561. package/dist/op/builders.d.ts +1 -1
  562. package/dist/op/builders.d.ts.map +1 -1
  563. package/dist/op/builders.js +801 -0
  564. package/dist/op/change-signal.js +118 -0
  565. package/dist/op/composites/apply-op.js +151 -0
  566. package/dist/op/composites/behaviour-op.js +65 -0
  567. package/dist/op/composites/converge-op.js +141 -0
  568. package/dist/op/composites/index.js +19 -0
  569. package/dist/op/composites/lexicon-upgrade-op.js +107 -0
  570. package/dist/op/composites/pipeline-audit-op.js +50 -0
  571. package/dist/op/composites/reconcile-op.js +84 -0
  572. package/dist/op/composites/watch-op.js +69 -0
  573. package/dist/op/composites/workflow-audit-op.js +57 -0
  574. package/dist/op/converge-rule.js +205 -0
  575. package/dist/op/cron.js +146 -0
  576. package/dist/op/decide-backend.js +181 -0
  577. package/dist/op/decide-config.js +68 -0
  578. package/dist/op/decide-read-inputs.js +141 -0
  579. package/dist/op/discover.d.ts.map +1 -1
  580. package/dist/op/discover.js +213 -0
  581. package/dist/op/duration.js +21 -0
  582. package/dist/op/emulator-freshness.js +80 -0
  583. package/dist/op/emulator-lifecycle.js +269 -0
  584. package/dist/op/factory.js +83 -0
  585. package/dist/op/gate-approval.js +172 -0
  586. package/dist/op/gate-name.js +86 -0
  587. package/dist/op/gate-plan-context.js +167 -0
  588. package/dist/op/gate-point-run.js +67 -0
  589. package/dist/op/gate-point.js +111 -0
  590. package/dist/op/gate-resume-plan.js +155 -0
  591. package/dist/op/gate-resume.js +31 -0
  592. package/dist/op/gate-review.js +290 -0
  593. package/dist/op/gate-run-locator.js +85 -0
  594. package/dist/op/gate-summary.js +100 -0
  595. package/dist/op/gate-wait.js +56 -0
  596. package/dist/op/gate.js +449 -0
  597. package/dist/op/generate-pipeline.js +124 -0
  598. package/dist/op/index.js +51 -0
  599. package/dist/op/lifecycle-receipt-store.js +45 -0
  600. package/dist/op/local-executor.js +1164 -0
  601. package/dist/op/local-output.js +140 -0
  602. package/dist/op/op-ir.js +317 -0
  603. package/dist/op/op-verb-class.js +131 -0
  604. package/dist/op/op-waves-notify.js +136 -0
  605. package/dist/op/op-waves-run.d.ts +1 -1
  606. package/dist/op/op-waves-run.d.ts.map +1 -1
  607. package/dist/op/op-waves-run.js +1657 -0
  608. package/dist/op/op-waves.js +409 -0
  609. package/dist/op/operator.js +743 -0
  610. package/dist/op/receipt-store.js +94 -0
  611. package/dist/op/resource.js +23 -0
  612. package/dist/op/run-context.js +28 -0
  613. package/dist/op/run-live.js +256 -0
  614. package/dist/op/runtime.js +21 -0
  615. package/dist/op/runtimes/local.js +195 -0
  616. package/dist/op/source-archive.js +131 -0
  617. package/dist/op/step-output-ref.js +397 -0
  618. package/dist/op/steward-beside.js +169 -0
  619. package/dist/op/steward-points.js +138 -0
  620. package/dist/op/steward-turn.js +59 -0
  621. package/dist/op/steward.js +317 -0
  622. package/dist/op/types.js +25 -0
  623. package/dist/op/work-lease-decl.js +81 -0
  624. package/dist/op/work-lease-run.js +393 -0
  625. package/dist/override-gate.js +284 -0
  626. package/dist/owner-chain.js +74 -0
  627. package/dist/ownership.js +92 -0
  628. package/dist/params.js +61 -0
  629. package/dist/plan-summary.js +711 -0
  630. package/dist/point-decision.js +211 -0
  631. package/dist/pr-forge.js +810 -0
  632. package/dist/pr-loop.js +203 -0
  633. package/dist/project-codegen.js +191 -0
  634. package/dist/project-root.js +74 -0
  635. package/dist/project-validation.js +50 -0
  636. package/dist/provenance.js +157 -0
  637. package/dist/pseudo-parameter.js +40 -0
  638. package/dist/reconcile.js +450 -0
  639. package/dist/resource-attributes.js +33 -0
  640. package/dist/runtime-adapter.js +77 -0
  641. package/dist/runtime.js +66 -0
  642. package/dist/secret-materialization.js +153 -0
  643. package/dist/secret-provenance.js +250 -0
  644. package/dist/serializer-walker.js +112 -0
  645. package/dist/serializer.js +1 -0
  646. package/dist/sort.js +45 -0
  647. package/dist/stack-output.js +115 -0
  648. package/dist/telemetry-attribution.js +149 -0
  649. package/dist/terraform/__fixtures__/build-graph.js +63 -0
  650. package/dist/terraform/adopt-state.js +40 -0
  651. package/dist/terraform/aws-resources.js +384 -0
  652. package/dist/terraform/bridge.js +204 -0
  653. package/dist/terraform/carve-provider.js +155 -0
  654. package/dist/terraform/carve.js +138 -0
  655. package/dist/terraform/data-source-shape.js +57 -0
  656. package/dist/terraform/emit-source.js +36 -0
  657. package/dist/terraform/excise.js +123 -0
  658. package/dist/terraform/graduate.js +128 -0
  659. package/dist/terraform/graph.js +435 -0
  660. package/dist/terraform/hcl2json.js +60 -0
  661. package/dist/terraform/manifest.js +149 -0
  662. package/dist/terraform/parse.js +81 -0
  663. package/dist/terraform/providers/aws.js +146 -0
  664. package/dist/terraform/providers/gcp.js +294 -0
  665. package/dist/terraform/providers/index.js +17 -0
  666. package/dist/terraform/providers/kubernetes.js +253 -0
  667. package/dist/terraform/score.js +151 -0
  668. package/dist/terraform/state.js +67 -0
  669. package/dist/terraform/tier-map.js +74 -0
  670. package/dist/terraform/types.js +13 -0
  671. package/dist/terraform/unified-diff.js +132 -0
  672. package/dist/testing.js +295 -0
  673. package/dist/toml-emit.js +153 -0
  674. package/dist/toml-parse.js +355 -0
  675. package/dist/toml-utils.js +60 -0
  676. package/dist/toml.js +428 -0
  677. package/dist/ts-loader.d.ts +46 -0
  678. package/dist/ts-loader.d.ts.map +1 -0
  679. package/dist/ts-loader.js +103 -0
  680. package/dist/types.js +1 -0
  681. package/dist/utils.js +61 -0
  682. package/dist/validation.js +20 -0
  683. package/dist/vendor/js-yaml-load.js +1662 -0
  684. package/dist/workspace/__fixtures__/contract-repo.d.ts +7 -0
  685. package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
  686. package/dist/workspace/__fixtures__/contract-repo.js +119 -0
  687. package/dist/workspace/__fixtures__/decide-workspace.js +112 -0
  688. package/dist/workspace/__fixtures__/sessions.d.ts +1 -1
  689. package/dist/workspace/__fixtures__/sessions.d.ts.map +1 -1
  690. package/dist/workspace/__fixtures__/sessions.js +91 -0
  691. package/dist/workspace/__fixtures__/two-member-workspace.js +34 -0
  692. package/dist/workspace/agent-cli.js +99 -0
  693. package/dist/workspace/agent.schema.json +390 -0
  694. package/dist/workspace/answers-ledger.js +89 -0
  695. package/dist/workspace/box-cli.js +142 -0
  696. package/dist/workspace/box-factory-write.js +196 -0
  697. package/dist/workspace/box-factory-write.schema.json +342 -0
  698. package/dist/workspace/box-factory.js +88 -0
  699. package/dist/workspace/box-intent.js +126 -0
  700. package/dist/workspace/box-isolation.js +169 -0
  701. package/dist/workspace/box-listing-write.schema.json +204 -0
  702. package/dist/workspace/box-listing.js +298 -0
  703. package/dist/workspace/box-publish.js +352 -0
  704. package/dist/workspace/box-publish.schema.json +498 -0
  705. package/dist/workspace/box-services.js +39 -0
  706. package/dist/workspace/broker-protocol.js +359 -0
  707. package/dist/workspace/broker-protocol.schema.json +228 -0
  708. package/dist/workspace/change-set.schema.json +462 -0
  709. package/dist/workspace/changes-cli.js +56 -0
  710. package/dist/workspace/changes.js +446 -0
  711. package/dist/workspace/changes.schema.json +642 -0
  712. package/dist/workspace/chant-migrations/chud-lexicon-exit-fly-site.js +198 -0
  713. package/dist/workspace/chant-migrations/chud-lexicon-exit-live-names.js +155 -0
  714. package/dist/workspace/chant-migrations/chud-lexicon-exit-rollback.js +214 -0
  715. package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.js +180 -0
  716. package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-policy.js +99 -0
  717. package/dist/workspace/chant-migrations/chud-lexicon-exit.js +847 -0
  718. package/dist/workspace/chant-migrations.js +113 -0
  719. package/dist/workspace/check.schema.json +433 -0
  720. package/dist/workspace/checks/box-isolation.js +62 -0
  721. package/dist/workspace/checks/boxes.js +491 -0
  722. package/dist/workspace/checks/diagrams.js +104 -0
  723. package/dist/workspace/checks/generated.js +419 -0
  724. package/dist/workspace/checks/ledgers.js +212 -0
  725. package/dist/workspace/checks/links.js +191 -0
  726. package/dist/workspace/checks/live.js +100 -0
  727. package/dist/workspace/checks/pipelines.js +188 -0
  728. package/dist/workspace/checks/records.js +169 -0
  729. package/dist/workspace/checks.js +426 -0
  730. package/dist/workspace/ci-green-cli.js +125 -0
  731. package/dist/workspace/ci-green-forge.js +83 -0
  732. package/dist/workspace/ci-green-workflow.d.ts +3 -1
  733. package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
  734. package/dist/workspace/ci-green-workflow.js +202 -0
  735. package/dist/workspace/ci-green.js +325 -0
  736. package/dist/workspace/ci-last-green.schema.json +158 -0
  737. package/dist/workspace/class-data.d.ts +84 -0
  738. package/dist/workspace/class-data.d.ts.map +1 -0
  739. package/dist/workspace/class-data.js +238 -0
  740. package/dist/workspace/compose-graph.js +235 -0
  741. package/dist/workspace/compose-reports.js +146 -0
  742. package/dist/workspace/composites.js +264 -0
  743. package/dist/workspace/composites.schema.json +617 -0
  744. package/dist/workspace/conformance/__fixture__/app/package.json +7 -0
  745. package/dist/workspace/conformance/__fixture__/app/src/server.mjs +29 -0
  746. package/dist/workspace/conformance/__fixture__/decisions/decision.kind.mjs +54 -0
  747. package/dist/workspace/conformance/__fixture__/decisions/decision.schema.json +512 -0
  748. package/dist/workspace/conformance/__fixture__/decisions/fix-001-how-the-app-is-deployed.md +40 -0
  749. package/dist/workspace/conformance/__fixture__/delivery/chant.config.ts +7 -0
  750. package/dist/workspace/conformance/__fixture__/delivery/lexicon/index.ts +26 -0
  751. package/dist/workspace/conformance/__fixture__/delivery/package.json +7 -0
  752. package/dist/workspace/conformance/__fixture__/delivery/src/app.component.ts +14 -0
  753. package/dist/workspace/conformance/__fixture__/delivery/src/app.ts +4 -0
  754. package/dist/workspace/conformance/__fixtures__/reference-broker.js +205 -0
  755. package/dist/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +32 -0
  756. package/dist/workspace/conformance/__writer_fixture__/answers/answer.schema.json +135 -0
  757. package/dist/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
  758. package/dist/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
  759. package/dist/workspace/conformance/__writer_fixture__/decisions/points.json +228 -0
  760. package/dist/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
  761. package/dist/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
  762. package/dist/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +54 -0
  763. package/dist/workspace/conformance/__writer_fixture__/sessions/session.schema.json +289 -0
  764. package/dist/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
  765. package/dist/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
  766. package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +603 -0
  767. package/dist/workspace/conformance/broker.js +736 -0
  768. package/dist/workspace/conformance/index.js +673 -0
  769. package/dist/workspace/conformance/vitest.js +108 -0
  770. package/dist/workspace/conformance/writer.js +1080 -0
  771. package/dist/workspace/decide.js +879 -0
  772. package/dist/workspace/decision-points.schema.json +135 -135
  773. package/dist/workspace/declaration-write-cli.js +74 -0
  774. package/dist/workspace/declaration-write.js +238 -0
  775. package/dist/workspace/declaration.js +938 -0
  776. package/dist/workspace/declaration.schema.json +1413 -1413
  777. package/dist/workspace/declared-kinds.js +106 -0
  778. package/dist/workspace/environments.js +164 -0
  779. package/dist/workspace/evidence.schema.json +279 -0
  780. package/dist/workspace/export-cli.js +185 -0
  781. package/dist/workspace/export.js +499 -0
  782. package/dist/workspace/factory-rules.js +175 -0
  783. package/dist/workspace/generated-files.js +92 -0
  784. package/dist/workspace/glob.js +45 -0
  785. package/dist/workspace/graph-cache.js +352 -0
  786. package/dist/workspace/graph-cli.js +348 -0
  787. package/dist/workspace/graph.schema.json +1338 -0
  788. package/dist/workspace/identity-gate-rule.js +75 -0
  789. package/dist/workspace/identity.js +126 -0
  790. package/dist/workspace/import.js +283 -0
  791. package/dist/workspace/init.js +620 -0
  792. package/dist/workspace/intent-cli.js +263 -0
  793. package/dist/workspace/intent-joins.js +201 -0
  794. package/dist/workspace/intent-record.js +352 -0
  795. package/dist/workspace/intent-record.schema.json +864 -0
  796. package/dist/workspace/intent.js +1582 -0
  797. package/dist/workspace/intent.schema.json +2420 -0
  798. package/dist/workspace/json-edit.js +221 -0
  799. package/dist/workspace/jsonc.js +235 -0
  800. package/dist/workspace/kind-readers.js +103 -0
  801. package/dist/workspace/kinds.d.ts +3 -7
  802. package/dist/workspace/kinds.d.ts.map +1 -1
  803. package/dist/workspace/kinds.js +553 -0
  804. package/dist/workspace/lexicon-symbols.js +112 -0
  805. package/dist/workspace/lineage-adopt-cli.js +102 -0
  806. package/dist/workspace/lineage-adopt.js +360 -0
  807. package/dist/workspace/lineage-check.js +282 -0
  808. package/dist/workspace/lineage-cli.js +121 -0
  809. package/dist/workspace/lineage-hash-index.js +284 -0
  810. package/dist/workspace/lineage-init.js +507 -0
  811. package/dist/workspace/lineage-lock.js +387 -0
  812. package/dist/workspace/lineage-merge.js +45 -0
  813. package/dist/workspace/lineage-migrations.d.ts.map +1 -1
  814. package/dist/workspace/lineage-migrations.js +329 -0
  815. package/dist/workspace/lineage-provenance.js +36 -0
  816. package/dist/workspace/lineage-update.js +138 -0
  817. package/dist/workspace/lineage-upgrade-cli.js +131 -0
  818. package/dist/workspace/lineage-upgrade.js +889 -0
  819. package/dist/workspace/lineage-vendor.js +171 -0
  820. package/dist/workspace/lineage-version.js +128 -0
  821. package/dist/workspace/lineage-versions.js +275 -0
  822. package/dist/workspace/links.js +330 -0
  823. package/dist/workspace/ls-generated.js +95 -0
  824. package/dist/workspace/ls.js +277 -0
  825. package/dist/workspace/ls.schema.json +333 -0
  826. package/dist/workspace/member-commands.js +508 -0
  827. package/dist/workspace/member-handles.js +216 -0
  828. package/dist/workspace/member-pipeline.js +258 -0
  829. package/dist/workspace/member-run.js +117 -0
  830. package/dist/workspace/member-write.schema.json +193 -0
  831. package/dist/workspace/nested-graph.js +156 -0
  832. package/dist/workspace/nesting.js +38 -0
  833. package/dist/workspace/patch.js +301 -0
  834. package/dist/workspace/patch.schema.json +321 -0
  835. package/dist/workspace/pin-cli.js +55 -0
  836. package/dist/workspace/pin-integrity.js +100 -0
  837. package/dist/workspace/plan-summary.schema.json +155 -0
  838. package/dist/workspace/point-answer.schema.json +129 -129
  839. package/dist/workspace/points-cli.js +291 -0
  840. package/dist/workspace/points-write.schema.json +660 -0
  841. package/dist/workspace/points.js +521 -0
  842. package/dist/workspace/points.schema.json +916 -0
  843. package/dist/workspace/pr-report.schema.json +108 -0
  844. package/dist/workspace/principal-classes.d.ts +4 -11
  845. package/dist/workspace/principal-classes.d.ts.map +1 -1
  846. package/dist/workspace/principal-classes.js +162 -0
  847. package/dist/workspace/reason-codes.js +326 -0
  848. package/dist/workspace/record-assets.js +151 -0
  849. package/dist/workspace/record-decided.js +105 -0
  850. package/dist/workspace/record-sessions.js +96 -0
  851. package/dist/workspace/record-source.js +114 -0
  852. package/dist/workspace/records-amend.schema.json +284 -0
  853. package/dist/workspace/records-checkout.js +76 -0
  854. package/dist/workspace/records-cli.js +707 -0
  855. package/dist/workspace/records-close.js +116 -0
  856. package/dist/workspace/records-close.schema.json +278 -0
  857. package/dist/workspace/records-new.schema.json +202 -0
  858. package/dist/workspace/records-review.schema.json +367 -0
  859. package/dist/workspace/records-since.js +317 -0
  860. package/dist/workspace/records-since.schema.json +218 -0
  861. package/dist/workspace/records-write.js +1229 -0
  862. package/dist/workspace/records.js +1345 -0
  863. package/dist/workspace/records.schema.json +604 -0
  864. package/dist/workspace/reference-kinds/app/package.json +10 -0
  865. package/dist/workspace/reference-kinds/app/workspace-kinds.json +45 -0
  866. package/dist/workspace/returns.js +303 -0
  867. package/dist/workspace/root-refusal.js +75 -0
  868. package/dist/workspace/run-statement.schema.json +622 -0
  869. package/dist/workspace/runs-cli.js +584 -0
  870. package/dist/workspace/runs-write.schema.json +994 -0
  871. package/dist/workspace/runs.js +708 -0
  872. package/dist/workspace/runs.schema.json +1257 -0
  873. package/dist/workspace/runtimes.js +76 -0
  874. package/dist/workspace/session-kinds.js +83 -0
  875. package/dist/workspace/signers.schema.json +206 -0
  876. package/dist/workspace/source-block.js +125 -0
  877. package/dist/workspace/squash.js +177 -0
  878. package/dist/workspace/status-gates.js +162 -0
  879. package/dist/workspace/status-stewards.js +330 -0
  880. package/dist/workspace/status.js +514 -0
  881. package/dist/workspace/status.schema.json +998 -0
  882. package/dist/workspace/steward-index.js +191 -0
  883. package/dist/workspace/symbols.js +188 -0
  884. package/dist/workspace/template-manifest.js +227 -0
  885. package/dist/workspace/template-pins.js +115 -0
  886. package/dist/workspace/trailer-joins.js +65 -0
  887. package/dist/workspace/trailers.js +111 -0
  888. package/dist/workspace/tree.js +136 -0
  889. package/dist/workspace/trust/attestor.js +63 -0
  890. package/dist/workspace/trust/dsse.js +108 -0
  891. package/dist/workspace/trust/evidence-cli.js +175 -0
  892. package/dist/workspace/trust/evidence.js +161 -0
  893. package/dist/workspace/trust/gate-seal.js +226 -0
  894. package/dist/workspace/trust/policy.js +190 -0
  895. package/dist/workspace/trust/provenance.js +180 -0
  896. package/dist/workspace/trust/rotation.js +298 -0
  897. package/dist/workspace/trust/run-commits.js +101 -0
  898. package/dist/workspace/trust/run-statement.js +182 -0
  899. package/dist/workspace/trust/seal.js +272 -0
  900. package/dist/workspace/trust/signers-cli.js +152 -0
  901. package/dist/workspace/trust/ssh-commit.js +178 -0
  902. package/dist/workspace/trust/test-repo.js +118 -0
  903. package/dist/workspace/trust/trust-files.js +193 -0
  904. package/dist/workspace/trust/verify-cli.js +63 -0
  905. package/dist/workspace/trust/verify.js +192 -0
  906. package/dist/workspace/which-chant.js +141 -0
  907. package/dist/workspace/wip-cli.js +95 -0
  908. package/dist/workspace/wip-write.schema.json +504 -0
  909. package/dist/workspace/wip.js +631 -0
  910. package/dist/workspace/wip.schema.json +334 -0
  911. package/dist/workspace/work-cli.js +448 -0
  912. package/dist/workspace/work-evidence.js +122 -0
  913. package/dist/workspace/work-evidence.schema.json +222 -0
  914. package/dist/workspace/work-history.schema.json +421 -0
  915. package/dist/workspace/work-lease.schema.json +246 -0
  916. package/dist/workspace/work-size.js +77 -0
  917. package/dist/workspace/work.js +283 -0
  918. package/dist/workspace/workspace-kinds.schema.json +259 -259
  919. package/dist/workspace/workspace-principals.schema.json +53 -53
  920. package/dist/workspace/write-lock-cli.js +105 -0
  921. package/dist/workspace/write-lock.js +424 -0
  922. package/dist/workspace/write-lock.schema.json +172 -0
  923. package/dist/workspace/write-scope.js +484 -0
  924. package/dist/yaml.js +459 -0
  925. package/package.json +2 -2
  926. package/src/build.ts +8 -0
  927. package/src/change-set.test.ts +48 -0
  928. package/src/change-set.ts +52 -2
  929. package/src/ci-jobs.test.ts +49 -0
  930. package/src/ci-jobs.ts +515 -0
  931. package/src/cli/commands/check-lexicon-plugin.ts +2 -0
  932. package/src/cli/commands/lint.ts +3 -0
  933. package/src/cli/commands/migrate.ts +2 -0
  934. package/src/cli/compiled-cli.e2e.test.ts +165 -0
  935. package/src/cli/main.ts +121 -27
  936. package/src/cli/mcp/workspace-tools.ts +1 -1
  937. package/src/codegen/pinned-upgrade.ts +2 -0
  938. package/src/components/discover.ts +2 -0
  939. package/src/components/pr-pipeline.ts +3 -2
  940. package/src/components/sandbox/driver.ts +3 -1
  941. package/src/composite.ts +15 -3
  942. package/src/config-import.ts +3 -0
  943. package/src/discovery/collect.ts +15 -1
  944. package/src/discovery/fold-build-parity.test.ts +71 -0
  945. package/src/discovery/fold-import.ts +25 -127
  946. package/src/discovery/fold-project-provenance.test.ts +21 -4
  947. package/src/discovery/host-composite.ts +101 -0
  948. package/src/discovery/import.ts +2 -0
  949. package/src/discovery/index.ts +11 -1
  950. package/src/discovery/sandbox/driver.ts +3 -1
  951. package/src/gate-decision-bundle.test.ts +5 -4
  952. package/src/gate-decision-identity.test.ts +59 -6
  953. package/src/gate-decision.ts +81 -21
  954. package/src/lexicon-module.ts +3 -0
  955. package/src/lifecycle/gate-audit.test.ts +55 -1
  956. package/src/lifecycle/gate-audit.ts +116 -3
  957. package/src/lifecycle/gate-ledger.test.ts +20 -1
  958. package/src/lifecycle/gate-ledger.ts +33 -1
  959. package/src/lint/config.ts +1 -1
  960. package/src/lint/discover.ts +28 -8
  961. package/src/lint/policy-import.ts +4 -1
  962. package/src/lint/rule-loader.ts +2 -0
  963. package/src/op/activities/activity-contracts.ts +1 -1
  964. package/src/op/activities/change-set.ts +11 -3
  965. package/src/op/activities/lexicon-upgrade.test.ts +2 -0
  966. package/src/op/activities/reconcile.test.ts +62 -2
  967. package/src/op/activities/reconcile.ts +46 -22
  968. package/src/op/builders.ts +1 -1
  969. package/src/op/discover.ts +3 -0
  970. package/src/op/op-waves-run.ts +4 -3
  971. package/src/op/op-waves.test.ts +2 -0
  972. package/src/op/work-lease-run.test.ts +12 -4
  973. package/src/ts-loader.test.ts +23 -0
  974. package/src/ts-loader.ts +122 -0
  975. package/src/workspace/__fixtures__/contract-repo.ts +17 -1
  976. package/src/workspace/__fixtures__/sessions.ts +3 -3
  977. package/src/workspace/change-set.schema.json +5 -3
  978. package/src/workspace/chant-migrations/chud-lexicon-exit.ts +1 -1
  979. package/src/workspace/ci-green-workflow.test.ts +4 -4
  980. package/src/workspace/ci-green-workflow.ts +5 -2
  981. package/src/workspace/class-data.test.ts +64 -0
  982. package/src/workspace/class-data.ts +236 -0
  983. package/src/workspace/declaration.ts +1 -1
  984. package/src/workspace/kinds.ts +7 -36
  985. package/src/workspace/lineage-migrations.ts +2 -0
  986. package/src/workspace/points.ts +1 -1
  987. package/src/workspace/principal-classes.ts +12 -95
  988. package/src/workspace/records-formats.test.ts +7 -2
  989. package/src/workspace/records-sessions-write.test.ts +3 -3
  990. package/src/workspace/status-contract.e2e.test.ts +37 -0
  991. package/src/workspace/status-contract.test.ts +23 -21
@@ -0,0 +1,313 @@
1
+ /**
2
+ * A gate's decision for a plan digest, and the seal check it needs, for a
3
+ * tool that runs from one bundled file (#3763, decision #3756).
4
+ *
5
+ * `@intentius/chant/gate-decision` holds what a tool needs to decide a
6
+ * plan-bound gate the way chant's own wave gate does (`chant run wave`,
7
+ * `./op/op-waves-run.ts`) under each approval mode:
8
+ *
9
+ * - `ledger`: an approval of this digest on `chant/lifecycle`, newer than the
10
+ * gate's newest pending fact ({@link decideGateApproval}).
11
+ * - `sealed`: the same, counting only an approval whose seal verifies for its
12
+ * approver against the signers file at base ({@link gateSignersAt},
13
+ * {@link gateSealRefusal}). The seal is checked with node:crypto, so the job
14
+ * needs no ssh-keygen.
15
+ * - `pr-review`: the same as `ledger`, or else the merged pull request's
16
+ * approving review, when its head planned this digest
17
+ * ({@link reviewApproval}).
18
+ *
19
+ * A gate the declaration at base names under `identity.gates` counts only a
20
+ * sealed approval from its class: {@link identityGateAdmissionAt} reads that
21
+ * rule from a bare clone at base, with the principal classes the pinned
22
+ * packages supply read as data (#3888), and judges by `admitApprover`, the
23
+ * function chant's `gateAdmission` judges by (#3862); pass its `refuses` to
24
+ * {@link decideGateApproval}.
25
+ *
26
+ * With `spend` (#3784), an approval a wave already applied under is spent and
27
+ * counts for nothing, as terragucci's wave gate has it: the caller hands in
28
+ * the lines of `_gates/<op>/applied.jsonl` ({@link parseAppliedGateLines}).
29
+ *
30
+ * The module reads the ledger lines and the review it is handed; reading
31
+ * them is the caller's. It imports no TypeScript, esbuild, zod, ajv, lint,
32
+ * fold or codegen module, no package's code, and none of chant's git ledger
33
+ * code, which
34
+ * `gate-decision-bundle.test.ts` holds it to. Its rules are chant's own:
35
+ * `./lifecycle/gate-ledger-select.ts` is what `evaluateGate` decides by, and
36
+ * `gate-decision.test.ts` decides the same ledgers both ways.
37
+ */
38
+ import { spawnSync } from "node:child_process";
39
+ import { readFileSync } from "node:fs";
40
+ import { join, posix } from "node:path";
41
+ import { isPendingGateExpired, latestPendingGate, latestResolutionForPlan, } from "./lifecycle/gate-ledger-select.js";
42
+ import { samePlanDigest } from "./lifecycle/plan-digest.js";
43
+ import { isApprovalSpent } from "./lifecycle/gate-applied.js";
44
+ import { gateSealRefusal } from "./workspace/trust/gate-seal.js";
45
+ import { DEFAULT_SIGNERS_PATH, TRUST_CONFIG_PATH, parseAllowedSigners, trustConfigProblems, } from "./workspace/trust/trust-files.js";
46
+ import { parseJsonText } from "./workspace/jsonc.js";
47
+ import { CORE_CLASSES, admitApprover } from "./workspace/identity-gate-rule.js";
48
+ import { diskFiles, findInstalledPackage, mergePinClasses, parseClassDataByHand, readClassFiles } from "./workspace/class-data.js";
49
+ export { GATE_APPROVAL_SOURCES } from "./op/op-waves.js";
50
+ export { isPendingGateExpired, latestPendingGate, latestResolutionForPlan, latestResolutionSince, } from "./lifecycle/gate-ledger-select.js";
51
+ export { GATE_SEAL_NAMESPACE, gateSealPayload, gateSealRefusal, sshKeyFingerprint, verifySshSignatureWith, } from "./workspace/trust/gate-seal.js";
52
+ export { DEFAULT_SIGNERS_PATH, TRUST_CONFIG_PATH, parseAllowedSigners, trustConfigProblems, } from "./workspace/trust/trust-files.js";
53
+ export { CORE_CLASSES, admitApprover, grantedClasses, } from "./workspace/identity-gate-rule.js";
54
+ export { appliedGateApplies, appliedGatePath, isApprovalSpent, parseAppliedGateLines, } from "./lifecycle/gate-applied.js";
55
+ // ── reading at base ──────────────────────────────────────────────────────
56
+ function git(repo, args) {
57
+ return spawnSync("git", args, { cwd: repo, encoding: "utf-8" });
58
+ }
59
+ /** A file's text at `base`, or undefined when `base` holds no file at `path`. */
60
+ function showAt(repo, base, path) {
61
+ const r = git(repo, ["cat-file", "blob", `${base}:${path}`]);
62
+ return r.status === 0 ? r.stdout : undefined;
63
+ }
64
+ /**
65
+ * The commit a gate's rule is read at when the default branch applies its
66
+ * own commit: the first parent of HEAD, the branch as it stood before the
67
+ * merge, so a merge that adds a signer or drops a gate does not judge its own
68
+ * apply. A shallow checkout fetches that one commit from `origin`. A root
69
+ * commit has no parent and is its own base. Throws when it cannot be read.
70
+ */
71
+ export function baseCommit(repo) {
72
+ const head = git(repo, ["rev-parse", "--verify", "-q", "HEAD^{commit}"]);
73
+ const sha = head.stdout.trim();
74
+ if (head.status !== 0 || !sha)
75
+ throw new Error(`${repo} has no commit checked out, so the gate cannot be decided`);
76
+ // The commit object's first `parent` line: a shallow clone keeps it even when it lacks the parent itself.
77
+ const header = git(repo, ["cat-file", "commit", sha]).stdout.split("\n\n")[0] ?? "";
78
+ const parent = /^parent ([0-9a-f]{40,64})$/m.exec(header)?.[1];
79
+ if (!parent)
80
+ return sha;
81
+ const has = () => git(repo, ["cat-file", "-e", `${parent}^{commit}`]).status === 0;
82
+ if (!has())
83
+ git(repo, ["fetch", "-q", "--depth=1", "origin", parent]);
84
+ if (!has())
85
+ throw new Error(`cannot fetch ${parent.slice(0, 12)}, the commit before this one, so the gate cannot be decided`);
86
+ return parent;
87
+ }
88
+ /** The signers and role grants at `base`, as chant's trust policy reads them. */
89
+ function trustAt(repo, base) {
90
+ const off = (problems) => ({ signers: { base, signersPath: DEFAULT_SIGNERS_PATH, active: false, signers: [], problems }, roles: {} });
91
+ const configText = showAt(repo, base, TRUST_CONFIG_PATH);
92
+ let signersPath = DEFAULT_SIGNERS_PATH;
93
+ let roles = {};
94
+ if (configText !== undefined) {
95
+ let raw;
96
+ try {
97
+ raw = JSON.parse(configText);
98
+ }
99
+ catch (err) {
100
+ return off([`${TRUST_CONFIG_PATH} is not JSON: ${err instanceof Error ? err.message : String(err)}`]);
101
+ }
102
+ const problems = trustConfigProblems(raw);
103
+ if (problems.length > 0)
104
+ return off([`${TRUST_CONFIG_PATH} is invalid: ${problems.join("; ")}`]);
105
+ signersPath = raw.signers ?? DEFAULT_SIGNERS_PATH;
106
+ roles = raw.roles ?? {};
107
+ }
108
+ const text = showAt(repo, base, signersPath);
109
+ return { signers: { base, signersPath, active: text !== undefined, signers: text === undefined ? [] : parseAllowedSigners(text).signers, problems: [] }, roles };
110
+ }
111
+ /**
112
+ * The signers at `base`: the file `.chant/trust.json` names there, else
113
+ * `.chant/allowed_signers`, read as chant's trust policy reads it. A
114
+ * trust.json that is not valid (`trustConfigProblems`) turns attestation
115
+ * off, as it does in chant, so a sealed gate passes nothing. `base` is a
116
+ * commit the repository holds, such as {@link baseCommit}'s answer.
117
+ */
118
+ export function gateSignersAt(repo, base) {
119
+ return trustAt(repo, base).signers;
120
+ }
121
+ /** The declaration at `base`, parsed, or null when there is none. Throws when it cannot be parsed. */
122
+ function declarationAt(repo, base) {
123
+ for (const file of ["chant.workspace.json", "chant.workspace.jsonc"]) {
124
+ const text = showAt(repo, base, file);
125
+ if (text === undefined)
126
+ continue;
127
+ const parsed = parseJsonText(text, { jsonc: file.endsWith(".jsonc") });
128
+ if (!parsed.ok)
129
+ throw new Error(`${file} at base is not valid JSON (${parsed.message}), so the gate cannot be decided`);
130
+ return { file, value: parsed.value };
131
+ }
132
+ return null;
133
+ }
134
+ function identityGatesOf(declaration) {
135
+ const gates = declaration?.identity?.gates ?? {};
136
+ return Object.entries(gates).map(([gate, entry]) => ({ gate, class: typeof entry?.class === "string" ? entry.class : null }));
137
+ }
138
+ /**
139
+ * The gates `chant.workspace.json` (or `.jsonc`) at `base` names under
140
+ * `identity.gates`: each counts only a sealed approval, from its class when
141
+ * it names one. {@link identityGateAdmissionAt} judges an approval by one.
142
+ * Empty when there is no declaration at base. Throws when the declaration
143
+ * there cannot be parsed, since the gate cannot be decided.
144
+ */
145
+ export function identityGatesAt(repo, base) {
146
+ const declaration = declarationAt(repo, base);
147
+ return declaration === null ? [] : identityGatesOf(declaration.value);
148
+ }
149
+ /**
150
+ * Read the classes each pin supplies, as chant's `gateAdmission(cwd, gate,
151
+ * base)` reads them: a path pin's `./workspace-principals` file from `base`
152
+ * itself, so a change can't remap a class by editing its own copy of the
153
+ * plugin; a package pin's from the package installed under `packages` (its
154
+ * `node_modules` or a parent's), which must be at the pinned version. Reads
155
+ * data only and imports no package.
156
+ */
157
+ function pinnedClassesAt(repo, base, pins, packages) {
158
+ const reads = [];
159
+ const unread = [];
160
+ (Array.isArray(pins) ? pins : []).forEach((raw, i) => {
161
+ const pin = (raw !== null && typeof raw === "object" ? raw : {});
162
+ if (typeof pin.path === "string" && pin.path) {
163
+ const dir = posix.normalize(pin.path);
164
+ const files = (path) => showAt(repo, base, dir === "." ? path : posix.join(dir, path));
165
+ reads.push({ pin: i, source: pin.path, read: readClassFiles(files, pin.path, parseClassDataByHand) });
166
+ return;
167
+ }
168
+ if (typeof pin.package !== "string" || !pin.package)
169
+ return;
170
+ const dir = findInstalledPackage(pin.package, packages);
171
+ if (!dir) {
172
+ unread.push(`${pin.package} is not installed under ${packages}`);
173
+ return;
174
+ }
175
+ let installed;
176
+ try {
177
+ installed = JSON.parse(readFileSync(join(dir, "package.json"), "utf-8")).version;
178
+ }
179
+ catch {
180
+ installed = undefined;
181
+ }
182
+ if (typeof pin.version === "string" && pin.version && installed !== pin.version) {
183
+ unread.push(`${pin.package} is pinned at ${pin.version}, and ${String(installed ?? "an unknown version")} is installed under ${packages}`);
184
+ return;
185
+ }
186
+ reads.push({ pin: i, source: pin.package, read: readClassFiles(diskFiles(dir), pin.package, parseClassDataByHand) });
187
+ });
188
+ return { classes: mergePinClasses(reads).classes, unread };
189
+ }
190
+ /** The core classes whose members no domain class can change: every one but `human`, which is the principals in no other class. */
191
+ const PIN_FREE = new Set(CORE_CLASSES.filter((c) => c.role !== null).map((c) => c.name));
192
+ /**
193
+ * The `identity.gates` rule for `gate` at `base`, or null when the
194
+ * declaration there names none: what chant's `gateAdmission(cwd, gate, base)`
195
+ * answers, read from a bare clone. An approval counts when its seal verifies
196
+ * for its approver against the signers at base and, when the gate names a
197
+ * class, the role grants in `.chant/trust.json` at base put the approver in
198
+ * it. Both judge with the same function ({@link admitApprover}).
199
+ *
200
+ * The classes are the four core ones, then the domain classes the
201
+ * declaration's pins supply, in pin order (#3888), read as chant reads them:
202
+ * a path pin's `./workspace-principals` file at `base`, and a package pin's
203
+ * from the package installed under `packages` (default `repo`) at the
204
+ * pinned version. A bare clone has no `node_modules`, so a caller that reads
205
+ * one passes the directory its packages are installed under. Only data is
206
+ * read; no package is imported. `classes`, when given, stands for every
207
+ * domain class instead and no pin is read.
208
+ *
209
+ * When a pin can't be read (its package is not installed, or not at the
210
+ * pinned version), a gate whose class it could change (a domain class, or
211
+ * `human`) refuses every approval and says which pins were not read; a gate
212
+ * naming `agent`, `runner` or `service`, or no class, is judged as usual.
213
+ * Throws when the declaration at base cannot be parsed.
214
+ */
215
+ export function identityGateAdmissionAt(repo, base, gate, opts = {}) {
216
+ const declaration = declarationAt(repo, base);
217
+ const requirement = declaration === null ? undefined : identityGatesOf(declaration.value).find((g) => g.gate === gate);
218
+ if (!requirement)
219
+ return null;
220
+ const { signers, roles } = trustAt(repo, base);
221
+ const pins = declaration.value.pins;
222
+ const pinned = opts.classes ? { classes: opts.classes, unread: [] } : pinnedClassesAt(repo, base, pins, opts.packages ?? repo);
223
+ const want = requirement.class;
224
+ if (want !== null && !PIN_FREE.has(want) && pinned.unread.length > 0) {
225
+ const reason = `identity.gates.${gate} names the class ${want}, and the pins in ${declaration.file} at base could not all be read, so no approval can show it is in that class: ${pinned.unread.join("; ")}`;
226
+ return { requirement, refuses: () => reason };
227
+ }
228
+ const rule = { gate, class: want, signers, roles, classes: [...CORE_CLASSES, ...pinned.classes] };
229
+ return { requirement, refuses: (a) => admitApprover(rule, a) };
230
+ }
231
+ /**
232
+ * Whether the merged pull request's review approves `digest` (#3684): a
233
+ * writer other than its author approved its head, and the head planned this
234
+ * digest (`headDigest`, from the plans `chant run wave --record-plans`
235
+ * recorded for the head; undefined when none were). Reading the review and
236
+ * the plans is the caller's; under `pr-review` the caller records the
237
+ * approval on the ledger when this approves.
238
+ */
239
+ export function reviewApproval(merged, headDigest, digest) {
240
+ const seen = { pr: merged.pr, head: merged.head, ...(merged.url ? { url: merged.url } : {}) };
241
+ if (merged.approvers.length === 0) {
242
+ const why = merged.refused.length > 0 ? merged.refused.join("; ") : "nobody approved it";
243
+ return { approved: false, review: { ...seen, reason: `no writer other than its author approved the head of #${merged.pr}: ${why}` } };
244
+ }
245
+ if (headDigest === undefined) {
246
+ return {
247
+ approved: false,
248
+ review: { ...seen, approvers: merged.approvers, reason: `no plans are recorded for the head ${merged.head.slice(0, 12)} of #${merged.pr} (its pipeline runs \`chant run wave --record-plans\`)` },
249
+ };
250
+ }
251
+ if (headDigest !== digest) {
252
+ return {
253
+ approved: false,
254
+ review: { ...seen, approvers: merged.approvers, reason: `the plan moved after the review: the head planned ${headDigest}, and the merge plans ${digest}` },
255
+ };
256
+ }
257
+ return { approved: true, review: { ...seen, approvers: merged.approvers } };
258
+ }
259
+ const EPOCH = new Date(0).toISOString();
260
+ /**
261
+ * Decide a plan-bound gate against its ledger lines, as chant's wave gate
262
+ * does: an approval counts when it names this gate and digest (and
263
+ * environment, when set), is newer than the gate's newest pending fact, and
264
+ * passes the mode's rule: any under `ledger` and `pr-review`, a verified seal
265
+ * under `sealed`. With none, `pr-review` takes the review's answer. Writes
266
+ * nothing: recording a pending fact, or the review's approval, is the
267
+ * caller's.
268
+ */
269
+ export function decideGateApproval(input) {
270
+ const { gate, planDigest, environment: env } = input;
271
+ const mode = input.mode ?? "ledger";
272
+ const pending = env === undefined ? input.ledger.pending : input.ledger.pending.filter((p) => p.environment === env);
273
+ const mine = (env === undefined ? input.ledger.resolutions : input.ledger.resolutions.filter((r) => r.environment === undefined || r.environment === env)).filter((r) => r.gate === gate);
274
+ const sealed = mode === "sealed";
275
+ const noSigners = { base: null, signersPath: DEFAULT_SIGNERS_PATH, active: false, signers: [], problems: ["no signers were read for this sealed gate"] };
276
+ const why = (r) => input.refuses?.(r) ?? (sealed ? gateSealRefusal(input.signers ?? noSigners, r) : null);
277
+ const standingFact = latestPendingGate(pending, gate);
278
+ const since = standingFact?.timestamp ?? EPOCH;
279
+ const counted = [];
280
+ const uncounted = [];
281
+ let spent;
282
+ for (const r of mine) {
283
+ if (input.spend && isApprovalSpent(input.ledger.applied ?? [], r)) {
284
+ if (new Date(r.timestamp).getTime() >= new Date(since).getTime() && (!spent || new Date(r.timestamp).getTime() >= new Date(spent.timestamp).getTime()))
285
+ spent = r;
286
+ continue;
287
+ }
288
+ const reason = why(r);
289
+ if (reason === null)
290
+ counted.push(r);
291
+ else if (samePlanDigest(r.planDigest, planDigest) && new Date(r.timestamp).getTime() >= new Date(since).getTime())
292
+ uncounted.push({ resolution: r, reason });
293
+ }
294
+ const found = latestResolutionForPlan(counted, gate, since, planDigest);
295
+ if (found.resolution)
296
+ return { status: "approved", via: "ledger", resolution: found.resolution };
297
+ const reviewSpent = input.spend === true && input.review?.approved === true &&
298
+ isApprovalSpent(input.ledger.applied ?? [], { gate, planDigest, review: { ...(input.review.review.head ? { head: input.review.review.head } : {}) } });
299
+ if (mode === "pr-review" && input.review?.approved && !reviewSpent)
300
+ return { status: "approved", via: "pr-review", review: input.review.review };
301
+ const now = input.now ?? new Date().toISOString();
302
+ const standing = standingFact && !isPendingGateExpired(standingFact, now) && samePlanDigest(standingFact.planDigest, planDigest) ? standingFact : undefined;
303
+ return {
304
+ status: "waiting",
305
+ ...(standing ? { standing } : {}),
306
+ ...(found.mismatched ? { mismatched: found.mismatched } : {}),
307
+ uncounted: uncounted.sort((a, b) => new Date(a.resolution.timestamp).getTime() - new Date(b.resolution.timestamp).getTime()),
308
+ ...(mode === "pr-review" && input.review
309
+ ? { review: reviewSpent ? { ...input.review.review, reason: `a wave already applied this digest under the review of ${input.review.review.head?.slice(0, 12) ?? "its head"}, so the review is spent` } : input.review.review }
310
+ : {}),
311
+ ...(spent ? { spent } : {}),
312
+ };
313
+ }
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Resume the job that waits at a gate (#3683), bundle-safe (#3854).
3
+ *
4
+ * A CI job that reaches a gate nobody approved records a pending fact on
5
+ * `chant/lifecycle` and exits 3. Nothing re-runs it when the approval lands,
6
+ * because a push to the ledger branch starts no pipeline. This module closes
7
+ * that loop through the forge's API.
8
+ *
9
+ * When the job runs in CI, the pending fact it records carries a
10
+ * {@link GateRunLocator}, read from the job's environment by
11
+ * {@link resolveGateRunLocator}: which forge, the API base, the repository,
12
+ * the run, and what the forge needs to start it again. After an approval,
13
+ * {@link resumeGateRun} starts it again:
14
+ *
15
+ * | Forge | Call | Token |
16
+ * |---|---|---|
17
+ * | GitHub | `POST /repos/{repo}/actions/runs/{run}/rerun-failed-jobs` | `actions: write` (the job's `GITHUB_TOKEN` with that permission, or a fine-grained token with Actions read and write) |
18
+ * | GitLab | `POST /projects/{id}/jobs/{job}/retry` | a project or personal access token with the `api` scope and the Developer role; `CI_JOB_TOKEN` cannot retry jobs |
19
+ * | Forgejo | `POST /repos/{repo}/actions/workflows/{file}/dispatches` on the run's branch | a token with the `write:repository` scope; Forgejo has no API to re-run a run, so it starts a new run of the workflow |
20
+ *
21
+ * GitHub re-runs the failed job and the jobs that need it, at the same
22
+ * commit. GitLab retries the job, and the jobs it skipped run after it. A
23
+ * Forgejo dispatch runs the whole workflow again at the branch's head, so the
24
+ * jobs before the gate run again too; they must be safe to repeat (a wave
25
+ * whose runs already applied plans nothing and applies nothing new).
26
+ *
27
+ * Resuming approves nothing. The resumed job decides the gate again from the
28
+ * ledger, so resuming a run whose approval does not count only makes it wait
29
+ * again. {@link resumeGateRun} skips a run that is still going, that ended
30
+ * well, or that was already resumed (a later GitHub attempt, a newer GitLab
31
+ * job of the same name, a newer Forgejo run of the workflow), so a scheduled
32
+ * resume job can call it every few minutes without starting a run twice.
33
+ *
34
+ * This module imports no workspace, ledger, schema or git code, so a product
35
+ * that ships one bundled file (terragucci) can import it as
36
+ * `@intentius/chant/gate-resume-run` and resume a job in process. Which
37
+ * approval answers a pending fact is `./op/gate-resume.ts`'s
38
+ * `resolutionAnswering`, which reads the gate's quorum rules and does pull the
39
+ * workspace in; that module re-exports everything here.
40
+ */
41
+ import { ForgeApiError } from "./pr-forge.js";
42
+ export { isGateRunLocator, resolveGateRunLocator } from "./op/gate-run-locator.js";
43
+ const trimSlash = (s) => s.replace(/\/+$/, "");
44
+ const isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
45
+ function client(base, headers, fetchImpl) {
46
+ return async (method, path, body) => {
47
+ const url = `${trimSlash(base)}${path}`;
48
+ const res = await fetchImpl(url, {
49
+ method,
50
+ headers: { ...headers, ...(body !== undefined ? { "Content-Type": "application/json" } : {}) },
51
+ ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
52
+ });
53
+ const text = await res.text();
54
+ if (!res.ok)
55
+ throw new ForgeApiError(method, url, res.status, text);
56
+ if (!text)
57
+ return null;
58
+ try {
59
+ return JSON.parse(text);
60
+ }
61
+ catch {
62
+ return text;
63
+ }
64
+ };
65
+ }
66
+ /**
67
+ * Start the job a pending fact's locator names again, or say why not. Throws
68
+ * {@link ForgeApiError} when the forge refuses a call, such as a token
69
+ * without the access the table in the module doc lists.
70
+ */
71
+ export async function resumeGateRun(loc, opts) {
72
+ const fetchImpl = opts.fetch ?? globalThis.fetch;
73
+ const url = loc.url ? { url: loc.url } : {};
74
+ const skip = (reason) => ({ status: "skipped", forge: loc.forge, reason, ...url });
75
+ const wouldResume = (how) => ({ status: "would-resume", forge: loc.forge, how: `would ${how}`, ...url });
76
+ if (loc.forge === "github") {
77
+ const call = client(loc.api, { Authorization: `Bearer ${opts.token}`, Accept: "application/vnd.github+json" }, fetchImpl);
78
+ const path = `/repos/${loc.repo}/actions/runs/${loc.run}`;
79
+ const run = await call("GET", path);
80
+ if (!isObject(run))
81
+ throw new Error(`GET ${path} returned no run`);
82
+ if (run.status !== "completed")
83
+ return skip(`run ${loc.run} is ${String(run.status)}, not finished`);
84
+ const attempt = typeof run.run_attempt === "number" ? run.run_attempt : undefined;
85
+ if (loc.attempt !== undefined && attempt !== undefined && attempt > loc.attempt) {
86
+ return skip(`run ${loc.run} was already re-run (attempt ${attempt}; attempt ${loc.attempt} waited)`);
87
+ }
88
+ if (run.conclusion === "success")
89
+ return skip(`run ${loc.run} succeeded`);
90
+ if (opts.dryRun)
91
+ return wouldResume(`re-run the failed jobs of run ${loc.run}`);
92
+ await call("POST", `${path}/rerun-failed-jobs`, {});
93
+ return { status: "resumed", forge: "github", how: `re-ran the failed jobs of run ${loc.run}`, ...url };
94
+ }
95
+ if (loc.forge === "gitlab") {
96
+ const call = client(loc.api, { "PRIVATE-TOKEN": opts.token }, fetchImpl);
97
+ const project = `/projects/${encodeURIComponent(decodeURIComponent(loc.repo))}`;
98
+ const job = await call("GET", `${project}/jobs/${loc.job}`);
99
+ if (!isObject(job))
100
+ throw new Error(`GET ${project}/jobs/${loc.job} returned no job`);
101
+ const status = String(job.status);
102
+ if (status === "success")
103
+ return skip(`job ${loc.job} succeeded`);
104
+ if (!["failed", "canceled", "skipped"].includes(status))
105
+ return skip(`job ${loc.job} is ${status}, not finished`);
106
+ const name = loc.jobName ?? (typeof job.name === "string" ? job.name : undefined);
107
+ if (name) {
108
+ // The pipeline's jobs list leaves retried jobs out, so the job of this name is its newest try.
109
+ const jobs = await call("GET", `${project}/pipelines/${loc.run}/jobs?per_page=100`);
110
+ const newest = Array.isArray(jobs) ? jobs.find((j) => isObject(j) && j.name === name) : undefined;
111
+ if (isObject(newest) && String(newest.id) !== String(loc.job)) {
112
+ return skip(`job ${loc.job} (${name}) was already retried as job ${String(newest.id)}`);
113
+ }
114
+ }
115
+ if (opts.dryRun)
116
+ return wouldResume(`retry job ${loc.job}`);
117
+ const retried = await call("POST", `${project}/jobs/${loc.job}/retry`);
118
+ const id = isObject(retried) && retried.id !== undefined ? ` as job ${String(retried.id)}` : "";
119
+ return { status: "resumed", forge: "gitlab", how: `retried job ${loc.job}${id}`, ...url };
120
+ }
121
+ const call = client(loc.api, { Authorization: `token ${opts.token}`, Accept: "application/json" }, fetchImpl);
122
+ const repo = `/repos/${loc.repo}`;
123
+ const run = await call("GET", `${repo}/actions/runs/${loc.run}`);
124
+ if (!isObject(run))
125
+ throw new Error(`GET ${repo}/actions/runs/${loc.run} returned no run`);
126
+ const status = String(run.status);
127
+ if (status === "success")
128
+ return skip(`run ${loc.run} succeeded`);
129
+ if (["waiting", "running", "blocked", "unknown"].includes(status))
130
+ return skip(`run ${loc.run} is ${status}, not finished`);
131
+ const listed = await call("GET", `${repo}/actions/runs?workflow_id=${encodeURIComponent(loc.workflow)}&limit=50`);
132
+ const runs = isObject(listed) && Array.isArray(listed.workflow_runs) ? listed.workflow_runs : Array.isArray(listed) ? listed : [];
133
+ // Forgejo reports `created` in whole seconds.
134
+ const since = opts.since ? Math.floor(new Date(opts.since).getTime() / 1000) * 1000 : undefined;
135
+ const later = runs.find((r) => isObject(r) && Number(r.id) > Number(loc.run) &&
136
+ (r.prettyref === undefined || r.prettyref === loc.ref) &&
137
+ (since === undefined || (typeof r.created === "string" && new Date(r.created).getTime() >= since)));
138
+ if (isObject(later))
139
+ return skip(`run ${String(later.id)} of ${loc.workflow} started after the approval`);
140
+ if (opts.dryRun)
141
+ return wouldResume(`dispatch ${loc.workflow} on ${loc.ref}`);
142
+ await call("POST", `${repo}/actions/workflows/${encodeURIComponent(loc.workflow)}/dispatches`, { ref: loc.ref });
143
+ return { status: "resumed", forge: "forgejo", how: `dispatched ${loc.workflow} on ${loc.ref}`, ...url };
144
+ }
145
+ /**
146
+ * The token a resume uses: `CHANT_FORGE_TOKEN`, else the forge's own
147
+ * (`GITHUB_TOKEN` or `GH_TOKEN` on GitHub and Forgejo, `GITLAB_TOKEN` on
148
+ * GitLab), the same order the pull-request loop reads (`../pr-forge.ts`).
149
+ */
150
+ export function resumeTokenFromEnv(forge, env = process.env) {
151
+ if (env.CHANT_FORGE_TOKEN)
152
+ return env.CHANT_FORGE_TOKEN;
153
+ return forge === "gitlab" ? env.GITLAB_TOKEN : env.GITHUB_TOKEN ?? env.GH_TOKEN;
154
+ }
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Gated waves (#3049): one change rolled out across many roots, a wave at a
3
+ * time, each wave behind its own gate bound to that wave's set digest.
4
+ *
5
+ * `chant components fan-out --wave-gate` is the runner. This module holds the
6
+ * parts that need no runner: how a set of roots is cut into waves, what a
7
+ * wave's digest is, what its gate is called, and what the attempt record says
8
+ * about each wave. They are kept apart from the runner because terragucci
9
+ * calls them from its CI stages as one bundled file with no TypeScript
10
+ * toolchain (#3421). Everything here imports `./change-set` and nothing else,
11
+ * and `gated-waves-bundle.test.ts` holds that.
12
+ *
13
+ * ## The set digest
14
+ *
15
+ * A wave's digest is {@link changeSetDigest} over its members' `{ member,
16
+ * planDigest }` pairs, the function #3181's change-set document uses. A
17
+ * terraform-family member is named after its root, so this is the issue's
18
+ * `jcs1-sha256` over sorted `{ root, planDigest }`, and a wave's digest equals
19
+ * the change-set digest of the wave's members. Each member's plan digest is
20
+ * the one a gate on that root alone binds (`terraformPlanDigest`, #2300), so a
21
+ * one-root wave and a one-root `TerraformApplyOp` approve the same value.
22
+ *
23
+ * ## Why a wave is planned when it is reached
24
+ *
25
+ * A later wave planned up front reads outputs that do not exist yet. Planned
26
+ * after the wave before it applied, its digest describes the real upstream
27
+ * values, which is what an approver of that wave is shown.
28
+ */
29
+ import { changeSetDigest } from "./change-set.js";
30
+ /** Thrown when a canary names something that is not in the set being planned. */
31
+ export class UnknownCanaryError extends Error {
32
+ constructor(canary, known) {
33
+ super(`canary names "${canary}", which is not in this set (known: ${known.join(", ") || "none"})`);
34
+ this.canary = canary;
35
+ this.name = "UnknownCanaryError";
36
+ }
37
+ }
38
+ /** Thrown when the nodes being layered depend on each other in a cycle. */
39
+ export class WaveCycleError extends Error {
40
+ constructor(members) {
41
+ super(`dependency cycle among: ${members.join(", ")}`);
42
+ this.members = members;
43
+ this.name = "WaveCycleError";
44
+ }
45
+ }
46
+ /**
47
+ * Cut `nodes` into ordered waves: each node lands after every node it reads
48
+ * from, and each wave is sorted by name so the same graph always produces the
49
+ * same waves. With a canary list, those nodes are wave 1.
50
+ *
51
+ * A dependency on a name outside `nodes` does not hold a node back. That is
52
+ * the subset case: the dependency already applied, or is not changing.
53
+ */
54
+ export function layerWaves(nodes, options = {}) {
55
+ const names = new Set(nodes.map((n) => n.name));
56
+ const known = new Set([...names, ...(options.known ?? [])]);
57
+ for (const canary of options.canary ?? []) {
58
+ if (!known.has(canary))
59
+ throw new UnknownCanaryError(canary, [...known].sort());
60
+ }
61
+ const canaries = [...new Set((options.canary ?? []).filter((c) => names.has(c)))].sort();
62
+ const waves = canaries.length > 0 ? [canaries] : [];
63
+ const remaining = new Set([...names].filter((n) => !canaries.includes(n)));
64
+ const deps = new Map(nodes.map((n) => [n.name, (n.dependsOn ?? []).filter((d) => remaining.has(d))]));
65
+ while (remaining.size > 0) {
66
+ const wave = [...remaining].filter((n) => deps.get(n).every((d) => !remaining.has(d))).sort();
67
+ if (wave.length === 0)
68
+ throw new WaveCycleError([...remaining].sort());
69
+ for (const n of wave)
70
+ remaining.delete(n);
71
+ waves.push(wave);
72
+ }
73
+ return waves;
74
+ }
75
+ /** Thrown when a wave's members include a provisional plan, which no gate may bind. */
76
+ export class ProvisionalWaveMemberError extends Error {
77
+ constructor(members) {
78
+ super(`a wave cannot be gated on a provisional plan: ${members.join(", ")} planned before what it reads applied. ` +
79
+ `Plan it again in its own wave, after its upstream applied`);
80
+ this.members = members;
81
+ this.name = "ProvisionalWaveMemberError";
82
+ }
83
+ }
84
+ /**
85
+ * A wave's set digest: {@link changeSetDigest} over its members. Order does
86
+ * not matter, and it moves whenever one member's plan digest does. A wave
87
+ * naming one member twice has no digest and is refused, and so is a wave
88
+ * holding a provisional plan (#3416): a gate bound to it would approve
89
+ * values nobody has yet.
90
+ */
91
+ export function waveSetDigest(members) {
92
+ const provisional = members.filter((m) => m.provisional === true).map((m) => m.member);
93
+ if (provisional.length > 0)
94
+ throw new ProvisionalWaveMemberError([...new Set(provisional)].sort());
95
+ return changeSetDigest(members);
96
+ }
97
+ /**
98
+ * The gate a wave waits on: `<gate>-wave-<n>`, under the fan-out's op.
99
+ *
100
+ * One gate name per wave keeps each wave's approvals apart. With one name
101
+ * shared by every wave, wave 2 would find wave 1's approval and report it as
102
+ * an approval of another plan, which is true and useless. Wave numbers come
103
+ * from the derivation, not from what is left to run, so wave 3 stays wave 3
104
+ * on a resumed attempt and its approval still applies.
105
+ */
106
+ export function waveGateName(gate, wave) {
107
+ return `${gate}-wave-${wave}`;
108
+ }
109
+ const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
110
+ const strings = (value) => Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
111
+ /**
112
+ * Read the `waves` array of an attempt record, dropping anything malformed.
113
+ * A record written before #3049 has none, which reads as no waves.
114
+ */
115
+ export function readWaveRecords(value) {
116
+ if (!Array.isArray(value))
117
+ return [];
118
+ const out = [];
119
+ for (const raw of value) {
120
+ if (!isObject(raw))
121
+ continue;
122
+ const { wave, op, gate, digest, status } = raw;
123
+ if (typeof wave !== "number" || typeof op !== "string" || typeof gate !== "string" || typeof digest !== "string")
124
+ continue;
125
+ if (status !== "gated" && status !== "applied" && status !== "failed")
126
+ continue;
127
+ const members = Array.isArray(raw.members)
128
+ ? raw.members.filter((m) => isObject(m) && typeof m.member === "string" && typeof m.planDigest === "string")
129
+ : [];
130
+ const failed = Array.isArray(raw.failed)
131
+ ? raw.failed
132
+ .filter((f) => isObject(f) && typeof f.component === "string")
133
+ .map((f) => ({ component: f.component, ...(typeof f.error === "string" ? { error: f.error } : {}) }))
134
+ : [];
135
+ out.push({
136
+ wave,
137
+ op,
138
+ gate,
139
+ components: strings(raw.components),
140
+ digest,
141
+ members: members.map((m) => ({ member: m.member, planDigest: m.planDigest })),
142
+ status,
143
+ ...(typeof raw.approvedBy === "string" ? { approvedBy: raw.approvedBy } : {}),
144
+ ...(typeof raw.approved === "string" ? { approved: raw.approved } : {}),
145
+ ...(failed.length > 0 ? { failed } : {}),
146
+ });
147
+ }
148
+ return out;
149
+ }
150
+ /** Put `record` in `records` in place of any earlier record for the same wave, sorted by wave. */
151
+ export function withWaveRecord(records, record) {
152
+ return [...records.filter((r) => r.wave !== record.wave), record].sort((a, b) => a.wave - b.wave);
153
+ }
154
+ /**
155
+ * The refusal for a wave whose set changed after it was approved: the digest
156
+ * that was approved, the one planned now, and that nothing in the wave ran.
157
+ * On a sealed gate the approve hint ends in `--sign`.
158
+ */
159
+ export function describeChangedWave(record,
160
+ /** True when the gate is sealed (`identity.gates`): an approval without `--sign` doesn't count, so the hint says to sign. */
161
+ sealed = false) {
162
+ return (`wave ${record.wave} changed after it was approved, so nothing in it was applied. ` +
163
+ `approved: ${record.approved ?? "(none)"}; planned now: ${record.digest}. ` +
164
+ `Read the new plan, then approve it: chant approve ${record.op} ${record.gate} --plan ${record.digest}${sealed ? " --sign" : ""}`);
165
+ }