@intentius/chant 0.124.45 → 0.124.48

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 (772) hide show
  1. package/dist/__golden__/wave-loop/op-by-apply-after-fails.json +10 -0
  2. package/dist/__golden__/wave-loop/op-by-apply-hold.json +10 -0
  3. package/dist/__golden__/wave-loop/op-by-apply-ignored.json +10 -0
  4. package/dist/__golden__/wave-loop/op-by-apply-pass.json +10 -0
  5. package/dist/__golden__/wave-loop/op-by-apply-skip.json +10 -0
  6. package/dist/__golden__/wave-loop/op-cost-member-clash.json +6 -0
  7. package/dist/__golden__/wave-loop/op-cost-member.json +13 -0
  8. package/dist/__golden__/wave-loop/op-denied-source.json +16 -0
  9. package/dist/__golden__/wave-loop/op-denied.json +16 -0
  10. package/dist/__golden__/wave-loop/op-discover-rest-short.json +6 -0
  11. package/dist/__golden__/wave-loop/op-discover-rest-stops.json +13 -0
  12. package/dist/__golden__/wave-loop/op-discover-rest.json +26 -0
  13. package/dist/__golden__/wave-loop/op-discover-wide.json +26 -0
  14. package/dist/__golden__/wave-loop/op-held-on-again.json +16 -0
  15. package/dist/__golden__/wave-loop/op-held-on-before-apply.json +16 -0
  16. package/dist/__golden__/wave-loop/op-held-on.json +16 -0
  17. package/dist/__golden__/wave-loop/op-hooks-apply-fails.json +13 -0
  18. package/dist/__golden__/wave-loop/op-hooks-fail-after-apply.json +13 -0
  19. package/dist/__golden__/wave-loop/op-hooks-fail-before-apply.json +13 -0
  20. package/dist/__golden__/wave-loop/op-hooks-fail-before-plan.json +13 -0
  21. package/dist/__golden__/wave-loop/op-hooks-held.json +13 -0
  22. package/dist/__golden__/wave-loop/op-hooks-hold-before-apply.json +13 -0
  23. package/dist/__golden__/wave-loop/op-hooks-pass.json +13 -0
  24. package/dist/__golden__/wave-loop/op-hooks-refused-at-base.json +13 -0
  25. package/dist/__golden__/wave-loop/op-hooks-share.json +33 -0
  26. package/dist/__golden__/wave-loop/op-outcome-held.json +10 -0
  27. package/dist/__golden__/wave-loop/op-outcome-replan-approved.json +10 -0
  28. package/dist/__golden__/wave-loop/op-outcome-replan-forever.json +10 -0
  29. package/dist/__golden__/wave-loop/op-outcome-replan.json +10 -0
  30. package/dist/__golden__/wave-loop/op-outcome-stood-down.json +10 -0
  31. package/dist/__golden__/wave-loop/op-outcome-unreadable.json +10 -0
  32. package/dist/__golden__/wave-loop/op-overridden.json +16 -0
  33. package/dist/__golden__/wave-loop/op-per-run.json +20 -0
  34. package/dist/__golden__/wave-loop/op-point.json +13 -0
  35. package/dist/__golden__/wave-loop/op-pr-review.json +10 -0
  36. package/dist/__golden__/wave-loop/op-sealed.json +10 -0
  37. package/dist/__golden__/wave-loop/op-spend-change-only.json +10 -0
  38. package/dist/__golden__/wave-loop/op-spend.json +10 -0
  39. package/dist/__golden__/wave-loop/op-wave-commands.json +55 -0
  40. package/dist/__golden__/wave-loop/op-wide-refused.json +26 -0
  41. package/dist/__golden__/wave-loop/op-wide-waiting.json +29 -0
  42. package/dist/__golden__/wave-loop/op-wide.json +39 -0
  43. package/dist/action-pins.d.ts +61 -0
  44. package/dist/action-pins.d.ts.map +1 -0
  45. package/dist/action-pins.js +77 -0
  46. package/dist/capabilities/aws.paths +148 -0
  47. package/dist/capabilities/base-mappings.json +122 -0
  48. package/dist/capabilities/catalog.d.ts +89 -0
  49. package/dist/capabilities/catalog.d.ts.map +1 -0
  50. package/dist/capabilities/catalog.js +204 -0
  51. package/dist/capabilities/language.d.ts +103 -0
  52. package/dist/capabilities/language.d.ts.map +1 -0
  53. package/dist/capabilities/language.js +335 -0
  54. package/dist/capabilities/matcher.d.ts +65 -0
  55. package/dist/capabilities/matcher.d.ts.map +1 -0
  56. package/dist/capabilities/matcher.js +299 -0
  57. package/dist/capabilities/view.d.ts +207 -0
  58. package/dist/capabilities/view.d.ts.map +1 -0
  59. package/dist/capabilities/view.js +484 -0
  60. package/dist/cli/commands/carve.d.ts +3 -0
  61. package/dist/cli/commands/carve.d.ts.map +1 -1
  62. package/dist/cli/commands/carve.js +36 -7
  63. package/dist/cli/commands/import-report.d.ts +26 -0
  64. package/dist/cli/commands/import-report.d.ts.map +1 -0
  65. package/dist/cli/commands/import-report.js +65 -0
  66. package/dist/cli/commands/import.d.ts +11 -1
  67. package/dist/cli/commands/import.d.ts.map +1 -1
  68. package/dist/cli/commands/import.js +22 -3
  69. package/dist/cli/commands/lint.d.ts.map +1 -1
  70. package/dist/cli/commands/lint.js +1 -0
  71. package/dist/cli/commands/migrate.d.ts +13 -1
  72. package/dist/cli/commands/migrate.d.ts.map +1 -1
  73. package/dist/cli/commands/migrate.js +134 -10
  74. package/dist/cli/handlers/approve.d.ts.map +1 -1
  75. package/dist/cli/handlers/approve.js +21 -2
  76. package/dist/cli/handlers/build.d.ts.map +1 -1
  77. package/dist/cli/handlers/build.js +6 -1
  78. package/dist/cli/handlers/declared-graph.d.ts +44 -0
  79. package/dist/cli/handlers/declared-graph.d.ts.map +1 -0
  80. package/dist/cli/handlers/declared-graph.js +87 -0
  81. package/dist/cli/handlers/graph.d.ts +25 -0
  82. package/dist/cli/handlers/graph.d.ts.map +1 -1
  83. package/dist/cli/handlers/graph.js +93 -87
  84. package/dist/cli/handlers/ledger.d.ts +3 -0
  85. package/dist/cli/handlers/ledger.d.ts.map +1 -0
  86. package/dist/cli/handlers/ledger.js +55 -0
  87. package/dist/cli/handlers/migrate.d.ts.map +1 -1
  88. package/dist/cli/handlers/migrate.js +18 -11
  89. package/dist/cli/handlers/misc.d.ts.map +1 -1
  90. package/dist/cli/handlers/misc.js +12 -1
  91. package/dist/cli/handlers/pr-env.d.ts.map +1 -1
  92. package/dist/cli/handlers/pr-env.js +4 -3
  93. package/dist/cli/handlers/pr.d.ts +15 -1
  94. package/dist/cli/handlers/pr.d.ts.map +1 -1
  95. package/dist/cli/handlers/pr.js +143 -39
  96. package/dist/cli/handlers/query.d.ts +7 -2
  97. package/dist/cli/handlers/query.d.ts.map +1 -1
  98. package/dist/cli/handlers/query.js +16 -4
  99. package/dist/cli/handlers/release.d.ts.map +1 -1
  100. package/dist/cli/handlers/release.js +6 -3
  101. package/dist/cli/handlers/search-count.d.ts +89 -0
  102. package/dist/cli/handlers/search-count.d.ts.map +1 -0
  103. package/dist/cli/handlers/search-count.js +132 -0
  104. package/dist/cli/handlers/search.d.ts +356 -6
  105. package/dist/cli/handlers/search.d.ts.map +1 -1
  106. package/dist/cli/handlers/search.js +1039 -155
  107. package/dist/cli/main.d.ts.map +1 -1
  108. package/dist/cli/main.js +88 -17
  109. package/dist/cli/mcp/server.d.ts.map +1 -1
  110. package/dist/cli/mcp/server.js +3 -0
  111. package/dist/cli/mcp/tools/capabilities.d.ts +7 -0
  112. package/dist/cli/mcp/tools/capabilities.d.ts.map +1 -0
  113. package/dist/cli/mcp/tools/capabilities.js +27 -0
  114. package/dist/cli/mcp/workspace-tools.d.ts +3 -1
  115. package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
  116. package/dist/cli/mcp/workspace-tools.js +47 -2
  117. package/dist/cli/parse-args.d.ts.map +1 -1
  118. package/dist/cli/parse-args.js +100 -19
  119. package/dist/cli/registry.d.ts +36 -4
  120. package/dist/cli/registry.d.ts.map +1 -1
  121. package/dist/components/builders.d.ts +5 -1
  122. package/dist/components/builders.d.ts.map +1 -1
  123. package/dist/components/builders.js +5 -0
  124. package/dist/components/capability-plugin-loader.d.ts.map +1 -1
  125. package/dist/components/capability-plugin-loader.js +16 -1
  126. package/dist/components/capability-plugin.d.ts +14 -0
  127. package/dist/components/capability-plugin.d.ts.map +1 -1
  128. package/dist/components/pr-env-ports.d.ts +29 -0
  129. package/dist/components/pr-env-ports.d.ts.map +1 -0
  130. package/dist/components/pr-env-ports.js +77 -0
  131. package/dist/components/pr-env-run.d.ts +5 -21
  132. package/dist/components/pr-env-run.d.ts.map +1 -1
  133. package/dist/components/pr-env-run.js +6 -70
  134. package/dist/components/pr-environment.d.ts +2 -1
  135. package/dist/components/pr-environment.d.ts.map +1 -1
  136. package/dist/components/pr-environment.js +1 -1
  137. package/dist/components/pr-hooks.d.ts +21 -1
  138. package/dist/components/pr-hooks.d.ts.map +1 -1
  139. package/dist/components/pr-hooks.js +72 -4
  140. package/dist/components/pr-pipeline.d.ts +45 -10
  141. package/dist/components/pr-pipeline.d.ts.map +1 -1
  142. package/dist/components/pr-pipeline.js +47 -14
  143. package/dist/components/pr-policy.d.ts +36 -0
  144. package/dist/components/pr-policy.d.ts.map +1 -1
  145. package/dist/components/pr-policy.js +36 -0
  146. package/dist/components/starter-plugin.d.ts +1 -0
  147. package/dist/components/starter-plugin.d.ts.map +1 -1
  148. package/dist/components/starter-plugin.js +5 -1
  149. package/dist/components/verbs/index.d.ts +2 -0
  150. package/dist/components/verbs/index.d.ts.map +1 -1
  151. package/dist/components/verbs/index.js +2 -0
  152. package/dist/components/verbs/publish-artifact.d.ts +65 -0
  153. package/dist/components/verbs/publish-artifact.d.ts.map +1 -0
  154. package/dist/components/verbs/publish-artifact.js +74 -0
  155. package/dist/components/verbs/publish-image.d.ts +129 -0
  156. package/dist/components/verbs/publish-image.d.ts.map +1 -0
  157. package/dist/components/verbs/publish-image.js +145 -0
  158. package/dist/config-environments.d.ts +112 -0
  159. package/dist/config-environments.d.ts.map +1 -0
  160. package/dist/config-environments.js +114 -0
  161. package/dist/config.d.ts +32 -84
  162. package/dist/config.d.ts.map +1 -1
  163. package/dist/config.js +13 -96
  164. package/dist/gate-decision.d.ts +11 -2
  165. package/dist/gate-decision.d.ts.map +1 -1
  166. package/dist/gate-decision.js +15 -3
  167. package/dist/graph-detail.d.ts.map +1 -1
  168. package/dist/graph-detail.js +15 -3
  169. package/dist/graph-effective.d.ts +33 -2
  170. package/dist/graph-effective.d.ts.map +1 -1
  171. package/dist/graph-effective.js +215 -68
  172. package/dist/graph-ir.d.ts +48 -0
  173. package/dist/graph-ir.d.ts.map +1 -1
  174. package/dist/graph-ir.js +130 -0
  175. package/dist/graph-sub-template.d.ts +11 -0
  176. package/dist/graph-sub-template.d.ts.map +1 -0
  177. package/dist/graph-sub-template.js +19 -0
  178. package/dist/graph-walk.d.ts +66 -0
  179. package/dist/graph-walk.d.ts.map +1 -0
  180. package/dist/graph-walk.js +70 -0
  181. package/dist/import/parser.d.ts +19 -0
  182. package/dist/import/parser.d.ts.map +1 -1
  183. package/dist/lexicon.d.ts +80 -6
  184. package/dist/lexicon.d.ts.map +1 -1
  185. package/dist/lifecycle/gate-ledger.d.ts +11 -0
  186. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  187. package/dist/lifecycle/git.d.ts +2 -5
  188. package/dist/lifecycle/git.d.ts.map +1 -1
  189. package/dist/lifecycle/ledger-read.d.ts +65 -0
  190. package/dist/lifecycle/ledger-read.d.ts.map +1 -0
  191. package/dist/lifecycle/ledger-read.js +160 -0
  192. package/dist/lifecycle/observe.d.ts +28 -0
  193. package/dist/lifecycle/observe.d.ts.map +1 -1
  194. package/dist/lifecycle/observe.js +23 -1
  195. package/dist/lifecycle/release-workstation.d.ts +7 -0
  196. package/dist/lifecycle/release-workstation.d.ts.map +1 -1
  197. package/dist/lifecycle/release-workstation.js +25 -0
  198. package/dist/lifecycle/run-ledger.d.ts +4 -3
  199. package/dist/lifecycle/run-ledger.d.ts.map +1 -1
  200. package/dist/lifecycle/run-ledger.js +1 -0
  201. package/dist/lint/discover.js +3 -1
  202. package/dist/lint/post-synth.d.ts +127 -1
  203. package/dist/lint/post-synth.d.ts.map +1 -1
  204. package/dist/lint/post-synth.js +84 -2
  205. package/dist/lint/rule.d.ts +6 -0
  206. package/dist/lint/rule.d.ts.map +1 -1
  207. package/dist/lint/rules/op/index.d.ts +1 -0
  208. package/dist/lint/rules/op/index.d.ts.map +1 -1
  209. package/dist/lint/rules/op/index.js +2 -0
  210. package/dist/lint/rules/op/ops019-workspace-op-target.d.ts +32 -0
  211. package/dist/lint/rules/op/ops019-workspace-op-target.d.ts.map +1 -0
  212. package/dist/lint/rules/op/ops019-workspace-op-target.js +63 -0
  213. package/dist/live-endpoint.d.ts +1 -1
  214. package/dist/live-endpoint.d.ts.map +1 -1
  215. package/dist/live-endpoint.js +1 -1
  216. package/dist/observation.d.ts +48 -1
  217. package/dist/observation.d.ts.map +1 -1
  218. package/dist/observation.js +21 -5
  219. package/dist/op/activities/activity-contracts.d.ts +9 -6
  220. package/dist/op/activities/activity-contracts.d.ts.map +1 -1
  221. package/dist/op/activities/activity-contracts.js +5 -2
  222. package/dist/op/activities/index.d.ts +2 -2
  223. package/dist/op/activities/index.d.ts.map +1 -1
  224. package/dist/op/activities/index.js +1 -1
  225. package/dist/op/activities/review-agent.d.ts +90 -4
  226. package/dist/op/activities/review-agent.d.ts.map +1 -1
  227. package/dist/op/activities/review-agent.js +217 -19
  228. package/dist/op/activities/work-evidence.d.ts +8 -1
  229. package/dist/op/activities/work-evidence.d.ts.map +1 -1
  230. package/dist/op/activities/work-evidence.js +1 -0
  231. package/dist/op/builders.d.ts +9 -5
  232. package/dist/op/builders.d.ts.map +1 -1
  233. package/dist/op/builders.js +9 -5
  234. package/dist/op/composites/apply-op.d.ts +29 -2
  235. package/dist/op/composites/apply-op.d.ts.map +1 -1
  236. package/dist/op/composites/apply-op.js +20 -1
  237. package/dist/op/gate-approval.d.ts +11 -5
  238. package/dist/op/gate-approval.d.ts.map +1 -1
  239. package/dist/op/gate-approval.js +11 -6
  240. package/dist/op/gate-quorum.d.ts +100 -3
  241. package/dist/op/gate-quorum.d.ts.map +1 -1
  242. package/dist/op/gate-quorum.js +108 -6
  243. package/dist/op/gate-review.d.ts +9 -0
  244. package/dist/op/gate-review.d.ts.map +1 -1
  245. package/dist/op/gate-review.js +13 -0
  246. package/dist/op/gate.d.ts +44 -3
  247. package/dist/op/gate.d.ts.map +1 -1
  248. package/dist/op/gate.js +25 -4
  249. package/dist/op/index.d.ts +3 -3
  250. package/dist/op/index.d.ts.map +1 -1
  251. package/dist/op/index.js +1 -1
  252. package/dist/op/local-executor.d.ts +38 -3
  253. package/dist/op/local-executor.d.ts.map +1 -1
  254. package/dist/op/local-executor.js +48 -6
  255. package/dist/op/op-waves-run.d.ts +26 -1
  256. package/dist/op/op-waves-run.d.ts.map +1 -1
  257. package/dist/op/op-waves-run.js +259 -13
  258. package/dist/op/op-waves.d.ts +72 -5
  259. package/dist/op/op-waves.d.ts.map +1 -1
  260. package/dist/op/op-waves.js +110 -15
  261. package/dist/op/runtime.d.ts +11 -0
  262. package/dist/op/runtime.d.ts.map +1 -1
  263. package/dist/op/schedule-overdue.d.ts +16 -0
  264. package/dist/op/schedule-overdue.d.ts.map +1 -1
  265. package/dist/op/schedule-overdue.js +36 -0
  266. package/dist/op/stage-hooks.d.ts +9 -2
  267. package/dist/op/stage-hooks.d.ts.map +1 -1
  268. package/dist/op/stage-hooks.js +7 -5
  269. package/dist/op/workspace-run-env.d.ts +22 -0
  270. package/dist/op/workspace-run-env.d.ts.map +1 -0
  271. package/dist/op/workspace-run-env.js +21 -0
  272. package/dist/pr-forge.d.ts +24 -0
  273. package/dist/pr-forge.d.ts.map +1 -1
  274. package/dist/pr-forge.js +47 -0
  275. package/dist/pr-post.d.ts +42 -0
  276. package/dist/pr-post.d.ts.map +1 -1
  277. package/dist/pr-post.js +67 -1
  278. package/dist/read-filter.d.ts +65 -0
  279. package/dist/read-filter.d.ts.map +1 -0
  280. package/dist/read-filter.js +179 -0
  281. package/dist/run-event.d.ts +1 -1
  282. package/dist/run-event.d.ts.map +1 -1
  283. package/dist/terraform/carve.d.ts +24 -3
  284. package/dist/terraform/carve.d.ts.map +1 -1
  285. package/dist/terraform/carve.js +32 -14
  286. package/dist/terraform/cuts.d.ts +97 -0
  287. package/dist/terraform/cuts.d.ts.map +1 -0
  288. package/dist/terraform/cuts.js +138 -0
  289. package/dist/terraform/folds.d.ts +26 -0
  290. package/dist/terraform/folds.d.ts.map +1 -0
  291. package/dist/terraform/folds.js +38 -0
  292. package/dist/terraform/graph.d.ts.map +1 -1
  293. package/dist/terraform/graph.js +10 -0
  294. package/dist/terraform/reach.d.ts +140 -0
  295. package/dist/terraform/reach.d.ts.map +1 -0
  296. package/dist/terraform/reach.js +170 -0
  297. package/dist/terraform/score.d.ts +14 -0
  298. package/dist/terraform/score.d.ts.map +1 -1
  299. package/dist/terraform/score.js +14 -31
  300. package/dist/terraform/state.d.ts.map +1 -1
  301. package/dist/terraform/state.js +4 -2
  302. package/dist/terraform/types.d.ts +8 -0
  303. package/dist/terraform/types.d.ts.map +1 -1
  304. package/dist/wave-blocked.d.ts +10 -1
  305. package/dist/wave-blocked.d.ts.map +1 -1
  306. package/dist/wave-blocked.js +31 -3
  307. package/dist/wave-runtime.mjs +266 -256
  308. package/dist/workspace/capabilities-contract.d.ts +66 -0
  309. package/dist/workspace/capabilities-contract.d.ts.map +1 -0
  310. package/dist/workspace/capabilities-contract.js +107 -0
  311. package/dist/workspace/capabilities.schema.json +229 -0
  312. package/dist/workspace/check.schema.json +11 -2
  313. package/dist/workspace/checks/ci-branch.d.ts +44 -0
  314. package/dist/workspace/checks/ci-branch.d.ts.map +1 -0
  315. package/dist/workspace/checks/ci-branch.js +133 -0
  316. package/dist/workspace/checks/links.d.ts +3 -0
  317. package/dist/workspace/checks/links.d.ts.map +1 -1
  318. package/dist/workspace/checks/links.js +12 -1
  319. package/dist/workspace/checks/org.d.ts +48 -0
  320. package/dist/workspace/checks/org.d.ts.map +1 -0
  321. package/dist/workspace/checks/org.js +156 -0
  322. package/dist/workspace/checks.d.ts +11 -1
  323. package/dist/workspace/checks.d.ts.map +1 -1
  324. package/dist/workspace/checks.js +59 -7
  325. package/dist/workspace/ci-branches.d.ts +16 -0
  326. package/dist/workspace/ci-branches.d.ts.map +1 -1
  327. package/dist/workspace/ci-branches.js +27 -0
  328. package/dist/workspace/ci-green-cli.js +7 -7
  329. package/dist/workspace/ci-green-workflow.d.ts +1 -1
  330. package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
  331. package/dist/workspace/ci-green-workflow.js +13 -8
  332. package/dist/workspace/ci-green.d.ts +14 -0
  333. package/dist/workspace/ci-green.d.ts.map +1 -1
  334. package/dist/workspace/ci-green.js +44 -11
  335. package/dist/workspace/ci-run.d.ts +9 -1
  336. package/dist/workspace/ci-run.d.ts.map +1 -1
  337. package/dist/workspace/ci-run.js +67 -6
  338. package/dist/workspace/ci-serve.d.ts +9 -0
  339. package/dist/workspace/ci-serve.d.ts.map +1 -1
  340. package/dist/workspace/ci-serve.js +114 -76
  341. package/dist/workspace/compose-graph.d.ts +23 -0
  342. package/dist/workspace/compose-graph.d.ts.map +1 -1
  343. package/dist/workspace/compose-graph.js +3 -1
  344. package/dist/workspace/composites.d.ts +4 -1
  345. package/dist/workspace/composites.d.ts.map +1 -1
  346. package/dist/workspace/composites.js +5 -2
  347. package/dist/workspace/composites.schema.json +22 -0
  348. package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +105 -1
  349. package/dist/workspace/conformance/index.d.ts +1 -1
  350. package/dist/workspace/conformance/index.d.ts.map +1 -1
  351. package/dist/workspace/conformance/index.js +39 -2
  352. package/dist/workspace/cross-root-lint.d.ts +56 -0
  353. package/dist/workspace/cross-root-lint.d.ts.map +1 -0
  354. package/dist/workspace/cross-root-lint.js +111 -0
  355. package/dist/workspace/dbt-models-reader.d.ts +44 -0
  356. package/dist/workspace/dbt-models-reader.d.ts.map +1 -0
  357. package/dist/workspace/dbt-models-reader.js +356 -0
  358. package/dist/workspace/dbt-project-common.d.ts +40 -0
  359. package/dist/workspace/dbt-project-common.d.ts.map +1 -0
  360. package/dist/workspace/dbt-project-common.js +106 -0
  361. package/dist/workspace/dbt-project-reader.d.ts +4 -3
  362. package/dist/workspace/dbt-project-reader.d.ts.map +1 -1
  363. package/dist/workspace/dbt-project-reader.js +14 -108
  364. package/dist/workspace/decision-rank.d.ts +26 -0
  365. package/dist/workspace/decision-rank.d.ts.map +1 -0
  366. package/dist/workspace/decision-rank.js +16 -0
  367. package/dist/workspace/declaration.d.ts +43 -2
  368. package/dist/workspace/declaration.d.ts.map +1 -1
  369. package/dist/workspace/declaration.js +45 -11
  370. package/dist/workspace/declaration.schema.json +133 -24
  371. package/dist/workspace/environments.d.ts +26 -2
  372. package/dist/workspace/environments.d.ts.map +1 -1
  373. package/dist/workspace/environments.js +26 -2
  374. package/dist/workspace/flyway-dir.d.ts +39 -0
  375. package/dist/workspace/flyway-dir.d.ts.map +1 -0
  376. package/dist/workspace/flyway-dir.js +104 -0
  377. package/dist/workspace/flyway-layout.d.ts +96 -0
  378. package/dist/workspace/flyway-layout.d.ts.map +1 -0
  379. package/dist/workspace/flyway-layout.js +308 -0
  380. package/dist/workspace/graph-cache.d.ts +8 -0
  381. package/dist/workspace/graph-cache.d.ts.map +1 -1
  382. package/dist/workspace/graph-cache.js +27 -3
  383. package/dist/workspace/graph-cli.d.ts +39 -2
  384. package/dist/workspace/graph-cli.d.ts.map +1 -1
  385. package/dist/workspace/graph-cli.js +92 -32
  386. package/dist/workspace/graph.schema.json +182 -0
  387. package/dist/workspace/intent.d.ts +2 -3
  388. package/dist/workspace/intent.d.ts.map +1 -1
  389. package/dist/workspace/intent.js +5 -9
  390. package/dist/workspace/kind-link-readers.d.ts +59 -2
  391. package/dist/workspace/kind-link-readers.d.ts.map +1 -1
  392. package/dist/workspace/kind-link-readers.js +17 -1
  393. package/dist/workspace/kind-readers.d.ts +3 -0
  394. package/dist/workspace/kind-readers.d.ts.map +1 -1
  395. package/dist/workspace/kind-readers.js +7 -1
  396. package/dist/workspace/kinds.d.ts +66 -2
  397. package/dist/workspace/kinds.d.ts.map +1 -1
  398. package/dist/workspace/kinds.js +98 -4
  399. package/dist/workspace/ledger.schema.json +158 -0
  400. package/dist/workspace/lexicon-outputs.d.ts +20 -1
  401. package/dist/workspace/lexicon-outputs.d.ts.map +1 -1
  402. package/dist/workspace/lexicon-outputs.js +102 -10
  403. package/dist/workspace/lineage-check.d.ts +3 -0
  404. package/dist/workspace/lineage-check.d.ts.map +1 -1
  405. package/dist/workspace/lineage-check.js +23 -4
  406. package/dist/workspace/links.d.ts +8 -1
  407. package/dist/workspace/links.d.ts.map +1 -1
  408. package/dist/workspace/links.js +25 -1
  409. package/dist/workspace/ls.d.ts +8 -0
  410. package/dist/workspace/ls.d.ts.map +1 -1
  411. package/dist/workspace/ls.js +7 -1
  412. package/dist/workspace/ls.schema.json +7 -0
  413. package/dist/workspace/member-commands.d.ts +10 -1
  414. package/dist/workspace/member-commands.d.ts.map +1 -1
  415. package/dist/workspace/member-commands.js +71 -6
  416. package/dist/workspace/migrate-links.d.ts +45 -0
  417. package/dist/workspace/migrate-links.d.ts.map +1 -0
  418. package/dist/workspace/migrate-links.js +100 -0
  419. package/dist/workspace/migration-dirs.d.ts +74 -0
  420. package/dist/workspace/migration-dirs.d.ts.map +1 -0
  421. package/dist/workspace/migration-dirs.js +254 -0
  422. package/dist/workspace/nested-graph.d.ts +2 -0
  423. package/dist/workspace/nested-graph.d.ts.map +1 -1
  424. package/dist/workspace/nested-graph.js +32 -1
  425. package/dist/workspace/reason-codes.d.ts +18 -0
  426. package/dist/workspace/reason-codes.d.ts.map +1 -1
  427. package/dist/workspace/reason-codes.js +23 -0
  428. package/dist/workspace/records-cli.d.ts +11 -0
  429. package/dist/workspace/records-cli.d.ts.map +1 -1
  430. package/dist/workspace/records-cli.js +57 -5
  431. package/dist/workspace/records.schema.json +5 -0
  432. package/dist/workspace/release-candidates.d.ts +2 -0
  433. package/dist/workspace/release-candidates.d.ts.map +1 -1
  434. package/dist/workspace/release-candidates.js +5 -2
  435. package/dist/workspace/release-train.d.ts +53 -0
  436. package/dist/workspace/release-train.d.ts.map +1 -0
  437. package/dist/workspace/release-train.js +134 -0
  438. package/dist/workspace/release-workflow.d.ts.map +1 -1
  439. package/dist/workspace/release-workflow.js +4 -3
  440. package/dist/workspace/repo-ref.d.ts +45 -0
  441. package/dist/workspace/repo-ref.d.ts.map +1 -0
  442. package/dist/workspace/repo-ref.js +114 -0
  443. package/dist/workspace/run-event.schema.json +2 -2
  444. package/dist/workspace/runs-cli.d.ts +9 -0
  445. package/dist/workspace/runs-cli.d.ts.map +1 -1
  446. package/dist/workspace/runs-cli.js +48 -3
  447. package/dist/workspace/runs.schema.json +7 -0
  448. package/dist/workspace/search-cli.d.ts +204 -0
  449. package/dist/workspace/search-cli.d.ts.map +1 -0
  450. package/dist/workspace/search-cli.js +466 -0
  451. package/dist/workspace/search-contract.d.ts +56 -0
  452. package/dist/workspace/search-contract.d.ts.map +1 -0
  453. package/dist/workspace/search-contract.js +70 -0
  454. package/dist/workspace/search.schema.json +822 -0
  455. package/dist/workspace/status-decisions.d.ts +37 -0
  456. package/dist/workspace/status-decisions.d.ts.map +1 -0
  457. package/dist/workspace/status-decisions.js +147 -0
  458. package/dist/workspace/status-gates.d.ts +9 -0
  459. package/dist/workspace/status-gates.d.ts.map +1 -1
  460. package/dist/workspace/status.d.ts +4 -0
  461. package/dist/workspace/status.d.ts.map +1 -1
  462. package/dist/workspace/status.js +14 -2
  463. package/dist/workspace/status.schema.json +6 -0
  464. package/dist/workspace/work-cli.d.ts.map +1 -1
  465. package/dist/workspace/work-cli.js +5 -3
  466. package/dist/workspace/work-evidence-ops.d.ts +83 -0
  467. package/dist/workspace/work-evidence-ops.d.ts.map +1 -0
  468. package/dist/workspace/work-evidence-ops.js +169 -0
  469. package/dist/workspace/work-evidence.d.ts +12 -2
  470. package/dist/workspace/work-evidence.d.ts.map +1 -1
  471. package/dist/workspace/work-evidence.js +21 -3
  472. package/dist/workspace/work-evidence.schema.json +49 -2
  473. package/dist/workspace/workspace-gates.d.ts +110 -0
  474. package/dist/workspace/workspace-gates.d.ts.map +1 -0
  475. package/dist/workspace/workspace-gates.js +140 -0
  476. package/dist/workspace/workspace-kinds.schema.json +58 -3
  477. package/dist/workspace/workspace-ledger.d.ts +76 -0
  478. package/dist/workspace/workspace-ledger.d.ts.map +1 -0
  479. package/dist/workspace/workspace-ledger.js +91 -0
  480. package/dist/workspace/workspace-run.d.ts +112 -0
  481. package/dist/workspace/workspace-run.d.ts.map +1 -0
  482. package/dist/workspace/workspace-run.js +432 -0
  483. package/package.json +1 -1
  484. package/src/__golden__/wave-loop/op-by-apply-after-fails.json +10 -0
  485. package/src/__golden__/wave-loop/op-by-apply-hold.json +10 -0
  486. package/src/__golden__/wave-loop/op-by-apply-ignored.json +10 -0
  487. package/src/__golden__/wave-loop/op-by-apply-pass.json +10 -0
  488. package/src/__golden__/wave-loop/op-by-apply-skip.json +10 -0
  489. package/src/__golden__/wave-loop/op-cost-member-clash.json +6 -0
  490. package/src/__golden__/wave-loop/op-cost-member.json +13 -0
  491. package/src/__golden__/wave-loop/op-denied-source.json +16 -0
  492. package/src/__golden__/wave-loop/op-denied.json +16 -0
  493. package/src/__golden__/wave-loop/op-discover-rest-short.json +6 -0
  494. package/src/__golden__/wave-loop/op-discover-rest-stops.json +13 -0
  495. package/src/__golden__/wave-loop/op-discover-rest.json +26 -0
  496. package/src/__golden__/wave-loop/op-discover-wide.json +26 -0
  497. package/src/__golden__/wave-loop/op-held-on-again.json +16 -0
  498. package/src/__golden__/wave-loop/op-held-on-before-apply.json +16 -0
  499. package/src/__golden__/wave-loop/op-held-on.json +16 -0
  500. package/src/__golden__/wave-loop/op-hooks-apply-fails.json +13 -0
  501. package/src/__golden__/wave-loop/op-hooks-fail-after-apply.json +13 -0
  502. package/src/__golden__/wave-loop/op-hooks-fail-before-apply.json +13 -0
  503. package/src/__golden__/wave-loop/op-hooks-fail-before-plan.json +13 -0
  504. package/src/__golden__/wave-loop/op-hooks-held.json +13 -0
  505. package/src/__golden__/wave-loop/op-hooks-hold-before-apply.json +13 -0
  506. package/src/__golden__/wave-loop/op-hooks-pass.json +13 -0
  507. package/src/__golden__/wave-loop/op-hooks-refused-at-base.json +13 -0
  508. package/src/__golden__/wave-loop/op-hooks-share.json +33 -0
  509. package/src/__golden__/wave-loop/op-outcome-held.json +10 -0
  510. package/src/__golden__/wave-loop/op-outcome-replan-approved.json +10 -0
  511. package/src/__golden__/wave-loop/op-outcome-replan-forever.json +10 -0
  512. package/src/__golden__/wave-loop/op-outcome-replan.json +10 -0
  513. package/src/__golden__/wave-loop/op-outcome-stood-down.json +10 -0
  514. package/src/__golden__/wave-loop/op-outcome-unreadable.json +10 -0
  515. package/src/__golden__/wave-loop/op-overridden.json +16 -0
  516. package/src/__golden__/wave-loop/op-per-run.json +20 -0
  517. package/src/__golden__/wave-loop/op-point.json +13 -0
  518. package/src/__golden__/wave-loop/op-pr-review.json +10 -0
  519. package/src/__golden__/wave-loop/op-sealed.json +10 -0
  520. package/src/__golden__/wave-loop/op-spend-change-only.json +10 -0
  521. package/src/__golden__/wave-loop/op-spend.json +10 -0
  522. package/src/__golden__/wave-loop/op-wave-commands.json +55 -0
  523. package/src/__golden__/wave-loop/op-wide-refused.json +26 -0
  524. package/src/__golden__/wave-loop/op-wide-waiting.json +29 -0
  525. package/src/__golden__/wave-loop/op-wide.json +39 -0
  526. package/src/__snapshots__/okf.test.ts.snap +10 -0
  527. package/src/action-pins.test.ts +78 -0
  528. package/src/action-pins.ts +92 -0
  529. package/src/capabilities/aws.paths +148 -0
  530. package/src/capabilities/base-mappings.json +122 -0
  531. package/src/capabilities/catalog.ts +230 -0
  532. package/src/capabilities/language.test.ts +191 -0
  533. package/src/capabilities/language.ts +373 -0
  534. package/src/capabilities/matcher.ts +315 -0
  535. package/src/capabilities/view-compose.test.ts +76 -0
  536. package/src/capabilities/view.ts +631 -0
  537. package/src/cli/commands/carve-score-once.test.ts +99 -0
  538. package/src/cli/commands/carve.ts +37 -6
  539. package/src/cli/commands/check-lexicon.test.ts +2 -2
  540. package/src/cli/commands/import-report.ts +71 -0
  541. package/src/cli/commands/import.ts +33 -3
  542. package/src/cli/commands/lint.ts +1 -0
  543. package/src/cli/commands/migrate-dialect.test.ts +145 -0
  544. package/src/cli/commands/migrate.ts +132 -11
  545. package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +4 -4
  546. package/src/cli/handlers/approve.ts +23 -2
  547. package/src/cli/handlers/build.ts +7 -1
  548. package/src/cli/handlers/declared-graph.ts +99 -0
  549. package/src/cli/handlers/graph.test.ts +94 -3
  550. package/src/cli/handlers/graph.ts +123 -96
  551. package/src/cli/handlers/ledger.ts +54 -0
  552. package/src/cli/handlers/migrate.ts +21 -12
  553. package/src/cli/handlers/misc.ts +10 -1
  554. package/src/cli/handlers/pr-env.ts +3 -4
  555. package/src/cli/handlers/pr.ts +138 -36
  556. package/src/cli/handlers/query.ts +16 -4
  557. package/src/cli/handlers/release.ts +6 -3
  558. package/src/cli/handlers/search-build-roots.test.ts +144 -0
  559. package/src/cli/handlers/search-count.test.ts +191 -0
  560. package/src/cli/handlers/search-count.ts +165 -0
  561. package/src/cli/handlers/search-json.test.ts +333 -0
  562. package/src/cli/handlers/search-live.test.ts +387 -0
  563. package/src/cli/handlers/search-paths.test.ts +235 -0
  564. package/src/cli/handlers/search.ts +1291 -166
  565. package/src/cli/main.test.ts +43 -3
  566. package/src/cli/main.ts +88 -17
  567. package/src/cli/mcp/server.test.ts +3 -3
  568. package/src/cli/mcp/server.ts +3 -0
  569. package/src/cli/mcp/tools/capabilities.ts +32 -0
  570. package/src/cli/mcp/workspace-tools.e2e.test.ts +21 -1
  571. package/src/cli/mcp/workspace-tools.ts +47 -2
  572. package/src/cli/parse-args.ts +79 -15
  573. package/src/cli/registry.ts +36 -4
  574. package/src/components/builders.ts +8 -0
  575. package/src/components/capability-plugin-loader.ts +13 -1
  576. package/src/components/capability-plugin.ts +16 -0
  577. package/src/components/pr-env-ports.ts +89 -0
  578. package/src/components/pr-env-run-bundle.test.ts +54 -0
  579. package/src/components/pr-env-run.ts +5 -76
  580. package/src/components/pr-environment.ts +2 -1
  581. package/src/components/pr-hooks.test.ts +73 -5
  582. package/src/components/pr-hooks.ts +95 -5
  583. package/src/components/pr-pipeline.ts +64 -16
  584. package/src/components/pr-policy.test.ts +64 -1
  585. package/src/components/pr-policy.ts +53 -0
  586. package/src/components/registry.test.ts +1 -1
  587. package/src/components/starter-plugin.ts +6 -0
  588. package/src/components/verbs/index.ts +2 -0
  589. package/src/components/verbs/publish-artifact.test.ts +60 -0
  590. package/src/components/verbs/publish-artifact.ts +122 -0
  591. package/src/components/verbs/publish-image.test.ts +101 -0
  592. package/src/components/verbs/publish-image.ts +265 -0
  593. package/src/config-environments.ts +160 -0
  594. package/src/config.ts +44 -124
  595. package/src/gate-decision-bundle.test.ts +1 -0
  596. package/src/gate-decision-identity.test.ts +9 -0
  597. package/src/gate-decision.ts +26 -3
  598. package/src/graph-detail.ts +15 -3
  599. package/src/graph-effective.ts +226 -75
  600. package/src/graph-ir.test.ts +163 -0
  601. package/src/graph-ir.ts +174 -0
  602. package/src/graph-sub-template.ts +22 -0
  603. package/src/graph-walk.test.ts +44 -0
  604. package/src/graph-walk.ts +102 -0
  605. package/src/import/parser.ts +20 -0
  606. package/src/lexicon.ts +84 -6
  607. package/src/lifecycle/gate-ledger.ts +8 -0
  608. package/src/lifecycle/git.ts +2 -2
  609. package/src/lifecycle/ledger-read.test.ts +107 -0
  610. package/src/lifecycle/ledger-read.ts +195 -0
  611. package/src/lifecycle/observe.test.ts +27 -1
  612. package/src/lifecycle/observe.ts +43 -1
  613. package/src/lifecycle/release-workstation.ts +24 -0
  614. package/src/lifecycle/run-ledger.ts +5 -2
  615. package/src/lint/cross-root.test.ts +122 -0
  616. package/src/lint/discover.ts +3 -1
  617. package/src/lint/post-synth.ts +212 -2
  618. package/src/lint/rule.ts +6 -0
  619. package/src/lint/rules/op/index.ts +2 -0
  620. package/src/lint/rules/op/ops019-workspace-op-target.ts +89 -0
  621. package/src/live-endpoint.ts +1 -1
  622. package/src/observation.test.ts +25 -0
  623. package/src/observation.ts +69 -5
  624. package/src/op/activities/activity-contracts.ts +5 -2
  625. package/src/op/activities/index.ts +2 -2
  626. package/src/op/activities/review-agent.test.ts +221 -4
  627. package/src/op/activities/review-agent.ts +265 -22
  628. package/src/op/activities/work-evidence.ts +9 -1
  629. package/src/op/builders.ts +9 -5
  630. package/src/op/composites/apply-op.test.ts +108 -0
  631. package/src/op/composites/apply-op.ts +37 -2
  632. package/src/op/gate-approval.test.ts +6 -1
  633. package/src/op/gate-approval.ts +12 -6
  634. package/src/op/gate-quorum-at-base.test.ts +211 -0
  635. package/src/op/gate-quorum.ts +156 -8
  636. package/src/op/gate-review.ts +14 -0
  637. package/src/op/gate.ts +67 -8
  638. package/src/op/index.ts +3 -2
  639. package/src/op/local-executor.ts +69 -9
  640. package/src/op/op-waves-depends-on.test.ts +81 -0
  641. package/src/op/op-waves-hook-targets.test.ts +4 -2
  642. package/src/op/op-waves-quorum-product.test.ts +158 -0
  643. package/src/op/op-waves-run.ts +288 -14
  644. package/src/op/op-waves.ts +143 -14
  645. package/src/op/runtime.ts +8 -0
  646. package/src/op/schedule-overdue.ts +33 -0
  647. package/src/op/stage-hooks.ts +13 -5
  648. package/src/op/workspace-run-env.ts +29 -0
  649. package/src/pr-forge-bundle.test.ts +2 -2
  650. package/src/pr-forge.test.ts +47 -0
  651. package/src/pr-forge.ts +68 -0
  652. package/src/pr-post-open.e2e.test.ts +36 -0
  653. package/src/pr-post.test.ts +102 -3
  654. package/src/pr-post.ts +89 -1
  655. package/src/read-filter.test.ts +54 -0
  656. package/src/read-filter.ts +193 -0
  657. package/src/run-event.ts +1 -1
  658. package/src/stage-hooks-bundle.test.ts +1 -0
  659. package/src/terraform/carve.ts +52 -15
  660. package/src/terraform/cuts.test.ts +173 -0
  661. package/src/terraform/cuts.ts +188 -0
  662. package/src/terraform/folds.ts +44 -0
  663. package/src/terraform/graph.ts +9 -0
  664. package/src/terraform/radius.test.ts +90 -0
  665. package/src/terraform/reach.test.ts +146 -0
  666. package/src/terraform/reach.ts +247 -0
  667. package/src/terraform/score.ts +27 -29
  668. package/src/terraform/state.ts +3 -1
  669. package/src/terraform/types.ts +8 -0
  670. package/src/wave-blocked.ts +28 -3
  671. package/src/wave-loop-golden.test.ts +4 -3
  672. package/src/workspace/behold-kinds.test.ts +1 -1
  673. package/src/workspace/capabilities-contract.test.ts +88 -0
  674. package/src/workspace/capabilities-contract.ts +132 -0
  675. package/src/workspace/capabilities.schema.json +229 -0
  676. package/src/workspace/check-contract.test.ts +7 -6
  677. package/src/workspace/check.schema.json +11 -2
  678. package/src/workspace/checks/ci-branch.test.ts +128 -0
  679. package/src/workspace/checks/ci-branch.ts +141 -0
  680. package/src/workspace/checks/links.ts +12 -1
  681. package/src/workspace/checks/org.ts +169 -0
  682. package/src/workspace/checks.ts +64 -7
  683. package/src/workspace/ci-branches.ts +31 -0
  684. package/src/workspace/ci-green-branches.test.ts +153 -0
  685. package/src/workspace/ci-green-cli.ts +7 -7
  686. package/src/workspace/ci-green-workflow.test.ts +4 -3
  687. package/src/workspace/ci-green-workflow.ts +13 -9
  688. package/src/workspace/ci-green.ts +49 -12
  689. package/src/workspace/ci-run.test.ts +72 -1
  690. package/src/workspace/ci-run.ts +68 -8
  691. package/src/workspace/ci-serve.test.ts +95 -0
  692. package/src/workspace/ci-serve.ts +106 -65
  693. package/src/workspace/component-environments.test.ts +25 -2
  694. package/src/workspace/compose-graph.ts +19 -3
  695. package/src/workspace/composites.schema.json +22 -0
  696. package/src/workspace/composites.test.ts +39 -8
  697. package/src/workspace/composites.ts +6 -2
  698. package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +105 -1
  699. package/src/workspace/conformance/conformance.e2e.test.ts +14 -1
  700. package/src/workspace/conformance/index.ts +31 -2
  701. package/src/workspace/cross-root-lint.test.ts +90 -0
  702. package/src/workspace/cross-root-lint.ts +126 -0
  703. package/src/workspace/dbt-kind.test.ts +3 -2
  704. package/src/workspace/dbt-models-reader.ts +362 -0
  705. package/src/workspace/dbt-models.test.ts +248 -0
  706. package/src/workspace/dbt-project-common.ts +113 -0
  707. package/src/workspace/dbt-project-reader.ts +29 -112
  708. package/src/workspace/decision-rank.ts +40 -0
  709. package/src/workspace/declaration.schema.json +133 -24
  710. package/src/workspace/declaration.ts +84 -15
  711. package/src/workspace/environments.ts +40 -4
  712. package/src/workspace/flyway-dir.ts +113 -0
  713. package/src/workspace/flyway-layout.ts +337 -0
  714. package/src/workspace/graph-cache.ts +27 -3
  715. package/src/workspace/graph-cli.ts +119 -32
  716. package/src/workspace/graph-contract.test.ts +4 -2
  717. package/src/workspace/graph.schema.json +182 -0
  718. package/src/workspace/identity.test.ts +14 -2
  719. package/src/workspace/intent.ts +6 -14
  720. package/src/workspace/kind-link-readers.ts +68 -3
  721. package/src/workspace/kind-readers.e2e.test.ts +28 -0
  722. package/src/workspace/kind-readers.test.ts +1 -1
  723. package/src/workspace/kind-readers.ts +7 -1
  724. package/src/workspace/kinds.test.ts +12 -7
  725. package/src/workspace/kinds.ts +132 -7
  726. package/src/workspace/ledger.schema.json +158 -0
  727. package/src/workspace/lexicon-outputs.ts +132 -13
  728. package/src/workspace/lineage-check.ts +30 -7
  729. package/src/workspace/links.ts +24 -1
  730. package/src/workspace/ls-contract.test.ts +1 -1
  731. package/src/workspace/ls.schema.json +7 -0
  732. package/src/workspace/ls.ts +10 -1
  733. package/src/workspace/member-commands.ts +82 -3
  734. package/src/workspace/member-file-schema.test.ts +124 -0
  735. package/src/workspace/migrate-links.test.ts +99 -0
  736. package/src/workspace/migrate-links.ts +108 -0
  737. package/src/workspace/migration-dirs.test.ts +272 -0
  738. package/src/workspace/migration-dirs.ts +267 -0
  739. package/src/workspace/nested-graph.ts +32 -1
  740. package/src/workspace/org-scope.test.ts +238 -0
  741. package/src/workspace/reason-codes.test.ts +13 -1
  742. package/src/workspace/reason-codes.ts +23 -0
  743. package/src/workspace/records-cli.ts +58 -5
  744. package/src/workspace/records.schema.json +5 -0
  745. package/src/workspace/release-candidates.ts +7 -2
  746. package/src/workspace/release-train.ts +157 -0
  747. package/src/workspace/release-workflow.ts +4 -3
  748. package/src/workspace/repo-ref.ts +113 -0
  749. package/src/workspace/run-event.schema.json +2 -2
  750. package/src/workspace/runs-cli.ts +48 -4
  751. package/src/workspace/runs.schema.json +7 -0
  752. package/src/workspace/search-cli.e2e.test.ts +305 -0
  753. package/src/workspace/search-cli.ts +591 -0
  754. package/src/workspace/search-contract.ts +95 -0
  755. package/src/workspace/search.schema.json +822 -0
  756. package/src/workspace/status-contract.test.ts +46 -1
  757. package/src/workspace/status-decisions.test.ts +100 -0
  758. package/src/workspace/status-decisions.ts +151 -0
  759. package/src/workspace/status-gates.ts +9 -0
  760. package/src/workspace/status.schema.json +6 -0
  761. package/src/workspace/status.ts +17 -3
  762. package/src/workspace/where-filters.test.ts +39 -0
  763. package/src/workspace/work-cli.ts +5 -3
  764. package/src/workspace/work-evidence-ops.test.ts +176 -0
  765. package/src/workspace/work-evidence-ops.ts +189 -0
  766. package/src/workspace/work-evidence.schema.json +49 -2
  767. package/src/workspace/work-evidence.ts +22 -3
  768. package/src/workspace/workspace-gates.ts +200 -0
  769. package/src/workspace/workspace-kinds.schema.json +58 -3
  770. package/src/workspace/workspace-ledger.ts +130 -0
  771. package/src/workspace/workspace-run.test.ts +322 -0
  772. package/src/workspace/workspace-run.ts +461 -0
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Cuts and reference-closed sets over the carve graph (#3909).
3
+ *
4
+ * `carve advise` scores one block at a time. A consumer splitting one root into
5
+ * several (terragucci's estate carving) needs the same question for a set:
6
+ * which edges cross its boundary and which way, and the smallest set around a
7
+ * seed whose crossings all run a way the caller allows. These are pure
8
+ * functions over `TfGraph`, on the index and walk in `reach.ts`, so the rules
9
+ * there hold here too: folds contract first, outputs are terminal and counted
10
+ * apart, modules and unresolved `count` are named as hiding their contents, a
11
+ * `depends_on` cycle terminates, and `crossStack` edges are counted apart.
12
+ *
13
+ * Nothing here ranks sets, reads state or plan times, writes HCL, or knows
14
+ * about roots or backends; that stays with the consumer.
15
+ */
16
+ import type { TfEdge, TfGraph } from "./types.js";
17
+ /** Cut edges of one direction, counted. */
18
+ export interface CutCount {
19
+ /** Edges whose reading side is a resource or module block. */
20
+ resources: number;
21
+ /** Edges whose reading side is an `output` block. */
22
+ outputs: number;
23
+ /** Of all of them, the `crossStack` edges (a CDK `Fn::ImportValue`). */
24
+ crossStack: number;
25
+ }
26
+ /** A set of blocks, as the walks see it. */
27
+ export interface BlockSet {
28
+ /** Resource and module addresses, each fold parent with the blocks folded into it. Sorted. */
29
+ resources: string[];
30
+ /** `output.<name>` pseudo-addresses in the set. Sorted. */
31
+ outputs: string[];
32
+ }
33
+ export interface Cuts extends BlockSet {
34
+ /** Edges where something outside reads something inside, as the graph holds them. */
35
+ inbound: TfEdge[];
36
+ /** Edges where something inside reads something outside. */
37
+ outbound: TfEdge[];
38
+ counts: {
39
+ inbound: CutCount;
40
+ outbound: CutCount;
41
+ };
42
+ /** Cuts run in both directions: the set can move only with wiring both ways. */
43
+ bothWays: boolean;
44
+ }
45
+ /** The cut directions a closure may leave: `inbound` (outside may read in), `outbound` (inside may read out), or `none`. */
46
+ export type CutAllowance = "inbound" | "outbound" | "none";
47
+ export interface Closure extends Cuts {
48
+ /** The seeds as the walk saw them, folds contracted. */
49
+ seeds: string[];
50
+ allow: CutAllowance;
51
+ /**
52
+ * How many resource instances the set stands for: each block once, or its
53
+ * instance count once `--state` resolved it. `"unknown"` where a module or an
54
+ * unresolved `count`/`for_each` hides how much it holds; `hiddenBy` names them.
55
+ */
56
+ instances: number | "unknown";
57
+ hiddenBy?: string[];
58
+ }
59
+ export interface Component extends BlockSet {
60
+ /** As {@link Closure.instances}. */
61
+ instances: number | "unknown";
62
+ hiddenBy?: string[];
63
+ }
64
+ /**
65
+ * The graph's weakly connected components (#3909): blocks joined by a
66
+ * reference either way, fold-contracted, each module one node. An output never
67
+ * joins two components, since outputs are terminal; it is listed in every
68
+ * component it reads into. Components are sorted by their first address.
69
+ */
70
+ export declare function components(graph: TfGraph): Component[];
71
+ /**
72
+ * Every edge crossing the boundary of `addresses` (#3909). A folded block in
73
+ * the set brings its parent and siblings, and a fold parent its folded blocks,
74
+ * before anything is counted, so an edge inside one fold is never a cut. An
75
+ * `output.<name>` in the set is inside it like any block.
76
+ *
77
+ * Throws when an address is not a block of the graph.
78
+ */
79
+ export declare function cuts(graph: TfGraph, addresses: Iterable<string>): Cuts;
80
+ /**
81
+ * The smallest superset of `seeds` whose remaining cuts all run in the
82
+ * direction `allow` permits, plus those cuts (#3909).
83
+ *
84
+ * - `outbound`: nothing outside may read in, so the set takes every
85
+ * dependent of the seeds, outputs included.
86
+ * - `inbound`: nothing inside may read out, so the set takes everything the
87
+ * seeds depend on.
88
+ * - `none`: the seeds' whole components, with each output that reads only
89
+ * into them.
90
+ *
91
+ * Outputs are terminal, so none of these walks passes through one. An output
92
+ * that reads both the set and something outside it is therefore a cut no
93
+ * closure removes: under `none` it stays outside and its read into the set is
94
+ * left as an inbound cut, for the caller to wire.
95
+ */
96
+ export declare function closure(graph: TfGraph, seeds: Iterable<string>, allow: CutAllowance): Closure;
97
+ //# sourceMappingURL=cuts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cuts.d.ts","sourceRoot":"","sources":["../../src/terraform/cuts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE/C,2CAA2C;AAC3C,MAAM,WAAW,QAAQ;IACvB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,4CAA4C;AAC5C,MAAM,WAAW,QAAQ;IACvB,8FAA8F;IAC9F,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,2DAA2D;IAC3D,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,IAAK,SAAQ,QAAQ;IACpC,qFAAqF;IACrF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE;QAAE,OAAO,EAAE,QAAQ,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,CAAC;IAClD,gFAAgF;IAChF,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,4HAA4H;AAC5H,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;AAE3D,MAAM,WAAW,OAAQ,SAAQ,IAAI;IACnC,wDAAwD;IACxD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,YAAY,CAAC;IACpB;;;;OAIG;IACH,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,SAAU,SAAQ,QAAQ;IACzC,oCAAoC;IACpC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,EAAE,CAatD;AAED;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAGtE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAmB7F"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Cuts and reference-closed sets over the carve graph (#3909).
3
+ *
4
+ * `carve advise` scores one block at a time. A consumer splitting one root into
5
+ * several (terragucci's estate carving) needs the same question for a set:
6
+ * which edges cross its boundary and which way, and the smallest set around a
7
+ * seed whose crossings all run a way the caller allows. These are pure
8
+ * functions over `TfGraph`, on the index and walk in `reach.ts`, so the rules
9
+ * there hold here too: folds contract first, outputs are terminal and counted
10
+ * apart, modules and unresolved `count` are named as hiding their contents, a
11
+ * `depends_on` cycle terminates, and `crossStack` edges are counted apart.
12
+ *
13
+ * Nothing here ranks sets, reads state or plan times, writes HCL, or knows
14
+ * about roots or backends; that stays with the consumer.
15
+ */
16
+ import { carveIndex, cmp, hidesContents, isOutputAddress, walkFrom, weigh } from "./reach.js";
17
+ /**
18
+ * The graph's weakly connected components (#3909): blocks joined by a
19
+ * reference either way, fold-contracted, each module one node. An output never
20
+ * joins two components, since outputs are terminal; it is listed in every
21
+ * component it reads into. Components are sorted by their first address.
22
+ */
23
+ export function components(graph) {
24
+ const index = carveIndex(graph);
25
+ const assigned = new Set();
26
+ const found = [];
27
+ for (const address of [...index.nodes.keys()].sort(cmp)) {
28
+ const start = index.rep(address);
29
+ if (assigned.has(start))
30
+ continue;
31
+ const reached = walkFrom(index, [start], "both");
32
+ const reps = [start, ...[...reached.keys()].filter((a) => !isOutputAddress(a))];
33
+ for (const rep of reps)
34
+ assigned.add(rep);
35
+ found.push({ ...blockSet(index, reps, [...reached.keys()].filter(isOutputAddress)), ...holdings(index, reps) });
36
+ }
37
+ return found;
38
+ }
39
+ /**
40
+ * Every edge crossing the boundary of `addresses` (#3909). A folded block in
41
+ * the set brings its parent and siblings, and a fold parent its folded blocks,
42
+ * before anything is counted, so an edge inside one fold is never a cut. An
43
+ * `output.<name>` in the set is inside it like any block.
44
+ *
45
+ * Throws when an address is not a block of the graph.
46
+ */
47
+ export function cuts(graph, addresses) {
48
+ const index = carveIndex(graph);
49
+ return cutsOf(index, contract(index, addresses));
50
+ }
51
+ /**
52
+ * The smallest superset of `seeds` whose remaining cuts all run in the
53
+ * direction `allow` permits, plus those cuts (#3909).
54
+ *
55
+ * - `outbound`: nothing outside may read in, so the set takes every
56
+ * dependent of the seeds, outputs included.
57
+ * - `inbound`: nothing inside may read out, so the set takes everything the
58
+ * seeds depend on.
59
+ * - `none`: the seeds' whole components, with each output that reads only
60
+ * into them.
61
+ *
62
+ * Outputs are terminal, so none of these walks passes through one. An output
63
+ * that reads both the set and something outside it is therefore a cut no
64
+ * closure removes: under `none` it stays outside and its read into the set is
65
+ * left as an inbound cut, for the caller to wire.
66
+ */
67
+ export function closure(graph, seeds, allow) {
68
+ const index = carveIndex(graph);
69
+ const start = contract(index, seeds);
70
+ const direction = allow === "outbound" ? "in" : allow === "inbound" ? "out" : "both";
71
+ const members = new Set([...start, ...walkFrom(index, start, direction).keys()]);
72
+ if (allow === "none") {
73
+ for (const address of [...members]) {
74
+ if (!isOutputAddress(address) || start.has(address))
75
+ continue;
76
+ const reads = (index.adj.out.get(address) ?? []).map((e) => e.to);
77
+ if (!reads.every((to) => members.has(to)))
78
+ members.delete(address);
79
+ }
80
+ }
81
+ const found = cutsOf(index, members);
82
+ return {
83
+ ...found,
84
+ seeds: [...start].sort(cmp),
85
+ allow,
86
+ ...holdings(index, [...members].filter((a) => !isOutputAddress(a))),
87
+ };
88
+ }
89
+ /** The addresses as the walks see them: each fold child replaced by its parent. Throws on an unknown address. */
90
+ function contract(index, addresses) {
91
+ const out = new Set();
92
+ for (const address of addresses) {
93
+ const known = index.nodes.has(address) || (isOutputAddress(address) && index.adj.out.has(address));
94
+ if (!known)
95
+ throw new Error(`carve: ${address} is not a resource, module or output in this graph`);
96
+ out.add(index.rep(address));
97
+ }
98
+ return out;
99
+ }
100
+ function cutsOf(index, members) {
101
+ const inbound = [];
102
+ const outbound = [];
103
+ for (const address of members) {
104
+ for (const e of index.adj.in.get(address) ?? [])
105
+ if (!members.has(e.from))
106
+ inbound.push(e.edge);
107
+ for (const e of index.adj.out.get(address) ?? [])
108
+ if (!members.has(e.to))
109
+ outbound.push(e.edge);
110
+ }
111
+ const byEnds = (a, b) => cmp(a.from, b.from) || cmp(a.to, b.to);
112
+ inbound.sort(byEnds);
113
+ outbound.sort(byEnds);
114
+ const reps = [...members];
115
+ return {
116
+ ...blockSet(index, reps.filter((a) => !isOutputAddress(a)), reps.filter(isOutputAddress)),
117
+ inbound,
118
+ outbound,
119
+ counts: { inbound: countOf(inbound), outbound: countOf(outbound) },
120
+ bothWays: inbound.length > 0 && outbound.length > 0,
121
+ };
122
+ }
123
+ function countOf(edges) {
124
+ const outputs = edges.filter((e) => e.fromKind === "output").length;
125
+ return { resources: edges.length - outputs, outputs, crossStack: edges.filter((e) => e.crossStack).length };
126
+ }
127
+ function blockSet(index, reps, outputs) {
128
+ return {
129
+ resources: reps.flatMap((rep) => index.membersOf(rep)).sort(cmp),
130
+ outputs: [...outputs].sort(cmp),
131
+ };
132
+ }
133
+ function holdings(index, reps) {
134
+ const instances = weigh(index, reps);
135
+ if (instances !== "unknown")
136
+ return { instances };
137
+ return { instances, hiddenBy: reps.filter((a) => hidesContents(index.nodes.get(a))).sort(cmp) };
138
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Fold detection for the carve graph, shared by the scorer and the walks.
3
+ *
4
+ * A sub-resource whose type inlines into a parent (`foldParentOf`) carves with
5
+ * that parent when the parent is in the estate under the same name:
6
+ * `aws_s3_bucket_versioning.assets` goes with `aws_s3_bucket.assets`. The
7
+ * scorer drops it from the ranking and discounts its edge to the parent; the
8
+ * walks in `reach.ts` contract it into the parent before stepping, since an
9
+ * uncontracted walk counts the child as a separate dependent (#2325 measured a
10
+ * 100% overstatement on the sample estate). It lived privately in `score.ts`
11
+ * until the walks needed it.
12
+ */
13
+ import type { TfGraph } from "./types.js";
14
+ export interface Folds {
15
+ /** Every address that folds into a parent present in the estate. */
16
+ folded: Set<string>;
17
+ /** Parent address → the addresses folded into it. */
18
+ childrenOf: Map<string, Set<string>>;
19
+ }
20
+ /**
21
+ * Build the set of addresses that fold into a parent present in the estate, plus
22
+ * the reverse lookup (parent → its folded children), so a parent can discount
23
+ * inbound edges coming from its own folded sub-resources.
24
+ */
25
+ export declare function computeFolds(graph: TfGraph): Folds;
26
+ //# sourceMappingURL=folds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folds.d.ts","sourceRoot":"","sources":["../../src/terraform/folds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,WAAW,KAAK;IACpB,oEAAoE;IACpE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,qDAAqD;IACrD,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CACtC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAelD"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Fold detection for the carve graph, shared by the scorer and the walks.
3
+ *
4
+ * A sub-resource whose type inlines into a parent (`foldParentOf`) carves with
5
+ * that parent when the parent is in the estate under the same name:
6
+ * `aws_s3_bucket_versioning.assets` goes with `aws_s3_bucket.assets`. The
7
+ * scorer drops it from the ranking and discounts its edge to the parent; the
8
+ * walks in `reach.ts` contract it into the parent before stepping, since an
9
+ * uncontracted walk counts the child as a separate dependent (#2325 measured a
10
+ * 100% overstatement on the sample estate). It lived privately in `score.ts`
11
+ * until the walks needed it.
12
+ */
13
+ import { foldParentOf } from "./tier-map.js";
14
+ /**
15
+ * Build the set of addresses that fold into a parent present in the estate, plus
16
+ * the reverse lookup (parent → its folded children), so a parent can discount
17
+ * inbound edges coming from its own folded sub-resources.
18
+ */
19
+ export function computeFolds(graph) {
20
+ const byAddress = new Map(graph.nodes.map((n) => [n.address, n]));
21
+ const folded = new Set();
22
+ const childrenOf = new Map();
23
+ for (const node of graph.nodes) {
24
+ if (node.kind !== "resource" || !node.type)
25
+ continue;
26
+ const parentType = foldParentOf(node.type);
27
+ if (!parentType)
28
+ continue;
29
+ const parentAddress = `${parentType}.${node.name}`;
30
+ if (!byAddress.has(parentAddress))
31
+ continue; // sub-resource without its parent → score it on its own
32
+ folded.add(node.address);
33
+ if (!childrenOf.has(parentAddress))
34
+ childrenOf.set(parentAddress, new Set());
35
+ childrenOf.get(parentAddress).add(node.address);
36
+ }
37
+ return { folded, childrenOf };
38
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/terraform/graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAU,MAAM,SAAS,CAAC;AAErE;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;AAKpE,UAAU,MAAM;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA4BD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAe/D;AAiBD;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,EAAE,CAiB/D;AA8LD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAsFhF;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAEtE;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAEvE"}
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/terraform/graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAU,MAAM,SAAS,CAAC;AAErE;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;AAKpE,UAAU,MAAM;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA4BD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAe/D;AAiBD;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,EAAE,CAiB/D;AAqMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAwFhF;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAEtE;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAEvE"}
@@ -266,6 +266,14 @@ function throughReferrers(refs, resolved) {
266
266
  function blockHasMeta(block, key) {
267
267
  return !!block && typeof block === "object" && key in block;
268
268
  }
269
+ /** Which expansion meta-argument a block carries, as a spreadable `TfNode` field (#2325). */
270
+ function expansionOf(block) {
271
+ if (blockHasMeta(block, "count"))
272
+ return { expansion: "count" };
273
+ if (blockHasMeta(block, "for_each"))
274
+ return { expansion: "for_each" };
275
+ return {};
276
+ }
269
277
  /**
270
278
  * The literal string at a dotted path into a block, or undefined when the path
271
279
  * misses or lands on an interpolation. A dotted path walks nested blocks —
@@ -365,6 +373,7 @@ export function buildGraph(tree, exprRefs) {
365
373
  name,
366
374
  instances: 1,
367
375
  hasDynamic: dynamic || touchesData,
376
+ ...expansionOf(block),
368
377
  identity: literalIdentity(block, type),
369
378
  dataSourceValues: dataSourceValues(block, type),
370
379
  });
@@ -384,6 +393,7 @@ export function buildGraph(tree, exprRefs) {
384
393
  name,
385
394
  instances: 1,
386
395
  hasDynamic: dynamic || touchesData,
396
+ ...expansionOf(block),
387
397
  });
388
398
  }
389
399
  // Output blocks: referrers without being nodes (#1638). Their pseudo-address
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Transitive reachability over the carve graph (#2325).
3
+ *
4
+ * `inboundEdges`/`outboundEdges` in `graph.ts` answer one hop with a linear
5
+ * scan, which is right for the scorer's depth-1 counts and wrong as the step of
6
+ * a walk: calling it per node per step is O(V²E). This module builds one
7
+ * index per graph instead, and walks it with the same breadth-first walk
8
+ * `chant search` uses (`graph-walk.ts`).
9
+ *
10
+ * Four rules from the spike (docs/design/carve-dependency-blast-radius-spike.md)
11
+ * hold for every walk here and for the set functions in `cuts.ts` built on it:
12
+ *
13
+ * - Folds contract first. A folded sub-resource is its parent for the walk, so
14
+ * `aws_s3_bucket_versioning.assets` is never a dependent of
15
+ * `aws_s3_bucket.assets`, and a node reading the child depends on the
16
+ * parent.
17
+ * - Outputs are terminal and counted apart. An `output.<name>` pseudo-address
18
+ * has no inbound edges, so it never extends a path; it is reported in its
19
+ * own list.
20
+ * - Modules and unresolved `count`/`for_each` hide how much a node holds. A
21
+ * `module.x` node is one node whatever it contains, and `count = 20` is one
22
+ * node until `--state` resolves it. They are walked through and named, so a
23
+ * caller can say `unknown` instead of a number.
24
+ * - Cross-stack hops are told apart. On the CDK path an `Fn::ImportValue` edge
25
+ * carries `crossStack: true`; what is reachable only through one is listed
26
+ * separately.
27
+ *
28
+ * Pure, like the rest of the carve analysis. `src/cdk/graph.ts` emits the same
29
+ * `TfGraph`, so one implementation covers both sources.
30
+ */
31
+ import { type Adjacency } from "../graph-walk.js";
32
+ import type { TfEdge, TfGraph, TfNode } from "./types.js";
33
+ /** An edge with both ends contracted to their fold parents. `edge` is the edge as the graph holds it. */
34
+ export interface ContractedEdge extends TfEdge {
35
+ edge: TfEdge;
36
+ }
37
+ /** The index every walk over one graph shares. Built once per graph; see {@link carveIndex}. */
38
+ export interface CarveIndex {
39
+ graph: TfGraph;
40
+ /** Every node by address, folded sub-resources included. */
41
+ nodes: Map<string, TfNode>;
42
+ /** The address a walk sees for `address`: its fold parent, or itself. */
43
+ rep(address: string): string;
44
+ /** A walked node's own blocks: itself first, then what folds into it, sorted. */
45
+ membersOf(address: string): string[];
46
+ /** Contracted edges by both ends. An edge internal to one fold is dropped. */
47
+ adj: Adjacency<ContractedEdge>;
48
+ /** The graph has at least one `crossStack` edge (a CDK assembly of several stacks). */
49
+ crossStack: boolean;
50
+ }
51
+ /**
52
+ * The fold-contracted adjacency index for a graph, built on first use and
53
+ * cached against the graph object. O(V+E) to build; every walk after that is
54
+ * O(V+E). A caller that mutates `graph.edges` after the first walk must pass a
55
+ * new graph object (`applyStateCounts` only touches node instance counts, which
56
+ * the index reads live).
57
+ */
58
+ export declare function carveIndex(graph: TfGraph): CarveIndex;
59
+ /** `output.<name>`: a pseudo-address `buildGraph` gives an output block's edges (#1638). */
60
+ export declare function isOutputAddress(address: string): boolean;
61
+ /**
62
+ * Whether a node stands for an amount of infrastructure the graph cannot see:
63
+ * a Terraform `module` block (one node, whatever it holds; state is not read
64
+ * inside modules), or a `count`/`for_each` block whose instance count no
65
+ * `.tfstate` resolved. A CDK L3 construct is also `kind: "module"`, but its
66
+ * members are listed and its address is a construct path, so it hides nothing.
67
+ */
68
+ export declare function hidesContents(node: TfNode): boolean;
69
+ /**
70
+ * Which way a walk steps: `in` follows who reads a node (its dependents), `out`
71
+ * what it reads, `both` either (weak connectivity, #3909). An output is
72
+ * terminal every way: it is reached, never stepped from.
73
+ */
74
+ export type WalkDirection = "in" | "out" | "both";
75
+ /**
76
+ * Walk from `seeds` (already contracted) and return every node reached with its
77
+ * shortest depth, seeds excluded. `sameStack` refuses `crossStack` edges.
78
+ */
79
+ export declare function walkFrom(index: CarveIndex, seeds: Iterable<string>, direction: WalkDirection, opts?: {
80
+ sameStack?: boolean;
81
+ }): Map<string, number>;
82
+ /** What a walk from one node reached. Every list is sorted and holds contracted addresses. */
83
+ export interface Reach {
84
+ /** The node the walk started from: the requested address, or its fold parent. */
85
+ address: string;
86
+ /** Resource and module nodes reached, the start excluded. */
87
+ resources: string[];
88
+ /** `output.<name>` pseudo-addresses reached; terminal, never in `resources`. */
89
+ outputs: string[];
90
+ /** The longest shortest path to anything reached, outputs included; 0 when nothing was. */
91
+ depth: number;
92
+ /** Of `resources`, those reached only through a `crossStack` edge. Empty off the CDK path. */
93
+ crossStack: string[];
94
+ /** Of `resources`, those that hide how much they hold (see {@link hidesContents}). */
95
+ hidden: string[];
96
+ }
97
+ /**
98
+ * Everything reachable from `address` (#2325). Direction `in` (the default)
99
+ * walks dependents: what a change to `address` reaches, its blast radius.
100
+ * Direction `out` walks dependencies: what `address` needs.
101
+ *
102
+ * Throws when `address` is not a node of the graph.
103
+ */
104
+ export declare function reach(graph: TfGraph, address: string, opts?: {
105
+ direction?: WalkDirection;
106
+ }): Reach;
107
+ /** Code-point order, as `buildGraph` sorts: locale-independent. */
108
+ export declare function cmp(a: string, b: string): number;
109
+ /**
110
+ * How far a change to one node reaches, as `carve advise` reports it (#2326):
111
+ * its own axis beside the peelability score, never a penalty term. Every score
112
+ * term is a unit of work (an inbound edge is one data-source patch); a
113
+ * transitive dependent is not work, nobody patches it, and its count can run
114
+ * far past what a 0-100 score carries.
115
+ */
116
+ export interface BlastRadius {
117
+ /**
118
+ * Resources and modules that depend on the node, directly or not, weighted by
119
+ * instance count when `--state` resolved it. `"unknown"` when one of them is
120
+ * a module or a `count`/`for_each` no state resolved: see `hiddenBy`.
121
+ */
122
+ resources: number | "unknown";
123
+ /** `output` blocks that read the node or one of its dependents. */
124
+ outputs: number;
125
+ /** Hops to the farthest dependent, outputs included; 0 when nothing depends on it. */
126
+ depth: number;
127
+ /**
128
+ * Of `resources`, those reachable only through a `crossStack` edge (a CDK
129
+ * `Fn::ImportValue`), weighted the same way. Present only when the graph has
130
+ * such an edge.
131
+ */
132
+ crossStack?: number | "unknown";
133
+ /** The dependents that make a count `"unknown"`. Present only when one does. */
134
+ hiddenBy?: string[];
135
+ }
136
+ /** The instances `addresses` stand for, or `"unknown"` when one of them hides its contents. */
137
+ export declare function weigh(index: CarveIndex, addresses: readonly string[]): number | "unknown";
138
+ /** The {@link BlastRadius} of `address`: its {@link reach} through dependents, counted. */
139
+ export declare function blastRadius(graph: TfGraph, address: string): BlastRadius;
140
+ //# sourceMappingURL=reach.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reach.d.ts","sourceRoot":"","sources":["../../src/terraform/reach.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAE9E,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEvD,yGAAyG;AACzG,MAAM,WAAW,cAAe,SAAQ,MAAM;IAC5C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,gGAAgG;AAChG,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,4DAA4D;IAC5D,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,yEAAyE;IACzE,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,iFAAiF;IACjF,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACrC,8EAA8E;IAC9E,GAAG,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IAC/B,uFAAuF;IACvF,UAAU,EAAE,OAAO,CAAC;CACrB;AAID;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAyBrD;AAED,4FAA4F;AAC5F,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGnD;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,KAAK,GAAG,MAAM,CAAC;AAElD;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EACvB,SAAS,EAAE,aAAa,EACxB,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAmBrB;AAED,8FAA8F;AAC9F,MAAM,WAAW,KAAK;IACpB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,gFAAgF;IAChF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,2FAA2F;IAC3F,KAAK,EAAE,MAAM,CAAC;IACd,8FAA8F;IAC9F,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,sFAAsF;IACtF,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,aAAa,CAAA;CAAO,GAAG,KAAK,CAqBtG;AAED,mEAAmE;AACnE,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,+FAA+F;AAC/F,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAQzF;AAED,2FAA2F;AAC3F,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,CAUxE"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Transitive reachability over the carve graph (#2325).
3
+ *
4
+ * `inboundEdges`/`outboundEdges` in `graph.ts` answer one hop with a linear
5
+ * scan, which is right for the scorer's depth-1 counts and wrong as the step of
6
+ * a walk: calling it per node per step is O(V²E). This module builds one
7
+ * index per graph instead, and walks it with the same breadth-first walk
8
+ * `chant search` uses (`graph-walk.ts`).
9
+ *
10
+ * Four rules from the spike (docs/design/carve-dependency-blast-radius-spike.md)
11
+ * hold for every walk here and for the set functions in `cuts.ts` built on it:
12
+ *
13
+ * - Folds contract first. A folded sub-resource is its parent for the walk, so
14
+ * `aws_s3_bucket_versioning.assets` is never a dependent of
15
+ * `aws_s3_bucket.assets`, and a node reading the child depends on the
16
+ * parent.
17
+ * - Outputs are terminal and counted apart. An `output.<name>` pseudo-address
18
+ * has no inbound edges, so it never extends a path; it is reported in its
19
+ * own list.
20
+ * - Modules and unresolved `count`/`for_each` hide how much a node holds. A
21
+ * `module.x` node is one node whatever it contains, and `count = 20` is one
22
+ * node until `--state` resolves it. They are walked through and named, so a
23
+ * caller can say `unknown` instead of a number.
24
+ * - Cross-stack hops are told apart. On the CDK path an `Fn::ImportValue` edge
25
+ * carries `crossStack: true`; what is reachable only through one is listed
26
+ * separately.
27
+ *
28
+ * Pure, like the rest of the carve analysis. `src/cdk/graph.ts` emits the same
29
+ * `TfGraph`, so one implementation covers both sources.
30
+ */
31
+ import { adjacencyOf, walkBreadthFirst } from "../graph-walk.js";
32
+ import { computeFolds } from "./folds.js";
33
+ const indexes = new WeakMap();
34
+ /**
35
+ * The fold-contracted adjacency index for a graph, built on first use and
36
+ * cached against the graph object. O(V+E) to build; every walk after that is
37
+ * O(V+E). A caller that mutates `graph.edges` after the first walk must pass a
38
+ * new graph object (`applyStateCounts` only touches node instance counts, which
39
+ * the index reads live).
40
+ */
41
+ export function carveIndex(graph) {
42
+ const cached = indexes.get(graph);
43
+ if (cached)
44
+ return cached;
45
+ const nodes = new Map(graph.nodes.map((n) => [n.address, n]));
46
+ const parentOf = new Map();
47
+ const { childrenOf } = computeFolds(graph);
48
+ for (const [parent, children] of childrenOf)
49
+ for (const child of children)
50
+ parentOf.set(child, parent);
51
+ const rep = (address) => parentOf.get(address) ?? address;
52
+ const contracted = [];
53
+ for (const e of graph.edges) {
54
+ const from = rep(e.from);
55
+ const to = rep(e.to);
56
+ if (from === to)
57
+ continue; // a folded child reading its own parent is not an edge of the fold
58
+ contracted.push({ ...e, from, to, edge: e });
59
+ }
60
+ const index = {
61
+ graph,
62
+ nodes,
63
+ rep,
64
+ membersOf: (address) => [address, ...[...(childrenOf.get(address) ?? [])].sort()],
65
+ adj: adjacencyOf(contracted),
66
+ crossStack: graph.edges.some((e) => e.crossStack),
67
+ };
68
+ indexes.set(graph, index);
69
+ return index;
70
+ }
71
+ /** `output.<name>`: a pseudo-address `buildGraph` gives an output block's edges (#1638). */
72
+ export function isOutputAddress(address) {
73
+ return address.startsWith("output.");
74
+ }
75
+ /**
76
+ * Whether a node stands for an amount of infrastructure the graph cannot see:
77
+ * a Terraform `module` block (one node, whatever it holds; state is not read
78
+ * inside modules), or a `count`/`for_each` block whose instance count no
79
+ * `.tfstate` resolved. A CDK L3 construct is also `kind: "module"`, but its
80
+ * members are listed and its address is a construct path, so it hides nothing.
81
+ */
82
+ export function hidesContents(node) {
83
+ if (node.kind === "module" && node.address.startsWith("module."))
84
+ return true;
85
+ return node.expansion !== undefined && node.instancesFrom !== "state";
86
+ }
87
+ /**
88
+ * Walk from `seeds` (already contracted) and return every node reached with its
89
+ * shortest depth, seeds excluded. `sameStack` refuses `crossStack` edges.
90
+ */
91
+ export function walkFrom(index, seeds, direction, opts = {}) {
92
+ const start = new Set(seeds);
93
+ const reached = new Map();
94
+ const stepsAlong = (edges, far) => (edges ?? []).filter((e) => !(opts.sameStack && e.crossStack)).map((e) => ({ far: e[far], hops: [] }));
95
+ walkBreadthFirst(start, {
96
+ steps: (id) => {
97
+ if (isOutputAddress(id) && !start.has(id))
98
+ return [];
99
+ const steps = [];
100
+ if (direction !== "out")
101
+ steps.push(...stepsAlong(index.adj.in.get(id), "from"));
102
+ if (direction !== "in")
103
+ steps.push(...stepsAlong(index.adj.out.get(id), "to"));
104
+ return steps;
105
+ },
106
+ arrive: ({ id, depth }) => {
107
+ if (!start.has(id) && !reached.has(id))
108
+ reached.set(id, depth);
109
+ return false;
110
+ },
111
+ });
112
+ return reached;
113
+ }
114
+ /**
115
+ * Everything reachable from `address` (#2325). Direction `in` (the default)
116
+ * walks dependents: what a change to `address` reaches, its blast radius.
117
+ * Direction `out` walks dependencies: what `address` needs.
118
+ *
119
+ * Throws when `address` is not a node of the graph.
120
+ */
121
+ export function reach(graph, address, opts = {}) {
122
+ const index = carveIndex(graph);
123
+ if (!index.nodes.has(address))
124
+ throw new Error(`reach: ${address} is not a resource or module in this graph`);
125
+ const start = index.rep(address);
126
+ const direction = opts.direction ?? "in";
127
+ const reached = walkFrom(index, [start], direction);
128
+ const sorted = [...reached.keys()].sort(cmp);
129
+ const resources = sorted.filter((a) => !isOutputAddress(a));
130
+ let crossStack = [];
131
+ if (index.crossStack) {
132
+ const inStack = walkFrom(index, [start], direction, { sameStack: true });
133
+ crossStack = resources.filter((a) => !inStack.has(a));
134
+ }
135
+ return {
136
+ address: start,
137
+ resources,
138
+ outputs: sorted.filter(isOutputAddress),
139
+ depth: Math.max(0, ...reached.values()),
140
+ crossStack,
141
+ hidden: resources.filter((a) => hidesContents(index.nodes.get(a))),
142
+ };
143
+ }
144
+ /** Code-point order, as `buildGraph` sorts: locale-independent. */
145
+ export function cmp(a, b) {
146
+ return a < b ? -1 : a > b ? 1 : 0;
147
+ }
148
+ /** The instances `addresses` stand for, or `"unknown"` when one of them hides its contents. */
149
+ export function weigh(index, addresses) {
150
+ let total = 0;
151
+ for (const address of addresses) {
152
+ const node = index.nodes.get(address);
153
+ if (hidesContents(node))
154
+ return "unknown";
155
+ total += node.instances;
156
+ }
157
+ return total;
158
+ }
159
+ /** The {@link BlastRadius} of `address`: its {@link reach} through dependents, counted. */
160
+ export function blastRadius(graph, address) {
161
+ const index = carveIndex(graph);
162
+ const r = reach(graph, address);
163
+ return {
164
+ resources: weigh(index, r.resources),
165
+ outputs: r.outputs.length,
166
+ depth: r.depth,
167
+ ...(index.crossStack ? { crossStack: weigh(index, r.crossStack) } : {}),
168
+ ...(r.hidden.length ? { hiddenBy: r.hidden } : {}),
169
+ };
170
+ }