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.
- package/LICENSE +661 -0
- package/README.md +244 -0
- package/dist/agents/claude.d.ts +113 -0
- package/dist/agents/claudePretoolGate.d.ts +137 -0
- package/dist/agents/dispatchMetrics.d.ts +77 -0
- package/dist/agents/gateServer.d.ts +7 -0
- package/dist/agents/index.d.ts +6 -0
- package/dist/agents/nativeFsDenies.d.ts +46 -0
- package/dist/agents/opencode.d.ts +284 -0
- package/dist/agents/opencodePlugin.d.ts +96 -0
- package/dist/agents/opencodeShared.d.ts +40 -0
- package/dist/agents/postRun.d.ts +126 -0
- package/dist/agents/reviewer.d.ts +41 -0
- package/dist/agents/sessionLabeler.d.ts +97 -0
- package/dist/agents/shared.d.ts +246 -0
- package/dist/agents/subagentModels.d.ts +19 -0
- package/dist/agents/tokenQuota.d.ts +118 -0
- package/dist/agents/writeGateSource.d.ts +22 -0
- package/dist/agents/writePolicy.d.ts +79 -0
- package/dist/brand.d.ts +67 -0
- package/dist/cli.mjs +247846 -0
- package/dist/external.d.ts +227 -0
- package/dist/i18n/scaffolding.d.ts +59 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +247061 -0
- package/dist/internal/index.d.ts +18 -0
- package/dist/internal.js +2398 -0
- package/dist/lifecycle.d.ts +2 -0
- package/dist/main.d.ts +8 -0
- package/dist/mcp/arkConfig.d.ts +1 -0
- package/dist/mcp/assess.d.ts +157 -0
- package/dist/mcp/capabilityContext.d.ts +71 -0
- package/dist/mcp/changeSummary.d.ts +52 -0
- package/dist/mcp/checkSuite.d.ts +27 -0
- package/dist/mcp/checkout.d.ts +92 -0
- package/dist/mcp/comment.d.ts +127 -0
- package/dist/mcp/commitInfo.d.ts +11 -0
- package/dist/mcp/crosswalk.d.ts +178 -0
- package/dist/mcp/crosswalkDigest.d.ts +1 -0
- package/dist/mcp/cyberEssentials.d.ts +24 -0
- package/dist/mcp/dashboard.d.ts +125 -0
- package/dist/mcp/dependencies.d.ts +12 -0
- package/dist/mcp/frameworks.d.ts +74 -0
- package/dist/mcp/geminiSanitizer.d.ts +28 -0
- package/dist/mcp/git.d.ts +60 -0
- package/dist/mcp/guardrails.d.ts +222 -0
- package/dist/mcp/issue.d.ts +20 -0
- package/dist/mcp/issueComments.d.ts +11 -0
- package/dist/mcp/issueEvents.d.ts +11 -0
- package/dist/mcp/issueInfo.d.ts +11 -0
- package/dist/mcp/labels.d.ts +14 -0
- package/dist/mcp/localContext.d.ts +26 -0
- package/dist/mcp/moduleExtraction.d.ts +79 -0
- package/dist/mcp/moduleTests.d.ts +106 -0
- package/dist/mcp/modules.d.ts +198 -0
- package/dist/mcp/output.d.ts +16 -0
- package/dist/mcp/pathSafety.d.ts +14 -0
- package/dist/mcp/policy.d.ts +50 -0
- package/dist/mcp/pr.d.ts +64 -0
- package/dist/mcp/prInfo.d.ts +11 -0
- package/dist/mcp/providerSchema.d.ts +52 -0
- package/dist/mcp/review.d.ts +212 -0
- package/dist/mcp/reviewComments.d.ts +245 -0
- package/dist/mcp/roots.d.ts +60 -0
- package/dist/mcp/scope.d.ts +26 -0
- package/dist/mcp/selectMode.d.ts +20 -0
- package/dist/mcp/server.d.ts +61 -0
- package/dist/mcp/shared.d.ts +62 -0
- package/dist/mcp/shell.d.ts +58 -0
- package/dist/mcp/staleFix.d.ts +138 -0
- package/dist/mcp/terraform/azurePrices.d.ts +8 -0
- package/dist/mcp/terraform/baseline.d.ts +57 -0
- package/dist/mcp/terraform/concernResult.d.ts +38 -0
- package/dist/mcp/terraform/cost.d.ts +55 -0
- package/dist/mcp/terraform/cspm.d.ts +80 -0
- package/dist/mcp/terraform/currency.d.ts +110 -0
- package/dist/mcp/terraform/decisions.d.ts +178 -0
- package/dist/mcp/terraform/eidas.d.ts +100 -0
- package/dist/mcp/terraform/evidence.d.ts +343 -0
- package/dist/mcp/terraform/findings.d.ts +76 -0
- package/dist/mcp/terraform/fixMemory.d.ts +81 -0
- package/dist/mcp/terraform/governance.d.ts +56 -0
- package/dist/mcp/terraform/hcl.d.ts +115 -0
- package/dist/mcp/terraform/iacLanguages.d.ts +120 -0
- package/dist/mcp/terraform/idleFloor.d.ts +78 -0
- package/dist/mcp/terraform/keyless.d.ts +68 -0
- package/dist/mcp/terraform/moduleDocs.d.ts +56 -0
- package/dist/mcp/terraform/nativeRules.d.ts +38 -0
- package/dist/mcp/terraform/nativeScan.d.ts +11 -0
- package/dist/mcp/terraform/noiseProfile.d.ts +100 -0
- package/dist/mcp/terraform/normalization.d.ts +52 -0
- package/dist/mcp/terraform/oscal.d.ts +103 -0
- package/dist/mcp/terraform/packs/azurerm-3-4.d.ts +2 -0
- package/dist/mcp/terraform/packs/cloudflare-4-5.d.ts +2 -0
- package/dist/mcp/terraform/paths.d.ts +28 -0
- package/dist/mcp/terraform/plan.d.ts +157 -0
- package/dist/mcp/terraform/planDrift.d.ts +199 -0
- package/dist/mcp/terraform/policyAuthor.d.ts +191 -0
- package/dist/mcp/terraform/prowlerOcsf.d.ts +136 -0
- package/dist/mcp/terraform/refactor.d.ts +183 -0
- package/dist/mcp/terraform/registry.d.ts +108 -0
- package/dist/mcp/terraform/risk.d.ts +41 -0
- package/dist/mcp/terraform/scanSession.d.ts +116 -0
- package/dist/mcp/terraform/scannerCache.d.ts +15 -0
- package/dist/mcp/terraform/scannerEgress.d.ts +72 -0
- package/dist/mcp/terraform/scannerJson.d.ts +13 -0
- package/dist/mcp/terraform/scanners.d.ts +205 -0
- package/dist/mcp/terraform/signing.d.ts +61 -0
- package/dist/mcp/terraform/stateLocking.d.ts +18 -0
- package/dist/mcp/terraform/subprocess.d.ts +43 -0
- package/dist/mcp/terraform/suppressions.d.ts +90 -0
- package/dist/mcp/terraform/taxonomy.d.ts +39 -0
- package/dist/mcp/terraform/tfquery.d.ts +47 -0
- package/dist/mcp/terraform/toolchainIntegrity.d.ts +82 -0
- package/dist/mcp/terraform/tools/authorPolicy.d.ts +59 -0
- package/dist/mcp/terraform/tools/detectPlanDrift.d.ts +20 -0
- package/dist/mcp/terraform/tools/emitCost.d.ts +11 -0
- package/dist/mcp/terraform/tools/emitSarif.d.ts +14 -0
- package/dist/mcp/terraform/tools/fixMemory.d.ts +19 -0
- package/dist/mcp/terraform/tools/infracostDiff.d.ts +22 -0
- package/dist/mcp/terraform/tools/ingestExternalFindings.d.ts +21 -0
- package/dist/mcp/terraform/tools/moduleLookup.d.ts +14 -0
- package/dist/mcp/terraform/tools/moduleSearch.d.ts +23 -0
- package/dist/mcp/terraform/tools/plan.d.ts +59 -0
- package/dist/mcp/terraform/tools/providerUpgrade.d.ts +55 -0
- package/dist/mcp/terraform/tools/readFindings.d.ts +17 -0
- package/dist/mcp/terraform/tools/scan.d.ts +114 -0
- package/dist/mcp/terraform/tools/validate.d.ts +31 -0
- package/dist/mcp/terraform/tools/verifyRemediation.d.ts +31 -0
- package/dist/mcp/terraform/tools/versionCurrency.d.ts +5 -0
- package/dist/mcp/terraform/tools.d.ts +16 -0
- package/dist/mcp/terraform/transformPacks.d.ts +267 -0
- package/dist/mcp/terraform/types.d.ts +226 -0
- package/dist/mcp/terraform/verification.d.ts +81 -0
- package/dist/mcp/terraform/vex.d.ts +115 -0
- package/dist/mcp/terraform/writeOnly.d.ts +67 -0
- package/dist/mcp/terraform.d.ts +51 -0
- package/dist/mcp/terratest.d.ts +85 -0
- package/dist/mcp/untrustedContent.d.ts +76 -0
- package/dist/mcp/upload.d.ts +8 -0
- package/dist/models.d.ts +181 -0
- package/dist/modes/address-reviews.d.ts +2 -0
- package/dist/modes/assess.d.ts +2 -0
- package/dist/modes/build.d.ts +2 -0
- package/dist/modes/compliance-audit.d.ts +2 -0
- package/dist/modes/cost-optimization.d.ts +2 -0
- package/dist/modes/drift-detect.d.ts +2 -0
- package/dist/modes/fix.d.ts +2 -0
- package/dist/modes/incremental-review.d.ts +2 -0
- package/dist/modes/index.d.ts +24 -0
- package/dist/modes/modernize-deprecated.d.ts +2 -0
- package/dist/modes/plan.d.ts +2 -0
- package/dist/modes/policy-gate.d.ts +2 -0
- package/dist/modes/prFormats.d.ts +3 -0
- package/dist/modes/refactor.d.ts +2 -0
- package/dist/modes/refresh-remediation.d.ts +2 -0
- package/dist/modes/remediate-and-refactor.d.ts +2 -0
- package/dist/modes/remediate.d.ts +2 -0
- package/dist/modes/resolve-conflicts.d.ts +2 -0
- package/dist/modes/review.d.ts +2 -0
- package/dist/modes/summarize-pr.d.ts +2 -0
- package/dist/modes/task.d.ts +2 -0
- package/dist/modes/terraform-code-review.d.ts +2 -0
- package/dist/modes/types.d.ts +9 -0
- package/dist/modes/update-dependencies.d.ts +2 -0
- package/dist/prep/index.d.ts +7 -0
- package/dist/prep/installNodeDependencies.d.ts +2 -0
- package/dist/prep/installPythonDependencies.d.ts +2 -0
- package/dist/prep/types.d.ts +31 -0
- package/dist/reviewQuality.d.ts +107 -0
- package/dist/skills/terraform-best-practices/SKILL.md +379 -0
- package/dist/toolState.d.ts +123 -0
- package/dist/utils/activity.d.ts +40 -0
- package/dist/utils/agent.d.ts +47 -0
- package/dist/utils/agentHangReport.d.ts +38 -0
- package/dist/utils/annotations.d.ts +17 -0
- package/dist/utils/apiFetch.d.ts +11 -0
- package/dist/utils/apiKeys.d.ts +48 -0
- package/dist/utils/apiUrl.d.ts +28 -0
- package/dist/utils/assets.d.ts +8 -0
- package/dist/utils/baseRefConfig.d.ts +121 -0
- package/dist/utils/billingErrors.d.ts +85 -0
- package/dist/utils/body.d.ts +34 -0
- package/dist/utils/buildInfraweaverFooter.d.ts +29 -0
- package/dist/utils/byokFallback.d.ts +85 -0
- package/dist/utils/changeImpact.d.ts +101 -0
- package/dist/utils/claudeSubscription.d.ts +30 -0
- package/dist/utils/cli.d.ts +10 -0
- package/dist/utils/cloudClient.d.ts +33 -0
- package/dist/utils/cloudFetchCore.d.ts +42 -0
- package/dist/utils/cloudReport.d.ts +114 -0
- package/dist/utils/codexHome.d.ts +29 -0
- package/dist/utils/codexOAuth.d.ts +60 -0
- package/dist/utils/diffCoverage.d.ts +63 -0
- package/dist/utils/env.d.ts +46 -0
- package/dist/utils/errorReport.d.ts +17 -0
- package/dist/utils/exitHandler.d.ts +8 -0
- package/dist/utils/fixDoubleEscapedString.d.ts +1 -0
- package/dist/utils/gitAuth.d.ts +84 -0
- package/dist/utils/gitAuthServer.d.ts +24 -0
- package/dist/utils/github.d.ts +104 -0
- package/dist/utils/globals.d.ts +3 -0
- package/dist/utils/infraweaverConfig.d.ts +56 -0
- package/dist/utils/install.d.ts +37 -0
- package/dist/utils/instructions.d.ts +48 -0
- package/dist/utils/keylessOidc.d.ts +28 -0
- package/dist/utils/leapingComment.d.ts +11 -0
- package/dist/utils/learnings.d.ts +62 -0
- package/dist/utils/learningsTruncate.d.ts +25 -0
- package/dist/utils/lifecycle.d.ts +57 -0
- package/dist/utils/log.d.ts +111 -0
- package/dist/utils/modelResolver.d.ts +63 -0
- package/dist/utils/moduleFetch.d.ts +39 -0
- package/dist/utils/normalizeEnv.d.ts +30 -0
- package/dist/utils/openCodeModels.d.ts +11 -0
- package/dist/utils/openaiCompatible.d.ts +26 -0
- package/dist/utils/opentofuMcp.d.ts +50 -0
- package/dist/utils/overrides.d.ts +40 -0
- package/dist/utils/packageManager.d.ts +49 -0
- package/dist/utils/patchWorkflowRunFields.d.ts +29 -0
- package/dist/utils/payload.d.ts +249 -0
- package/dist/utils/prSummary.d.ts +61 -0
- package/dist/utils/presets.d.ts +36 -0
- package/dist/utils/progressComment.d.ts +146 -0
- package/dist/utils/providerErrors.d.ts +31 -0
- package/dist/utils/proxyModel.d.ts +76 -0
- package/dist/utils/rangeDiff.d.ts +51 -0
- package/dist/utils/redact.d.ts +33 -0
- package/dist/utils/registryAuth.d.ts +52 -0
- package/dist/utils/remediationCommand.d.ts +58 -0
- package/dist/utils/retry.d.ts +38 -0
- package/dist/utils/reviewCleanup.d.ts +14 -0
- package/dist/utils/run.d.ts +9 -0
- package/dist/utils/runContext.d.ts +112 -0
- package/dist/utils/runContextData.d.ts +42 -0
- package/dist/utils/runErrorRenderer.d.ts +64 -0
- package/dist/utils/runLifecycle.d.ts +89 -0
- package/dist/utils/runStartupLog.d.ts +15 -0
- package/dist/utils/secrets.d.ts +34 -0
- package/dist/utils/setup.d.ts +90 -0
- package/dist/utils/shell.d.ts +44 -0
- package/dist/utils/skills.d.ts +10 -0
- package/dist/utils/subprocess.d.ts +81 -0
- package/dist/utils/terraformMcp.d.ts +46 -0
- package/dist/utils/time.d.ts +15 -0
- package/dist/utils/timer.d.ts +23 -0
- package/dist/utils/todoTracking.d.ts +16 -0
- package/dist/utils/token.d.ts +52 -0
- package/dist/utils/toolLicensing.d.ts +56 -0
- package/dist/utils/toolSelection.d.ts +73 -0
- package/dist/utils/toon.d.ts +16 -0
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/versioning.d.ts +7 -0
- package/dist/utils/vertex.d.ts +16 -0
- package/dist/utils/workflow.d.ts +13 -0
- package/package.json +132 -0
- package/src/agents/claude.ts +1588 -0
- package/src/agents/claudePretoolGate.ts +286 -0
- package/src/agents/dispatchMetrics.ts +162 -0
- package/src/agents/gateServer.ts +178 -0
- package/src/agents/index.ts +10 -0
- package/src/agents/nativeFsDenies.ts +164 -0
- package/src/agents/opencode.ts +1600 -0
- package/src/agents/opencodePlugin.ts +304 -0
- package/src/agents/opencodeShared.ts +134 -0
- package/src/agents/postRun.ts +615 -0
- package/src/agents/reviewer.ts +134 -0
- package/src/agents/sessionLabeler.ts +185 -0
- package/src/agents/shared.ts +377 -0
- package/src/agents/subagentModels.ts +40 -0
- package/src/agents/tokenQuota.ts +203 -0
- package/src/agents/writeGateSource.ts +148 -0
- package/src/agents/writePolicy.ts +132 -0
- package/src/brand.ts +84 -0
- package/src/cli.ts +117 -0
- package/src/commands/gha.ts +188 -0
- package/src/commands/mcp.ts +126 -0
- package/src/commands/verifyEvidence.ts +100 -0
- package/src/entry.ts +7 -0
- package/src/entryPost.ts +109 -0
- package/src/external.ts +308 -0
- package/src/i18n/scaffolding.ts +191 -0
- package/src/index.ts +7 -0
- package/src/internal/index.ts +74 -0
- package/src/lifecycle.ts +2 -0
- package/src/main.ts +815 -0
- package/src/mcp/__fixtures__/infraweaver-scratch-pr-49-review-3485940013.json +110 -0
- package/src/mcp/__fixtures__/infraweaver-scratch-pr-64-review-3531000326.json +14 -0
- package/src/mcp/__fixtures__/infraweaver-test-repo-pr-1.diff.json +67 -0
- package/src/mcp/__snapshots__/checkout.test.ts.snap +109 -0
- package/src/mcp/__snapshots__/reviewComments.test.ts.snap +71 -0
- package/src/mcp/arkConfig.ts +7 -0
- package/src/mcp/assess.ts +723 -0
- package/src/mcp/capabilityContext.ts +80 -0
- package/src/mcp/changeSummary.ts +145 -0
- package/src/mcp/checkSuite.ts +261 -0
- package/src/mcp/checkout.ts +1015 -0
- package/src/mcp/comment.ts +683 -0
- package/src/mcp/commitInfo.ts +57 -0
- package/src/mcp/crosswalk.ts +1253 -0
- package/src/mcp/crosswalkDigest.ts +5 -0
- package/src/mcp/cyberEssentials.ts +60 -0
- package/src/mcp/dashboard.ts +232 -0
- package/src/mcp/dependencies.ts +190 -0
- package/src/mcp/frameworks.ts +236 -0
- package/src/mcp/geminiSanitizer.ts +212 -0
- package/src/mcp/git.ts +1116 -0
- package/src/mcp/guardrails.ts +771 -0
- package/src/mcp/issue.ts +74 -0
- package/src/mcp/issueComments.ts +48 -0
- package/src/mcp/issueEvents.ts +100 -0
- package/src/mcp/issueInfo.ts +72 -0
- package/src/mcp/labels.ts +35 -0
- package/src/mcp/localContext.ts +65 -0
- package/src/mcp/localServer.ts +217 -0
- package/src/mcp/moduleExtraction.ts +368 -0
- package/src/mcp/moduleTests.ts +421 -0
- package/src/mcp/modules.ts +752 -0
- package/src/mcp/output.ts +71 -0
- package/src/mcp/pathSafety.ts +28 -0
- package/src/mcp/policy.ts +226 -0
- package/src/mcp/pr.ts +238 -0
- package/src/mcp/prInfo.ts +91 -0
- package/src/mcp/providerSchema.ts +175 -0
- package/src/mcp/review.ts +1081 -0
- package/src/mcp/reviewComments.ts +1137 -0
- package/src/mcp/roots.ts +217 -0
- package/src/mcp/scope.ts +82 -0
- package/src/mcp/selectMode.ts +207 -0
- package/src/mcp/server.ts +498 -0
- package/src/mcp/shared.ts +120 -0
- package/src/mcp/shell.ts +631 -0
- package/src/mcp/staleFix.ts +557 -0
- package/src/mcp/terraform/__snapshots__/moduleDocs.test.ts.snap +40 -0
- package/src/mcp/terraform/azurePrices.ts +38 -0
- package/src/mcp/terraform/baseline.ts +172 -0
- package/src/mcp/terraform/concernResult.ts +111 -0
- package/src/mcp/terraform/cost.ts +175 -0
- package/src/mcp/terraform/cspm.ts +326 -0
- package/src/mcp/terraform/currency.ts +354 -0
- package/src/mcp/terraform/decisions.ts +590 -0
- package/src/mcp/terraform/eidas.ts +134 -0
- package/src/mcp/terraform/evidence.ts +771 -0
- package/src/mcp/terraform/findings.ts +383 -0
- package/src/mcp/terraform/fixMemory.ts +253 -0
- package/src/mcp/terraform/governance.ts +231 -0
- package/src/mcp/terraform/hcl.ts +273 -0
- package/src/mcp/terraform/iacLanguages.ts +431 -0
- package/src/mcp/terraform/idleFloor.ts +304 -0
- package/src/mcp/terraform/keyless.ts +123 -0
- package/src/mcp/terraform/moduleDocs.ts +303 -0
- package/src/mcp/terraform/nativeRules.ts +152 -0
- package/src/mcp/terraform/nativeScan.ts +67 -0
- package/src/mcp/terraform/noiseProfile.ts +183 -0
- package/src/mcp/terraform/normalization.ts +265 -0
- package/src/mcp/terraform/oscal.ts +283 -0
- package/src/mcp/terraform/packs/azurerm-3-4.ts +382 -0
- package/src/mcp/terraform/packs/cloudflare-4-5.ts +114 -0
- package/src/mcp/terraform/paths.ts +59 -0
- package/src/mcp/terraform/plan.ts +377 -0
- package/src/mcp/terraform/planDrift.ts +520 -0
- package/src/mcp/terraform/policyAuthor.ts +886 -0
- package/src/mcp/terraform/prowlerOcsf.ts +380 -0
- package/src/mcp/terraform/refactor.ts +879 -0
- package/src/mcp/terraform/registry.ts +317 -0
- package/src/mcp/terraform/risk.ts +99 -0
- package/src/mcp/terraform/scanSession.ts +242 -0
- package/src/mcp/terraform/scannerCache.ts +86 -0
- package/src/mcp/terraform/scannerEgress.ts +141 -0
- package/src/mcp/terraform/scannerJson.ts +22 -0
- package/src/mcp/terraform/scanners.ts +1134 -0
- package/src/mcp/terraform/signing.ts +151 -0
- package/src/mcp/terraform/stateLocking.ts +106 -0
- package/src/mcp/terraform/subprocess.ts +102 -0
- package/src/mcp/terraform/suppressions.ts +551 -0
- package/src/mcp/terraform/taxonomy.ts +0 -0
- package/src/mcp/terraform/tfquery.ts +159 -0
- package/src/mcp/terraform/toolchainIntegrity.ts +151 -0
- package/src/mcp/terraform/tools/authorPolicy.ts +185 -0
- package/src/mcp/terraform/tools/detectPlanDrift.ts +279 -0
- package/src/mcp/terraform/tools/emitCost.ts +130 -0
- package/src/mcp/terraform/tools/emitSarif.ts +108 -0
- package/src/mcp/terraform/tools/fixMemory.ts +82 -0
- package/src/mcp/terraform/tools/infracostDiff.ts +110 -0
- package/src/mcp/terraform/tools/ingestExternalFindings.ts +259 -0
- package/src/mcp/terraform/tools/moduleLookup.ts +86 -0
- package/src/mcp/terraform/tools/moduleSearch.ts +46 -0
- package/src/mcp/terraform/tools/plan.ts +384 -0
- package/src/mcp/terraform/tools/providerUpgrade.ts +217 -0
- package/src/mcp/terraform/tools/readFindings.ts +138 -0
- package/src/mcp/terraform/tools/scan.ts +303 -0
- package/src/mcp/terraform/tools/validate.ts +160 -0
- package/src/mcp/terraform/tools/verifyRemediation.ts +190 -0
- package/src/mcp/terraform/tools/versionCurrency.ts +64 -0
- package/src/mcp/terraform/tools.ts +62 -0
- package/src/mcp/terraform/transformPacks.ts +594 -0
- package/src/mcp/terraform/types.ts +382 -0
- package/src/mcp/terraform/verification.ts +150 -0
- package/src/mcp/terraform/vex.ts +367 -0
- package/src/mcp/terraform/writeOnly.ts +252 -0
- package/src/mcp/terraform.ts +52 -0
- package/src/mcp/terratest.ts +215 -0
- package/src/mcp/untrustedContent.ts +126 -0
- package/src/mcp/upload.ts +123 -0
- package/src/models.ts +753 -0
- package/src/modes/address-reviews.ts +35 -0
- package/src/modes/assess.ts +27 -0
- package/src/modes/build.ts +86 -0
- package/src/modes/compliance-audit.ts +25 -0
- package/src/modes/cost-optimization.ts +36 -0
- package/src/modes/drift-detect.ts +31 -0
- package/src/modes/fix.ts +29 -0
- package/src/modes/incremental-review.ts +103 -0
- package/src/modes/index.ts +94 -0
- package/src/modes/modernize-deprecated.ts +36 -0
- package/src/modes/plan.ts +21 -0
- package/src/modes/policy-gate.ts +27 -0
- package/src/modes/prFormats.ts +325 -0
- package/src/modes/refactor.ts +74 -0
- package/src/modes/refresh-remediation.ts +40 -0
- package/src/modes/remediate-and-refactor.ts +42 -0
- package/src/modes/remediate.ts +78 -0
- package/src/modes/resolve-conflicts.ts +32 -0
- package/src/modes/review.ts +135 -0
- package/src/modes/summarize-pr.ts +42 -0
- package/src/modes/task.ts +26 -0
- package/src/modes/terraform-code-review.ts +68 -0
- package/src/modes/types.ts +17 -0
- package/src/modes/update-dependencies.ts +44 -0
- package/src/prep/index.ts +96 -0
- package/src/prep/installNodeDependencies.ts +251 -0
- package/src/prep/installPythonDependencies.ts +235 -0
- package/src/prep/types.ts +38 -0
- package/src/reviewQuality.ts +237 -0
- package/src/runCli.ts +335 -0
- package/src/skills/terraform-best-practices/SKILL.md +379 -0
- package/src/toolState.ts +241 -0
- package/src/utils/activity.ts +210 -0
- package/src/utils/agent.ts +245 -0
- package/src/utils/agentHangReport.ts +180 -0
- package/src/utils/annotations.ts +56 -0
- package/src/utils/apiFetch.ts +19 -0
- package/src/utils/apiKeys.ts +305 -0
- package/src/utils/apiUrl.ts +42 -0
- package/src/utils/assets.ts +123 -0
- package/src/utils/baseRefConfig.ts +254 -0
- package/src/utils/billingErrors.ts +210 -0
- package/src/utils/body.ts +168 -0
- package/src/utils/buildInfraweaverFooter.ts +104 -0
- package/src/utils/byokFallback.ts +137 -0
- package/src/utils/changeImpact.ts +330 -0
- package/src/utils/claudeSubscription.ts +93 -0
- package/src/utils/cli.ts +36 -0
- package/src/utils/cloudClient.ts +57 -0
- package/src/utils/cloudFetchCore.ts +139 -0
- package/src/utils/cloudReport.ts +316 -0
- package/src/utils/codexHome.ts +204 -0
- package/src/utils/codexOAuth.ts +154 -0
- package/src/utils/codexRefreshDetect.ts +36 -0
- package/src/utils/diffCoverage.ts +404 -0
- package/src/utils/env.ts +84 -0
- package/src/utils/errorReport.ts +94 -0
- package/src/utils/exitHandler.ts +35 -0
- package/src/utils/fixDoubleEscapedString.ts +9 -0
- package/src/utils/ghaCore.ts +13 -0
- package/src/utils/gitAuth.ts +268 -0
- package/src/utils/gitAuthServer.ts +186 -0
- package/src/utils/github.ts +676 -0
- package/src/utils/globals.ts +9 -0
- package/src/utils/humanEditCapture.ts +198 -0
- package/src/utils/infraweaverConfig.ts +202 -0
- package/src/utils/install.ts +279 -0
- package/src/utils/instructions.ts +640 -0
- package/src/utils/keylessOidc.ts +47 -0
- package/src/utils/leapingComment.ts +20 -0
- package/src/utils/learnings.ts +145 -0
- package/src/utils/learningsTruncate.ts +42 -0
- package/src/utils/lifecycle.ts +198 -0
- package/src/utils/log.ts +452 -0
- package/src/utils/modelResolver.ts +105 -0
- package/src/utils/moduleFetch.ts +138 -0
- package/src/utils/normalizeEnv.ts +106 -0
- package/src/utils/openCodeModels.ts +86 -0
- package/src/utils/openaiCompatible.ts +52 -0
- package/src/utils/opentofuMcp.ts +61 -0
- package/src/utils/overrides.ts +100 -0
- package/src/utils/packageManager.ts +257 -0
- package/src/utils/patchWorkflowRunFields.ts +173 -0
- package/src/utils/payload.ts +1206 -0
- package/src/utils/prSummary.ts +148 -0
- package/src/utils/presets.ts +105 -0
- package/src/utils/progressComment.ts +266 -0
- package/src/utils/providerErrors.ts +189 -0
- package/src/utils/proxyModel.ts +239 -0
- package/src/utils/rangeDiff.ts +182 -0
- package/src/utils/redact.ts +86 -0
- package/src/utils/registryAuth.ts +115 -0
- package/src/utils/remediationCommand.ts +144 -0
- package/src/utils/retry.ts +180 -0
- package/src/utils/reviewCleanup.ts +116 -0
- package/src/utils/run.ts +100 -0
- package/src/utils/runContext.ts +276 -0
- package/src/utils/runContextData.ts +121 -0
- package/src/utils/runErrorRenderer.ts +282 -0
- package/src/utils/runFixture.ts +91 -0
- package/src/utils/runLifecycle.ts +360 -0
- package/src/utils/runStartupLog.ts +67 -0
- package/src/utils/secrets.ts +208 -0
- package/src/utils/setup.ts +368 -0
- package/src/utils/shell.ts +132 -0
- package/src/utils/skills.ts +67 -0
- package/src/utils/subprocess.ts +474 -0
- package/src/utils/terraformMcp.ts +99 -0
- package/src/utils/time.ts +59 -0
- package/src/utils/timer.ts +72 -0
- package/src/utils/todoTracking.ts +168 -0
- package/src/utils/token.ts +294 -0
- package/src/utils/toolLicensing.ts +152 -0
- package/src/utils/toolSelection.ts +239 -0
- package/src/utils/toon.ts +76 -0
- package/src/utils/version.ts +10 -0
- package/src/utils/versioning.ts +44 -0
- package/src/utils/vertex.ts +94 -0
- package/src/utils/workflow.ts +25 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Mode, ToolRef } from "./types.ts";
|
|
2
|
+
|
|
3
|
+
export function addressReviewsMode(t: ToolRef): Mode {
|
|
4
|
+
return {
|
|
5
|
+
name: "AddressReviews",
|
|
6
|
+
description:
|
|
7
|
+
"Address PR review feedback; respond to reviewer comments; make requested changes to an existing PR",
|
|
8
|
+
prompt: `### Checklist
|
|
9
|
+
|
|
10
|
+
1. **task list**: create your task list for this run as your first action.
|
|
11
|
+
|
|
12
|
+
2. Checkout the PR branch via \`${t("checkout_pr")}\`.
|
|
13
|
+
|
|
14
|
+
3. Fetch review comments via \`${t("get_review_comments")}\`.
|
|
15
|
+
|
|
16
|
+
4. For each comment:
|
|
17
|
+
- understand the feedback
|
|
18
|
+
- **verify the finding yourself** against the actual code before deciding whether to apply — every comment (human or agent) is a hypothesis, not a directive. agent reviewers especially are fallible.
|
|
19
|
+
- you are searching for a solution that is **complete, minimal, and elegant** — you may need to think hard to find it. do not over-engineer, do not be over-defensive, **do not write AI slop**. reviewers bias toward *recommending additions*, and that bias has a recognizable slop texture: defensive checks for impossible cases, extra abstractions used once, comments restating obvious code, tests asserting tautologies, "just-in-case" guards, error handlers for cases the type system already rules out. reject those. evaluate whether applying the finding would leave the code more **sound, correct, AND elegant**; two-out-of-three is a signal to look harder for a fix that gets all three. if a request would add bloat — ceremony without commensurate correctness benefit — push back in your reply rather than mechanically applying it.
|
|
20
|
+
- if the request stands, make the code change using your native tools; otherwise reply explaining why
|
|
21
|
+
- record what was done (or why nothing was done)
|
|
22
|
+
|
|
23
|
+
5. Quality check:
|
|
24
|
+
- test changes, then review the diff before committing — verify only intended changes are present, no debug artifacts remain, no fix turned out to be bloat in context (revert any that did), and the changes are clean enough that a senior engineer would approve without hesitation
|
|
25
|
+
- commit locally via \`${t("git")}\` (\`git add\` the changed files, then \`git commit -m "..."\`) — works even when \`shell\` is disabled
|
|
26
|
+
|
|
27
|
+
6. Finalize. Reply + resolve are paired write actions: do BOTH or NEITHER for each thread.
|
|
28
|
+
- confirm a clean working tree, then push via \`${t("push_branch")}\` (same push/prepush guidance as Build mode in *SYSTEM*)
|
|
29
|
+
- **if push fails**, call \`${t("report_progress")}\` with the exact error and STOP — do NOT reply or resolve any thread until the fix is live on the remote. Resolving a thread without the fix landing misleads the reviewer.
|
|
30
|
+
- **on push success**, for each thread you acted on:
|
|
31
|
+
- reply ONCE via \`${t("reply_to_review_comment")}\`. The \`comment_id\` parameter takes the root comment's numeric \`id=\` (from the first \`comment author=...\` tag in the \`${t("get_review_comments")}\` output) — NOT the \`thread=\` value; that's a separate GraphQL ID used by resolve. The runtime dedupes identical bodies within a session.
|
|
32
|
+
- **immediately** call \`${t("resolve_review_thread")}\` with that thread's \`thread=\` value as \`thread_id\`. Resolve every thread where you (a) made the requested code change in full — partial fixes leave the thread open — OR (b) replied with a substantive answer the user explicitly asked for. Do NOT resolve threads where you pushed back on the request and the disagreement is unresolved; leave those open for the human to mediate.
|
|
33
|
+
- call \`${t("report_progress")}\` with a brief summary`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { PRODUCT_NAME, SARIF_FILE } from "#app/brand";
|
|
2
|
+
import type { Mode, ToolRef } from "./types.ts";
|
|
3
|
+
|
|
4
|
+
export function assessMode(t: ToolRef): Mode {
|
|
5
|
+
return {
|
|
6
|
+
name: "Assess",
|
|
7
|
+
nonCommitting: true,
|
|
8
|
+
description:
|
|
9
|
+
"Read-only IaC best-practice ASSESSMENT: scan with the deterministic check tools, map findings to compliance controls, and report the posture (clean / advisory / action-required) — without modifying any file or opening a PR. Terraform-first, but also assesses the other IaC languages the scanners parse (CloudFormation, Kubernetes, Helm, Dockerfile, ARM/Bicep, Serverless, Ansible).",
|
|
10
|
+
prompt: `### Checklist
|
|
11
|
+
|
|
12
|
+
This mode is **read-only** — the Assess half of ${PRODUCT_NAME}'s one-engine-two-modes design. It reports posture; it never fixes. Do NOT edit any repo source file (\`*.tf\`, \`*.tfvars\`, config), commit, push, or open a PR/issue in this mode. The one exception is a tool-emitted artifact such as \`${SARIF_FILE}\` from \`${t("terraform_emit_sarif")}\` (step 3) — those are reporting outputs, not source edits, and are fine to write. If the findings warrant a fix, say so and recommend re-running in \`remediate\` mode — but note that the proven \`✗→✓\` fix loop is **Terraform-only**; non-Terraform findings are assessed for reporting and must be fixed by hand.
|
|
13
|
+
|
|
14
|
+
1. **task list**: create your task list for this run as your first action.
|
|
15
|
+
|
|
16
|
+
2. **assess**: call \`${t("terraform_assess")}\`. It runs the scanners and returns a deterministic \`scorecard\` (overall \`posture\`, \`by_severity\` counts, a \`languages\` breadth block — which IaC languages were detected/scanned, and any detected-but-unscannable language like Pulumi surfaced honestly — \`top_risks\`, and an indicative compliance-crosswalk summary) plus a ready-to-post \`markdown\` report. This is the core deliverable — built from tool results, not your own judgement. Report every language's posture faithfully; never imply a non-Terraform finding will be auto-fixed.
|
|
17
|
+
|
|
18
|
+
3. **optional lenses** (fold each into the report only when it actually ran):
|
|
19
|
+
- \`${t("infracost_diff")}\` — current monthly cost (auto-skips without \`INFRACOST_API_KEY\`/the CLI).
|
|
20
|
+
- \`${t("terraform_version_currency")}\` — provider/module pins that are outdated or unpinned.
|
|
21
|
+
- \`${t("terraform_emit_sarif")}\` — when the workflow has a SARIF upload step, emit \`${SARIF_FILE}\` so every concern also lands in the repo's Security tab (read-only, complementary).
|
|
22
|
+
|
|
23
|
+
4. **report**: call \`${t("report_progress")}\` once with the assessment. Use the \`markdown\` from \`${t("terraform_assess")}\` as the base (it carries the posture banner, severity counts, top risks, and the indicative-crosswalk note verbatim — do not soften or inflate it), then append one-line **Cost** / **Version currency** notes if those lenses ran. If \`${t("set_output")}\` is available (standalone runs), also emit the structured result (\`posture\`, \`total\`, \`by_severity\`, the touched \`frameworks\`) so a CI step can gate on \`posture\`.
|
|
24
|
+
|
|
25
|
+
5. **guardrails**: never modify \`*.tf\`/\`*.tfvars\`, never push, never open a PR or issue. The assessment is the only deliverable.`,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { REVIEWER_AGENT_NAME } from "#app/agents/reviewer";
|
|
2
|
+
import type { Mode, ToolRef } from "./types.ts";
|
|
3
|
+
|
|
4
|
+
export function buildMode(t: ToolRef): Mode {
|
|
5
|
+
return {
|
|
6
|
+
name: "Build",
|
|
7
|
+
description:
|
|
8
|
+
"Implement, build, create, or develop code changes; make specific changes to files or features; execute a plan; or handle tasks with specific implementation details",
|
|
9
|
+
prompt: `### Checklist
|
|
10
|
+
|
|
11
|
+
1. **task list**: create your task list for this run as your first action.
|
|
12
|
+
|
|
13
|
+
2. **plan** (optional, for complex tasks): analyze requirements, read AGENTS.md and relevant code, produce a step-by-step implementation plan.
|
|
14
|
+
|
|
15
|
+
3. **setup**: checkout or create the branch:
|
|
16
|
+
- **PR event, modifying the existing PR**: call \`${t("checkout_pr")}\`
|
|
17
|
+
- **new branch**: use \`${t("git")}\` to create a branch (\`git checkout -b infraweaver/branch-name\`)
|
|
18
|
+
|
|
19
|
+
4. **build**: implement changes using your native file and shell tools:
|
|
20
|
+
- follow the plan (if you ran a plan phase)
|
|
21
|
+
- plan your approach before writing code: identify which files need to change, key design decisions, and edge cases. for non-trivial changes, consider whether there's a more elegant approach.
|
|
22
|
+
- run relevant tests/lints before committing
|
|
23
|
+
|
|
24
|
+
5. **self-review**: judgment call — does YOUR diff warrant a fresh-eyes pass?
|
|
25
|
+
|
|
26
|
+
Skip self-review (commit directly) when the diff is **genuinely trivial**:
|
|
27
|
+
- doc typos, comment-only edits, whitespace/format-only, import reordering
|
|
28
|
+
- lockfile or generated-code regeneration, mechanical rename whose only effect is import-path updates (size of diff is irrelevant — read the *shape*, not the line count)
|
|
29
|
+
- low-risk dep patch bump from a trusted source
|
|
30
|
+
|
|
31
|
+
Run self-review when the diff has **any behavioral surface, however small**:
|
|
32
|
+
- 1-line changes to SQL operators / comparison logic / regexes / redirects / HTTP methods / response codes
|
|
33
|
+
- any change to money / tax / currency / billing / fee / refund / payout calculations or constants
|
|
34
|
+
- any change to auth / permissions / roles / sessions / tokens / signature verification
|
|
35
|
+
- any change to feature-flag defaults, retry counts, timeouts, rate limits, batch sizes
|
|
36
|
+
- new endpoints, new code paths, new error branches — even small ones
|
|
37
|
+
- mixed diffs (whitespace + a single semantic line) — the semantic line still triggers self-review
|
|
38
|
+
- anything you're uncertain about
|
|
39
|
+
|
|
40
|
+
Tie-breaker: when in doubt, run self-review. One false-positive subagent dispatch costs cents; one false-negative shipped bug costs much more. There's no value in dispatching for a typo, but there's also no excuse for skipping on a 1-line change to a billing path.
|
|
41
|
+
|
|
42
|
+
Otherwise delegate the \`${REVIEWER_AGENT_NAME}\` subagent to review your diff with fresh eyes against YOUR TASK. The subagent's baked-in system prompt enforces a non-mutative + non-recursive contract: read-only file/search/web tools and read-only MCP queries only; no writes, shell side effects, state-changing MCP calls, or nested subagent dispatch. Enforcement is prose-only — restate the constraint in your dispatch instructions and do not relax it.
|
|
43
|
+
|
|
44
|
+
Before dispatching, ensure \`origin/<base>\` is locally available — the runner is often a shallow single-branch \`actions/checkout\` (depth=1, head-only refspec), and the reviewer's \`git diff --merge-base origin/<base>\` will fail with \`ambiguous argument\` or \`no merge base\` otherwise. Run \`git fetch --no-tags --deepen=1000 origin <base>:refs/remotes/origin/<base>\` once (the explicit destination refspec is required — a shallow single-branch checkout configures a head-only refspec, so a bare \`origin <base>\` only updates \`FETCH_HEAD\` and never creates the \`origin/<base>\` tracking ref); it's a no-op if the ref already has enough history. (The reviewer is read-only by contract, so it cannot do this itself — fetching is the orchestrator's job.)
|
|
45
|
+
|
|
46
|
+
Compose your \`${REVIEWER_AGENT_NAME}\` dispatch prompt using this template verbatim, substituting the \`<...>\` placeholders. The preamble aligns the orchestrator side of the dispatch contract with the reviewer's baked-in system prompt — both ends say the same thing about where the work lives and what to do on an empty diff.
|
|
47
|
+
|
|
48
|
+
\`\`\`
|
|
49
|
+
## What you're reviewing
|
|
50
|
+
This is a PRE-COMMIT Build-mode self-review. The work to review lives in the working tree (uncommitted), NOT in committed history.
|
|
51
|
+
|
|
52
|
+
Branch: <branch> (off <base>)
|
|
53
|
+
Canonical diff command: git diff --merge-base origin/<base>
|
|
54
|
+
|
|
55
|
+
Use \`--merge-base\` (single MCP \`git\` call, no shell substitution required). NOT bare \`git diff origin/<base>\` or two-dot \`git diff origin/<base>..HEAD\` — the symmetric forms include the inverse of every commit landed on \`<base>\` since this branch forked, which is noise (and the git tool will reject those forms when the divergence is detected). \`origin/<base>...HEAD\` (three-dot) and \`--cached\` both miss the uncommitted edits self-review runs on, so they're also wrong here.
|
|
56
|
+
|
|
57
|
+
If the merge-base diff returns empty, treat it as "no changes — nothing to review" and stop per your system prompt. Do not search for the work elsewhere.
|
|
58
|
+
|
|
59
|
+
## Your task
|
|
60
|
+
<YOUR TASK content>
|
|
61
|
+
|
|
62
|
+
## Build-phase failures
|
|
63
|
+
<tight summary — what broke, root cause, the fix — or "no build-phase failures">
|
|
64
|
+
\`\`\`
|
|
65
|
+
|
|
66
|
+
Follow the template with the diff content (\`git diff --merge-base origin/<base-branch>\` — single MCP \`git\` call, captures committed + staged + unstaged, excludes base-branch progress) and your task brief. Instruct the subagent to flag bugs, logic errors, missing edge cases, gaps between request and diff, and unintended changes.
|
|
67
|
+
|
|
68
|
+
Delegation + research discipline (distilled from \`/anneal\` canonical — these are codified learnings from many review rounds, not theoretical best practices):
|
|
69
|
+
- Do NOT summarize what you implemented — that biases the subagent toward validating the shape of your solution rather than questioning it.
|
|
70
|
+
- Do NOT curate a reading list of files. Let the subagent discover scope from the diff and codebase.
|
|
71
|
+
- Do NOT pre-shape output with a severity / category schema. That leaks your hypotheses; severity is your call during evaluation.
|
|
72
|
+
- Do NOT defect-hunt the diff yourself in parallel with the subagent. Your role is dispatch + evaluation; doing the review yourself reintroduces the implementation bias the subagent is meant to mitigate.
|
|
73
|
+
- For diffs that rely on third-party API contracts, SDK semantics, framework directives, or DB engine specifics, instruct the subagent to verify load-bearing claims via web search and quote source URLs rather than trust training data — this is the single most common review-quality failure mode.
|
|
74
|
+
|
|
75
|
+
Be **discerning** about what comes back. The reviewer is an AI subagent and is fallible — treat every finding as a hypothesis, not a directive, and **verify each one yourself** against the diff and the code before deciding whether to apply. You are searching for a solution that is **complete, minimal, and elegant** — you may need to think hard to find it. Do not over-engineer, do not be over-defensive, **do not write AI slop**. Reviewers bias toward *recommending additions*, and that bias has a recognizable slop texture: defensive checks for cases that cannot happen, extra logging, new abstractions used once, comments restating code, tests asserting tautologies, "just-in-case" guards, error handlers for cases the type system already rules out. Reject those. For each surviving finding, ask: would applying it leave the code more sound, correct, AND elegant? Two-out-of-three means look harder for a fix that gets all three before settling. After applying the fixes you accept, re-read your diff and be discerning about what *you just changed*: if any fix turned out to be bloat in context, revert it. Then verify only intended changes are present, no debug artifacts or commented-out code remain, no unrelated files were modified. Commit locally via \`${t("git")}\` (\`git add\` the files you changed, then \`git commit -m "..."\`) — the same MCP \`git\` tool used for the branch above, so this works even when \`shell\` is disabled.
|
|
76
|
+
|
|
77
|
+
6. **finalize**:
|
|
78
|
+
- confirm a clean working tree, then push via \`${t("push_branch")}\` (see *SYSTEM* Git rules if this fails — prepush errors are usually the repo's tests/lint, not infra timeouts)
|
|
79
|
+
- create a PR via \`${t("create_pull_request")}\`
|
|
80
|
+
- call \`${t("report_progress")}\` with the PR link or the exact error if push/PR failed
|
|
81
|
+
|
|
82
|
+
### Notes
|
|
83
|
+
|
|
84
|
+
For simple, well-defined tasks, skip the plan phase and go straight to build.`,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Mode, ToolRef } from "./types.ts";
|
|
2
|
+
|
|
3
|
+
export function complianceAuditMode(t: ToolRef): Mode {
|
|
4
|
+
return {
|
|
5
|
+
name: "ComplianceAudit",
|
|
6
|
+
nonCommitting: true,
|
|
7
|
+
description:
|
|
8
|
+
"Read-only COMPLIANCE audit: scan the Terraform, map findings to the operator's required_controls across the supported frameworks (NCSC Cloud Principles, Cyber Essentials, NHS DSPT, Secure by Design, CIS, SOC 2), and emit a machine-readable OSCAL assessment-results document. A read-only, controls-focused companion to Assess; opens no PR and modifies nothing.",
|
|
9
|
+
prompt: `### Checklist
|
|
10
|
+
|
|
11
|
+
This mode is **read-only** — a compliance audit focused on the operator's \`required_controls\`. It maps the repo's Terraform findings onto compliance controls and emits an OSCAL assessment-results document an auditor / GRC tool can consume. It never fixes, edits, commits, pushes, or opens a PR. The crosswalk is an **indicative alignment**, not a certified audit verdict — say so.
|
|
12
|
+
|
|
13
|
+
1. **task list**: create your task list for this run as your first action.
|
|
14
|
+
|
|
15
|
+
2. **assess**: call \`${t("terraform_assess")}\` to get the deterministic \`scorecard\` (posture, \`by_severity\`, the \`languages\` breadth block, \`top_risks\`) and the underlying concerns. Assess is Terraform-first but also covers the other IaC languages the scanners parse (CloudFormation, Kubernetes, Helm, Dockerfile, ARM/Bicep) — the control mapping is built from ALL of them. This is the evidence, never your own judgement.
|
|
16
|
+
|
|
17
|
+
3. **map to controls**: call \`${t("terraform_compliance_crosswalk")}\` with the concerns to get the frameworks + controls each finding touches (\`by_framework\`), plus the \`unmapped_concern_ids\`. When the run carries a \`required_controls\` directive, lead with those controls: report each as **met** (no open finding maps to it), **at risk** (an open finding maps to it), or **not-code-verifiable** (the control can't be evidenced from Terraform alone — say so honestly rather than implying a pass).
|
|
18
|
+
|
|
19
|
+
4. **emit OSCAL**: call \`${t("terraform_emit_oscal")}\` to write the machine-readable OSCAL assessment-results document (findings + observations + the posture marking). This is the audit artefact — a workflow step can upload it or attach it to a GRC pipeline. Record the evidence with \`${t("terraform_emit_evidence")}\` when an evidence bundle is wanted, and \`${t("terraform_emit_vex")}\` when the consumer ingests CycloneDX VEX (an SBOM-aware scanner) — both are signed (detached Ed25519 \`.sig\`) when the run configures \`INFRAWEAVER_SIGNING_KEY\`.
|
|
20
|
+
|
|
21
|
+
5. **report**: call \`${t("report_progress")}\` once with the audit summary — posture, the required-controls verdict table (met / at-risk / not-code-verifiable), the frameworks touched, and where the OSCAL document was written. Prefix the crosswalk note "Indicative alignment (crosswalk v{version}) — not an audit verdict." When \`${t("set_output")}\` is available, emit a structured result (e.g. \`{ "posture": "...", "controls_met": <n>, "controls_at_risk": <n>, "frameworks": [...] }\`) so CI can gate on an at-risk required control. Pair this with the action's \`output_schema\` input to expose those keys as named outputs (without it, \`${t("set_output")}\` exposes a single \`result\` string).
|
|
22
|
+
|
|
23
|
+
6. **guardrails**: never modify \`*.tf\`/\`*.tfvars\`, never push, never open a PR or issue. The audit report + the OSCAL document are the only deliverables.`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { PRODUCT_NAME } from "#app/brand";
|
|
2
|
+
import type { Mode, ToolRef } from "./types.ts";
|
|
3
|
+
|
|
4
|
+
export function costOptimizationMode(t: ToolRef): Mode {
|
|
5
|
+
return {
|
|
6
|
+
name: "CostOptimization",
|
|
7
|
+
description:
|
|
8
|
+
"Find and fix Terraform cost waste — resources that bill at zero traffic, oversized instances, idle/unattached resources, gp2 → gp3, missing lifecycle/retention — and open one scoped rightsizing PR per opportunity, quantified by the credential-free IDLE FLOOR and, when infracost is connected, the monthly delta too. The cost counterpart to the security remediation flow. Works with no cloud credentials and no pricing key; infracost (INFRACOST_API_KEY) is an optional deep mode.",
|
|
9
|
+
prompt: `### Checklist
|
|
10
|
+
|
|
11
|
+
This mode reduces Terraform spend the same disciplined way Remediate reduces risk: a minimal, reviewable change per opportunity, QUANTIFIED by the infracost monthly delta, opened as a PR for a human — never auto-applied. A rightsizing change ALTERS capacity/behaviour, so every PR carries the plan + the projected saving and escalates anything risky to human review.
|
|
12
|
+
|
|
13
|
+
1. **task list**: create your task list for this run as your first action.
|
|
14
|
+
|
|
15
|
+
2. **idle floor (FIRST, always available)**: call \`${t("terraform_emit_cost")}\`. It needs NO cloud credentials, NO pricing key and makes NO network call — it prices what this config bills at **zero traffic** from a bundled snapshot of public list prices and writes the \`cost.md\` artifact. This is your baseline evidence and the one cost number that is deterministic. If it returns \`found: false\`, the config has no catalogued always-on resources — say so and continue to step 3.
|
|
16
|
+
|
|
17
|
+
3. **optional deep mode (infracost)**: call \`${t("infracost_diff")}\` for a full breakdown + base-vs-current delta. It needs the operator's \`INFRACOST_API_KEY\` (a third-party tool ${PRODUCT_NAME} does not bundle or pay for). If it returns \`ran: false\`, **do not stop** — you still have the idle floor from step 2; just say the delta is unavailable and quantify from the floor instead. Never guess a number that neither tool produced: usage-dependent lines (data processed, requests, egress) are NOT derivable from Terraform, so never publish a monthly total as if it were one.
|
|
18
|
+
|
|
19
|
+
4. **find opportunities**: rank candidates by evidence you actually have. The idle floor is the strongest signal — a resource billing at zero traffic is waste until proven otherwise (an over-provisioned App Service plan, an Azure Firewall or VPN gateway in a dev environment, a Premium cache serving nothing). Then the usual classes: oversized compute (rightsize to a smaller instance/SKU that still meets stated needs), \`gp2\` → \`gp3\` EBS, idle/unattached resources (unused EIPs, detached EBS), missing autoscaling floors, absent S3 lifecycle / log retention. Prefer changes that cut cost with NO capacity loss; anything that reduces capacity is a human decision — surface it, never silently shrink production.
|
|
20
|
+
|
|
21
|
+
5. **pick scope — ONE opportunity (or one coherent class) per PR**: take the largest safe monthly saving first. **Targeted override:** if YOUR TASK names a resource/file, act only on it. Unless asked for more, open **at most one PR this run**.
|
|
22
|
+
|
|
23
|
+
6. **apply the minimal change**: edit only \`*.tf\`/\`*.tfvars\`, the smallest change that captures the saving; match the file's existing formatting (do NOT \`terraform fmt\` pre-existing drift). For a capacity-affecting change, expose it via a variable with a sensible default and call out the trade-off — never hard-shrink without a flag.
|
|
24
|
+
|
|
25
|
+
7. **validate → plan → quantify**:
|
|
26
|
+
- \`${t("terraform_validate")}\` — never push a change whose validate didn't pass.
|
|
27
|
+
- \`${t("terraform_plan")}\` when creds are present — treat \`has_destroy_or_replace\`/\`stateful_destructive\` exactly as Remediate (a stateful destroy/replace is hard-blocked at push unless \`allow_replace\` covers it; high blast radius / \`needs_human\` → \`needs-human\` label + callout). A rightsizing that replaces a stateful resource is almost never worth the risk — prefer to abandon it.
|
|
28
|
+
- re-run \`${t("terraform_emit_cost")}\` to refresh \`cost.md\` and show the floor the change removes, and \`${t("infracost_diff")}\` (when it ran in step 3) to quantify the full delta. If neither shows a saving, abandon the change.
|
|
29
|
+
|
|
30
|
+
8. **open the PR (MANDATORY body)**: branch \`infraweaver/cost-<slug>\` from the scanned HEAD, commit naming the resource + the saving (include the regenerated \`cost.md\`), \`${t("push_branch")}\`, \`${t("create_pull_request")}\` (omit \`base\`). The body must lead with the **monthly saving** — the idle-floor reduction, plus the \`${t("infracost_diff")}\` delta when available — then per change: **Was** (current sizing/cost) · **Changed** (the rightsizing) · **Trade-off** (capacity/behaviour impact, or "none — same capacity") · the collapsed plan · a blast-radius / needs-human callout when the plan flagged one. Evidence-built — every number from \`${t("terraform_emit_cost")}\`/\`${t("infracost_diff")}\`/\`${t("terraform_plan")}\`, never self-reported. State plainly that the floor excludes usage-dependent charges; never present it as a total bill. Never auto-merge.
|
|
31
|
+
|
|
32
|
+
9. **guardrails**: one opportunity per PR; never auto-merge; only modify \`*.tf\`/\`*.tfvars\` (plus the generated \`cost.md\`); never shrink production capacity without surfacing the trade-off for human sign-off.
|
|
33
|
+
|
|
34
|
+
10. **finalize**: \`${t("report_progress")}\` once — the resource, the projected monthly saving, the PR link, and any deferred opportunities (or the exact tool error / the infracost-absent note).`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { PRODUCT_NAME } from "#app/brand";
|
|
2
|
+
import type { Mode, ToolRef } from "./types.ts";
|
|
3
|
+
|
|
4
|
+
export function driftDetectMode(t: ToolRef): Mode {
|
|
5
|
+
return {
|
|
6
|
+
name: "DriftDetect",
|
|
7
|
+
nonCommitting: true,
|
|
8
|
+
description: `Read-only DRIFT detection: report whether the deployed infrastructure has drifted from the committed Terraform. Prefers a zero-credential path — reading a \`terraform show -json\` plan artifact the customer's CI already produced (${PRODUCT_NAME} never holds cloud creds) — and falls back to running terraform plan against live state. The continuous-posture-over-time companion to Assess; reports INCONCLUSIVE (never a false 'no drift') when it can't measure, opens no PR and modifies nothing. Best run on a schedule.`,
|
|
9
|
+
prompt: `### Checklist
|
|
10
|
+
|
|
11
|
+
This mode is **read-only** — it detects whether live infrastructure has DRIFTED from the committed Terraform. Drift is the plan showing changes when the code hasn't changed (someone edited a resource in the console, an out-of-band change, a failed apply). It never fixes drift (that is an \`apply\` or a code change a human owns) — it reports it. Do NOT edit Terraform, commit, push, or open a PR.
|
|
12
|
+
|
|
13
|
+
1. **task list**: create your task list for this run as your first action.
|
|
14
|
+
|
|
15
|
+
2. **measure drift — prefer the sovereign path**:
|
|
16
|
+
- **If a plan artifact is available** (\`$INFRAWEAVER_PLAN_JSON_PATH\`, or \`./plan.json\` from \`terraform show -json plan.out\` in the customer's CI), call \`${t("detect_plan_drift")}\` FIRST. It reads that artifact and needs **no cloud credentials** — the CI already ran the plan where the creds live. Each drifted resource comes back as a concern at its \`file:line\`; \`drift: true\` when any resource drifted.
|
|
17
|
+
- **Otherwise**, call \`${t("terraform_plan")}\` to plan against live state. It auto-skips (\`ran: false\`) when no cloud credentials / the terraform CLI are present.
|
|
18
|
+
- **If neither can measure** (no artifact AND no creds/CLI), the gate is INCONCLUSIVE, not "no drift" — report INCONCLUSIVE plainly (step 4) so a green check never masks an unchecked stack.
|
|
19
|
+
|
|
20
|
+
3. **read the verdict**: from \`detect_plan_drift\`, \`drift\`/\`summary.drifted\` and the drifted concerns are the signal. From \`terraform_plan\` (when \`ran: true\`), any \`to_change\` / \`to_destroy\` / \`has_destroy_or_replace\` on a repo whose code is unchanged is drift. Distinguish:
|
|
21
|
+
- **NO DRIFT** — a clean / no-op plan (\`+0 ~0 -0\`): live state matches the code.
|
|
22
|
+
- **DRIFT** — the plan would change/replace/destroy resources to reconcile state with code. List the drifted resource addresses (from \`destructive\` / the plan summary), the \`blast_radius.tier\`, and call out any \`stateful_destructive\` entry loudly (reconciling it could destroy data). Surface a non-deterministic plan (\`idempotent: false\`) separately — a perpetual diff is config non-determinism, not true drift.
|
|
23
|
+
- **also read from \`detect_plan_drift\`**: \`noise_filtered\` (updates excluded as provider-computed churn, e.g. aws \`tags_all\` — mention the count, they are not drift); \`forgotten\` (resources this plan drops from management — the cloud object survives but drift detection goes blind to it; when \`needs_human\` is true a STATEFUL resource is leaving management: surface \`needs_human_reasons\` prominently); and \`action_invocations\` (provider actions THIS apply will run — flag any with \`declared_in_code: false\`).
|
|
24
|
+
|
|
25
|
+
4. **report + gate**:
|
|
26
|
+
- call \`${t("report_progress")}\` once with the verdict — **NO DRIFT**, **DRIFT** (the drifted addresses + blast radius + any stateful/needs-human callout, with the collapsed \`plan_text\`), or **INCONCLUSIVE** (no creds / plan couldn't run — say which). Recommend the human action for drift (reconcile via the console change's reversal, an \`apply\`, or a code update) — never auto-fix it.
|
|
27
|
+
- when \`${t("set_output")}\` is available, emit a structured result (e.g. \`{ "drift": <bool>, "drifted_resources": <n>, "stateful_at_risk": <n>, "inconclusive": <bool> }\`) so a scheduled workflow can open an alert / fail a check on \`drift == true\`. Pair this with the action's \`output_schema\` input to expose those keys as named outputs (without it, \`${t("set_output")}\` exposes a single \`result\` string).
|
|
28
|
+
|
|
29
|
+
5. **guardrails**: never modify \`*.tf\`/\`*.tfvars\`, never push, never open a PR. ${PRODUCT_NAME} never applies and never reconciles drift itself — the verdict is the only deliverable.`,
|
|
30
|
+
};
|
|
31
|
+
}
|
package/src/modes/fix.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Mode, ToolRef } from "./types.ts";
|
|
2
|
+
|
|
3
|
+
export function fixMode(t: ToolRef): Mode {
|
|
4
|
+
return {
|
|
5
|
+
name: "Fix",
|
|
6
|
+
description:
|
|
7
|
+
"Fix CI failures; debug failing tests or builds; investigate and resolve check suite failures",
|
|
8
|
+
prompt: `### Checklist
|
|
9
|
+
|
|
10
|
+
1. **task list**: create your task list for this run as your first action.
|
|
11
|
+
|
|
12
|
+
2. Checkout the PR branch via \`${t("checkout_pr")}\`.
|
|
13
|
+
|
|
14
|
+
3. Fetch check suite logs via \`${t("get_check_suite_logs")}\`.
|
|
15
|
+
|
|
16
|
+
4. **CRITICAL**: verify the failure was INTRODUCED BY THIS PR before fixing. If unrelated, abort and report.
|
|
17
|
+
|
|
18
|
+
5. Diagnose and fix:
|
|
19
|
+
- read the workflow file, reproduce locally with the EXACT same commands CI runs
|
|
20
|
+
- fix the issue using your native file and shell tools
|
|
21
|
+
- verify the fix by re-running the exact CI command
|
|
22
|
+
- review the diff before committing — verify only the fix is present, no debug artifacts, no unrelated changes. the fix should be clean enough that a senior engineer would approve without hesitation.
|
|
23
|
+
- commit locally via \`${t("git")}\` (\`git add\` the changed files, then \`git commit -m "..."\`) — works even when \`shell\` is disabled
|
|
24
|
+
|
|
25
|
+
6. Finalize:
|
|
26
|
+
- confirm a clean working tree, then push via \`${t("push_branch")}\` (same push/prepush guidance as Build mode in *SYSTEM*)
|
|
27
|
+
- call \`${t("report_progress")}\` with the diagnosis and fix summary (or the exact push error if push failed)`,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { REVIEWER_AGENT_NAME } from "#app/agents/reviewer";
|
|
2
|
+
import { BOT_LOGIN, PRODUCT_NAME, PRODUCT_SLUG } from "#app/brand";
|
|
3
|
+
import { FINDING_VERIFICATION_PASS, REVIEW_FINDING_PRECEDENTS } from "#app/reviewQuality";
|
|
4
|
+
import { PR_SUMMARY_FORMAT } from "./prFormats.ts";
|
|
5
|
+
import type { Mode, ToolRef } from "./types.ts";
|
|
6
|
+
|
|
7
|
+
export function incrementalReviewMode(t: ToolRef): Mode {
|
|
8
|
+
return {
|
|
9
|
+
name: "IncrementalReview",
|
|
10
|
+
nonCommitting: true,
|
|
11
|
+
description:
|
|
12
|
+
"Re-review a PR after new commits are pushed; focus on new changes since the last review",
|
|
13
|
+
prompt: `### Checklist
|
|
14
|
+
|
|
15
|
+
1. **task list**: create your task list for this run as your first action.
|
|
16
|
+
|
|
17
|
+
2. **checkout**: call \`${t("checkout_pr")}\` — this returns PR metadata, \`diffPath\` (full diff), \`incrementalDiffPath\` (changes since last reviewed version, if available), and (when TF declarations changed) a supplemental \`impactPath\`. read the diff TOC first and use its line ranges as your coverage checklist. only AFTER establishing scope from the diffs, use \`impactPath\` as an explicitly-incomplete list of reference leads — it never replaces raw-diff reading or establishes coverage.
|
|
18
|
+
|
|
19
|
+
3. **incremental scope**: if \`incrementalDiffPath\` is present, read it to see what changed since the last review. this is a range-diff that isolates the net changes, filtering out base branch noise. if not present, fall back to reviewing the full PR diff and determine what changed since ${PRODUCT_NAME}'s most recent review.
|
|
20
|
+
|
|
21
|
+
4. **prior feedback — read AND retire it**: fetch previous reviews via \`${t("list_pull_request_reviews")}\`, then call \`${t("get_review_comments")}\` on each prior ${PRODUCT_NAME} review. Each thread renders as a section whose first line is a fenced tag \`comment author=<login> id=<fullDatabaseId> review=<reviewId> thread=<graphqlId>\`; section headers carry \`[RESOLVED]\` / \`[OUTDATED]\` when relevant. For every **open, ${PRODUCT_NAME}-originated** thread, decide and act:
|
|
22
|
+
|
|
23
|
+
- **${PRODUCT_NAME}-originated** means the FIRST \`comment author=...\` tag in the section is \`author=${BOT_LOGIN}\`. The \`*\` marker on individual comments is unrelated — it flags whether a comment belongs to the queried review, not whether it is the thread root.
|
|
24
|
+
- **addressed?** read the file at the thread's anchor and judge whether the substantive concern is now resolved by the new commits. Lines being modified isn't enough: reformatting, renaming, or moving the same code elsewhere doesn't address a concern. If the comment raised multiple distinct concerns, ALL must be addressed. The \`[OUTDATED]\` tag means GitHub moved the anchor (line shift, force-push, rename) — it does NOT mean the concern was addressed; re-read the code at its new location before deciding.
|
|
25
|
+
- **if addressed**: call \`${t("reply_to_review_comment")}\` with the root tag's numeric \`id=\` as \`comment_id\` (NOT the \`thread=\` value — that's a separate GraphQL ID used only by resolve) and a one-line body (e.g. \`Addressed in <short-sha>.\`), then call \`${t("resolve_review_thread")}\` with the root tag's \`thread=\` value as \`thread_id\`. Do this BEFORE drafting the new review so the GitHub thread state aligns with the new review by the time it lands.
|
|
26
|
+
- **if uncertain or partially addressed**: leave open. False-positive resolutions erode trust faster than false negatives.
|
|
27
|
+
- **scope**: only retire ${PRODUCT_NAME}-originated threads. Threads from human reviewers belong to those humans to resolve, even if the commit happened to address them.
|
|
28
|
+
- **reaction signal**: comment tags may carry \`reactions=👍N,👎N\` — human votes on the finding. A 👎 on a ${PRODUCT_NAME}-originated root comment is the human telling you the finding was wrong or unwanted: do NOT re-raise that finding class in this review, and treat it as false-positive feedback — when a LEARNINGS file is configured, record the rejected finding class (rule/pattern + why the human rejected it, if discernible) so future reviews stop flagging it. A 👍 confirms the finding class is valued; no action needed beyond noting it. Reactions never override the addressed/unaddressed judgment for retiring threads — a 👍 on an unfixed finding does not make it addressed.
|
|
29
|
+
|
|
30
|
+
The remaining open threads feed step 8's dedup filter — anything already flagged and unchanged by the new commits should not be re-raised. The rolling PR summary snapshot is the durable record of retire activity; you don't need to surface it in the review body.
|
|
31
|
+
|
|
32
|
+
5. **triage**: orient on the *incremental* changes — domain, seams, external contracts, user-facing surfaces. pull as much context as you need to render a confident review: read related files, grep for callers of changed symbols, check tests that exercise the touched paths. **you are the synthesizer.**
|
|
33
|
+
|
|
34
|
+
if the incremental changes are **genuinely trivial**, skip the fan-out entirely and jump to step 10's non-substantive path (do NOT submit a review).
|
|
35
|
+
|
|
36
|
+
"Genuinely trivial" (skip): formatting/comment tweaks, import reordering, lockfile regen, mechanical rename of import paths, whitespace-only.
|
|
37
|
+
"Looks trivial but isn't" (do NOT skip — same anti-patterns as Review mode): 1-line changes to SQL/regex/auth/billing/permissions/signature-verification code; flipping feature-flag defaults or retry/timeout constants; money/tax/HTTP-method/redirect changes; tightening or loosening a comparison operator; mixed diffs with a semantic line buried in formatting.
|
|
38
|
+
When unsure, treat as non-trivial.
|
|
39
|
+
|
|
40
|
+
6. **lens dispatch — one lens per unresolved, load-bearing hypothesis (0, 1, or 2+)**.
|
|
41
|
+
|
|
42
|
+
Re-review the incremental changes yourself first. A lens is an independent pass at a *specific, falsifiable question the new commits raise that you could not confidently resolve on your own* — not a second opinion for its own sake. The default is **0 lenses**: most incremental reviews resolve fully yourself, especially thread-reply re-reviews where the user asks "did you address X?" rather than "review the diff again." After your own pass, keep only the open questions that meet ALL THREE bars:
|
|
43
|
+
- **falsifiable** — you can state in one line what evidence confirms it and what refutes it.
|
|
44
|
+
- **load-bearing** — if it resolves the wrong way, the review's verdict or a specific finding changes.
|
|
45
|
+
- **beyond your own reach** — the code alone doesn't settle it (needs an external-contract check, a cross-file trace too wide to hold confidently, or an independent adversarial read of subtle logic). "A second look to be thorough" does NOT qualify.
|
|
46
|
+
|
|
47
|
+
Dispatch **one \`${REVIEWER_AGENT_NAME}\` lens per surviving hypothesis** — **0** for most re-reviews, **1** when a single real question remains, **2+** when several do. The count follows the questions: never manufacture a hypothesis to reach two, never drop a real one to avoid dispatching alone. When you dispatch 2+, they go out together in parallel (step 7). High-stakes subsystems (auth, billing, payments, schema migration, webhooks, secrets, RBAC, multi-tenant isolation, cron/scheduling) and substantive deltas (>5 files, >200 net new lines) are where an unresolved question is most likely load-bearing — but a 1-line change to a security boundary can raise exactly one lens-worthy hypothesis, and a large mechanical delta can raise none. Size is a hint, never the gate.
|
|
48
|
+
|
|
49
|
+
Lens framing follows Review mode: themed lenses (correctness, security, etc.) and subsystem lenses (auth, billing, schema-migration, etc.) — for high-stakes domains lead with the subsystem lens.
|
|
50
|
+
|
|
51
|
+
7. **fan out (only if step 6 raised ≥1 hypothesis)**: dispatch every \`${REVIEWER_AGENT_NAME}\` lens for this run **IN A SINGLE ASSISTANT TURN.** One hypothesis is a single Task block; **2+ hypotheses are MULTIPLE PARALLEL TASK TOOL_USE BLOCKS IN ONE MESSAGE.**
|
|
52
|
+
|
|
53
|
+
⚠️ CRITICAL — WHEN YOU DISPATCH 2+ LENSES, PARALLELISM IS MANDATORY. ⚠️
|
|
54
|
+
Default tool-call behavior is **serial dispatch**: emit one Task call, await result, emit next, await, etc. With multiple lenses this collapses your fan-out into a sequential review where each lens adds N × (orchestrator-think-time + lens-execution-time) to wall time. **YOU MUST OVERRIDE THIS DEFAULT.** Emit ALL of your Task tool_use blocks in the SAME assistant message, BEFORE you read ANY result from ANY of them. (A lone lens is one block in one turn.)
|
|
55
|
+
|
|
56
|
+
✅ Right pattern: one assistant turn with N Task tool_use blocks → wait → N results arrive together → aggregate.
|
|
57
|
+
❌ Wrong pattern: turn 1 = Task(lens A) → turn 2 (after A's result) = Task(lens B). This is the failure mode.
|
|
58
|
+
|
|
59
|
+
You can also include your own \`read\` / \`grep\` / \`webfetch\` calls in the SAME turn as the parallel \`${REVIEWER_AGENT_NAME}\` dispatches.
|
|
60
|
+
|
|
61
|
+
if a subagent errors out, times out, or returns nothing usable, retry once with the same lens; if it still fails, proceed with partial coverage and note the missing lens in the review body. each subagent gets:
|
|
62
|
+
- **the absolute diff path(s) from step 2's \`${t("checkout_pr")}\` return, named verbatim in the dispatch prompt.** when \`incrementalDiffPath\` is present, name BOTH (\`incrementalDiffPath: /tmp/.../pr-NNN-SHA-incremental.diff\` then \`diffPath: /tmp/.../pr-NNN-SHA.diff\`) — the reviewer's baked-in prompt reads incremental first and uses full for context; when only \`diffPath\` exists, name it alone. the subagent \`read\`s those files; it must NOT re-derive via \`git diff\` (bare \`git diff origin/<base>\` is symmetric and pulls in the inverse of base-branch progress — pure noise, and the git tool rejects it), and paraphrasing ("review the new commits") sends it down that fallback, which also fails on shallow GHA checkouts. do NOT tell them to skip pre-existing issues — that suppresses regressions the new commits amplified; the "issues must be NEW" filter lives at aggregation time (step 8), not in the subagent prompt.
|
|
63
|
+
- **only one lens = one hypothesis** — state it as the falsifiable question with its scope boundary and what evidence would confirm vs refute it; never a multi-section "review for X, Y, and Z" prompt and never a vague "review for security"
|
|
64
|
+
- **a Task \`description\` set to the lens name** — the harness reads this field to label log lines so parallel runs can be told apart.
|
|
65
|
+
- if the lens touches external contracts, instruct the subagent to verify load-bearing claims via web search and quote source URLs.
|
|
66
|
+
- ask the subagent to report findings with file paths and NEW line numbers from the full PR diff so you can anchor inline comments.
|
|
67
|
+
|
|
68
|
+
delegation discipline:
|
|
69
|
+
- do NOT summarize the changes for them (biases toward validation frame)
|
|
70
|
+
- do NOT hand them a curated reading list (let them discover scope)
|
|
71
|
+
- do NOT pre-shape their output with a finding schema
|
|
72
|
+
- do NOT mention the other lenses (independence is the point)
|
|
73
|
+
|
|
74
|
+
8. **aggregate, draft, self-critique**: merge findings (yours + any subagent output if you went multi-lens); de-dup overlaps; trace each finding yourself. drop praise, style preferences, speculative/unverified claims, findings about pre-existing code unrelated to the new commits, anything not actionable, and anything that re-states prior review feedback (heuristic: if the finding's root cause lives in lines the *new commits* added or modified, it's in scope; otherwise drop). also drop **bloat-shaped findings** — proposed fixes that would add defensive checks for cases that can't happen, abstractions used once, comments restating obvious code, tests asserting tautologies, or "just-in-case" guards. subagents are fallible and bias toward recommending changes; the bar for an actionable inline comment is sound + correct + elegant. recommending a change that improves only one of the three (or degrades elegance to nominally improve correctness) makes the codebase worse, not better. To compute "lines the new commits added or modified": if \`incrementalDiffPath\` from step 2 is present, use it directly. Otherwise, take the prior ${PRODUCT_NAME} review's \`commit_id\` (returned alongside each entry from \`${t("list_pull_request_reviews")}\` in step 4) and run \`git diff <prior-review-sha>...HEAD\` (three-dot merge-base form) to isolate the lines added since that review. Do NOT use the two-dot \`<prior-review-sha>..HEAD\` form — after a force-push the prior SHA may no longer be an ancestor of HEAD, and the \`git\` tool rejects the symmetric two-dot diff on divergence.
|
|
75
|
+
|
|
76
|
+
Apply the **Finding precedents** (defined after this checklist, before the body format) to every candidate — a precedent match means drop, unless you have specific evidence the precedent does not apply here.
|
|
77
|
+
|
|
78
|
+
**Hunt for non-anchored concerns before drafting.** After collecting your anchored findings, deliberately scan for concerns that have no specific line to point at — typically: deletion / cleanup plans for code the new commits replace or shadow; rollout sequencing (what happens to in-flight state during deploy / revert?); coverage gaps the new commits imply but don't add; scope questions that only the human can answer (e.g. is the legacy path going away or is this a long-term dual track?); architectural risks the new commits open up that aren't a single-line bug. On substantial incremental diffs (migrations, refactors, multi-file rewrites, version bumps that change runtime semantics), at least one such concern almost always exists; if you can't think of any, your bar is probably too high.
|
|
79
|
+
|
|
80
|
+
${FINDING_VERIFICATION_PASS}
|
|
81
|
+
|
|
82
|
+
draft inline comments with NEW line numbers from the full PR diff — attach a \`<details>Technical details</details>\` block to any inline comment whose fix is non-trivial or has cross-file implications (see Inline technical details in the format below). every comment must be actionable, 2-3 sentences max in the visible part.
|
|
83
|
+
|
|
84
|
+
9. **build the review body**: use the same default format as Review mode (preamble + optional cross-cutting \`### \` sections + optional \`### ℹ️ Nitpicks\` + optional suppressed-findings block) — scoped to the **incremental delta**, not the full PR. The "Reviewed changes" bullets describe what changed since the prior ${PRODUCT_SLUG} review (each bullet starts with a past-tense verb, e.g. \`- Extracted shared CLI runtime into a single module\`). Do NOT include a separate "Prior review feedback" checklist — that's tracked in the rolling PR summary snapshot for the next agent run, and surfacing it in the user-facing body is noise (changes that addressed prior feedback are already covered by the Reviewed-changes bullets). In some cases you may receive a complete diff for the whole PR instead of an incremental one; when this happens, determine what changed since ${PRODUCT_NAME}'s most recent review yourself before drafting bullets.
|
|
85
|
+
|
|
86
|
+
10. Submit — every run must end with EXACTLY ONE of \`${t("create_pull_request_review")}\` (substantive review) or \`${t("report_progress")}\` (no-review acknowledgement). do NOT call \`create_issue_comment\` for review output.
|
|
87
|
+
|
|
88
|
+
Same callout ladder as Review mode — \`[!CAUTION]\` (red, "will break") → \`[!IMPORTANT]\` (purple, "must address before merging") → \`> ℹ️ ...\` (informational, "minor suggestions only") → \`> ✅ ...\` (green friendly, "no concerns"). Same Fix-button lever: the footer renders a Fix button on every non-approving review, so \`approved: true\` suppresses it. Wrapping mergeable feedback in \`[!IMPORTANT]\` trains users to click Fix on reviews that don't need fixing — pick the tier the author's actual next action justifies.
|
|
89
|
+
|
|
90
|
+
Follow these rules:
|
|
91
|
+
- note: the first create_pull_request_review submission may error with a one-time diff-coverage nudge listing unread TOC regions. retry the same call to proceed — optionally after reading the listed ranges. the pre-flight will not block again this session.
|
|
92
|
+
- IF NO NEW ISSUES, NON-SUBSTANTIVE CHANGES ONLY (trivial formatting, import reordering, comment tweaks): do NOT submit a review. Instead call \`${t("report_progress")}\` with a 1-2 sentence note explaining no review was warranted (e.g. "No new issues. Changes since last review are formatting-only."). this leaves a visible signal that the run completed.
|
|
93
|
+
- ELSE IF NEW CRITICAL ISSUES (blocks merge — bugs, security, data loss, broken core flows): call \`${t("create_pull_request_review")}\` with \`approved: false\`, all comments, and the review body. body opens with \`> [!CAUTION]\\n> This PR introduces ...\`, followed by the PR summary using the default format below.
|
|
94
|
+
- ELSE IF NEW MUST-ADDRESS NON-CRITICAL FINDINGS (real consequences if shipped — incorrect behavior, missing validation, regressions the author should fix before merge): call \`${t("create_pull_request_review")}\` with \`approved: false\`, all comments, and the review body. body opens with \`> [!IMPORTANT]\\n> ...\`, followed by the PR summary using the default format below. Do NOT use this tier for nits, style preferences, or "consider also" suggestions.
|
|
95
|
+
- ELSE IF NEW MINOR SUGGESTIONS ONLY (single-line nits, doc/comment polish, defer-able observations, "rough edges"): call \`${t("create_pull_request_review")}\` with \`approved: false\`, all comments, and the review body. body opens with \`> ℹ️ No critical issues — minor suggestions inline.\\n\\n\` (vary the wording after ℹ️ to fit the review), followed by the PR summary using the default format below.
|
|
96
|
+
- ELSE IF INFORMATIONAL OBSERVATIONS (mergeable as-is, but worth surfacing — e.g. prior feedback addressed cleanly with one minor stale doc reference, or a noteworthy positive observation): call \`${t("create_pull_request_review")}\` with \`approved: true\`, NO inline comments, and the review body. body opens with \`> ✅ No new issues found.\\n\\n\` (or similar friendly green opener), followed by the PR summary using the default format below. If a point is concrete enough to anchor to a line, downgrade the whole review to "minor suggestions only" (\`approved: false\`) instead — the ✅ signals "no action needed", which contradicts an actionable anchor.
|
|
97
|
+
- ELSE IF NO NEW ISSUES, SUBSTANTIVE CHANGES (new functionality, behavior changes, or fixes to prior review feedback): call \`${t("create_pull_request_review")}\` to create a PR review. If all previous reviews have been properly addressed and no new issues were discovered, set \`approved: true\`. body opens with \`> ✅ No new issues found.\\n\\n\`, followed by the PR summary using the default format below.
|
|
98
|
+
|
|
99
|
+
${REVIEW_FINDING_PRECEDENTS}
|
|
100
|
+
|
|
101
|
+
${PR_SUMMARY_FORMAT}`,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// changes to mode definitions should be reflected in action.yml's `mode:` input,
|
|
2
|
+
// the regenerated docs/action-inputs.md (`pnpm docs:inputs` — this repo uses pnpm),
|
|
3
|
+
// and the human-facing modes reference on the website (infraweaver.dev/docs/modes —
|
|
4
|
+
// infraweaver-ui src/app/[locale]/(marketing)/docs/modes/page.tsx; the [locale]
|
|
5
|
+
// segment came in with next-intl, and a stale path here is exactly how the
|
|
6
|
+
// generated action-inputs manifest silently missed inputs before — see the header
|
|
7
|
+
// of scripts/generate-ui-inputs.ts).
|
|
8
|
+
//
|
|
9
|
+
// Each built-in mode lives in its own file in this directory as a
|
|
10
|
+
// `(t: ToolRef) => Mode` factory; a new mode means a new file plus a wiring line
|
|
11
|
+
// in the `computeModes` array below (the array order is the canonical mode
|
|
12
|
+
// order, asserted by modes.test.ts). Shared pieces: ./types.ts (Mode, ToolRef)
|
|
13
|
+
// and ./prFormats.ts (the PR-body format constants).
|
|
14
|
+
import { type AgentId, formatMcpToolRef } from "#app/external";
|
|
15
|
+
import { addressReviewsMode } from "./address-reviews.ts";
|
|
16
|
+
import { assessMode } from "./assess.ts";
|
|
17
|
+
import { buildMode } from "./build.ts";
|
|
18
|
+
import { complianceAuditMode } from "./compliance-audit.ts";
|
|
19
|
+
import { costOptimizationMode } from "./cost-optimization.ts";
|
|
20
|
+
import { driftDetectMode } from "./drift-detect.ts";
|
|
21
|
+
import { fixMode } from "./fix.ts";
|
|
22
|
+
import { incrementalReviewMode } from "./incremental-review.ts";
|
|
23
|
+
import { modernizeDeprecatedMode } from "./modernize-deprecated.ts";
|
|
24
|
+
import { planMode } from "./plan.ts";
|
|
25
|
+
import { policyGateMode } from "./policy-gate.ts";
|
|
26
|
+
import { refactorMode } from "./refactor.ts";
|
|
27
|
+
import { refreshRemediationMode } from "./refresh-remediation.ts";
|
|
28
|
+
import { remediateMode } from "./remediate.ts";
|
|
29
|
+
import { remediateAndRefactorMode } from "./remediate-and-refactor.ts";
|
|
30
|
+
import { resolveConflictsMode } from "./resolve-conflicts.ts";
|
|
31
|
+
import { reviewMode } from "./review.ts";
|
|
32
|
+
import { summarizePrMode } from "./summarize-pr.ts";
|
|
33
|
+
import { taskMode } from "./task.ts";
|
|
34
|
+
import { terraformCodeReviewMode } from "./terraform-code-review.ts";
|
|
35
|
+
import type { Mode } from "./types.ts";
|
|
36
|
+
import { updateDependenciesMode } from "./update-dependencies.ts";
|
|
37
|
+
|
|
38
|
+
export {
|
|
39
|
+
PR_SUMMARY_FORMAT,
|
|
40
|
+
REFACTOR_PR_FORMAT,
|
|
41
|
+
REMEDIATION_PR_FORMAT,
|
|
42
|
+
} from "./prFormats.ts";
|
|
43
|
+
export type { Mode, ToolRef } from "./types.ts";
|
|
44
|
+
|
|
45
|
+
export function computeModes(agentId: AgentId): Mode[] {
|
|
46
|
+
const t = (toolName: string) => formatMcpToolRef(agentId, toolName);
|
|
47
|
+
return [
|
|
48
|
+
buildMode(t),
|
|
49
|
+
addressReviewsMode(t),
|
|
50
|
+
reviewMode(t),
|
|
51
|
+
incrementalReviewMode(t),
|
|
52
|
+
terraformCodeReviewMode(t),
|
|
53
|
+
summarizePrMode(t),
|
|
54
|
+
planMode(t),
|
|
55
|
+
fixMode(t),
|
|
56
|
+
resolveConflictsMode(t),
|
|
57
|
+
assessMode(t),
|
|
58
|
+
remediateMode(t),
|
|
59
|
+
refreshRemediationMode(t),
|
|
60
|
+
refactorMode(t),
|
|
61
|
+
remediateAndRefactorMode(t),
|
|
62
|
+
policyGateMode(t),
|
|
63
|
+
updateDependenciesMode(t),
|
|
64
|
+
modernizeDeprecatedMode(t),
|
|
65
|
+
costOptimizationMode(t),
|
|
66
|
+
driftDetectMode(t),
|
|
67
|
+
complianceAuditMode(t),
|
|
68
|
+
taskMode(t),
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const modes: Mode[] = computeModes("opencode");
|
|
73
|
+
|
|
74
|
+
/** built-in mode names in canonical casing. used to validate / canonicalize the
|
|
75
|
+
* `mode` action input so a CI run can pin a mode deterministically instead of
|
|
76
|
+
* relying on the agent's prompt-driven `select_mode` choice. mode names are
|
|
77
|
+
* agent-independent (only the embedded tool refs differ per agent), so the
|
|
78
|
+
* opencode-rendered list is the authoritative name set. */
|
|
79
|
+
export const BUILTIN_MODE_NAMES: readonly string[] = modes.map((m) => m.name);
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* modes that legitimately never modify the working tree. used by the post-run
|
|
83
|
+
* dirty-tree gate to suppress the "commit and push" nudge — those modes
|
|
84
|
+
* complete by submitting a review, posting a comment, or reporting a verdict,
|
|
85
|
+
* not by touching files. any leftover in the tree at end-of-run is incidental
|
|
86
|
+
* tool noise (e.g. a `node_modules/` from a stray install attempt) on an
|
|
87
|
+
* ephemeral worktree; nudging the agent to commit it would produce a spurious
|
|
88
|
+
* PR. derived from the `nonCommitting` flag each read-only mode declares in
|
|
89
|
+
* its own factory, so a new mode carries its committing-ness with it instead
|
|
90
|
+
* of needing a second edit here.
|
|
91
|
+
*/
|
|
92
|
+
export const NON_COMMITTING_MODES: ReadonlySet<string> = new Set(
|
|
93
|
+
modes.filter((m) => m.nonCommitting).map((m) => m.name),
|
|
94
|
+
);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { REFACTOR_PR_FORMAT } from "./prFormats.ts";
|
|
2
|
+
import type { Mode, ToolRef } from "./types.ts";
|
|
3
|
+
|
|
4
|
+
export function modernizeDeprecatedMode(t: ToolRef): Mode {
|
|
5
|
+
return {
|
|
6
|
+
name: "ModernizeDeprecated",
|
|
7
|
+
description:
|
|
8
|
+
"Migrate deprecated Terraform patterns to their modern equivalents (aws_launch_configuration → aws_launch_template, the template_file data source → the templatefile() function, EOL provider pins), one PR per pattern class. These ALTER the resource set, so they are proven by a reviewed plan delta (or shipped `proposed — unproven`) with a `moved {}` block wherever an address can be preserved; equivalence is never claimed.",
|
|
9
|
+
prompt: `### Checklist
|
|
10
|
+
|
|
11
|
+
This mode migrates DEPRECATED Terraform patterns to modern ones. Unlike Refactor, these migrations swap a resource TYPE / data source / function and therefore ALTER the resource set — so equivalence is FALSE and must NEVER be claimed (the equivalence guard would block such a claim anyway). The proof is a reviewed plan delta when cloud credentials exist, otherwise the change ships labelled \`proposed — unproven\`. Author a \`moved {}\` block wherever an address genuinely carries over, and use \`create_before_destroy\` where a replace is unavoidable.
|
|
12
|
+
|
|
13
|
+
1. **task list**: create your task list for this run as your first action.
|
|
14
|
+
|
|
15
|
+
2. **detect**: find deprecated patterns. \`${t("terraform_version_currency")}\` surfaces EOL provider pins; read the Terraform for the well-known deprecated forms — \`aws_launch_configuration\` (→ \`aws_launch_template\`), \`aws_elb\` (→ \`aws_lb\`), the \`template_file\` data source / archived \`hashicorp/template\` provider (→ the built-in \`templatefile()\` function), and other documented EOL resources. Pick **one pattern class** to migrate this run.
|
|
16
|
+
|
|
17
|
+
3. **pick scope — ONE pattern class per PR**: migrate every site of that single pattern (e.g. all \`aws_launch_configuration\` → \`aws_launch_template\`) in one coherent PR; do NOT mix pattern classes. **Targeted directive override:** if YOUR TASK names a pattern or files, act only on those. Unless asked for more, open **at most one PR this run**.
|
|
18
|
+
|
|
19
|
+
4. **migrate (preserve behaviour as far as the new shape allows)**: rewrite each site to the modern equivalent with the **same effective configuration** (same AMI / instance type / user-data, same listener / target behaviour). Where the new resource keeps the logical address, author a \`moved {}\` block via \`${t("terraform_generate_moved")}\` so state carries over instead of a destroy/recreate; where the migration is an inherent replace (e.g. a launch config referenced by an ASG), use \`create_before_destroy\` and call it out. Only touch \`*.tf\`/\`*.tfvars\`.
|
|
20
|
+
|
|
21
|
+
5. **validate**: \`${t("terraform_validate")}\` — never push a migration whose validate didn't pass. Check its \`providers\` majors and \`${t("terraform_provider_schema")}\` for the modern resource's argument shape.
|
|
22
|
+
|
|
23
|
+
6. **prove via plan, never equivalence**: do NOT call \`${t("terraform_equivalence_check")}\` — this change is behaviour-altering and an equivalence claim would be false (and is hard-blocked at push). Instead:
|
|
24
|
+
- **cloud credentials present**: call \`${t("terraform_plan")}\` and attach the **reviewed plan delta**. Treat \`has_destroy_or_replace\`/\`stateful_destructive\` exactly as Remediate — a stateful destroy/replace is hard-blocked at push unless \`allow_replace\` covers it; a high \`blast_radius.tier\` or \`needs_human\` adds the \`needs-human\` label (\`${t("add_labels")}\`) + a prominent callout.
|
|
25
|
+
- **no credentials**: ship \`proposed — unproven\` — add the label, put the proposed-unproven banner unmissably at the top of the body, and state plainly that this migration ALTERS resources and the plan must be reviewed before merge.
|
|
26
|
+
- record the outcome with \`${t("terraform_emit_evidence")}\`.
|
|
27
|
+
|
|
28
|
+
7. **keep module tests consistent** (if a local module changed): \`${t("terraform_module_tests")}\` — update drifting \`examples/\`/tests, never weaken an assertion.
|
|
29
|
+
|
|
30
|
+
8. **open the PR (MANDATORY body)**: branch \`infraweaver/modernize-<pattern>\` from the scanned HEAD, commit naming the pattern (old → modern), \`${t("push_branch")}\`, \`${t("create_pull_request")}\` (omit \`base\`). Build the body with the **Refactor PR format** below, using the \`## Proposed change — unproven\` / \`## Reviewed plan delta\` section (NOT \`## Equivalence proof\`), naming the moved addresses and listing every migrated site. Never auto-merge.
|
|
31
|
+
|
|
32
|
+
9. **finalize**: \`${t("report_progress")}\` once — which pattern class was migrated, how many sites, the proof (reviewed-plan / proposed-unproven), and the PR link (or the exact tool error).
|
|
33
|
+
|
|
34
|
+
${REFACTOR_PR_FORMAT}`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Mode, ToolRef } from "./types.ts";
|
|
2
|
+
|
|
3
|
+
export function planMode(t: ToolRef): Mode {
|
|
4
|
+
return {
|
|
5
|
+
name: "Plan",
|
|
6
|
+
nonCommitting: true,
|
|
7
|
+
description:
|
|
8
|
+
"Create plans, break down tasks, outline steps, analyze requirements, understand scope of work, or provide task breakdowns",
|
|
9
|
+
prompt: `### Checklist
|
|
10
|
+
|
|
11
|
+
1. **task list**: create your task list for this run as your first action.
|
|
12
|
+
|
|
13
|
+
2. Analyze the task and gather context:
|
|
14
|
+
- read AGENTS.md and relevant codebase files
|
|
15
|
+
- understand the architecture and constraints
|
|
16
|
+
|
|
17
|
+
3. Produce a structured, actionable plan with clear milestones.
|
|
18
|
+
|
|
19
|
+
4. Call \`${t("report_progress")}\` with the plan body. Do NOT set \`target_plan_comment\` — that flag is exclusively for revising an existing plan, and \`${t("select_mode")}\` will route you to a separate PlanEdit checklist when a prior plan comment exists for this issue.`,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Mode, ToolRef } from "./types.ts";
|
|
2
|
+
|
|
3
|
+
export function policyGateMode(t: ToolRef): Mode {
|
|
4
|
+
return {
|
|
5
|
+
name: "PolicyGate",
|
|
6
|
+
nonCommitting: true,
|
|
7
|
+
description:
|
|
8
|
+
"Read-only policy-as-code CI gate: run the repository's own OPA/conftest Rego policies against a Terraform plan and report PASS / FAIL / INCONCLUSIVE — the policy counterpart to the Assess security gate. Opens no PR and modifies nothing.",
|
|
9
|
+
prompt: `### Checklist
|
|
10
|
+
|
|
11
|
+
This mode is **read-only** — a policy-as-code gate, the conftest/OPA companion to Assess. It reports whether the repo's OWN Rego policies pass; it never fixes, edits, commits, pushes, or opens a PR.
|
|
12
|
+
|
|
13
|
+
1. **task list**: create your task list for this run as your first action.
|
|
14
|
+
|
|
15
|
+
2. **locate policy**: confirm the repo ships policy-as-code — a \`policy/\`, \`policies/\`, or \`.conftest\` directory of Rego. If none exists, call \`${t("report_progress")}\` with "No policy-as-code found (no policy/, policies/, or .conftest Rego) — nothing to gate." and **stop** (an absent policy set is not a failure).
|
|
16
|
+
|
|
17
|
+
3. **produce a plan to evaluate**: conftest evaluates a Terraform **plan JSON**, so a plan must exist first. Call \`${t("terraform_plan")}\`. It auto-skips (\`ran: false\`) when no cloud credentials / the terraform CLI are present — in that case the gate is **INCONCLUSIVE, not passing**: report that plainly (step 5) so a green check never masks an unevaluated policy.
|
|
18
|
+
|
|
19
|
+
4. **evaluate**: call \`${t("policy_check")}\`. It runs conftest against the plan JSON and returns \`passed\` plus any \`failures\`, or a skip \`code\` (\`no_target\`, \`conftest_not_installed\`, \`no_policy_dir\`) when it couldn't run — treat any skip as INCONCLUSIVE, never PASS.
|
|
20
|
+
|
|
21
|
+
5. **report + gate**:
|
|
22
|
+
- call \`${t("report_progress")}\` once with the verdict: **PASS** (no failures), **FAIL** (list each \`failures\` entry — the policy, the resource, the message), or **INCONCLUSIVE** (conftest / plan / policy dir absent — say which).
|
|
23
|
+
- when \`${t("set_output")}\` is available, emit a structured result (e.g. \`{ "passed": <bool>, "violations": <n>, "inconclusive": <bool> }\`) so the workflow can fail the check on \`passed == false\`. Pair this with the action's \`output_schema\` input to make the gate enforceable.
|
|
24
|
+
|
|
25
|
+
6. **guardrails**: never modify \`*.tf\`/\`*.tfvars\`, never push, never open a PR or issue. The verdict is the only deliverable.`,
|
|
26
|
+
};
|
|
27
|
+
}
|