LLM-based code review tool that finds issues tests and linters miss
Project description
Vet : Verify Everything
Vet is a standalone verification tool for code changes and coding agent behavior.
It reviews git diffs, and optionally an agent's conversation history, to find issues that tests and linters often miss. Vet is optimized for use by humans, CI, and coding agents.
Installation
pip install verify-everything
Or install from source:
pip install git+https://github.com/imbue-ai/vet.git
Quickstart
Run Vet in the current repo:
vet "Implement X without breaking Y"
Compare against a base ref/commit:
vet "Refactor storage layer" --base-commit main
GitHub PRs (Actions)
Vet can run on pull requests.
Create .github/workflows/vet.yml:
name: Vet
permissions:
contents: read
pull-requests: write
on:
pull_request:
types: [opened, edited, synchronize, reopened]
jobs:
vet:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: pip install verify-everything==0.1.2
- name: Run vet
if: github.event.pull_request.head.repo.full_name == github.repository
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VET_GOAL: |
${{ github.event.pull_request.title }}
Additional context (not necessarily part of the goal):
${{ github.event.pull_request.body }}
run: |
set +e
vet "$VET_GOAL" --quiet --output-format github \
--base-commit "${{ github.event.pull_request.base.sha }}" \
> "$RUNNER_TEMP/review.json"
status=$?
if [ "$status" -ne 0 ] && [ "$status" -ne 10 ]; then exit "$status"; fi
jq --arg sha "${{ github.event.pull_request.head.sha }}" \
'. + {commit_id: $sha}' "$RUNNER_TEMP/review.json" > "$RUNNER_TEMP/review-final.json"
gh api "repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews" \
--method POST --input "$RUNNER_TEMP/review-final.json" > /dev/null || \
gh pr comment "${{ github.event.pull_request.number }}" \
--body "$(jq -r '[.body] + [.comments[] | "**\(.path):\(.line)**\n\n\(.body)"] | join("\n\n---\n\n")' "$RUNNER_TEMP/review-final.json")"
exit 0
NOTE: This will not fail in CI if Vet finds an issue.
Environment variables
ANTHROPIC_API_KEYis required for the default model configuration.
Using Vet with Coding Agents
Vet ships as an agent skill that coding agents like OpenCode and Codex can discover and use automatically. When installed, agents will proactively run vet after code changes and include conversation history for better analysis.
Install the skill
for dir in ~/.agents ~/.opencode ~/.claude ~/.codex; do
mkdir -p "$dir/skills/vet/scripts"
for file in SKILL.md scripts/export_opencode_session.py scripts/export_codex_session.py scripts/export_claude_code_session.py; do
curl -fsSL "https://raw.githubusercontent.com/imbue-ai/vet/main/skills/vet/$file" \
-o "$dir/skills/vet/$file"
done
done
This places the skill in ~/.agents/skills/vet/, ~/.opencode/skills/vet/, ~/.claude/skills/vet/, and ~/.codex/skills/vet/, so it is discovered by OpenCode, Claude Code, and Codex.
Security note
The --history-loader option executes the specified shell command as the current user to load the conversation history. It is important to review history loader commands and shared config presets before use.
How it works
Vet snapshots the repo and diff, optionally adds a goal and agent conversation, runs LLM checks, then filters/deduplicates findings into a final list of issues.
Why Vet
- Verification for agentic workflows: "the agent said it ran tests" is not the same as "all tests ran successfully".
- CI-friendly safety net: catches classes of problems that may not be covered by existing tests.
- Bring-your-own-model: can run against hosted providers or local/self-hosted OpenAI-compatible endpoints.
Output & exit codes
- Exit code
0: no issues found - Exit code
1: unexpected runtime error - Exit code
2: invalid usage/configuration error - Exit code
10: issues found
Output formats:
textjsongithub
Configuration
Model configuration
Vet supports custom model definitions using OpenAI-compatible endpoints via JSON config files searched in:
$XDG_CONFIG_HOME/vet/models.json(or~/.config/vet/models.json)models.jsonat your repo root
Example models.json
{
"providers": {
"openai": {
"name": "OpenAI",
"api_type": "openai_compatible",
"base_url": "https://api.openai.com/v1",
"api_key_env": "OPENAI_API_KEY",
"models": {
"gpt-4o": {
"model_id": "gpt-4o-2024-08-06",
"context_window": 128000,
"max_output_tokens": 16384
},
"gpt-4o-mini": {
"model_id": "gpt-4o-mini-2024-07-18",
"context_window": 128000,
"max_output_tokens": 16384
},
"o1": {
"model_id": "o1-2024-12-17",
"context_window": 200000,
"max_output_tokens": 100000
}
}
}
}
}
Then:
vet "Harden error handling" --model gpt-4o-mini
Configuration profiles (TOML)
Vet supports named profiles so teams can standardize CI usage without long CLI invocations.
Profiles set defaults like model choice, enabled issue codes, output format, and thresholds.
See the example in this project.
Custom issue guides
You can customize the guide text for the issue codes via guides.toml. Guide files are loaded from:
$XDG_CONFIG_HOME/vet/guides.toml(or~/.config/vet/guides.toml)guides.tomlat your repo root
Example guides.toml
[logic_error]
suffix = """
- Check for integer overflow in arithmetic operations
"""
[insecure_code]
replace = """
- Check for SQL injection: flag any string concatenation or f-string formatting used to build SQL queries rather than parameterized queries
- Check for XSS: flag user-supplied data rendered into HTML templates without proper escaping or sanitization
- Check for path traversal: flag file operations where user input flows into file paths without validation against directory traversal (e.g. ../)
- Check for insecure cryptography: flag use of deprecated or weak algorithms (e.g. MD5, SHA1 for security purposes, DES, RC4)
- Check for hardcoded credentials: flag passwords, API keys, or tokens embedded directly in source code
"""
Section keys must be valid issue codes (vet --list-issue-codes). Each section supports three optional fields: prefix (prepends to built-in guide), suffix (appends to built-in guide), and replace (fully replaces the built-in guide). prefix and suffix can be used together, but replace is mutually exclusive with the other two. Guide text should be formatted as a list.
License
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0-only).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file verify_everything-0.1.3.tar.gz.
File metadata
- Download URL: verify_everything-0.1.3.tar.gz
- Upload date:
- Size: 188.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bfbcf3bc56d48852cc546a94320cd70602282c13b1ed247dd7fc862f4e218e5e
|
|
| MD5 |
0f005f2334288013f491026ad66b548e
|
|
| BLAKE2b-256 |
b2c952972ef043d7c8b313785c2803f46e709fa4aed09a92be1712231047fce9
|
File details
Details for the file verify_everything-0.1.3-py3-none-any.whl.
File metadata
- Download URL: verify_everything-0.1.3-py3-none-any.whl
- Upload date:
- Size: 242.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64d2b234493ce40851e5b7e260e429ec7e918a2d40e166da34d86d1be3359517
|
|
| MD5 |
1136c102de909f9bc70991796dcdf5ab
|
|
| BLAKE2b-256 |
5eca39c36279dd15c44590bc38c0ee33691e57baa28dd573ff9c1ba5077bbda3
|