infraweaver 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (524) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +244 -0
  3. package/dist/agents/claude.d.ts +113 -0
  4. package/dist/agents/claudePretoolGate.d.ts +137 -0
  5. package/dist/agents/dispatchMetrics.d.ts +77 -0
  6. package/dist/agents/gateServer.d.ts +7 -0
  7. package/dist/agents/index.d.ts +6 -0
  8. package/dist/agents/nativeFsDenies.d.ts +46 -0
  9. package/dist/agents/opencode.d.ts +284 -0
  10. package/dist/agents/opencodePlugin.d.ts +96 -0
  11. package/dist/agents/opencodeShared.d.ts +40 -0
  12. package/dist/agents/postRun.d.ts +126 -0
  13. package/dist/agents/reviewer.d.ts +41 -0
  14. package/dist/agents/sessionLabeler.d.ts +97 -0
  15. package/dist/agents/shared.d.ts +246 -0
  16. package/dist/agents/subagentModels.d.ts +19 -0
  17. package/dist/agents/tokenQuota.d.ts +118 -0
  18. package/dist/agents/writeGateSource.d.ts +22 -0
  19. package/dist/agents/writePolicy.d.ts +79 -0
  20. package/dist/brand.d.ts +67 -0
  21. package/dist/cli.mjs +247846 -0
  22. package/dist/external.d.ts +227 -0
  23. package/dist/i18n/scaffolding.d.ts +59 -0
  24. package/dist/index.d.ts +6 -0
  25. package/dist/index.js +247061 -0
  26. package/dist/internal/index.d.ts +18 -0
  27. package/dist/internal.js +2398 -0
  28. package/dist/lifecycle.d.ts +2 -0
  29. package/dist/main.d.ts +8 -0
  30. package/dist/mcp/arkConfig.d.ts +1 -0
  31. package/dist/mcp/assess.d.ts +157 -0
  32. package/dist/mcp/capabilityContext.d.ts +71 -0
  33. package/dist/mcp/changeSummary.d.ts +52 -0
  34. package/dist/mcp/checkSuite.d.ts +27 -0
  35. package/dist/mcp/checkout.d.ts +92 -0
  36. package/dist/mcp/comment.d.ts +127 -0
  37. package/dist/mcp/commitInfo.d.ts +11 -0
  38. package/dist/mcp/crosswalk.d.ts +178 -0
  39. package/dist/mcp/crosswalkDigest.d.ts +1 -0
  40. package/dist/mcp/cyberEssentials.d.ts +24 -0
  41. package/dist/mcp/dashboard.d.ts +125 -0
  42. package/dist/mcp/dependencies.d.ts +12 -0
  43. package/dist/mcp/frameworks.d.ts +74 -0
  44. package/dist/mcp/geminiSanitizer.d.ts +28 -0
  45. package/dist/mcp/git.d.ts +60 -0
  46. package/dist/mcp/guardrails.d.ts +222 -0
  47. package/dist/mcp/issue.d.ts +20 -0
  48. package/dist/mcp/issueComments.d.ts +11 -0
  49. package/dist/mcp/issueEvents.d.ts +11 -0
  50. package/dist/mcp/issueInfo.d.ts +11 -0
  51. package/dist/mcp/labels.d.ts +14 -0
  52. package/dist/mcp/localContext.d.ts +26 -0
  53. package/dist/mcp/moduleExtraction.d.ts +79 -0
  54. package/dist/mcp/moduleTests.d.ts +106 -0
  55. package/dist/mcp/modules.d.ts +198 -0
  56. package/dist/mcp/output.d.ts +16 -0
  57. package/dist/mcp/pathSafety.d.ts +14 -0
  58. package/dist/mcp/policy.d.ts +50 -0
  59. package/dist/mcp/pr.d.ts +64 -0
  60. package/dist/mcp/prInfo.d.ts +11 -0
  61. package/dist/mcp/providerSchema.d.ts +52 -0
  62. package/dist/mcp/review.d.ts +212 -0
  63. package/dist/mcp/reviewComments.d.ts +245 -0
  64. package/dist/mcp/roots.d.ts +60 -0
  65. package/dist/mcp/scope.d.ts +26 -0
  66. package/dist/mcp/selectMode.d.ts +20 -0
  67. package/dist/mcp/server.d.ts +61 -0
  68. package/dist/mcp/shared.d.ts +62 -0
  69. package/dist/mcp/shell.d.ts +58 -0
  70. package/dist/mcp/staleFix.d.ts +138 -0
  71. package/dist/mcp/terraform/azurePrices.d.ts +8 -0
  72. package/dist/mcp/terraform/baseline.d.ts +57 -0
  73. package/dist/mcp/terraform/concernResult.d.ts +38 -0
  74. package/dist/mcp/terraform/cost.d.ts +55 -0
  75. package/dist/mcp/terraform/cspm.d.ts +80 -0
  76. package/dist/mcp/terraform/currency.d.ts +110 -0
  77. package/dist/mcp/terraform/decisions.d.ts +178 -0
  78. package/dist/mcp/terraform/eidas.d.ts +100 -0
  79. package/dist/mcp/terraform/evidence.d.ts +343 -0
  80. package/dist/mcp/terraform/findings.d.ts +76 -0
  81. package/dist/mcp/terraform/fixMemory.d.ts +81 -0
  82. package/dist/mcp/terraform/governance.d.ts +56 -0
  83. package/dist/mcp/terraform/hcl.d.ts +115 -0
  84. package/dist/mcp/terraform/iacLanguages.d.ts +120 -0
  85. package/dist/mcp/terraform/idleFloor.d.ts +78 -0
  86. package/dist/mcp/terraform/keyless.d.ts +68 -0
  87. package/dist/mcp/terraform/moduleDocs.d.ts +56 -0
  88. package/dist/mcp/terraform/nativeRules.d.ts +38 -0
  89. package/dist/mcp/terraform/nativeScan.d.ts +11 -0
  90. package/dist/mcp/terraform/noiseProfile.d.ts +100 -0
  91. package/dist/mcp/terraform/normalization.d.ts +52 -0
  92. package/dist/mcp/terraform/oscal.d.ts +103 -0
  93. package/dist/mcp/terraform/packs/azurerm-3-4.d.ts +2 -0
  94. package/dist/mcp/terraform/packs/cloudflare-4-5.d.ts +2 -0
  95. package/dist/mcp/terraform/paths.d.ts +28 -0
  96. package/dist/mcp/terraform/plan.d.ts +157 -0
  97. package/dist/mcp/terraform/planDrift.d.ts +199 -0
  98. package/dist/mcp/terraform/policyAuthor.d.ts +191 -0
  99. package/dist/mcp/terraform/prowlerOcsf.d.ts +136 -0
  100. package/dist/mcp/terraform/refactor.d.ts +183 -0
  101. package/dist/mcp/terraform/registry.d.ts +108 -0
  102. package/dist/mcp/terraform/risk.d.ts +41 -0
  103. package/dist/mcp/terraform/scanSession.d.ts +116 -0
  104. package/dist/mcp/terraform/scannerCache.d.ts +15 -0
  105. package/dist/mcp/terraform/scannerEgress.d.ts +72 -0
  106. package/dist/mcp/terraform/scannerJson.d.ts +13 -0
  107. package/dist/mcp/terraform/scanners.d.ts +205 -0
  108. package/dist/mcp/terraform/signing.d.ts +61 -0
  109. package/dist/mcp/terraform/stateLocking.d.ts +18 -0
  110. package/dist/mcp/terraform/subprocess.d.ts +43 -0
  111. package/dist/mcp/terraform/suppressions.d.ts +90 -0
  112. package/dist/mcp/terraform/taxonomy.d.ts +39 -0
  113. package/dist/mcp/terraform/tfquery.d.ts +47 -0
  114. package/dist/mcp/terraform/toolchainIntegrity.d.ts +82 -0
  115. package/dist/mcp/terraform/tools/authorPolicy.d.ts +59 -0
  116. package/dist/mcp/terraform/tools/detectPlanDrift.d.ts +20 -0
  117. package/dist/mcp/terraform/tools/emitCost.d.ts +11 -0
  118. package/dist/mcp/terraform/tools/emitSarif.d.ts +14 -0
  119. package/dist/mcp/terraform/tools/fixMemory.d.ts +19 -0
  120. package/dist/mcp/terraform/tools/infracostDiff.d.ts +22 -0
  121. package/dist/mcp/terraform/tools/ingestExternalFindings.d.ts +21 -0
  122. package/dist/mcp/terraform/tools/moduleLookup.d.ts +14 -0
  123. package/dist/mcp/terraform/tools/moduleSearch.d.ts +23 -0
  124. package/dist/mcp/terraform/tools/plan.d.ts +59 -0
  125. package/dist/mcp/terraform/tools/providerUpgrade.d.ts +55 -0
  126. package/dist/mcp/terraform/tools/readFindings.d.ts +17 -0
  127. package/dist/mcp/terraform/tools/scan.d.ts +114 -0
  128. package/dist/mcp/terraform/tools/validate.d.ts +31 -0
  129. package/dist/mcp/terraform/tools/verifyRemediation.d.ts +31 -0
  130. package/dist/mcp/terraform/tools/versionCurrency.d.ts +5 -0
  131. package/dist/mcp/terraform/tools.d.ts +16 -0
  132. package/dist/mcp/terraform/transformPacks.d.ts +267 -0
  133. package/dist/mcp/terraform/types.d.ts +226 -0
  134. package/dist/mcp/terraform/verification.d.ts +81 -0
  135. package/dist/mcp/terraform/vex.d.ts +115 -0
  136. package/dist/mcp/terraform/writeOnly.d.ts +67 -0
  137. package/dist/mcp/terraform.d.ts +51 -0
  138. package/dist/mcp/terratest.d.ts +85 -0
  139. package/dist/mcp/untrustedContent.d.ts +76 -0
  140. package/dist/mcp/upload.d.ts +8 -0
  141. package/dist/models.d.ts +181 -0
  142. package/dist/modes/address-reviews.d.ts +2 -0
  143. package/dist/modes/assess.d.ts +2 -0
  144. package/dist/modes/build.d.ts +2 -0
  145. package/dist/modes/compliance-audit.d.ts +2 -0
  146. package/dist/modes/cost-optimization.d.ts +2 -0
  147. package/dist/modes/drift-detect.d.ts +2 -0
  148. package/dist/modes/fix.d.ts +2 -0
  149. package/dist/modes/incremental-review.d.ts +2 -0
  150. package/dist/modes/index.d.ts +24 -0
  151. package/dist/modes/modernize-deprecated.d.ts +2 -0
  152. package/dist/modes/plan.d.ts +2 -0
  153. package/dist/modes/policy-gate.d.ts +2 -0
  154. package/dist/modes/prFormats.d.ts +3 -0
  155. package/dist/modes/refactor.d.ts +2 -0
  156. package/dist/modes/refresh-remediation.d.ts +2 -0
  157. package/dist/modes/remediate-and-refactor.d.ts +2 -0
  158. package/dist/modes/remediate.d.ts +2 -0
  159. package/dist/modes/resolve-conflicts.d.ts +2 -0
  160. package/dist/modes/review.d.ts +2 -0
  161. package/dist/modes/summarize-pr.d.ts +2 -0
  162. package/dist/modes/task.d.ts +2 -0
  163. package/dist/modes/terraform-code-review.d.ts +2 -0
  164. package/dist/modes/types.d.ts +9 -0
  165. package/dist/modes/update-dependencies.d.ts +2 -0
  166. package/dist/prep/index.d.ts +7 -0
  167. package/dist/prep/installNodeDependencies.d.ts +2 -0
  168. package/dist/prep/installPythonDependencies.d.ts +2 -0
  169. package/dist/prep/types.d.ts +31 -0
  170. package/dist/reviewQuality.d.ts +107 -0
  171. package/dist/skills/terraform-best-practices/SKILL.md +379 -0
  172. package/dist/toolState.d.ts +123 -0
  173. package/dist/utils/activity.d.ts +40 -0
  174. package/dist/utils/agent.d.ts +47 -0
  175. package/dist/utils/agentHangReport.d.ts +38 -0
  176. package/dist/utils/annotations.d.ts +17 -0
  177. package/dist/utils/apiFetch.d.ts +11 -0
  178. package/dist/utils/apiKeys.d.ts +48 -0
  179. package/dist/utils/apiUrl.d.ts +28 -0
  180. package/dist/utils/assets.d.ts +8 -0
  181. package/dist/utils/baseRefConfig.d.ts +121 -0
  182. package/dist/utils/billingErrors.d.ts +85 -0
  183. package/dist/utils/body.d.ts +34 -0
  184. package/dist/utils/buildInfraweaverFooter.d.ts +29 -0
  185. package/dist/utils/byokFallback.d.ts +85 -0
  186. package/dist/utils/changeImpact.d.ts +101 -0
  187. package/dist/utils/claudeSubscription.d.ts +30 -0
  188. package/dist/utils/cli.d.ts +10 -0
  189. package/dist/utils/cloudClient.d.ts +33 -0
  190. package/dist/utils/cloudFetchCore.d.ts +42 -0
  191. package/dist/utils/cloudReport.d.ts +114 -0
  192. package/dist/utils/codexHome.d.ts +29 -0
  193. package/dist/utils/codexOAuth.d.ts +60 -0
  194. package/dist/utils/diffCoverage.d.ts +63 -0
  195. package/dist/utils/env.d.ts +46 -0
  196. package/dist/utils/errorReport.d.ts +17 -0
  197. package/dist/utils/exitHandler.d.ts +8 -0
  198. package/dist/utils/fixDoubleEscapedString.d.ts +1 -0
  199. package/dist/utils/gitAuth.d.ts +84 -0
  200. package/dist/utils/gitAuthServer.d.ts +24 -0
  201. package/dist/utils/github.d.ts +104 -0
  202. package/dist/utils/globals.d.ts +3 -0
  203. package/dist/utils/infraweaverConfig.d.ts +56 -0
  204. package/dist/utils/install.d.ts +37 -0
  205. package/dist/utils/instructions.d.ts +48 -0
  206. package/dist/utils/keylessOidc.d.ts +28 -0
  207. package/dist/utils/leapingComment.d.ts +11 -0
  208. package/dist/utils/learnings.d.ts +62 -0
  209. package/dist/utils/learningsTruncate.d.ts +25 -0
  210. package/dist/utils/lifecycle.d.ts +57 -0
  211. package/dist/utils/log.d.ts +111 -0
  212. package/dist/utils/modelResolver.d.ts +63 -0
  213. package/dist/utils/moduleFetch.d.ts +39 -0
  214. package/dist/utils/normalizeEnv.d.ts +30 -0
  215. package/dist/utils/openCodeModels.d.ts +11 -0
  216. package/dist/utils/openaiCompatible.d.ts +26 -0
  217. package/dist/utils/opentofuMcp.d.ts +50 -0
  218. package/dist/utils/overrides.d.ts +40 -0
  219. package/dist/utils/packageManager.d.ts +49 -0
  220. package/dist/utils/patchWorkflowRunFields.d.ts +29 -0
  221. package/dist/utils/payload.d.ts +249 -0
  222. package/dist/utils/prSummary.d.ts +61 -0
  223. package/dist/utils/presets.d.ts +36 -0
  224. package/dist/utils/progressComment.d.ts +146 -0
  225. package/dist/utils/providerErrors.d.ts +31 -0
  226. package/dist/utils/proxyModel.d.ts +76 -0
  227. package/dist/utils/rangeDiff.d.ts +51 -0
  228. package/dist/utils/redact.d.ts +33 -0
  229. package/dist/utils/registryAuth.d.ts +52 -0
  230. package/dist/utils/remediationCommand.d.ts +58 -0
  231. package/dist/utils/retry.d.ts +38 -0
  232. package/dist/utils/reviewCleanup.d.ts +14 -0
  233. package/dist/utils/run.d.ts +9 -0
  234. package/dist/utils/runContext.d.ts +112 -0
  235. package/dist/utils/runContextData.d.ts +42 -0
  236. package/dist/utils/runErrorRenderer.d.ts +64 -0
  237. package/dist/utils/runLifecycle.d.ts +89 -0
  238. package/dist/utils/runStartupLog.d.ts +15 -0
  239. package/dist/utils/secrets.d.ts +34 -0
  240. package/dist/utils/setup.d.ts +90 -0
  241. package/dist/utils/shell.d.ts +44 -0
  242. package/dist/utils/skills.d.ts +10 -0
  243. package/dist/utils/subprocess.d.ts +81 -0
  244. package/dist/utils/terraformMcp.d.ts +46 -0
  245. package/dist/utils/time.d.ts +15 -0
  246. package/dist/utils/timer.d.ts +23 -0
  247. package/dist/utils/todoTracking.d.ts +16 -0
  248. package/dist/utils/token.d.ts +52 -0
  249. package/dist/utils/toolLicensing.d.ts +56 -0
  250. package/dist/utils/toolSelection.d.ts +73 -0
  251. package/dist/utils/toon.d.ts +16 -0
  252. package/dist/utils/version.d.ts +2 -0
  253. package/dist/utils/versioning.d.ts +7 -0
  254. package/dist/utils/vertex.d.ts +16 -0
  255. package/dist/utils/workflow.d.ts +13 -0
  256. package/package.json +132 -0
  257. package/src/agents/claude.ts +1588 -0
  258. package/src/agents/claudePretoolGate.ts +286 -0
  259. package/src/agents/dispatchMetrics.ts +162 -0
  260. package/src/agents/gateServer.ts +178 -0
  261. package/src/agents/index.ts +10 -0
  262. package/src/agents/nativeFsDenies.ts +164 -0
  263. package/src/agents/opencode.ts +1600 -0
  264. package/src/agents/opencodePlugin.ts +304 -0
  265. package/src/agents/opencodeShared.ts +134 -0
  266. package/src/agents/postRun.ts +615 -0
  267. package/src/agents/reviewer.ts +134 -0
  268. package/src/agents/sessionLabeler.ts +185 -0
  269. package/src/agents/shared.ts +377 -0
  270. package/src/agents/subagentModels.ts +40 -0
  271. package/src/agents/tokenQuota.ts +203 -0
  272. package/src/agents/writeGateSource.ts +148 -0
  273. package/src/agents/writePolicy.ts +132 -0
  274. package/src/brand.ts +84 -0
  275. package/src/cli.ts +117 -0
  276. package/src/commands/gha.ts +188 -0
  277. package/src/commands/mcp.ts +126 -0
  278. package/src/commands/verifyEvidence.ts +100 -0
  279. package/src/entry.ts +7 -0
  280. package/src/entryPost.ts +109 -0
  281. package/src/external.ts +308 -0
  282. package/src/i18n/scaffolding.ts +191 -0
  283. package/src/index.ts +7 -0
  284. package/src/internal/index.ts +74 -0
  285. package/src/lifecycle.ts +2 -0
  286. package/src/main.ts +815 -0
  287. package/src/mcp/__fixtures__/infraweaver-scratch-pr-49-review-3485940013.json +110 -0
  288. package/src/mcp/__fixtures__/infraweaver-scratch-pr-64-review-3531000326.json +14 -0
  289. package/src/mcp/__fixtures__/infraweaver-test-repo-pr-1.diff.json +67 -0
  290. package/src/mcp/__snapshots__/checkout.test.ts.snap +109 -0
  291. package/src/mcp/__snapshots__/reviewComments.test.ts.snap +71 -0
  292. package/src/mcp/arkConfig.ts +7 -0
  293. package/src/mcp/assess.ts +723 -0
  294. package/src/mcp/capabilityContext.ts +80 -0
  295. package/src/mcp/changeSummary.ts +145 -0
  296. package/src/mcp/checkSuite.ts +261 -0
  297. package/src/mcp/checkout.ts +1015 -0
  298. package/src/mcp/comment.ts +683 -0
  299. package/src/mcp/commitInfo.ts +57 -0
  300. package/src/mcp/crosswalk.ts +1253 -0
  301. package/src/mcp/crosswalkDigest.ts +5 -0
  302. package/src/mcp/cyberEssentials.ts +60 -0
  303. package/src/mcp/dashboard.ts +232 -0
  304. package/src/mcp/dependencies.ts +190 -0
  305. package/src/mcp/frameworks.ts +236 -0
  306. package/src/mcp/geminiSanitizer.ts +212 -0
  307. package/src/mcp/git.ts +1116 -0
  308. package/src/mcp/guardrails.ts +771 -0
  309. package/src/mcp/issue.ts +74 -0
  310. package/src/mcp/issueComments.ts +48 -0
  311. package/src/mcp/issueEvents.ts +100 -0
  312. package/src/mcp/issueInfo.ts +72 -0
  313. package/src/mcp/labels.ts +35 -0
  314. package/src/mcp/localContext.ts +65 -0
  315. package/src/mcp/localServer.ts +217 -0
  316. package/src/mcp/moduleExtraction.ts +368 -0
  317. package/src/mcp/moduleTests.ts +421 -0
  318. package/src/mcp/modules.ts +752 -0
  319. package/src/mcp/output.ts +71 -0
  320. package/src/mcp/pathSafety.ts +28 -0
  321. package/src/mcp/policy.ts +226 -0
  322. package/src/mcp/pr.ts +238 -0
  323. package/src/mcp/prInfo.ts +91 -0
  324. package/src/mcp/providerSchema.ts +175 -0
  325. package/src/mcp/review.ts +1081 -0
  326. package/src/mcp/reviewComments.ts +1137 -0
  327. package/src/mcp/roots.ts +217 -0
  328. package/src/mcp/scope.ts +82 -0
  329. package/src/mcp/selectMode.ts +207 -0
  330. package/src/mcp/server.ts +498 -0
  331. package/src/mcp/shared.ts +120 -0
  332. package/src/mcp/shell.ts +631 -0
  333. package/src/mcp/staleFix.ts +557 -0
  334. package/src/mcp/terraform/__snapshots__/moduleDocs.test.ts.snap +40 -0
  335. package/src/mcp/terraform/azurePrices.ts +38 -0
  336. package/src/mcp/terraform/baseline.ts +172 -0
  337. package/src/mcp/terraform/concernResult.ts +111 -0
  338. package/src/mcp/terraform/cost.ts +175 -0
  339. package/src/mcp/terraform/cspm.ts +326 -0
  340. package/src/mcp/terraform/currency.ts +354 -0
  341. package/src/mcp/terraform/decisions.ts +590 -0
  342. package/src/mcp/terraform/eidas.ts +134 -0
  343. package/src/mcp/terraform/evidence.ts +771 -0
  344. package/src/mcp/terraform/findings.ts +383 -0
  345. package/src/mcp/terraform/fixMemory.ts +253 -0
  346. package/src/mcp/terraform/governance.ts +231 -0
  347. package/src/mcp/terraform/hcl.ts +273 -0
  348. package/src/mcp/terraform/iacLanguages.ts +431 -0
  349. package/src/mcp/terraform/idleFloor.ts +304 -0
  350. package/src/mcp/terraform/keyless.ts +123 -0
  351. package/src/mcp/terraform/moduleDocs.ts +303 -0
  352. package/src/mcp/terraform/nativeRules.ts +152 -0
  353. package/src/mcp/terraform/nativeScan.ts +67 -0
  354. package/src/mcp/terraform/noiseProfile.ts +183 -0
  355. package/src/mcp/terraform/normalization.ts +265 -0
  356. package/src/mcp/terraform/oscal.ts +283 -0
  357. package/src/mcp/terraform/packs/azurerm-3-4.ts +382 -0
  358. package/src/mcp/terraform/packs/cloudflare-4-5.ts +114 -0
  359. package/src/mcp/terraform/paths.ts +59 -0
  360. package/src/mcp/terraform/plan.ts +377 -0
  361. package/src/mcp/terraform/planDrift.ts +520 -0
  362. package/src/mcp/terraform/policyAuthor.ts +886 -0
  363. package/src/mcp/terraform/prowlerOcsf.ts +380 -0
  364. package/src/mcp/terraform/refactor.ts +879 -0
  365. package/src/mcp/terraform/registry.ts +317 -0
  366. package/src/mcp/terraform/risk.ts +99 -0
  367. package/src/mcp/terraform/scanSession.ts +242 -0
  368. package/src/mcp/terraform/scannerCache.ts +86 -0
  369. package/src/mcp/terraform/scannerEgress.ts +141 -0
  370. package/src/mcp/terraform/scannerJson.ts +22 -0
  371. package/src/mcp/terraform/scanners.ts +1134 -0
  372. package/src/mcp/terraform/signing.ts +151 -0
  373. package/src/mcp/terraform/stateLocking.ts +106 -0
  374. package/src/mcp/terraform/subprocess.ts +102 -0
  375. package/src/mcp/terraform/suppressions.ts +551 -0
  376. package/src/mcp/terraform/taxonomy.ts +0 -0
  377. package/src/mcp/terraform/tfquery.ts +159 -0
  378. package/src/mcp/terraform/toolchainIntegrity.ts +151 -0
  379. package/src/mcp/terraform/tools/authorPolicy.ts +185 -0
  380. package/src/mcp/terraform/tools/detectPlanDrift.ts +279 -0
  381. package/src/mcp/terraform/tools/emitCost.ts +130 -0
  382. package/src/mcp/terraform/tools/emitSarif.ts +108 -0
  383. package/src/mcp/terraform/tools/fixMemory.ts +82 -0
  384. package/src/mcp/terraform/tools/infracostDiff.ts +110 -0
  385. package/src/mcp/terraform/tools/ingestExternalFindings.ts +259 -0
  386. package/src/mcp/terraform/tools/moduleLookup.ts +86 -0
  387. package/src/mcp/terraform/tools/moduleSearch.ts +46 -0
  388. package/src/mcp/terraform/tools/plan.ts +384 -0
  389. package/src/mcp/terraform/tools/providerUpgrade.ts +217 -0
  390. package/src/mcp/terraform/tools/readFindings.ts +138 -0
  391. package/src/mcp/terraform/tools/scan.ts +303 -0
  392. package/src/mcp/terraform/tools/validate.ts +160 -0
  393. package/src/mcp/terraform/tools/verifyRemediation.ts +190 -0
  394. package/src/mcp/terraform/tools/versionCurrency.ts +64 -0
  395. package/src/mcp/terraform/tools.ts +62 -0
  396. package/src/mcp/terraform/transformPacks.ts +594 -0
  397. package/src/mcp/terraform/types.ts +382 -0
  398. package/src/mcp/terraform/verification.ts +150 -0
  399. package/src/mcp/terraform/vex.ts +367 -0
  400. package/src/mcp/terraform/writeOnly.ts +252 -0
  401. package/src/mcp/terraform.ts +52 -0
  402. package/src/mcp/terratest.ts +215 -0
  403. package/src/mcp/untrustedContent.ts +126 -0
  404. package/src/mcp/upload.ts +123 -0
  405. package/src/models.ts +753 -0
  406. package/src/modes/address-reviews.ts +35 -0
  407. package/src/modes/assess.ts +27 -0
  408. package/src/modes/build.ts +86 -0
  409. package/src/modes/compliance-audit.ts +25 -0
  410. package/src/modes/cost-optimization.ts +36 -0
  411. package/src/modes/drift-detect.ts +31 -0
  412. package/src/modes/fix.ts +29 -0
  413. package/src/modes/incremental-review.ts +103 -0
  414. package/src/modes/index.ts +94 -0
  415. package/src/modes/modernize-deprecated.ts +36 -0
  416. package/src/modes/plan.ts +21 -0
  417. package/src/modes/policy-gate.ts +27 -0
  418. package/src/modes/prFormats.ts +325 -0
  419. package/src/modes/refactor.ts +74 -0
  420. package/src/modes/refresh-remediation.ts +40 -0
  421. package/src/modes/remediate-and-refactor.ts +42 -0
  422. package/src/modes/remediate.ts +78 -0
  423. package/src/modes/resolve-conflicts.ts +32 -0
  424. package/src/modes/review.ts +135 -0
  425. package/src/modes/summarize-pr.ts +42 -0
  426. package/src/modes/task.ts +26 -0
  427. package/src/modes/terraform-code-review.ts +68 -0
  428. package/src/modes/types.ts +17 -0
  429. package/src/modes/update-dependencies.ts +44 -0
  430. package/src/prep/index.ts +96 -0
  431. package/src/prep/installNodeDependencies.ts +251 -0
  432. package/src/prep/installPythonDependencies.ts +235 -0
  433. package/src/prep/types.ts +38 -0
  434. package/src/reviewQuality.ts +237 -0
  435. package/src/runCli.ts +335 -0
  436. package/src/skills/terraform-best-practices/SKILL.md +379 -0
  437. package/src/toolState.ts +241 -0
  438. package/src/utils/activity.ts +210 -0
  439. package/src/utils/agent.ts +245 -0
  440. package/src/utils/agentHangReport.ts +180 -0
  441. package/src/utils/annotations.ts +56 -0
  442. package/src/utils/apiFetch.ts +19 -0
  443. package/src/utils/apiKeys.ts +305 -0
  444. package/src/utils/apiUrl.ts +42 -0
  445. package/src/utils/assets.ts +123 -0
  446. package/src/utils/baseRefConfig.ts +254 -0
  447. package/src/utils/billingErrors.ts +210 -0
  448. package/src/utils/body.ts +168 -0
  449. package/src/utils/buildInfraweaverFooter.ts +104 -0
  450. package/src/utils/byokFallback.ts +137 -0
  451. package/src/utils/changeImpact.ts +330 -0
  452. package/src/utils/claudeSubscription.ts +93 -0
  453. package/src/utils/cli.ts +36 -0
  454. package/src/utils/cloudClient.ts +57 -0
  455. package/src/utils/cloudFetchCore.ts +139 -0
  456. package/src/utils/cloudReport.ts +316 -0
  457. package/src/utils/codexHome.ts +204 -0
  458. package/src/utils/codexOAuth.ts +154 -0
  459. package/src/utils/codexRefreshDetect.ts +36 -0
  460. package/src/utils/diffCoverage.ts +404 -0
  461. package/src/utils/env.ts +84 -0
  462. package/src/utils/errorReport.ts +94 -0
  463. package/src/utils/exitHandler.ts +35 -0
  464. package/src/utils/fixDoubleEscapedString.ts +9 -0
  465. package/src/utils/ghaCore.ts +13 -0
  466. package/src/utils/gitAuth.ts +268 -0
  467. package/src/utils/gitAuthServer.ts +186 -0
  468. package/src/utils/github.ts +676 -0
  469. package/src/utils/globals.ts +9 -0
  470. package/src/utils/humanEditCapture.ts +198 -0
  471. package/src/utils/infraweaverConfig.ts +202 -0
  472. package/src/utils/install.ts +279 -0
  473. package/src/utils/instructions.ts +640 -0
  474. package/src/utils/keylessOidc.ts +47 -0
  475. package/src/utils/leapingComment.ts +20 -0
  476. package/src/utils/learnings.ts +145 -0
  477. package/src/utils/learningsTruncate.ts +42 -0
  478. package/src/utils/lifecycle.ts +198 -0
  479. package/src/utils/log.ts +452 -0
  480. package/src/utils/modelResolver.ts +105 -0
  481. package/src/utils/moduleFetch.ts +138 -0
  482. package/src/utils/normalizeEnv.ts +106 -0
  483. package/src/utils/openCodeModels.ts +86 -0
  484. package/src/utils/openaiCompatible.ts +52 -0
  485. package/src/utils/opentofuMcp.ts +61 -0
  486. package/src/utils/overrides.ts +100 -0
  487. package/src/utils/packageManager.ts +257 -0
  488. package/src/utils/patchWorkflowRunFields.ts +173 -0
  489. package/src/utils/payload.ts +1206 -0
  490. package/src/utils/prSummary.ts +148 -0
  491. package/src/utils/presets.ts +105 -0
  492. package/src/utils/progressComment.ts +266 -0
  493. package/src/utils/providerErrors.ts +189 -0
  494. package/src/utils/proxyModel.ts +239 -0
  495. package/src/utils/rangeDiff.ts +182 -0
  496. package/src/utils/redact.ts +86 -0
  497. package/src/utils/registryAuth.ts +115 -0
  498. package/src/utils/remediationCommand.ts +144 -0
  499. package/src/utils/retry.ts +180 -0
  500. package/src/utils/reviewCleanup.ts +116 -0
  501. package/src/utils/run.ts +100 -0
  502. package/src/utils/runContext.ts +276 -0
  503. package/src/utils/runContextData.ts +121 -0
  504. package/src/utils/runErrorRenderer.ts +282 -0
  505. package/src/utils/runFixture.ts +91 -0
  506. package/src/utils/runLifecycle.ts +360 -0
  507. package/src/utils/runStartupLog.ts +67 -0
  508. package/src/utils/secrets.ts +208 -0
  509. package/src/utils/setup.ts +368 -0
  510. package/src/utils/shell.ts +132 -0
  511. package/src/utils/skills.ts +67 -0
  512. package/src/utils/subprocess.ts +474 -0
  513. package/src/utils/terraformMcp.ts +99 -0
  514. package/src/utils/time.ts +59 -0
  515. package/src/utils/timer.ts +72 -0
  516. package/src/utils/todoTracking.ts +168 -0
  517. package/src/utils/token.ts +294 -0
  518. package/src/utils/toolLicensing.ts +152 -0
  519. package/src/utils/toolSelection.ts +239 -0
  520. package/src/utils/toon.ts +76 -0
  521. package/src/utils/version.ts +10 -0
  522. package/src/utils/versioning.ts +44 -0
  523. package/src/utils/vertex.ts +94 -0
  524. package/src/utils/workflow.ts +25 -0
@@ -0,0 +1,594 @@
1
+ /**
2
+ * Versioned provider-upgrade transform packs (TC-2.2).
3
+ *
4
+ * WHAT A PACK IS — AND, MORE IMPORTANTLY, WHAT IT IS NOT. A pack is *codified
5
+ * knowledge* about one provider major-version boundary: which resource types
6
+ * disappeared, which arguments were renamed, and — the part that actually
7
+ * matters — which of those changes cannot be made without moving state. It is
8
+ * modelled on `fix_memory` deliberately (same shape: identity, match, merge,
9
+ * coerce, fleet stats): a pack entry is a **PRIOR, never a patch**. Nothing here
10
+ * rewrites HCL. The agent edits, `terraform plan` proves, and the existing
11
+ * destroy/replace guardrail blocks.
12
+ *
13
+ * WHY NOT A CODEMOD. A rewriter that silently renamed `enable_x` to `x_enabled`
14
+ * across a repo would be the single most dangerous thing in this codebase: a
15
+ * wrong rename that still parses produces a plan that destroys and recreates
16
+ * live infrastructure, and the failure surfaces in production, not in CI. The
17
+ * whole product thesis is proof over assertion, so the upgrade path is: detect
18
+ * deterministically → hand the agent leads → make it prove the plan → route
19
+ * anything state-moving to a human.
20
+ *
21
+ * ⚠️ THE SELF-TEST IS THE LOAD-BEARING PART. A hand-written migration table goes
22
+ * stale, and a stale entry is worse than no entry. So a rename entry is checked
23
+ * against the **installed provider schema** before it is offered
24
+ * (`verifyEntry`): a pack claiming `a → b` is believed only when the schema
25
+ * agrees that exactly one of the two exists. That is the same discipline §5.2
26
+ * applies to generated rules — a rule that can never fire is refused rather
27
+ * than shipped.
28
+ *
29
+ * What the self-test does NOT cover, stated rather than implied: a whole-resource
30
+ * rename (asking the schema about a type that v4 removed cannot distinguish
31
+ * "removed" from "provider not installed"), a pure deletion (absence of the old
32
+ * name is equally consistent with a misattributed entry), and `argument_required`
33
+ * (a schema says what exists, not what is mandatory). Those come back
34
+ * `unverified`, which is reported honestly and — the part that matters —
35
+ * **excluded from fleet capture**, so doubt is never laundered into a proven
36
+ * counter. It still reaches the agent as a lead, because a lead it can check is
37
+ * more use than silence.
38
+ *
39
+ * PACKS ARE NOT EXHAUSTIVE AND SAY SO. `terraform_validate`'s `unknown_arguments`
40
+ * (checked against the installed schema, not a table) remains the authoritative
41
+ * answer to "what did I miss". A pack's job is to say what to replace a thing
42
+ * WITH — the direction `unknown_arguments` can't give you.
43
+ */
44
+ import { AZURERM_3_TO_4 } from "#app/mcp/terraform/packs/azurerm-3-4";
45
+ import { CLOUDFLARE_4_TO_5 } from "#app/mcp/terraform/packs/cloudflare-4-5";
46
+ import { STATEFUL_RESOURCE_TYPES } from "#app/mcp/terraform/plan";
47
+ import type {
48
+ LocatedResource,
49
+ ProviderRequirement,
50
+ } from "#app/mcp/terraform/scanners";
51
+
52
+ /** Bumped when the pack SHAPE changes (not when an individual pack's content
53
+ * does — each pack carries its own `version`). Mirrors `FixMemoryFile.version`. */
54
+ export const TRANSFORM_PACK_SCHEMA = "infraweaver-transform-pack/v1" as const;
55
+
56
+ /**
57
+ * The built-in packs.
58
+ *
59
+ * Built in rather than fetched: a migration table pulled at runtime is a remote
60
+ * input that decides how live infrastructure gets edited, which is the last
61
+ * thing that should be mutable outside a reviewed release. Adding a pack is a
62
+ * code change with a diff, a review and a version — exactly like the crosswalk.
63
+ *
64
+ * These ship to everyone, OSS included, with no input to enable. The only
65
+ * Cloud-gated part of TC-2.2 is the fleet-wide *proven* counters.
66
+ */
67
+ export const BUILTIN_TRANSFORM_PACKS: readonly TransformPack[] = [
68
+ AZURERM_3_TO_4,
69
+ CLOUDFLARE_4_TO_5,
70
+ ];
71
+
72
+ /**
73
+ * How a transform's state has to move.
74
+ *
75
+ * This is the field the whole feature turns on, because it — not the size of the
76
+ * diff — decides whether a human must look. `auto` is a pure config edit that
77
+ * `plan` should show as a no-op. `moved_block` needs a `moved {}` block authored
78
+ * (Terraform ≥ 1.8) but keeps the resource. `manual_import` means the state
79
+ * entry cannot be carried across: without `state rm` + `import`, applying the
80
+ * change DESTROYS and RECREATES the resource.
81
+ */
82
+ export type StateMove = "auto" | "moved_block" | "manual_import";
83
+
84
+ export type TransformKind =
85
+ | "resource_renamed"
86
+ | "resource_removed"
87
+ | "argument_renamed"
88
+ | "argument_removed"
89
+ | "argument_required"
90
+ | "provider_setting";
91
+
92
+ /** One codified breaking change. */
93
+ export interface TransformEntry {
94
+ /** stable id, `<provider>.<from>-<to>.<slug>` — the fleet-sharing match key. */
95
+ id: string;
96
+ kind: TransformKind;
97
+ /** the resource type the change applies to; `null` for provider-block changes. */
98
+ resource_type: string | null;
99
+ /** what the config says today (old resource type, old argument name). */
100
+ from: string;
101
+ /** what it becomes; `null` when the thing was removed with no replacement. */
102
+ to: string | null;
103
+ state_move: StateMove;
104
+ /** true when applying this change is expected to force replacement even after
105
+ * the config edit — the pre-plan signal that a human will be needed. */
106
+ forces_replacement: boolean;
107
+ /**
108
+ * Set when the VALUE must change too, not just the identifier.
109
+ *
110
+ * This exists because the most dangerous entry in any migration table is the
111
+ * one that looks like a pure rename and isn't: `disable_bgp_route_propagation`
112
+ * → `bgp_route_propagation_enabled` inverts the boolean, and a mechanical
113
+ * rename would silently flip the routing behaviour of a live network while
114
+ * `validate`, `plan` and every scanner stayed green. When this is set, the
115
+ * transform is never presented as a rename.
116
+ */
117
+ value_change?: string;
118
+ /** one line the agent can act on. */
119
+ note: string;
120
+ }
121
+
122
+ export interface TransformPack {
123
+ /** registry provider name, e.g. `azurerm`. */
124
+ provider: string;
125
+ from_major: number;
126
+ to_major: number;
127
+ /** pack content version — bump when entries change. */
128
+ version: string;
129
+ /** the upstream guide these entries were transcribed from. Every claim in this
130
+ * file is someone else's documented breaking change, so it gets a citation. */
131
+ source: string;
132
+ /** ALWAYS false in practice, and stated rather than implied: no pack here is a
133
+ * complete migration. `unknown_arguments` is the exhaustive check. */
134
+ exhaustive: boolean;
135
+ /** upstream's own migration tool, when one exists. Preferring it over our own
136
+ * leads is "integrate upward, don't compete" applied to migrations. */
137
+ official_tool?: string;
138
+ entries: TransformEntry[];
139
+ }
140
+
141
+ /**
142
+ * Whether the installed provider schema CORROBORATES a pack entry.
143
+ *
144
+ * - `pre-upgrade` — schema has `from`, not `to`. Consistent with the old major
145
+ * still being installed; the entry is a valid lead.
146
+ * - `post-upgrade` — schema has `to`, not `from`. The new major is installed, so
147
+ * any remaining use of `from` is a confirmed must-fix.
148
+ * - `unverified` — schema has both, neither, or wasn't loadable. The pack is
149
+ * not believed; the entry is reported but never actionable.
150
+ */
151
+ export type SchemaAgreement = "pre-upgrade" | "post-upgrade" | "unverified";
152
+
153
+ /**
154
+ * How sure we are that this entry applies to a specific piece of the config.
155
+ *
156
+ * `absent` exists because one entry kind — `argument_required` — fires on the
157
+ * argument NOT being there. Reporting that as `confirmed` (which is documented
158
+ * as "the identifier was found") would tell the reader the exact opposite of
159
+ * what happened.
160
+ */
161
+ export type MatchConfidence = "confirmed" | "nested" | "absent";
162
+
163
+ export interface TransformMatch {
164
+ entry: TransformEntry;
165
+ /** the pack that produced it. Carried per-match rather than read from the
166
+ * run's primary pack, because a repo can be mid-upgrade on two providers and
167
+ * the fleet row's provider/major columns must describe the right one. */
168
+ provider: string;
169
+ from_major: number;
170
+ to_major: number;
171
+ /** where it was found. */
172
+ file: string;
173
+ /** the resource block's local name (`""` for provider-block matches). */
174
+ resource_name: string;
175
+ /**
176
+ * `confirmed` — the exact top-level identifier was found in the parsed config.
177
+ * `nested` — the entry names a path inside a block (`a.b.c`) and the parser
178
+ * only sees top-level argument names, so the resource TYPE
179
+ * matched but the argument itself was not confirmed. Reported as
180
+ * a lead to check by hand, never as a certainty.
181
+ */
182
+ confidence: MatchConfidence;
183
+ schema_agreement: SchemaAgreement;
184
+ /** true when this match must not be applied autonomously. */
185
+ needs_human: boolean;
186
+ /** why, when it does. */
187
+ needs_human_reason: string | null;
188
+ }
189
+
190
+ /** A pack entry is nested when it names a path inside a block. */
191
+ function isNestedPath(arg: string): boolean {
192
+ return arg.includes(".");
193
+ }
194
+
195
+ /** The leaf identifier of a possibly-dotted path. */
196
+ function leafOf(path: string): string {
197
+ const parts = path.split(".");
198
+ return parts[parts.length - 1] ?? path;
199
+ }
200
+
201
+ /**
202
+ * Does this transform need a human?
203
+ *
204
+ * Two independent triggers, both deliberately conservative:
205
+ * 1. `manual_import` — the state cannot be carried across automatically, so an
206
+ * unattended apply destroys and recreates. Always human, every resource type.
207
+ * 2. `forces_replacement` on a STATEFUL resource type. Stateful-ness is read
208
+ * from `plan.ts`'s `STATEFUL_RESOURCE_TYPES` — the exact set the push-time
209
+ * `assertNoBlockedDestroy` guardrail uses — and NOT from `governance.ts`'s
210
+ * regex heuristic, because the point of pre-declaring this is to predict
211
+ * what the guard will actually block. Predicting it with a different
212
+ * definition than the guard uses would be worse than not predicting it.
213
+ */
214
+ export function transformNeedsHuman(entry: TransformEntry): {
215
+ needs: boolean;
216
+ reason: string | null;
217
+ } {
218
+ if (entry.state_move === "manual_import") {
219
+ return {
220
+ needs: true,
221
+ reason:
222
+ "state cannot be moved automatically — without `terraform state rm` + `import` this destroys and recreates the resource",
223
+ };
224
+ }
225
+ if (entry.forces_replacement) {
226
+ const type = entry.resource_type ?? "";
227
+ if (STATEFUL_RESOURCE_TYPES.has(type)) {
228
+ return {
229
+ needs: true,
230
+ reason: `forces replacement of ${type}, which holds data — the push guardrail blocks this unless explicitly allowed`,
231
+ };
232
+ }
233
+ return {
234
+ needs: true,
235
+ reason: "forces resource replacement — confirm the plan before shipping",
236
+ };
237
+ }
238
+ return { needs: false, reason: null };
239
+ }
240
+
241
+ /** Schema lookup seam. Returns the argument names known for a resource type, or
242
+ * `null` when the schema could not be loaded / the type is unknown to it. */
243
+ export type SchemaLookup = (resourceType: string) => ReadonlySet<string> | null;
244
+
245
+ /**
246
+ * Check one entry against the installed provider schema.
247
+ *
248
+ * Only argument-level entries are checkable this way — a removed RESOURCE type
249
+ * cannot be corroborated by asking the schema about it (its absence is equally
250
+ * consistent with "removed in v4" and "this provider isn't installed"), so those
251
+ * return `unverified` and lean on the deterministic type match instead.
252
+ */
253
+ export function verifyEntry(
254
+ entry: TransformEntry,
255
+ lookup: SchemaLookup,
256
+ ): SchemaAgreement {
257
+ if (entry.kind !== "argument_renamed" && entry.kind !== "argument_removed")
258
+ return "unverified";
259
+ if (!entry.resource_type) return "unverified";
260
+ const known = lookup(entry.resource_type);
261
+ if (!known) return "unverified";
262
+ const hasFrom = known.has(leafOf(entry.from));
263
+ // A pure deletion has no replacement name to look for, so the ONLY signal is
264
+ // the old name's absence — which is equally consistent with "v4 is installed"
265
+ // and "this entry names the wrong argument". Treating absence as
266
+ // `post-upgrade` made the verdict unfalsifiable and, worse, made a
267
+ // misattributed entry read as MORE confirmed, not less. Deletions therefore
268
+ // corroborate in one direction only.
269
+ if (entry.to === null) return hasFrom ? "pre-upgrade" : "unverified";
270
+ const hasTo = known.has(leafOf(entry.to));
271
+ if (hasFrom && !hasTo) return "pre-upgrade";
272
+ if (!hasFrom && hasTo) return "post-upgrade";
273
+ return "unverified";
274
+ }
275
+
276
+ /**
277
+ * Select the packs that apply to what this repo actually pins.
278
+ *
279
+ * A pack applies when the provider is required AND the pinned lower-bound major
280
+ * equals the pack's `from_major`. An unconstrained provider (`major: null`)
281
+ * matches nothing: guessing which major an unpinned provider resolves to is how
282
+ * you hand someone a migration they don't need.
283
+ */
284
+ export function packsForRequirements(
285
+ packs: readonly TransformPack[],
286
+ requirements: readonly ProviderRequirement[],
287
+ ): TransformPack[] {
288
+ const pinned = new Map<string, number>();
289
+ for (const r of requirements) {
290
+ if (r.major !== null && !pinned.has(r.name)) pinned.set(r.name, r.major);
291
+ }
292
+ return packs.filter((p) => pinned.get(p.provider) === p.from_major);
293
+ }
294
+
295
+ /**
296
+ * Match a pack's entries against the parsed configuration. Pure.
297
+ *
298
+ * `resources` comes from `parseResourceArguments`, which reports TOP-LEVEL
299
+ * argument names only. That bound is honoured rather than papered over: a
300
+ * dotted entry produces a `nested` match (resource type present, argument not
301
+ * confirmed) so the agent knows to look inside the block itself.
302
+ */
303
+ export function matchTransforms(
304
+ pack: TransformPack,
305
+ resources: readonly LocatedResource[],
306
+ lookup: SchemaLookup,
307
+ ): TransformMatch[] {
308
+ const matches: TransformMatch[] = [];
309
+ for (const entry of pack.entries) {
310
+ const agreement = verifyEntry(entry, lookup);
311
+ const { needs, reason } = transformNeedsHuman(entry);
312
+ const base = {
313
+ entry,
314
+ provider: pack.provider,
315
+ from_major: pack.from_major,
316
+ to_major: pack.to_major,
317
+ schema_agreement: agreement,
318
+ needs_human: needs,
319
+ needs_human_reason: reason,
320
+ };
321
+
322
+ if (
323
+ entry.kind === "resource_renamed" ||
324
+ entry.kind === "resource_removed"
325
+ ) {
326
+ for (const r of resources) {
327
+ if (r.resourceType !== entry.from) continue;
328
+ matches.push({
329
+ ...base,
330
+ file: r.file,
331
+ resource_name: r.name,
332
+ confidence: "confirmed",
333
+ });
334
+ }
335
+ continue;
336
+ }
337
+ if (entry.kind === "provider_setting") {
338
+ // Provider-block settings aren't resources; they are reported once, without
339
+ // a location, because `parseResourceArguments` doesn't see provider blocks.
340
+ matches.push({
341
+ ...base,
342
+ file: "",
343
+ resource_name: "",
344
+ confidence: "nested",
345
+ });
346
+ continue;
347
+ }
348
+ // argument-level
349
+ for (const r of resources) {
350
+ if (r.resourceType !== entry.resource_type) continue;
351
+ if (isNestedPath(entry.from)) {
352
+ matches.push({
353
+ ...base,
354
+ file: r.file,
355
+ resource_name: r.name,
356
+ confidence: "nested",
357
+ });
358
+ continue;
359
+ }
360
+ // `argument_required` is the one entry kind whose trigger is ABSENCE: the
361
+ // argument became mandatory, so the resources that need work are the ones
362
+ // NOT carrying it. Matching on presence here (as every other kind does)
363
+ // would report exactly the resources that are already correct.
364
+ const present = r.args.includes(entry.from);
365
+ const requiredAndMissing = entry.kind === "argument_required" && !present;
366
+ if (requiredAndMissing) {
367
+ matches.push({
368
+ ...base,
369
+ file: r.file,
370
+ resource_name: r.name,
371
+ confidence: "absent",
372
+ });
373
+ } else if (present && entry.kind !== "argument_required") {
374
+ matches.push({
375
+ ...base,
376
+ file: r.file,
377
+ resource_name: r.name,
378
+ confidence: "confirmed",
379
+ });
380
+ }
381
+ }
382
+ }
383
+ return matches;
384
+ }
385
+
386
+ /**
387
+ * Fleet reuse stats for a transform id — the §5.12-shaped half.
388
+ *
389
+ * Notice what is NOT here: no config, no snippet, no repo name. A transform is
390
+ * already fully described by the pack every engine ships; the only thing worth
391
+ * sharing across an org is *whether it has been proven to plan cleanly, and how
392
+ * widely*. That keeps the fleet payload a set of counters, so there is no path
393
+ * by which one repo's configuration reaches another.
394
+ */
395
+ export interface ProvenTransform {
396
+ /** matches `TransformEntry.id`. */
397
+ transform_id: string;
398
+ provider: string;
399
+ from_major: number;
400
+ to_major: number;
401
+ /** how many times this transform's upgrade planned cleanly. */
402
+ times_proven?: number;
403
+ /** distinct repos it has been proven on. */
404
+ repos_count?: number;
405
+ last_proven?: string;
406
+ /** operator retired it in the dashboard — never offered as proven. */
407
+ disabled?: boolean;
408
+ }
409
+
410
+ export function isProvenTransform(value: unknown): value is ProvenTransform {
411
+ if (!value || typeof value !== "object") return false;
412
+ const p = value as Record<string, unknown>;
413
+ return (
414
+ typeof p.transform_id === "string" &&
415
+ p.transform_id.length > 0 &&
416
+ typeof p.provider === "string" &&
417
+ typeof p.from_major === "number" &&
418
+ typeof p.to_major === "number"
419
+ );
420
+ }
421
+
422
+ /** Coerce the untrusted Cloud `provenTransforms` blob. Pure — the wire boundary
423
+ * can't be typechecked across repos (same reasoning as `coerceLibrary`). */
424
+ export function coerceProvenTransforms(raw: unknown): ProvenTransform[] {
425
+ if (!Array.isArray(raw)) return [];
426
+ return raw.filter(isProvenTransform).filter((p) => !p.disabled);
427
+ }
428
+
429
+ /**
430
+ * What `terraform_provider_upgrade` detected this run, parked on the session so
431
+ * the evidence builder can bind it to the plan that came after.
432
+ */
433
+ export interface UpgradeIntent {
434
+ provider: string;
435
+ from_major: number;
436
+ to_major: number;
437
+ pack_version: string;
438
+ pack_source: string;
439
+ pack_exhaustive: boolean;
440
+ /** ids of every transform matched in this config, deduped, sorted. */
441
+ transform_ids: string[];
442
+ /** how many of those must not be applied autonomously. */
443
+ needing_human: number;
444
+ }
445
+
446
+ /** The plan facts the proof rests on. Supplied by the caller from the session so
447
+ * this stays pure and testable. */
448
+ export interface UpgradePlanFacts {
449
+ to_add: number;
450
+ to_change: number;
451
+ to_destroy: number;
452
+ /** count of destroy/replace actions across all roots. */
453
+ destructive: number;
454
+ /** count of those that hit a data-bearing resource type. */
455
+ stateful_destructive: number;
456
+ /** false when a second plan disagreed with the first. */
457
+ idempotent: boolean;
458
+ }
459
+
460
+ /**
461
+ * The signed-evidence statement for a provider upgrade (TC-2.2's "carrying the
462
+ * passing plan as proof").
463
+ *
464
+ * The verdict is computed from the plan, never asserted by the agent, and — per
465
+ * §8 — the statement carries what it does NOT claim. A clean plan proves that
466
+ * Terraform intends no destructive change to the resources it can see. It does
467
+ * not prove the upgrade is behaviourally correct, and it says so.
468
+ */
469
+ export interface UpgradeEvidenceStatement {
470
+ provider: string;
471
+ from_major: number;
472
+ to_major: number;
473
+ pack_version: string;
474
+ pack_source: string;
475
+ /** always false, carried into the signed bytes so a reader cannot mistake the
476
+ * transform list for a complete migration. */
477
+ pack_exhaustive: boolean;
478
+ verdict: "plan-proven" | "plan-unclean" | "no-plan";
479
+ transforms_detected: number;
480
+ transforms_needing_human: number;
481
+ transform_ids: string[];
482
+ plan?: UpgradePlanFacts | undefined;
483
+ asserts: string;
484
+ does_not_assert: string;
485
+ }
486
+
487
+ const UPGRADE_DOES_NOT_ASSERT =
488
+ "Does NOT assert that the upgraded configuration is behaviourally equivalent to the previous " +
489
+ "major, that the transform list was complete, or that unlisted breaking changes were handled. " +
490
+ "A plan reflects only what Terraform can see from the configuration and state it was given.";
491
+
492
+ /**
493
+ * Build the upgrade statement. Pure. `facts` is undefined when no plan ran —
494
+ * which is itself recorded as a verdict rather than omitted, because an upgrade
495
+ * shipped without a plan is precisely the case a reader must be able to spot.
496
+ */
497
+ export function buildUpgradeStatement(
498
+ intent: UpgradeIntent | undefined,
499
+ facts: UpgradePlanFacts | undefined,
500
+ ): UpgradeEvidenceStatement | undefined {
501
+ if (!intent) return undefined;
502
+ // ⚠️ `destructive`, not just `stateful_destructive`. A migration's entire
503
+ // premise is that state survives it, so ANY destroy/replace refutes it —
504
+ // including on resource types `STATEFUL_RESOURCE_TYPES` has never heard of.
505
+ // The first cut gated on stateful-ness alone, which meant 200 renamed
506
+ // `cloudflare_record`s missing their `moved {}` blocks planned as 200
507
+ // destroy+create, agreed with themselves across both runs, and signed as
508
+ // `plan-proven` — a clean bill of health for a plan that erases a DNS zone.
509
+ const verdict: UpgradeEvidenceStatement["verdict"] = !facts
510
+ ? "no-plan"
511
+ : facts.destructive === 0 &&
512
+ facts.to_destroy === 0 &&
513
+ facts.stateful_destructive === 0 &&
514
+ facts.idempotent
515
+ ? "plan-proven"
516
+ : "plan-unclean";
517
+ const asserts =
518
+ verdict === "plan-proven"
519
+ ? `A \`terraform plan\` after the ${intent.provider} v${intent.from_major}→v${intent.to_major} upgrade was stable across two runs and destroys or replaces NOTHING.`
520
+ : verdict === "plan-unclean"
521
+ ? `A \`terraform plan\` ran after the ${intent.provider} v${intent.from_major}→v${intent.to_major} upgrade and was NOT clean — it is recorded here as evidence, not as a pass.`
522
+ : `The ${intent.provider} v${intent.from_major}→v${intent.to_major} transforms below were detected in the configuration. NO plan backs this run, so nothing is proven about runtime behaviour.`;
523
+ return {
524
+ provider: intent.provider,
525
+ from_major: intent.from_major,
526
+ to_major: intent.to_major,
527
+ pack_version: intent.pack_version,
528
+ pack_source: intent.pack_source,
529
+ pack_exhaustive: intent.pack_exhaustive,
530
+ verdict,
531
+ transforms_detected: intent.transform_ids.length,
532
+ transforms_needing_human: intent.needing_human,
533
+ transform_ids: intent.transform_ids,
534
+ ...(facts ? { plan: facts } : {}),
535
+ asserts,
536
+ does_not_assert: UPGRADE_DOES_NOT_ASSERT,
537
+ };
538
+ }
539
+
540
+ /**
541
+ * The transforms this run may report to the org's fleet library as PROVEN.
542
+ *
543
+ * Only on a `plan-proven` verdict, and only transforms that did not need a
544
+ * human — a transform a person had to intervene on is not evidence that the
545
+ * transform is safe to apply unattended, which is the only claim the fleet
546
+ * counter is allowed to make.
547
+ */
548
+ export function captureProvenTransforms(
549
+ statement: UpgradeEvidenceStatement | undefined,
550
+ matches: readonly TransformMatch[],
551
+ ): ProvenTransform[] {
552
+ if (statement?.verdict !== "plan-proven") return [];
553
+ const seen = new Set<string>();
554
+ const out: ProvenTransform[] = [];
555
+ for (const m of matches) {
556
+ if (m.needs_human) continue;
557
+ // A provider-block setting matches unconditionally — there is no config to
558
+ // confirm it against — so counting it as proven would inflate its fleet
559
+ // counter with every repo that never used the setting at all.
560
+ if (m.entry.kind === "provider_setting") continue;
561
+ // An entry the installed schema did not corroborate must not become fleet
562
+ // evidence. `unverified` is the honest "we could not check this"; promoting
563
+ // it to a proven counter would launder the doubt away.
564
+ if (
565
+ m.schema_agreement === "unverified" &&
566
+ m.entry.kind !== "resource_renamed"
567
+ )
568
+ continue;
569
+ if (seen.has(m.entry.id)) continue;
570
+ seen.add(m.entry.id);
571
+ // Coordinates come from the match's OWN pack, not the statement's. A repo
572
+ // mid-upgrade on two providers records the intent for the primary pack
573
+ // only, so stamping every match with those majors filed cloudflare
574
+ // migrations in the org's table as `azurerm` 3→4.
575
+ out.push({
576
+ transform_id: m.entry.id,
577
+ provider: m.provider,
578
+ from_major: m.from_major,
579
+ to_major: m.to_major,
580
+ });
581
+ }
582
+ return out;
583
+ }
584
+
585
+ /** Index a fleet library by transform id for O(1) lookup while rendering. */
586
+ export function indexProvenTransforms(
587
+ library: readonly ProvenTransform[],
588
+ ): Map<string, ProvenTransform> {
589
+ const byId = new Map<string, ProvenTransform>();
590
+ for (const p of library) {
591
+ if (!byId.has(p.transform_id)) byId.set(p.transform_id, p);
592
+ }
593
+ return byId;
594
+ }