Fix audit tool bootstrap and add per-run preflight

audit-code install-tools.sh:
- Buffer the opengrep release JSON before grep -m1; curl died with (23)
  under pipefail when grep quit early.
- Use ${m}: in the PowerShell block; $m: parsed as a scope-qualified var.
- On Arch, skip paru/yay when pacman -Q shows every package installed,
  since --needed still invokes sudo.
- Add --check-only (fast, installs nothing, non-zero naming missing tools)
  and --user-only (no system package managers, no sudo).

log-run.py (both skills): put the skill dir on sys.path so running it as
a script from any cwd no longer raises ModuleNotFoundError.

audit-terraform: move deps from requirements.txt into pyproject
dependency groups and add scripts/install-tools.sh (uv sync --group tools,
then check trivy, tflint, tofu, terragrunt, gh).

Both SKILL.md files gain a 0.5 Preflight step and call scripts through
uv run --project ${SKILL_DIR}. tools_unavailable is now a map of tool to
exact install command; audit-terraform skips trivy when absent and stops
with an install hint instead of crashing when tofu/terragrunt is missing.
This commit is contained in:
2026-09-22 15:21:28 -05:00
parent d3258b224a
commit 37fc3fb291
30 changed files with 1045 additions and 84 deletions
@@ -187,6 +187,51 @@ def test_cli_writes_per_agent_slices(tmp_path):
assert sliced["trivy_findings"] == full["trivy_findings"]
def test_cli_records_missing_scanners_with_install_command(tmp_path):
repo = _stage_fixture(tmp_path / "repo")
out_dir = tmp_path / "out"
mod = _load_cli()
ran: list[str] = []
def _fake(cmd, **kw):
ran.append(cmd[0])
return _fake_subprocess(cmd, **kw)
with patch("subprocess.run", side_effect=_fake), \
patch("shutil.which", side_effect=lambda t: None if t in ("trivy", "tflint") else f"/usr/bin/{t}"):
rc = mod.main([
"--repo", str(repo), "--base", "main", "--head", "HEAD",
"--output-dir", str(out_dir), "--mode", "local",
])
assert rc == 0
manifest = json.loads((out_dir / "manifest.json").read_text())
assert manifest["tools_unavailable"] == {
"trivy": "go install github.com/aquasecurity/trivy/cmd/trivy@latest",
"tflint": "go install github.com/terraform-linters/tflint@latest",
}
assert "trivy" not in ran
assert manifest["trivy_findings"] == []
def test_cli_stops_with_install_command_when_plan_tool_missing(tmp_path):
repo = _stage_fixture(tmp_path / "repo")
out_dir = tmp_path / "out"
mod = _load_cli()
with patch("subprocess.run", side_effect=_fake_subprocess), \
patch("shutil.which", side_effect=lambda t: None if t == "tofu" else f"/usr/bin/{t}"):
rc = mod.main([
"--repo", str(repo), "--base", "main", "--head", "HEAD",
"--output-dir", str(out_dir), "--mode", "local",
])
assert rc == 1
manifest = json.loads((out_dir / "manifest.json").read_text())
install = "go install github.com/opentofu/opentofu/cmd/tofu@latest"
assert manifest["tools_unavailable"] == {"tofu": install}
assert manifest["errors"] == [
f"tofu is not installed, so the changed units cannot be planned. Install it with `{install}` and re-run."
]
def test_cli_preserves_terragrunt_only_change_context(tmp_path):
repo = _stage_fixture(tmp_path / "repo")
terragrunt_dir = repo / "live" / "prod" / "app"