argus-review 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,326 @@
1
- # Temporary Holding Version
1
+ # Argus
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Self-hosted AI code review for **GitHub, GitLab, Bitbucket (Cloud and Server) and Azure DevOps**. Argus reviews pull requests the way a careful staff engineer would. It reads the full changed files and the code around them, and it verifies every finding before posting. Comments are inline, with one-click fixes, and the summary is kept up to date. It learns from your team's feedback.
4
+
5
+ It runs four ways, from the same engine and settings:
6
+
7
+ | Mode | Command | Use it for |
8
+ |---|---|---|
9
+ | Server + web UI | `argus serve` | Webhook-driven reviews, settings UI, review history, chat and learnings |
10
+ | One pull request | `argus review <url>` | Reviewing any PR or MR from your terminal |
11
+ | CI | `argus ci` | GitHub Actions, GitLab CI, Bitbucket Pipelines or Azure Pipelines, with no server |
12
+ | Local | `argus local` / `argus hook install` | Reviewing staged changes before you commit |
13
+
14
+ ## How a review works
15
+
16
+ 1. **Scope.** Lock files, generated, minified, vendored and binary files are skipped, plus your own path filters. Re-reviews only look at commits pushed since the last review.
17
+ 2. **Intent.** The title, description, commits and an AI summary tell the reviewer what the change is supposed to do.
18
+ 3. **Context.** Linked issues (`#12`, `owner/repo#7`, issue URLs, Jira or Linear keys such as `PAY-42`) are read and their acceptance criteria checked against the diff. Each changed file is shown in full with line numbers and `+`/`-` markers. Argus also adds files it imports and other places that use the changed symbols (via `git grep` on a local mirror). Repository guidelines (`AGENTS.md`, `CLAUDE.md`, `.cursorrules`, `.cursor/rules`, `copilot-instructions.md`, nested per directory, read from the target branch), your team guidelines, custom rules, path instructions and learnings all go into the prompt. Everything taken from the pull request is marked as data, not instructions.
19
+ 4. **Static analysis.** The repository's own `tsc` and ESLint (they execute repository code, so only inside the test sandbox or on your own checkout with `argus local`), plus Ruff, Semgrep, Gitleaks, OSV-Scanner, ShellCheck, Hadolint and `go vet` (also sandbox-only, with cgo and network module downloads off) when installed, run on the changed files. Results on changed lines (and type errors elsewhere that mention a changed symbol) become evidence for the model. Leaked secrets and vulnerable dependencies are posted directly.
20
+ 5. **Review with exploration.** Files are reviewed in parallel batches against an explicit checklist: logic, security, performance, concurrency, error handling, data integrity, API contracts and more. The model can read files, search the code, find definitions and references and read history before it reports anything. Claude Code and Codex do the same in a read-only checkout.
21
+ 6. **Multi-pass voting.** High-risk files (auth, payments, migrations, money arithmetic, large changes, files named in the summary's risks) get extra passes with different lenses: adversarial, edge cases, contracts. Findings are clustered across passes. Agreement raises confidence, and lone findings need a stronger verification score.
22
+ 7. **Cross-file pass.** Catches contract changes whose callers were not updated.
23
+ 8. **Secret scan.** Deterministic detection of keys and tokens in added lines.
24
+ 9. **Verification.** A second model pass, also able to explore the repository, re-derives every finding from the code and discards speculation, already-handled cases and style noise. Each finding gets a 0-10 score. A skeptical second verifier must also confirm every critical finding. Verification fails closed: a finding without a usable verdict (verifier error, missing or unknown verdict) is suppressed, with the reason recorded.
25
+ 10. **Proof (opt-in, `execution.enabled: true`).** It runs pull request code, so it is off by default. In a Docker sandbox, Argus installs the dependencies (with network) and runs the test suite (without network). It detects vitest, jest, `node --test`, `npm test`, pytest and go test. A failing test that passes on the base branch is reported as a regression. For serious findings the model writes a test that should fail because of the bug. It is marked as reproduced only if the test fails and then passes once the suggested fix is applied (or there is no suggested fix).
26
+ 11. **Follow-up.** On every push, findings whose code changed are re-checked; fixed ones get a "✅ Fixed in abc123" reply and their thread is resolved. Fixes, 👍/👎 reactions and replies such as "false positive" are tracked per category, and categories a team keeps dismissing need more confidence.
27
+ 12. **Anchoring and dedupe.** Quoted code is relocated to the right lines and mapped onto the diff. Near-duplicates are merged, and findings posted in earlier reviews are not repeated.
28
+ 13. **Publish.** Inline comments go out with severity, category, the analyzers that confirm them, how many passes found them, a committable suggestion and a "prompt for AI agents". One persistent summary comment holds the walkthrough, a changes table, a sequence diagram, the review effort and findings outside the diff. The PR is optionally approved or marked as changes requested; approval is only given when the review ran to completion (no errors, no unverifiable findings, no files skipped for the size limits, at least one file reviewed).
29
+ 14. **Merge gate.** An `argus` commit status goes to pending when the review starts and ends as failure (a finding of at least `review.status.failOn`, default major), error (the review did not complete, timed out or crashed) or success. Make it a required check to block merges until Argus passes; see [Blocking merges](#blocking-merges).
30
+
31
+ Every dropped candidate is kept with its reason, and the web UI shows it under **Filtered out**.
32
+
33
+ ## Requirements
34
+
35
+ - Node.js 22.12 or newer, and git
36
+ - A model: an OpenRouter, Anthropic or OpenAI key, any OpenAI-compatible endpoint (Ollama, vLLM, LM Studio, a company gateway), or a **Claude Pro/Max**, **ChatGPT** or **GitHub Copilot** plan through the official `claude`, `codex` or `copilot` CLI
37
+
38
+ ## Install
39
+
40
+ Pick one:
41
+
42
+ ```sh
43
+ npm install -g argus-review # the `argus` CLI with the web UI, Node 22.12+
44
+ docker compose -f deploy/docker-compose.yml up -d # server in Docker (copy deploy/.env.example to deploy/.env first)
45
+ ```
46
+
47
+ From source:
48
+
49
+ ```sh
50
+ git clone https://github.com/anevski-stefan/argus.git && cd argus
51
+ npm install && npm run build
52
+ npm link -w @argus/server # puts `argus` on your PATH
53
+ ```
54
+
55
+ For development without building, use `bin/argus` (it runs the TypeScript sources directly). Releases are listed in [CHANGELOG.md](CHANGELOG.md).
56
+
57
+ ## Server and web UI
58
+
59
+ ```sh
60
+ argus serve # http://127.0.0.1:4747, data in ~/.argus
61
+ argus serve --port 8080 --host 0.0.0.0
62
+ ```
63
+
64
+ On the first visit, create the admin with the setup token printed at start-up (see [Access and exposure](#access-and-exposure)). Then, in the UI:
65
+
66
+ 1. **Models & providers.** Add an API key, or log in to `claude` / `codex` / `copilot` in a terminal to use your plan. Pick a model for each stage (review, verification, summary, chat) and press **Test connection**.
67
+ 2. **Repositories.** Connect GitHub, GitLab, Bitbucket or Azure DevOps with a token (the dialog lists the exact permissions), then add repositories.
68
+ 3. **Server & CI.** Set the public URL (your domain or a tunnel) and press **Install webhook** on each repository. This works on all five platforms; an Azure DevOps token needs the **Service Hooks (read, write & manage)** scope for it, and a Bitbucket Server token repository admin.
69
+
70
+ Tokens and API keys are encrypted at rest (AES-256-GCM, key in `~/.argus/secret.key` or `ARGUS_SECRET_KEY`). Stored provider keys are only sent to the model endpoints an admin configured (each vendor's default endpoint, plus the provider/base URL pairs in the global settings). Environment keys such as `OPENAI_API_KEY` are only sent to the vendor's own endpoint.
71
+
72
+ ### Access and exposure
73
+
74
+ - **No users yet:** the API is **locked** (`401 {setupRequired: true}`) until the first admin is created, whatever address Argus listens on. The server prints a one-time setup token at start-up and the web UI asks for it on the first visit. Alternatively set `ARGUS_ADMIN_EMAIL` and `ARGUS_ADMIN_PASSWORD`, and that admin is created at start-up.
75
+ - **Without sign-in, on purpose:** `ARGUS_ALLOW_OPEN=1` serves every request as admin while there are no users, for example behind an authenticating proxy or for local development. Creating the first user turns it off.
76
+ - **Host and Origin checks:** requests must use a loopback host, the public URL's host or a name in `ARGUS_ALLOWED_HOSTS` (comma-separated, `*.example.com` allowed, `*` turns the check off). State-changing API calls must not come from another origin and must send their body as `application/json`. Webhooks are exempt and authenticated by their own signatures.
77
+ - **Behind a reverse proxy:** set `ARGUS_TRUST_PROXY=1` so `X-Forwarded-For`/`-Proto`/`-Host` are honoured (client IPs for login throttling, `Secure` cookies). Only set it when Argus is reachable exclusively through that proxy.
78
+ - **Sessions:** signing out ends every session of that user, and a password or role change ends that user's other sessions. Failed sign-ins are throttled per email and per IP.
79
+
80
+ Boolean variables accept `1`/`true`/`yes` and `0`/`false`/`no`.
81
+
82
+ | Environment variable | Meaning |
83
+ |---|---|
84
+ | `ARGUS_DATA_DIR` | Data directory (default `~/.argus`) |
85
+ | `ARGUS_SECRET_KEY` | Passphrase for encrypting stored secrets (otherwise a key file is generated) |
86
+ | `ARGUS_CONCURRENCY` | Reviews that run in parallel, a whole number of at least 1 (default 2) |
87
+ | `ARGUS_ADMIN_EMAIL`, `ARGUS_ADMIN_PASSWORD` | Create this admin at start-up if it does not exist |
88
+ | `ARGUS_ALLOW_OPEN=1` | Serve without sign-in while there are no users (see above) |
89
+ | `ARGUS_ALLOWED_HOSTS` | Extra host names the dashboard is reached by |
90
+ | `ARGUS_TRUST_PROXY=1` | Honour `X-Forwarded-*` headers from a reverse proxy |
91
+ | `ARGUS_SHUTDOWN_GRACE_MS` | How long a stopping process lets running reviews finish before handing them back to the queue (default 25000). Keep it below your process manager's kill timeout (Docker `stop_grace_period`) |
92
+ | `ARGUS_GIT_TIMEOUT_MS` | Timeout for git operations on the local mirror (default 300000) |
93
+ | `ARGUS_EXEC_DIR` | Directory for test-sandbox workspaces (default: the system temp dir) |
94
+ | `ARGUS_SANDBOX_NETWORK` | Docker network for the dependency install phase |
95
+ | `OPENROUTER_API_KEY`, `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `OPENAI_COMPATIBLE_API_KEY` | Provider keys, used when none is stored in the UI. Vendor keys only go to the vendor's default endpoint |
96
+ | `ARGUS_CLAUDE_BIN`, `ARGUS_CODEX_BIN`, `ARGUS_COPILOT_BIN` | Paths to the `claude`, `codex` and `copilot` CLIs |
97
+
98
+ ## Teams and production
99
+
100
+ **People and roles.** Under **Settings → Team & access**, create the first admin; from then on everyone signs in with an email and password. Viewers see everything, maintainers also start, cancel and retry reviews and edit learnings and per-repository settings, admins manage integrations, models, keys, global settings and users. Listing and testing models, the GitHub App setup and listing an integration's remote repositories are admin-only too. In repository settings, maintainers cannot set the keys that only the operator may change (models, execution, analyzer configuration, ticket allow-lists, approvals, the cost cap; see [Trust model](#trust-model)); the server ignores them and the UI says which.
101
+
102
+ **Storage.** Everything lives in one SQLite database in the data directory, with a queue in it that survives restarts: a graceful shutdown hands unfinished reviews back to the queue, and a review left running by a process that crashed or was killed is marked failed at the next start. One Argus process serves one data directory; do not point several processes at the same one. To review more pull requests at once, raise `ARGUS_CONCURRENCY`.
103
+
104
+ **Docker.** `docker build -t argus .` builds a small image that runs as a non-root user. `deploy/docker-compose.yml` starts Argus with its data in a volume (copy `deploy/.env.example` to `deploy/.env` first; admin credentials are required). For the test sandbox, build with `--build-arg DOCKER_CLI=true` (adds only the static Docker client) and mount the Docker socket into the container. The container user then needs the socket's group (`group_add`), and because the daemon resolves bind mounts on the host, the workspace directory must exist at the same path on the host and in the container: point `ARGUS_EXEC_DIR` (and `TMPDIR`) at it. `docker-compose.yml` has the commented block. Socket access is root-equivalent on the host.
105
+
106
+ **Upgrading.** Stop Argus, back up the data directory (the database and `secret.key`, or keep `ARGUS_SECRET_KEY`), install the new version and start it again; database migrations run at start-up. Coming from 0.1.0, the shared dashboard password is gone: create an admin with the setup token printed at start-up (or `ARGUS_ADMIN_EMAIL`/`ARGUS_ADMIN_PASSWORD`).
107
+
108
+ **npm.** `npm run pack:npm` produces `argus-review-<version>.tgz`: one bundled CLI with the web UI, installable with `npm install -g` on any machine with Node 22.
109
+
110
+ ## GitHub App
111
+
112
+ On **Repositories → Connect GitHub**, choose **GitHub App** and click **Create on GitHub**. GitHub creates a private app with the exact permissions Argus needs and hands its key back to Argus. You then pick the repositories to install it on, and they are added automatically. Comments appear as the app's bot, tokens rotate hourly, and repositories added to the installation later appear on their own (when a public URL is set for webhooks). An existing app can be connected with its App ID and private key.
113
+
114
+ ## VS Code
115
+
116
+ `npm run vscode:package` builds `apps/vscode/argus-vscode.vsix`. Install it with **Extensions → … → Install from VSIX**, then set `argus.command` to the path of `bin/argus` (and `argus.provider` / `argus.model`, for example `claude-code` / `claude-sonnet-5-5`). `argus.command` and `argus.extraArgs` are machine-scoped: set them in user settings, a workspace cannot override them. Run **Argus: Review staged changes** from the command palette or the status bar: findings appear in the Problems panel with quick fixes for suggested code. `npm run vscode:e2e` runs the extension end to end in an isolated VS Code profile.
117
+
118
+ ## Review a pull request from the terminal
119
+
120
+ ```sh
121
+ export OPENROUTER_API_KEY=…
122
+ export GITHUB_TOKEN=… # or log in with `gh auth login`; GITLAB_TOKEN; BITBUCKET_TOKEN (+ BITBUCKET_USERNAME for API tokens)
123
+ argus review https://github.com/owner/repo/pull/42 --dry-run
124
+ argus review https://gitlab.com/group/project/-/merge_requests/7 --full
125
+ argus review https://bitbucket.org/workspace/repo/pull-requests/3 --focus "auth and sessions"
126
+ ```
127
+
128
+ ## Review before you commit
129
+
130
+ ```sh
131
+ argus local # staged changes
132
+ argus local --working # everything uncommitted
133
+ argus local --base main # the current branch since main
134
+ argus hook install # run on every commit; ARGUS_FAIL_ON=major blocks the commit
135
+ ```
136
+
137
+ ## CI
138
+
139
+ `argus ci` detects GitHub Actions, GitLab CI merge request pipelines, Bitbucket pull request pipelines and Azure Pipelines pull request builds, and it answers `@argus` comments in GitHub Actions. Ready-made workflow files are in the web UI under **Server & CI**, and for each repository added as reviewed in CI (see [Connecting CI to the dashboard](#connecting-ci-to-the-dashboard)). They pin `argus-review` to the server's version, and the GitHub workflow only reacts to comments whose `author_association` is `OWNER`, `MEMBER` or `COLLABORATOR`. They call `npx argus-review`, which needs the package published to npm or a private registry. Until then, switch on **Build Argus from source**, which clones the repository (`main`; there are no version tags yet), runs `npm ci` and calls `bin/argus ci`. In CI, `.argus.yml` is read from the target branch like on the server, and API keys only go to endpoints configured outside the repository.
140
+
141
+ | Platform | Token |
142
+ |---|---|
143
+ | GitHub | `GITHUB_TOKEN` (provided by Actions; needs `pull-requests: write` and `statuses: write`) |
144
+ | GitLab | `GITLAB_TOKEN`: a token with the `api` scope (the built-in job token cannot post comments) |
145
+ | Bitbucket | `BITBUCKET_TOKEN`: a repository access token with pull request write |
146
+ | Azure DevOps | `SYSTEM_ACCESSTOKEN` (the pipeline's `$(System.AccessToken)`; allow the build service to contribute to pull requests) |
147
+
148
+ ### Choosing a provider for CI
149
+
150
+ The generator on **Server & CI** has a provider and a model field (free text; the list only suggests). It sets `ARGUS_PROVIDER` and `ARGUS_MODEL`, installs the pinned CLI (`@anthropic-ai/claude-code@2.1.296`, `@github/copilot@1.0.95` or `@openai/codex@0.162.1`) and lists the secrets to add. To change the model later without editing the file, set an `ARGUS_MODEL` variable in the CI settings (a GitHub repository variable, a GitLab CI/CD variable, a Bitbucket repository variable or an Azure pipeline or variable-group variable); it overrides the model in the file.
151
+
152
+ | Provider | Secret |
153
+ |---|---|
154
+ | OpenRouter | `OPENROUTER_API_KEY` |
155
+ | Claude subscription | `CLAUDE_CODE_OAUTH_TOKEN` from `claude setup-token` |
156
+ | GitHub Copilot | `COPILOT_GITHUB_TOKEN`: a fine-grained PAT owned by a personal account with "Copilot Requests" |
157
+ | ChatGPT subscription (Codex) | `ARGUS_CODEX_AUTH` from `argus codex-secret` after `codex login`, plus `ARGUS_SECRET_WRITE_TOKEN` |
158
+
159
+ Codex logins refresh, so Argus writes the new login back to the CI secret after each run, also when the job is cancelled or times out. It can only update the current repository's own secret, so use **one ChatGPT login per repository**: run `codex login` and `argus codex-secret` separately for each repository and store the value as a repository-level (GitLab: project-level) secret, not an organization, group or workspace one. Two repositories sharing one login break each other: every refresh rotates the login, and the repository that did not refresh is left with a dead one. `ARGUS_CODEX_AUTH` is only used when a model in the review runs on Codex; with another provider it is ignored. `ARGUS_SECRET_WRITE_TOKEN` needs: GitHub, a fine-grained PAT with "Secrets: write"; GitLab, a project access token with `api` (Maintainer); Bitbucket, a repository access token with "Pipelines: Edit variables"; Azure, a PAT with "Variable Groups (Read, create, & manage)". Limits: Codex runs on private repositories only, one run at a time (the generated file serialises runs: `queue: max` on GitHub, `resource_group` on GitLab, `concurrency-group` on Bitbucket, `lockBehavior: sequential` plus an Exclusive lock check you add to the `argus-codex` environment on Azure), and on Azure the secret lives in a dedicated variable group (`ARGUS_AZURE_VARIABLE_GROUP_ID`) that holds nothing else.
160
+
161
+ ### Connecting CI to the dashboard
162
+
163
+ A CI run can pull its settings from an Argus dashboard and send each review back to it, so the reviews show up next to the ones the server ran. Under **Repositories → Add → Reviewed in CI**, enter the platform, host and `owner/name` (or the repository URL). Argus adds the repository and shows its **repository token** once, together with a pipeline generated for it (it points at the dashboard's public URL: the one set under **Server & CI**, else `ARGUS_PUBLIC_URL`, else the page's own address). A repository added through an integration has no CI token; to connect its CI, remove it and add it again as **Reviewed in CI**. Add two things to the repository's CI settings:
164
+
165
+ | Name | Kind | Value |
166
+ |---|---|---|
167
+ | `ARGUS_URL` | Variable (the generated file sets it in the job's environment; with your own file, set it there or as a CI variable) | The dashboard's public URL, for example `https://argus.example.com`. It must be `https://`; `http://` is accepted only for `localhost` (any other `http://` URL prints a warning, because the token and the results would travel unencrypted) |
168
+ | `ARGUS_TOKEN` | Secret | The token shown when you added the repository (`argus_…`) |
169
+
170
+ `argus ci` talks to the dashboard only when both are set; with one of them missing it warns and reviews as before. The token only works for its own repository (another one gets 403 `This token belongs to <owner>/<name>`), and GitHub Actions masks it in the log. The repository's page in the dashboard shows the token's prefix, when it was created and last used, and has **Regenerate token** (shows a new token once; the old one stops working at once) and **Revoke** (CI then neither pulls settings nor sends results until an admin creates a new token). A rejected token (401 or 403) is reported in the job log, with what to fix.
171
+
172
+ **Settings.** Before the review, `argus ci` reads the repository's settings from the dashboard (global settings plus the repository's overrides). Layers, lowest first:
173
+
174
+ ```
175
+ built-in defaults ─► global config file ─► CI variables and flags (ARGUS_PROVIDER, ARGUS_MODEL, …) ─► dashboard ─► .argus.yml (target branch, admin-only keys removed)
176
+ ```
177
+
178
+ The dashboard layer is filtered in CI, so a dashboard can never make a CI job run commands or send secrets elsewhere: it may choose each model's `provider` and `model` and every review setting that is not admin-only, but never the execution and sandbox settings (sandbox, isolation, runtime, image, install and test commands, resources, timeouts), the analyzer configuration (`semgrepConfig`, analyzer timeouts), ticket allow-lists (`tickets.allowedRepos`, `tickets.projectKeys`), approvals, the cost cap, or any model's `baseUrl` or `apiKey`. It may switch `execution.enabled`, `execution.runTests`, `execution.proveFindings` and `analyzers.enabled` off, but not on: a `true` from the dashboard is ignored. Those stay in the CI flags, the CI environment or the global config file, and the job log lists any dashboard setting it ignored. API keys always come from the CI secrets.
179
+
180
+ **Reviews off.** When reviews are turned off for the repository in the dashboard, `argus ci` prints `argus: skipped — Reviews are turned off for this repository in the Argus dashboard`, posts nothing to the pull request, sends nothing to the dashboard and exits 0. The server also refuses results for such a repository (409 `Reviews are turned off for this repository`).
181
+
182
+ **Results.** After the review, skip or failure (also for `@argus` commands), `argus ci` sends the result, gzip-compressed, to `POST /api/ci/reviews`. The dashboard shows it as a CI review with a **View CI run** link; it cannot be retried or cancelled from the dashboard. The findings' outcomes (open, fixed, accepted, resolved, dismissed) are recorded like those of server reviews. **Send summary only** on the repository's page (admins) keeps only the outline (counts, titles and locations of findings, timings and usage) and leaves explanations, suggested fixes, code and the summary text on the pull request; the server enforces it on everything it stores, whatever the client sends. Results stored before the switch was turned on stay as they were stored.
183
+
184
+ **Waits.** Reading the settings waits at most 30 s and sending the result at most 30 s, retrying network errors, 5xx and 429 with 1 s, 2 s, 4 s, … backoff (401, 403, 409, 413 and an answer over 1 MB are final). If the settings cannot be read, the review runs with the CI settings only; if the dashboard rejected the token while reading them (401 or 403), the result is not sent either. Nothing the dashboard does changes the job's exit code. The generated files start a background `curl` to `$ARGUS_URL/api/health` at the start of the job, so a dashboard that sleeps when idle is awake by the time the review ends. The server accepts bodies up to 32 MiB, compressed or not (413 above that).
185
+
186
+ The Docker sandbox needs Docker in the job. GitHub and Azure hosted Ubuntu agents have it. The GitLab file adds a `docker:27-dind` service (the runner must be privileged and x86_64; gitlab.com `saas-linux` runners are, because the job downloads the x86_64 Docker CLI). The GitLab file also sets `ARGUS_EXEC_DIR` inside the project because dind cannot see `/tmp`. Do not mark any Argus variable on GitLab Protected, or it will not reach merge request pipelines on unprotected branches. The Bitbucket file uses `services: [docker]` and Runtime v3; without Runtime v3 the sandbox is skipped and the AI review still runs. Plan availability of Runtime v3 and `concurrency-group` is not verified.
187
+
188
+ ## Blocking merges
189
+
190
+ Every review sets an `argus` commit status on the pull request's head commit (on Azure DevOps a pull request status `argus/review`). To block merging until Argus passes, make it required:
191
+
192
+ | Platform | Where |
193
+ |---|---|
194
+ | GitHub | Branch protection or ruleset → Require status checks → `argus` |
195
+ | GitLab | Settings → Merge requests → "Pipelines must succeed" (external statuses count) |
196
+ | Bitbucket Cloud | Branch restrictions → Require passing builds |
197
+ | Bitbucket Server / Data Center | Repository settings → Required builds → `argus` |
198
+ | Azure DevOps | Branch policies → Status checks → Add `argus/review` |
199
+
200
+ The token Argus uses needs permission to set statuses: GitHub `statuses: write` (the GitHub App manifest and the generated Actions workflow include it), GitLab the `api` scope, Azure DevOps "Contribute to pull requests". If a token may not set statuses, the review still runs and the summary says so. In CI, `--fail-on <severity>` also fails the job itself.
201
+
202
+ Change the threshold with `review.status.failOn` (`critical`, `major` or `minor`), or turn statuses off with `review.status.enabled: false`. Only the operator can change these; `.argus.yml` cannot.
203
+
204
+ ## Using a Claude, ChatGPT or Copilot subscription
205
+
206
+ Choose the provider **Claude subscription (Claude Code)**, **ChatGPT subscription (Codex)** or **GitHub Copilot**. Argus runs the official CLI in headless mode (`claude -p --json-schema …`, `codex exec --output-schema …`, `copilot`) in a read-only checkout, so reviews count against your plan instead of API billing. Usage limits of your plan apply.
207
+
208
+ - **Claude Code and Codex:** log in once with `claude` or `codex login` on the machine that runs Argus.
209
+ - **GitHub Copilot:** the Copilot CLI gets only read-only tools (view, glob, grep). Log in with `copilot login`, or set `COPILOT_GITHUB_TOKEN` (or `GH_TOKEN`) to a fine-grained personal access token with the "Copilot Requests" permission. `GITHUB_TOKEN` is only used inside GitHub Actions; on a server it is Argus's own GitHub credential and is never handed to Copilot. The dashboard can't check a `copilot login` and shows the login as unknown until you set a token. The model is free text (for example `auto`, `claude-sonnet-5.5`, `gpt-6-luna` or `gemini-3.8-flash`); Copilot offers Claude, GPT and Gemini families.
210
+
211
+ **In a company.** Subscription plans belong to a person and have personal usage limits. They suit `argus local`, the pre-commit hook and small teams. Before running one plan as the reviewer for a whole team on a server, check the provider's terms. For a shared server, an API key or a company gateway that speaks the OpenAI API (provider `openai-compatible` with a base URL) is the safer choice, and `review.maxCostUsd` keeps each review bounded.
212
+
213
+ ## Configuration
214
+
215
+ Settings come in layers: built-in defaults, then global settings (UI), then repository overrides (UI), then `.argus.yml` in the repository, then command-line flags. `argus init` writes a starter file, and every repository page in the UI can export its effective settings as YAML.
216
+
217
+ ### Trust model
218
+
219
+ A pull request author must not be able to change how Argus reviews their pull request, so `.argus.yml` and the guideline files are read from the **target (base) branch**, never from the pull request's head. What changes there takes effect after it is merged.
220
+
221
+ A repository file may only tune a review (allow-list; anything else is dropped and listed in the summary comment):
222
+ - `review`: language, profile, severity and confidence floors, categories, suggestions, agent prompts, incremental; numeric limits (`maxComments`, `maxFiles`, `maxCostUsd`, passes, steps, …) only lower than the operator's; extra stages (verification, cross-file, voting, agent, auto-resolve, adaptive feedback) can only be turned off
223
+ - `summary`: presentation keys; `applyLabels` only off, `updateDescription` only towards `never` (`append` > `when-empty` > `never`)
224
+ - `files`: include/exclude, guideline files; code graph and bug history only off; `contextDepth` only lower (`related` > `files` > `diff`); `maxContextChars` lower only
225
+ - `autoReview`: turn off, add ignored title keywords and authors; `labels`/`baseBranches` only when the operator set none
226
+ - `chat.mention` (one word, 2–50 characters), and turning off chat, learning from feedback, analyzers, tickets and test execution (`analyzers.disabled` adds to the operator's list)
227
+ - `guidelines`, `pathInstructions`, `rules`, `learnings`
228
+
229
+ Operator-only (global settings, or a repository's settings saved by an admin): `models` (providers, endpoints, keys), `execution` (sandbox, isolation, runtime, image, install/test commands, resources, timeouts), analyzer configuration (`semgrepConfig`, timeouts), `review.examples.paths`, `review.approveWhenClean`, `review.requestChangesOn`, `tickets.allowedRepos` / `projectKeys`, and anything that raises cost or turns on work the operator turned off. Maintainers editing repository settings in the UI cannot set the operator-only keys either.
230
+
231
+ `argus local` reads `.argus.yml` from your working tree: it is your own checkout.
232
+
233
+ ```yaml
234
+ models:
235
+ review: { provider: openrouter, model: anthropic/claude-sonnet-5.5 }
236
+ summary: { provider: openrouter, model: anthropic/claude-haiku-4.5 }
237
+ review:
238
+ profile: chill # quiet | chill | assertive
239
+ minSeverity: minor # critical | major | minor | nitpick
240
+ minConfidence: 0.6
241
+ maxComments: 30
242
+ requestChangesOn: never # never | critical | major
243
+ agent: { enabled: true, maxSteps: 8, verify: true }
244
+ voting: { enabled: true, passes: 3, scope: risky, maxFiles: 6, doubleCheckCritical: true }
245
+ analyzers:
246
+ enabled: true
247
+ disabled: [go-vet]
248
+ semgrepConfig: [p/default, p/owasp-top-ten]
249
+ files:
250
+ exclude: ["docs/**"]
251
+ guidelines: |
252
+ All handlers validate input with zod.
253
+ pathInstructions:
254
+ - path: "src/billing/**"
255
+ instructions: "Amounts are integer cents; flag any floating point math."
256
+ rules:
257
+ - id: no-sql-concatenation
258
+ title: No SQL built from strings
259
+ description: Use parameterized queries only.
260
+ severity: critical
261
+ ```
262
+
263
+ Argus can also:
264
+ - **Use past bug fixes as context.** Commits that fixed bugs in the changed files are shown to the reviewer.
265
+ - **Learn from past human reviews.** `argus learn <repo-url>`, or **Learn from past reviews** on a repository page, turns the conventions your reviewers keep asking for into suggested learnings.
266
+ - **Cache** identical model answers, code-graph symbols and Docker dependency installs, and report time per stage.
267
+
268
+ A syntax-tree code graph (tree-sitter: TypeScript, JavaScript, Python, Go, Java, Rust, Ruby, PHP, C#, C++) gives the reviewer real callers with the function they sit in, definitions, implementations and the transitive impact of a change.
269
+
270
+ Files are routed by risk: formatting-only and trivial changes go to an optional light model without exploration, and high-risk files get extra voting passes. `review.maxCostUsd` (default $5) caps the spend of one review on paid APIs, and `review.timeoutMinutes` (default 30) stops a review that runs too long. When a provider reports no cost, it is estimated from the token counts, and calls in flight are counted against the cap before they finish. Local and private-network endpoints, `openai-compatible` endpoints with a custom base URL, and the `claude`/`codex` CLIs on a subscription count as free; set `inputPricePerMTok` and `outputPricePerMTok` on a model to price it yourself. A platform rate limit that resets more than a minute away fails the review with a rate-limit error instead of waiting.
271
+
272
+ ### Linked tickets
273
+
274
+ Issues of the pull request's own repository are always read. Issues of any other repository, including other repositories of the same organization, group or workspace, are only read when they match `tickets.allowedRepos` (`owner/name`, globs allowed; `acme/*` allows the whole organization). Jira and Linear tickets are only read for the project keys in `tickets.projectKeys`; with the list empty, none are fetched. Both lists are operator-only.
275
+
276
+ ### Test sandbox
277
+
278
+ `execution.sandbox: auto` (the default) uses Docker and skips test execution when Docker is not available. Dependencies are installed with network access; tests and proofs run without it. Package-manager caches are Docker volumes scoped per repository, mounted only for the cached install of unchanged dependency files; any other install (changed dependencies, a custom command, the project's own package) runs without them, so pull request code cannot plant packages for later reviews. Installed third-party dependencies are cached in one volume per lockfile, only for pull requests that don't change a manifest or lockfile, and only with the auto-detected install command (a custom `installCommand` is never cached). The project's own Python package is installed afterwards, outside the cache. The install phase blocks cloud metadata host names; to block metadata IPs and private ranges too, create a network, set `ARGUS_SANDBOX_NETWORK` to it, and add `DOCKER-USER` firewall rules that drop its traffic to `169.254.169.254` and RFC 1918 addresses. `sandbox: host` runs the project's commands directly on the Argus machine with a scrubbed environment; it is an explicit opt-in for trusted repositories only.
279
+
280
+ Run `argus analyzers` to see which linters and scanners are installed. `--no-agent`, `--no-voting`, `--passes <n>` and `--no-analyzers` switch the depth stages per run.
281
+
282
+ Cost scales with pull-request size. With every stage on, a small PR costs about $0.10 on Claude Sonnet through OpenRouter, and a large one (around 900 changed lines against 1,000+ line files) costs $1-1.50. Every stage can be turned off under **Depth & analysis**.
283
+
284
+ ## Chat commands
285
+
286
+ Reply to any Argus comment, or mention `@argus` in a pull request:
287
+
288
+ `review` · `full review` · `review focus <topic>` · `summary` · `pause` · `resume` · `ignore` · `resolve` · `remember <convention>` · `configuration` · `help`
289
+
290
+ Anyone can ask questions and read `help`. `review`, `full review`, `review focus`, `summary`, `pause`, `resume` and `ignore` need write access to the repository or being the pull request's author. `resolve`, `remember` and `configuration` need write access. If the permission lookup fails, Argus treats the commenter as having no access. The lookup needs:
291
+
292
+ | Platform | Permission lookup |
293
+ |---|---|
294
+ | GitHub | The commenter's collaborator permission on the repository |
295
+ | GitLab | Project membership |
296
+ | Bitbucket Cloud | A token that can read the workspace's repository permissions (group grants included) |
297
+ | Bitbucket Server | A token with repository or project admin; permissions granted only through groups are not visible |
298
+ | Azure DevOps | The commenter's effective Git permissions on the repository (Contribute = write, Manage permissions = admin, group grants included); the token needs the **Identity (Read)** and **Security (Manage)** scopes, otherwise only the pull request's author can use the author commands |
299
+
300
+ When someone with write access corrects a finding or uses `remember`, Argus stores the lesson as a **learning** scoped to the relevant paths. On the server it arrives **pending approval** (disabled): a maintainer or admin approves it under **Learnings** before later reviews apply it. In CI, Argus replies with the `.argus.yml` snippet instead. The server handles at most 10 chat comments per pull request per 10 minutes.
301
+
302
+ ## Development
303
+
304
+ ```sh
305
+ npm test # unit and integration tests
306
+ npm run typecheck
307
+ npm run dev:server # API on :4747 with reload
308
+ npm run dev:web # UI on :5317, proxied to the API
309
+ ```
310
+
311
+ ### Measuring quality
312
+
313
+ ```sh
314
+ npm run eval # 10 planted-bug PRs (recall and precision)
315
+ npm run eval:mine -- --repo https://github.com/sindresorhus/ky --limit 10
316
+ npm run eval:mined -- evals/mined/*.json --sample 9 --save evals/results/run.json # one case per repository
317
+ npm run eval:mined -- evals/mined/*.json --save evals/results/full.json --resume # all 99, resumable
318
+ npm run eval:compare -- evals/baselines/claude-sonnet-5-5-sample9.json evals/results/run.json
319
+ npm run eval:analyze -- evals/results/run.json # why each bug was missed, and the top fixes
320
+ ```
321
+
322
+ The eval runners use the `claude-code` provider (your Claude subscription) by default and stop paid API calls after `--max-cost` dollars (default 1). Cases that fail to run count as misses. `eval:mined` takes its judge from `--judge-provider`/`--judge-model` or `ARGUS_EVAL_JUDGE=provider/model` and warns when the judge is the model under review. `ARGUS_DOCKER_TESTS=1 npm test` also runs the Docker execution tests.
323
+
324
+ `eval:mine` uses the SZZ method. It finds bug-fix commits, blames the lines each fix changed back to the commit that introduced them, and stores that commit as a pull request together with the later fix. `eval:mined` reviews each introducing commit as if it were a new PR. An LLM judge then decides whether any finding names the same bug the fix addressed. `evals/mined/` has 99 cases from ky, got, axios (TypeScript and JavaScript), click, flask, httpx (Python), cobra, chi (Go) and gson (Java). These bugs were subtle enough to get past the maintainers, so the scores are much lower than on planted bugs and show real progress more honestly. Ablation flags (`--no-agent`, `--no-voting`, `--no-analyzers`, `--no-verify`) work on both runners.
325
+
326
+ Layout: `packages/core` (engine, platforms, providers), `apps/server` (CLI, API, webhooks, queue), `apps/web` (React UI). Design notes are in `docs/design.md`.