Agents & Profiles
On every PR push, this action:
- Computes the diff (full on the first run, incremental on later pushes)
- Detects languages from changed file extensions
- Runs a roster of AI review agents against the diff
- Runs deterministic checks on changed files: shellcheck, CVE lookups (OSV.dev), semgrep SAST, trufflehog secret scanning, ruff (Python), golangci-lint (Go), hadolint (Dockerfiles), checkov (Terraform/K8s/IaC), phpcs (PHP/Drupal), eslint (JS/TS), dep-exists (new dependencies that no public registry knows), phpstan (PHP static analysis), kube-linter (Kubernetes), tflint (Terraform), suppression-check (comments that turn off a security rule), and three documentation checks (docs-api-check, docs-ref-check, docs-drift-check). See Static Analyzers
- Posts a summary comment (first run only) and a review with inline findings
- Auto-resolves stale bot threads and dismisses superseded reviews
Review agents
Quick mode (default) runs one or two finding agents. On the first run it also runs a summary agent:
| Agent | Purpose |
|---|---|
| pr-summarizer | Generates a walkthrough summary (first run only) |
| code-reviewer | Finds bugs, logic errors, and code quality issues |
| silent-failure-hunter | Detects swallowed errors and unsafe fallbacks (runs when the diff has error-handling patterns) |
Full mode adds five more agents:
| Agent | Purpose |
|---|---|
| architecture-reviewer (conditional) | Evaluates design patterns, coupling, and scalability. Runs when the diff touches code or infra files |
| security-reviewer (conditional) | Checks for injection, auth, crypto, and supply chain issues. Runs when the diff has security-relevant patterns |
| blind-hunter | Context-free review (zero project knowledge, finds issues that familiarity hides) |
| edge-case-hunter (conditional) | Traces every branching path for unhandled gaps. Runs when the diff has control-flow constructs |
| adversarial-general | Cynical adversarial review |
Full mode also runs issue-linker (GitHub only). It finds related issues and PRs and assesses whether the current changes resolve them.
Controlling which agents run
The agents (allowlist) and exclude-agents (denylist) settings control which agents run. Both accept a comma-separated list of the agent names above. An empty value (default) means all eligible agents run. When agents is set, the action ignores exclude-agents (the allowlist takes precedence). Existing gates still apply:
- A tier-2 agent in the allowlist does not run in quick mode.
- A conditional agent does not run if its trigger did not fire.
If you exclude pr-summarizer, the action does not post the PR summary comment. The action rejects unknown names with an error and a suggestion.
You can set these in three places. The list shows them in precedence order (highest wins):
/ai-pr-review review-fullslash command: always runs the full roster and ignores any allowlist or denylist for that one run.-
Action input or repo variable: set it directly in the calling workflow, or with the
AI_AGENTS/AI_EXCLUDE_AGENTSenv vars (see Configuration → Analyzer and agent selection):- uses: tag1consulting/ai-pr-review@main with: agents: 'code-reviewer,security-reviewer' # Run only these two # exclude-agents: 'edge-case-hunter,adversarial-general' # or: run everything except these two .ai-pr-review/policy.yml(the action also reads.github/ai-pr-review/policy.ymlas a fallback): theagentsandexclude-agentsfields of a named policy. The action routes by changed-file path, base branch, or head branch. Different PRs can get different agent rosters without a change to the workflow file. See Policies for the full schema.
An explicit action input or repo variable always wins over a policy.yml route match. A route match wins over the engine default (all eligible agents run). The same three-place precedence applies to the analyzers/exclude-analyzers allowlist and denylist for static analyzers. See Static Analyzers → Controlling which analyzers run.
Severity icons
Findings use icons with distinct shapes:
| Icon | Severity | Review action |
|---|---|---|
| ⛔ | Critical | REQUEST_CHANGES |
| 🚨 | High | REQUEST_CHANGES |
| 🔶 | Medium | APPROVE (informational) |
| 💬 | Low | APPROVE (informational) |
Review modes
Quick mode (default): Runs the code-reviewer and, if its trigger fires, silent-failure-hunter. This mode is fast and cheap, so it suits every push.
Full mode: Runs up to 9 agents. These are the 6 finding agents in the tables above (code-reviewer, architecture-reviewer, security-reviewer, blind-hunter, edge-case-hunter, adversarial-general), and 3 of them depend on diff content. Full mode also runs silent-failure-hunter (conditional), pr-summarizer (first run), and issue-linker (GitHub only). Start full mode in one of these ways:
- Adding the
ai-review-fulllabel to the PR - Using
workflow_dispatchwithreview_mode: full - Setting the
review-modeinput tofull - Routing by changed-file path, base branch, or head branch via a repo-local
.ai-pr-review/policy.yml(see below)
Routing review depth by branch or path
For anything beyond a single global quick/full choice (for example, near-zero-cost review for content-only PRs, one full smoke-test review when features land on a staging branch, and quick review on other feature branches), add .ai-pr-review/policy.yml to your repo. See Policies for the full schema, the precedence chain (an explicit ai-review-full label or review-mode input always wins over policy routing), and worked examples that include a release-branch escalation.
The ai-review-full label and review_mode input of workflow_dispatch are the way to force a one-time full review, whatever the policy file says.
Bitbucket Pipelines and GitLab CI work the same way, because policy.yml is engine-side and not specific to GitHub. Export BASE_REF and HEAD_REF (see the example pipelines in examples/pipelines/).
Language profiles
The action detects languages from file extensions and adds per-language context to agent prompts. Language profiles are markdown files in language-profiles/:
| Profile file | Covers |
|---|---|
go.md |
Go |
python.md |
Python |
javascript.md |
JavaScript |
typescript.md |
TypeScript |
php.md |
PHP / Drupal |
shell.md |
Shell / Bash |
ruby.md |
Ruby / Rails |
rust.md |
Rust |
java.md |
Java |
c++.md |
C and C++ |
terraform.md |
Terraform |
yaml.md |
YAML |
kotlin.md |
Kotlin |
swift.md |
Swift |
csharp.md |
C# |
scala.md |
Scala |
sql.md |
SQL |
lua.md |
Lua |
perl.md |
Perl |
To add a language, create a language-profiles/<language>.md file. The filename (without extension) must match the lowercase language key that detect_language() in ai_pr_review/languages.py returns for the relevant file extensions.