{"slug": "vigilant-pr-adversarial-ai-code-review-that-posts-as-you-not-a-bot", "title": "Vigilant PR – adversarial AI code review that posts as you, not a bot", "summary": "Vigilant PR v1 is a portable, workflow-agnostic AI pull-request reviewer that posts review comments on behalf of the user's GitHub identity, not a generic bot. Developed by tllongdev, it supports any AI model (Claude, GPT, Gemini, Grok, Llama, NVIDIA, OpenRouter, or local models) and requires no repo-side setup or GitHub App—just a token. The tool is ready for GitHub pull requests, with Slack and Teams support in beta.", "body_md": "*A portable, workflow-agnostic AI pull-request reviewer that posts review comments on behalf of you - your GitHub identity, not a generic bot.*\n\nGet tagged as a reviewer on a pull request, and Vigilant PR reviews it and posts\nthe comments as **you** - your GitHub identity, not a bot. No repo-side setup, no\nGitHub App, just your token.\n\n``` php\nflowchart LR\n    CFG([\"Configure in the terminal:<br/>vigilant init\"]) --> C1\n    CFG -.-> C2\n    C1([\"vigilant github-watch\"]) --> A[\"You are tagged as a<br/>reviewer on a GitHub PR\"]\n    C2([\"vigilant slack-watch<br/>or vigilant teams-watch\"]) -.-> A2[\"Beta: you are @-mentioned in a<br/>configured Slack or Teams channel\"]\n    A --> B[\"Vigilant PR reads<br/>the PR and diff\"]\n    A2 -.-> B\n    B --> C[\"Adversarial review,<br/>severity-tagged findings\"]\n    C --> D[\"Posts inline comments<br/>as you, not a bot\"]\n    D --> E[\"Approves if nothing blocks,<br/>comments if it does\"]\n    classDef beta stroke:#a98bff,color:#a98bff,stroke-dasharray:5 5;\n    classDef cmd fill:#0d2038,stroke:#4da3ff,color:#cfe6ff;\n    class A2 beta;\n    class C2 beta;\n    class CFG cmd;\n    class C1 cmd;\n```\n\n**v1 - ready to use** for reviewing GitHub pull requests.\n\n**Use any AI model you want.** Give Vigilant PR an API key for your preferred\nprovider and it uses that model - Claude, GPT, Gemini, Grok (xAI), Llama,\nNVIDIA, OpenRouter, or a model you run locally. Some are free, some paid - your choice.\nYou just set your key and pick a model (or run `vigilant init`\n\n, which does it\nfor you). See [Models](#models) for the exact options.\n\nSlack and Teams support also exists, but is still beta.\n\n- Python 3.12+\n- The GitHub CLI\n`gh`\n\n, authenticated as the user who should author the comments (`gh auth login`\n\n), or a`GH_TOKEN`\n\nenv var with Pull requests: read/write. - An API key for\n**any supported model provider**- including free, no-card tiers (Groq, Google Gemini, NVIDIA NIM). See[Models](#models).\n\nThe core engine is dependency-free (standard library only) - model calls go over plain HTTP, no SDKs.\n\nRun `vigilant init`\n\nonce. It connects your GitHub account (runs `gh auth login`\n\nfor you if needed) and stores a model key - there are no files to edit. Keys are\nkept in a `0600`\n\nfile at `~/.config/vigilant-pr/credentials.json`\n\n(the same\nposture as the `gh`\n\nand `aws`\n\nCLIs).\n\nManage and switch models with the `model`\n\ncommand:\n\n```\nvigilant model add            # pick a provider, paste a key (stored, becomes active)\nvigilant model add groq       # or name the provider directly\nvigilant model list           # see stored providers, masked keys, and the active one\nvigilant model use groq       # switch the active model (by provider or provider/model)\nvigilant model remove openai  # delete a stored key\n```\n\nPrefer files/CI? A `.env`\n\nfile and real environment variables still work and\nalways take precedence over the stored keys (real env > `.env`\n\n> store). Copy\n`.env.example`\n\nto `.env`\n\nand fill in what you use. If you set no model, Vigilant\nauto-selects one from whichever provider key it finds (Anthropic preferred) and\nprints which model it chose.\n\n```\npipx install git+https://github.com/tllongdev/vigilant-pr\n# or pin a specific release:\npipx install git+https://github.com/tllongdev/vigilant-pr@v1.1.0\n# or, from a clone:\nuv tool install .\n```\n\n`main`\n\nis the stable release line, so the unpinned command always gets the\nlatest release.\n\nCheck what you have, then upgrade in place - your stored config and API keys\nlive in `~/.config/vigilant-pr/`\n\nand are never touched by an upgrade:\n\n```\nvigilant --version\n\n# pipx: force a reinstall from the latest main (most reliable)\npipx install --force git+https://github.com/tllongdev/vigilant-pr\n# uv:\nuv tool install --force git+https://github.com/tllongdev/vigilant-pr\n# container:\ndocker pull ghcr.io/tllongdev/vigilant-pr:latest\n```\n\nUse `--force`\n\n. `pipx upgrade`\n\n/ `uv tool upgrade`\n\ncompare version strings, so a\nplain upgrade can report \"already up to date\" and skip a newer `main`\n\ncommit\nthat didn't bump the version - and a pinned `@vX.Y.Z`\n\ninstall won't move at all.\nA forced reinstall always pulls the current code. To pin instead, reinstall with\nan explicit tag: `pipx install --force git+https://github.com/tllongdev/vigilant-pr@v1.7.0`\n\n.\n\nFrom zero to auto-reviewing PRs as you, in three commands:\n\n```\npipx install git+https://github.com/tllongdev/vigilant-pr\nvigilant init      # connects GitHub, picks + stores a model key (free options first)\nvigilant github-watch   # auto-reviews any open PR where you're a requested reviewer\n```\n\n`vigilant init`\n\nwalks you through everything: it connects your GitHub account\n(running `gh auth login`\n\nfor you if needed), lets you pick a model provider\n(leading with free, no-credit-card options like Groq), validates the key, and\nstores it. Nothing to hand-edit; switch models later with `vigilant model use`\n\n.\n\nWant to see a review before it posts anything? Dry-run any PR first:\n\n```\nvigilant review https://github.com/owner/repo/pull/123 --dry-run\n```\n\nThat's the whole flow: install, `init`\n\n, watch. Everything below is reference for\nspecific models, watcher tuning, and the chat surfaces.\n\n**Vigilant PR is free to use right now.**\n\nIf it adds value to your workflow, [donations](https://square.link/u/A8qxaJVb) go directly toward its continued development and maintenance.\n\nApple Pay and Google Pay supported - one tap, no card number.\n\n```\n# Review a PR and post as you (Sonnet 5, the default tier)\nvigilant review https://github.com/owner/repo/pull/123\n\n# Escalate to Opus 4.8 for a hard PR\nvigilant review 123 --repo owner/repo --opus\n\n# Preview without posting\nvigilant review 123 --repo owner/repo --dry-run\n\n# Preview, then approve before it posts (great while trying a new model)\nvigilant review 123 --repo owner/repo --approve\n```\n\nBy default reviews post automatically. If you're trying an unfamiliar model - or\njust want to watch what it produces before trusting it - turn on the approval\ngate: Vigilant prints the full review (summary + inline comments) and asks for a\n`y/N`\n\nbefore anything is posted.\n\n- One-off: add\n`--approve`\n\nto`review`\n\nor`github-watch`\n\n. - Always on: set\n`VIGILANT_REQUIRE_APPROVAL=1`\n\n(or answer \"yes\" in`vigilant init`\n\n). - Turn it back off:\n`--no-approve`\n\nor`VIGILANT_REQUIRE_APPROVAL=0`\n\n.\n\nOnce you trust the model, drop the flag and let it post on your behalf.\n\nVigilant PR is model-agnostic. Pick a model with a `provider/model`\n\nstring via\n`--model`\n\nor the `VIGILANT_MODEL`\n\nenv var, and supply that provider's key. A bare\nname (e.g. `claude-sonnet-5`\n\n) is treated as Anthropic, so existing setups keep\nworking. Under the hood there are just two wire protocols - the Anthropic\nMessages API and the OpenAI-compatible `/chat/completions`\n\nAPI - so most\nproviders, local servers, and gateways work out of the box.\n\n| You have... | `VIGILANT_MODEL` |\nAlso set |\n|---|---|---|\nNothing - want a free real model |\n`groq/llama-3.3-70b-versatile` |\n`GROQ_API_KEY` (free, no card) |\n| A free Gemini key | `gemini/gemini-2.5-flash` |\n`GEMINI_API_KEY` (free tier) |\n| A free NVIDIA key | `nvidia_nim/deepseek-ai/deepseek-v3.2-exp` |\n`NVIDIA_NIM_API_KEY` (free, no card) |\n| A Claude / Anthropic key (best results) | `anthropic/claude-sonnet-5` (or `-opus-4-8` ) |\n`ANTHROPIC_API_KEY` |\n| An OpenAI key | `openai/gpt-5.5` |\n`OPENAI_API_KEY` |\n| An OpenRouter key | `openrouter/meta-llama/llama-3.3-70b-instruct` |\n`OPENROUTER_API_KEY` |\nAn xAI Grok key (not Groq) |\n`xai/grok-4.5` |\n`XAI_API_KEY` |\n| A local model (Ollama) | `ollama/qwen2.5:14b` |\n`VIGILANT_API_BASE=http://localhost:11434/v1` if not default |\n| Any OpenAI-compatible server (vLLM, LM Studio, TGI) | `openai_compatible/<model>` |\n`VIGILANT_API_BASE` , `VIGILANT_API_KEY` (if required) |\n| An AI gateway / LLM proxy | `gateway/<model>` |\n`VIGILANT_API_BASE` + auth (see below) |\n| Just want to see it run | `mock` |\nnothing (scripted output, no key, no cost) |\n\nIf your models are fronted by an OpenAI-compatible AI gateway or LLM proxy\n(LiteLLM, Portkey, Cloudflare AI Gateway, Kong, a self-hosted proxy, or an\ninternal enterprise gateway - often for centrally-managed, lower-cost access),\npoint Vigilant at it with the `gateway`\n\nprovider. It's fully vendor-neutral - no\ngateway is named in code, you just supply the endpoint and credentials.\n\nThe easiest path is the guided wizard, which prompts for the base URL and auth mode and saves everything to the managed credential store:\n\n```\nvigilant model add gateway\n```\n\nOr configure it manually with environment variables (or a `.env`\n\n). Set the model\nand base URL, then pick one auth mode:\n\n```\nexport VIGILANT_MODEL=gateway/your-model-name\nexport VIGILANT_API_BASE=https://gateway.example.com/v1\n\n# Auth A: a static bearer token\nexport VIGILANT_API_KEY=...\n\n# Auth B: OAuth2 client-credentials (token is fetched, cached, and auto-refreshed)\nexport VIGILANT_OAUTH_TOKEN_URL=https://auth.example.com/oauth/token\nexport VIGILANT_OAUTH_CLIENT_ID=...\nexport VIGILANT_OAUTH_CLIENT_SECRET=...\n# optional:\nexport VIGILANT_OAUTH_SCOPE=...        # scope, if your IdP requires one\nexport VIGILANT_OAUTH_AUDIENCE=...     # audience, if your IdP requires one\nexport VIGILANT_OAUTH_AUTH_STYLE=basic # send client id/secret as HTTP Basic (default: body)\n```\n\nFree tiers get you started in ~2 minutes:\n\n**Groq**(fastest):[https://console.groq.com/keys](https://console.groq.com/keys)(key starts with`gsk_`\n\n)**Gemini**:[https://aistudio.google.com/apikey](https://aistudio.google.com/apikey)** NVIDIA NIM**:[https://build.nvidia.com](https://build.nvidia.com)(key starts with`nvapi-`\n\n)\n\n```\nexport GROQ_API_KEY=gsk_...\nexport VIGILANT_MODEL=groq/llama-3.3-70b-versatile\nvigilant review https://github.com/owner/repo/pull/123\n```\n\nRun `vigilant models`\n\nto see which providers your credentials can reach (and, where\nthe provider exposes a list endpoint, the exact model ids you can use).\n\nFor the deepest reviews, use a frontier model.Adversarial bug-finding scales with model quality; Claude Sonnet 5 (default) or Opus 4.8 catch subtler issues than small free models. The free tiers are great for trying it out and for lighter PRs. Extended-thinking tuning (Opus adaptive thinking) applies only to the Anthropic path; other providers run with a low review temperature.\n\n`vigilant github-watch`\n\npolls GitHub for open PRs where **you** are a requested\nreviewer and auto-reviews them on your behalf. It is idempotent (never re-reviews\nthe same head SHA), bounded (poll interval + per-day cap), and resilient (a\nfailure on one PR never crashes the loop). No GitHub App, no webhooks - just your\ntoken. (The old name `vigilant watch`\n\nstill works as an alias.)\n\n```\n# Run continuously (default: poll every 120s, cap 50 reviews/UTC-day)\nvigilant github-watch\n\n# One pass and exit - ideal for cron\nvigilant github-watch --once\n\n# Tune cadence and cap\nvigilant github-watch --poll-interval 300 --daily-cap 20\n```\n\nBy default the watcher reviews any PR you are requested on. Constrain it with env vars (comma-separated). Deny always wins; a non-empty allow list is exclusive:\n\n```\nexport VIGILANT_ORG_ALLOW=\"acme,acme-labs\"      # only these orgs\nexport VIGILANT_REPO_DENY=\"acme/secret-repo\"    # never this repo\nexport VIGILANT_MODEL=\"claude-opus-4-8\"          # default tier for the daemon\n```\n\nThe seen-cache lives at `~/.vigilant/seen.json`\n\n(override with\n`VIGILANT_SEEN_PATH`\n\n). Mount a volume so idempotency survives restarts:\n\n```\ndocker run -d --name vigilant-pr --restart unless-stopped \\\n  -e ANTHROPIC_API_KEY \\\n  -e GH_TOKEN \\\n  -e VIGILANT_ORG_ALLOW=\"acme\" \\\n  -v vigilant-state:/root/.vigilant \\\n  -e VIGILANT_SEEN_PATH=/root/.vigilant/seen.json \\\n  ghcr.io/tllongdev/vigilant-pr:latest github-watch\n```\n\nThe watcher uses only your token. It needs:\n\n**Contents: read** and**Pull requests: read/write** on the target repos (post reviews, read diffs).- Repo read access sufficient for\n`gh search prs --review-requested=@me`\n\nto see the PRs you are tagged on.\n\nBeta.The GitHub`review`\n\n/`github-watch`\n\nflow above is the stable core.`slack-watch`\n\nworks with no Slack app, but it depends on your Slack session token, so validate it in your own workspace before relying on it.\n\n`vigilant slack-watch`\n\npolls a Slack channel and reviews any PR you're\n**@-mentioned** on - whether the mention is a top-level message or a reply\ninside a thread. It needs **no Slack app and no workspace-admin approval** - it\nauthenticates with a token you already have and only reads a channel you can\nalready read. It's dependency-free (stdlib only).\n\nThere are two app-free ways to give it a token:\n\n**Auto (recommended) - --auto-token.** Vigilant reads the token straight from\nyour logged-in Slack session in Chrome and\n\n**automatically re-extracts it when Slack expires it**, so a long-running monitor never dies on an expired session. This needs the optional refresh extra (one-time):\n\n```\npipx install 'vigilant-pr[slack-refresh] @ git+https://github.com/tllongdev/vigilant-pr'\n# or, into an existing install: pip install 'vigilant-pr[slack-refresh] @ git+https://github.com/tllongdev/vigilant-pr'\npython -m playwright install chromium\n\nexport GH_TOKEN=\"ghp_...\"\nexport VIGILANT_MODEL=\"groq/llama-3.3-70b-versatile\"   # or any provider\nvigilant slack-watch --auto-token --channel C0123ABCD\n```\n\nIf you belong to multiple Slack workspaces, Vigilant picks the one that can read\nyour channel automatically; set `VIGILANT_SLACK_TEAM=T0123`\n\nto force one.\n\n**Static - set the token yourself.** No refresh (an `xoxc-`\n\ntoken expires in a\nfew hours; an `xoxb-`\n\n/`xoxp-`\n\nOAuth token lasts):\n\n```\nexport SLACK_TOKEN=\"xoxc-...\"               # or xoxb-/xoxp-\nexport SLACK_COOKIE_D=\"xoxd-...\"            # required only for xoxc- tokens\nexport GH_TOKEN=\"ghp_...\"\nexport VIGILANT_MODEL=\"groq/llama-3.3-70b-versatile\"\nvigilant slack-watch --channel C0123ABCD    # repeatable, or VIGILANT_SLACK_CHANNELS=C1,C2\n```\n\nA message triggers a review only when it both @-mentions you **and** contains a\nGitHub PR link, so it won't fire on every PR posted in a busy channel (and it\nnever loops on its own reply). By default it posts the outcome back in-thread;\npass `--no-reply`\n\nto stay silent. Your Slack user id is auto-detected from the\ntoken via `auth.test`\n\n; override with `VIGILANT_SLACK_USER_ID`\n\n. Find a channel ID\nfrom the channel's \"View channel details\" footer, or the `/archives/C…`\n\nURL.\n\nIt also **persists progress** to `~/.config/vigilant-pr/slack_watch/`\n\n(override\nwith `VIGILANT_SLACK_STATE_DIR`\n\n), so a restart resumes where it left off: it\nreviews anything that arrived while it was down, and won't re-review or lose\ntrack of threads. At startup it seeds tracked threads from the last week of\nhistory, so it catches @-mentions in replies to recently-active threads, not\njust brand-new ones. (Residual edge: a reply to a thread with no activity in the\nlast ~7 days won't be tracked.)\n\n```\ndocker run -d --name vigilant-slack-watch --restart unless-stopped \\\n  -e GH_TOKEN -e GROQ_API_KEY -e VIGILANT_MODEL \\\n  -e SLACK_TOKEN -e SLACK_COOKIE_D -e VIGILANT_SLACK_CHANNELS \\\n  ghcr.io/tllongdev/vigilant-pr:latest slack-watch\n```\n\n`vigilant teams-watch`\n\nserves a Microsoft Teams **Outgoing Webhook** endpoint.\nTeams has no Socket-Mode equivalent, so this surface needs an inbound HTTPS URL\n(put it behind your reverse proxy or a tunnel). It is dependency-free (stdlib\nHMAC + HTTP). (The old name `vigilant teams`\n\nstill works as an alias.)\n\nBecause a review outlasts Teams' ~5s response budget, the webhook acks\nimmediately and posts the result to a Teams **Incoming Webhook**\n(`TEAMS_INCOMING_WEBHOOK_URL`\n\n) when the review finishes.\n\n```\nexport TEAMS_HMAC_SECRET=\"<base64 secret Teams shows on webhook creation>\"\nexport TEAMS_INCOMING_WEBHOOK_URL=\"https://outlook.office.com/webhook/...\"  # optional\nexport ANTHROPIC_API_KEY=\"sk-ant-...\" GH_TOKEN=\"ghp_...\"\nvigilant teams-watch --port 8080\n```\n\nThen @-mention the outgoing webhook with a PR link in a channel.\n\nComments are authored by your GitHub token, so they are *your* review and read\nas your own writing. By default each review summary ends with a short, quiet\nfootnote disclosing that it was AI-assisted, which model produced it, and who it\nwas posted on behalf of - honest attribution without a heavy bot banner:\n\nAI-assisted review via Vigilant PR · claude-sonnet-5 · posted by @you\n\nDisable it with `--no-attribution`\n\nor `VIGILANT_ATTRIBUTION=0`\n\nfor private/personal\nuse. Separately, each body carries a hidden HTML-comment marker (invisible on\nGitHub) that lets the tool recognize its own prior comments for dedup and\nre-review.\n\nApproval is mechanical and honest: the review is submitted as **APPROVE** when\nthere are no blocking findings (no critical, no medium) - so nit-only or clean\nPRs get approved with their comments attached - and as a **COMMENT** when\nanything blocks (or a prior concern is re-flagged as unresolved). It never uses\n`REQUEST_CHANGES`\n\n, so it surfaces problems without hard-blocking the PR. The\ngoal is to move PRs forward unless something genuinely blocks merge.\n\nVigilant PR runs entirely on your machine or CI. It has no server, no account, and no telemetry - it never sends your data to us or to any third party you didn't configure. Here is exactly what leaves your machine, and when:\n\n| Data | Goes to | When | Notes |\n|---|---|---|---|\nPR diff, changed-file context, and your repo's guidance files (`AGENTS.md` /`CLAUDE.md` ) |\nThe model provider you choose | Every review | A cloud model (Anthropic, OpenAI, Groq, Gemini, NVIDIA, OpenRouter, xAI) receives this over the internet under that provider's API data policy. A local model (Ollama) or your own self-hosted/gateway endpoint keeps it on your machine/network. |\n| PR metadata and your review comments | GitHub, via the `gh` CLI |\nEvery review | GitHub already hosts your code; the review is posted as you. |\n| Channel messages / @-mentions | Slack or Teams | Only if you run `slack-watch` / `teams-watch` |\nUses a token you already have. |\n| API keys and tokens | Stored locally in a `0600` file |\nSetup | Transmitted only as auth headers to the services above - never anywhere else. |\n\n**Maximum privacy:** pick a local model (`ollama/...`\n\n) or your own\nOpenAI-compatible gateway. Then your code is never sent to a third party -\ninference runs on your own hardware and the only external call is to GitHub,\nwhich already has your code.\n\nVigilant PR is licensed under the Apache License 2.0 - see [LICENSE](/tllongdev/vigilant-pr/blob/develop/LICENSE)\nand [NOTICE](/tllongdev/vigilant-pr/blob/develop/NOTICE). Copyright (c) 2026 Timothy Long / Longitudinal Intelligence Technologies (LIT).\n\n\"Vigilant PR\" and the Vigilant PR logo are trademarks of Longitudinal Intelligence Technologies (LIT). The license covers the source code; it does not grant rights to the name or logo. You're welcome to build on the code under Apache-2.0, but forks and derivatives must use their own name and branding.\n\nContributions are accepted under the terms in [CONTRIBUTING.md](/tllongdev/vigilant-pr/blob/develop/CONTRIBUTING.md).", "url": "https://wpnews.pro/news/vigilant-pr-adversarial-ai-code-review-that-posts-as-you-not-a-bot", "canonical_source": "https://github.com/tllongdev/vigilant-pr", "published_at": "2026-07-27 17:00:42+00:00", "updated_at": "2026-07-27 17:22:44.238466+00:00", "lang": "en", "topics": ["developer-tools", "artificial-intelligence", "ai-tools", "ai-products"], "entities": ["Vigilant PR", "tllongdev", "GitHub", "Claude", "GPT", "Gemini", "Grok", "OpenRouter"], "alternates": {"html": "https://wpnews.pro/news/vigilant-pr-adversarial-ai-code-review-that-posts-as-you-not-a-bot", "markdown": "https://wpnews.pro/news/vigilant-pr-adversarial-ai-code-review-that-posts-as-you-not-a-bot.md", "text": "https://wpnews.pro/news/vigilant-pr-adversarial-ai-code-review-that-posts-as-you-not-a-bot.txt", "jsonld": "https://wpnews.pro/news/vigilant-pr-adversarial-ai-code-review-that-posts-as-you-not-a-bot.jsonld"}}