Part of #1367 (Phase 2 — AI Review Parity).
Goal
Generalize the existing workflow-security auditor into a multi-tool static-analysis orchestration engine — CodeRabbit's biggest non-AI differentiator (~60 auto-selected tools, tools list). We don't need 60 on day one; we need the engine + a strong first tier.
Current state (the seed)
src/security/ is already a clean rule engine for one domain: engine.ts (audit), loader.ts, parser.ts (Bun.YAML), 6 rules in rules/ (unpinned-action, excessive-permissions, dangerous-pull-request-target, bash-injection, missing-timeout, self-hosted-exposure), 3 reporters (pretty/json/github — auto-selects github annotations on a runner), CLI buddy-bot security (bin/cli.ts:2074). Tests in test/security/.
Spec
1. Engine generalization → src/analysis/
Analyzerinterface:{ name, filePatterns: string[], available(): Promise<boolean>, run(files): Promise<Finding[]> }- Two analyzer kinds:
- Native rules (in-process, like today's 6 security rules — migrate them under
src/analysis/analyzers/github-actions.ts) - External tools (spawn if installed or fetchable via
bunx/pipx-style runners): auto-selected by changed-file types, config-file aware (respect the repo's own.eslintrc/biome.jsonetc.)
- Native rules (in-process, like today's 6 security rules — migrate them under
- Unified
Findingtype shared with the review engine (#1375'sReviewFinding) so linter findings and AI findings merge into one review posting with one dedupe pass - Auto-selection: map changed files → applicable analyzers; skip analyzers whose tool is unavailable (report which were skipped — CodeRabbit logs tool selection)
2. First-tier analyzers (priority order)
| Tool | Files | Notes |
|---|---|---|
| existing 6 GH Actions rules | .github/workflows/* | migration of src/security/ |
| pickier/ESLint/Biome/Oxlint (whichever repo uses) | *.ts/js/tsx/jsx | detect repo's own linter + config |
| actionlint | workflows | external, complements native rules |
| ShellCheck | *.sh | external |
| Hadolint | Dockerfile* | pairs with our Docker updates |
| YAMLlint / JSON validation | *.yml/yaml/json | cheap native |
| markdownlint | *.md | cheap |
| Gitleaks-style secret scan | all changed lines | native regex ruleset first, tool later |
| OSV-Scanner semantics | lockfiles | we already have OSV (src/services/security-advisories.ts) — run on PR diffs too, not just scans |
3. Integration points
- Standalone:
buddy-bot analyze [path] --format pretty|json|github(supersedes and aliasesbuddy-bot security) - PR review: findings posted as inline comments alongside AI review, tagged
[tool] - Config:
analysis: { enabled?: boolean, tools?: Record<string, boolean | { configFile?: string }>, failOn?: 'error' | 'warning' | 'never' }
Tasks
src/analysis/engine +Analyzerinterface; migratesrc/security/rules (keepbuddy-bot securityas alias)- File-type auto-selection + availability probing + skipped-tool reporting
- First-tier analyzers per table (each with fixture tests; external tools mocked in CI)
- Secret-scan native ruleset (common token shapes; entropy check; test fixtures with fake keys)
- Merge/dedupe pipeline into review posting (#1375)
- Config + validation +
docs/analysis.mdwith the tool table
Acceptance criteria
buddy-bot analyzeon this repo runs the GH Actions rules + TS linter + markdownlint and reports in all three formats- A PR touching a Dockerfile with a Hadolint violation gets an inline
[hadolint]comment - Analyzer unavailability degrades gracefully with an explicit skipped list
- No AI key required — this entire feature is non-AI and works standalone
Dependencies
- Independent to build; posting-path integration lands with #1375