From c23e0f63188ca0235319899ea12e5c232969a77f Mon Sep 17 00:00:00 2001 From: Devin Date: Mon, 31 Aug 2026 21:31:30 +0000 Subject: [PATCH 1/2] docs: fix self-host first-run break, pgvector prereq, licensing drift --- README.md | 6 +++--- backend/.env.example | 27 +++++++++++++++++++-------- docs/CONTRIBUTING.md | 8 ++++++++ docs/architecture.md | 27 +++++++++++---------------- docs/self-hosting.md | 24 ++++++++++++++++++++++++ 5 files changed, 65 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index db312fa5..6a3b78bd 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ Running Argus against your own repos means creating a GitHub App and pointing a ### Prerequisites - Go 1.24+ -- PostgreSQL (or a serverless Postgres like [Neon](https://neon.tech)) +- PostgreSQL with the **pgvector >= 0.8.2** extension available (`docker compose up` ships it; on a managed/serverless Postgres like [Neon](https://neon.tech), check the version — the migration fails fast on anything older) - A [GitHub App](docs/self-hosting.md) — Argus receives its webhooks and posts as it ### External services @@ -202,8 +202,8 @@ Key environment variables — see [`backend/.env.example`](backend/.env.example) | `MERMAID_VALIDATOR_SECRET` | Shared backend/dashboard secret for Mermaid parser requests; configure with the validator base URL | | `SELF_HOSTED` | `true` applies self-host defaults (reviews auto-run unconditionally) | | `EMBEDDINGS_API_KEY` | Embeddings key for memory (optional; without it rows are full-text-searchable only) | -| `EMBEDDINGS_BASE_URL` | Embeddings endpoint (OpenAI-compatible), default Voyage via the AI gateway | -| `EMBEDDINGS_MODEL` | Embedding model, default `voyage/voyage-4-large` (1024 dims) | +| `EMBEDDINGS_BASE_URL` | Embeddings endpoint (OpenAI-compatible), default `https://api.voyageai.com/v1`; `.env.example` uses the Vercel AI Gateway instead | +| `EMBEDDINGS_MODEL` | Embedding model, default `voyage-4` (`voyage/voyage-4-large` in gateway form); must serve `EMBEDDINGS_DIMENSIONS` (1024) dims | --- diff --git a/backend/.env.example b/backend/.env.example index 6262a182..605718a4 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -37,17 +37,22 @@ PORT=8080 ENV=development CORS_ALLOW_ORIGIN=http://localhost:3000 -# Deployment identity (self-hosting) +# Deployment identity (self-hosting) — set these to YOUR hosts. Left unset the +# backend falls back to the hosted argus.reviews origins, and GitHub comments +# from your install will link to a dashboard you do not run. # Web dashboard base URL, linked from GitHub review comments. -DASHBOARD_BASE_URL=https://argus.reviews +DASHBOARD_BASE_URL=http://localhost:3000 # Explicit dashboard origin and shared secret for server-side Mermaid validation. -# Configure both together; there is no validator-origin default. -MERMAID_VALIDATOR_BASE_URL=http://localhost:3000 -MERMAID_VALIDATOR_SECRET= +# Configure both together or neither — the server refuses to start on a half-set +# pair. Both unset = diagrams disabled. Generate the secret with +# `openssl rand -hex 32` and set the same value on the web deployment. +# MERMAID_VALIDATOR_BASE_URL=http://localhost:3000 +# MERMAID_VALIDATOR_SECRET= # Public API base URL, used to build signed export links. -API_BASE_URL=https://api.argus.reviews -# Your GitHub App slug, used to build install URLs. -GITHUB_APP_SLUG=argus-eye +API_BASE_URL=http://localhost:8080 +# Your GitHub App slug — drives install URLs and the @mention Argus answers to. +# Must match the slug of the App you created, not the hosted one. +GITHUB_APP_SLUG=your-app-slug # true disables plan gating (self-hosts have no billing). SELF_HOSTED=false @@ -67,9 +72,15 @@ POSTHOG_API_KEY= # reachable through the full-text leg only; nothing re-embeds them later. # The model string is the vector-space id: changing it means existing rows are # no longer retrievable by new queries. +# +# Defaults when unset: https://api.voyageai.com/v1 + voyage-4. The values below +# route the same model through the Vercel AI Gateway (`creator/model` form). +# EMBEDDINGS_DIMENSIONS must match the stored vector width (1024) — changing it +# requires re-embedding every row. EMBEDDINGS_API_KEY= EMBEDDINGS_BASE_URL=https://ai-gateway.vercel.sh/v1 EMBEDDINGS_MODEL=voyage/voyage-4-large +EMBEDDINGS_DIMENSIONS=1024 # Extra logins classified as agents (comma-separated), on top of built-in # "[bot]" / "-bot" / "-agent" suffix detection. diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 47630b23..5ca90d94 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -72,6 +72,14 @@ Run `pnpm lint` and `pnpm typecheck` before submitting PRs that touch `web/`. 6. Commit with a descriptive message following the convention below 7. Push and open a PR against `main` +## Review gate + +Beyond CI, maintainers run an adversarial verification workflow +(`.claude/workflows/adversarial-verify.js`, described in `CLAUDE.md`) over every +PR before merge. It needs maintainer-side agent tooling — external contributors +are not expected to run it, only to have `make test`, `make lint`, and the +frontend checks green. + ## Commit Messages Use conventional commit prefixes: diff --git a/docs/architecture.md b/docs/architecture.md index 77985475..6e40a3b2 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -380,7 +380,7 @@ Outcomes land in the comment outcome vocabulary (`comment_outcomes`, migration 0 ## Command Dispatch Flow -Commands are triggered by `@argus-eye ` in PR issue comments. The webhook handler dispatches to `dispatchCommand()` which parses the command with regex `(?i)@argus-eye\s+(review|remember|resolve|fix|help)(.*)` and routes to the appropriate handler. +Commands are triggered by `@argus-eye ` in PR issue comments. The webhook handler dispatches to `dispatchCommand()` which parses the command with regex `(?i)@\s+(review|remember|resolve|fix|test|help)(.*)` and routes to the appropriate handler. ```mermaid flowchart TD @@ -392,6 +392,7 @@ flowchart TD PARSE --> |"remember"| REM["handleRememberCommand()"] PARSE --> |"resolve"| RES["handleResolveCommand()"] PARSE --> |"fix"| FIX["handleFixCommand()"] + PARSE --> |"test"| TEST["handleTestCommand()"] PARSE --> |"help"| HELP["handleHelpCommand()"] PARSE --> |"no match"| DROP["silently ignored"] @@ -426,6 +427,7 @@ flowchart TD | `remember` | `@argus-eye remember [--org] ` | Stores a pattern in memory. `--org` scopes to the installation-wide `_shared` container, otherwise the repo container. Also persists to the `patterns` table | | `resolve` | `@argus-eye resolve` | Resolves all unresolved Argus review threads on the PR via GraphQL and marks each finding `state=resolved`. Maintainer-only — a non-privileged commenter (not owner/member/collaborator) is refused | | `fix` | `@argus-eye fix` | Auto-applies suggested fixes from unresolved Argus comments. Creates a commit on the PR branch via Git Data API | +| `test` | `@argus-eye test [--code]` | Generates a test plan from the latest review's findings; `--code` drafts executable test code | | `help` | `@argus-eye help` | Posts a help table listing all available commands | --- @@ -590,20 +592,13 @@ All IDs are truncated to 100 characters max via `truncateIDWithSuffix()`. Hashes ## Licensing -Argus follows the **Sustainable Use License** model (similar to n8n): +Argus is licensed under [AGPL-3.0](../LICENSE) in full. There is no separate +enterprise tier, no `.ee` directory, and no feature gating: every capability in +this repository is available to every installation, hosted or self-hosted. -- **Core**: Licensed under the [Sustainable Use License](../LICENSE). Free for internal business use and non-commercial/personal use. Self-hosting is allowed. -- **Enterprise**: Files containing `.ee.` in their filename or `.ee/` in their directory path require a commercial Argus Enterprise License. +The practical obligation the AGPL adds over a permissive license: if you run a +modified Argus as a network service, you must offer your users the modified +source. -**What the Sustainable Use License allows:** -- Self-host Argus for your internal code reviews -- Modify and customize for your own use -- Free for personal and non-commercial projects - -**What it restricts:** -- Cannot offer Argus as a competing hosted/SaaS service -- Cannot remove licensing notices - -The hosted service at [argus.reviews](https://argus.reviews) offers managed hosting with both core and enterprise features, which funds ongoing development. - -Examples of this model: n8n, Cal.com \ No newline at end of file +The hosted service at [argus.reviews](https://argus.reviews) runs this same code +and offers managed hosting, which funds ongoing development. \ No newline at end of file diff --git a/docs/self-hosting.md b/docs/self-hosting.md index a067ef1d..fc43796a 100644 --- a/docs/self-hosting.md +++ b/docs/self-hosting.md @@ -6,6 +6,21 @@ Argus has no paid tier and no feature gating — every capability is available t `SELF_HOSTED=true` remains meaningful for one behavioural default: a self-host reviews **unconditionally**, on every opened/pushed/reopened PR, regardless of the stored `auto_run` setting (see [Auto-run & re-review](#auto-run--re-review)). +## 0. Postgres requirements + +Argus stores everything in one Postgres database and the migrations install two +extensions: + +- **pgvector >= 0.8.2** — required. Migration `057` fails fast on anything older + (iterative index scans and the parallel-HNSW-build fix are both assumed), so a + managed Postgres shipping an older `vector` extension aborts the migration + rather than breaking memory search later. `docker compose up` uses + `pgvector/pgvector:pg16`, which satisfies this. +- **pgcontext** — optional. Installed when the server has it, skipped with a + NOTICE everywhere else (no managed Postgres can install it). + +The migrating role needs `CREATE EXTENSION` privileges. + ## 1. Create the GitHub App Go to **GitHub → Settings → Developer settings → GitHub Apps → New GitHub App** (use an org account if the app should live under an org). @@ -62,6 +77,11 @@ go run ./cmd/migrate # apply DB migrations go run ./cmd/argus # start the server ``` +`.env.example` defaults `DASHBOARD_BASE_URL` / `API_BASE_URL` to localhost and +`GITHUB_APP_SLUG` to a placeholder on purpose: unset, the backend falls back to +the hosted `argus.reviews` origins and the `argus-eye` slug, and your install +would post GitHub comments linking to a dashboard you don't run. + Or `docker compose up` from the repo root (Postgres + migrations + server). Compose mounts `backend/secrets/` into the container read-only and expects the GitHub App PEM at `backend/secrets/github-app.pem` — `GITHUB_PRIVATE_KEY_PATH` from `backend/.env` is overridden inside the container. Deploying on Fly.io: change the `app` name in `backend/fly.toml`, then `fly deploy` from `backend/`. @@ -100,6 +120,10 @@ pnpm dev Point `NEXT_PUBLIC_API_URL` at your backend and set `CORS_ALLOW_ORIGIN` on the backend to the dashboard origin. +Diagrams are optional and off by default — leave both `MERMAID_VALIDATOR_*` vars +unset and the rest of the review works unchanged. Setting only one of the pair is +a startup error (`must be configured together`), not a warning. + PR diagrams use the dashboard's server-side Mermaid parser before the backend stores a diagram or edits a PR description. Generate one shared value (`openssl rand -hex 32`) and set it as `MERMAID_VALIDATOR_SECRET` on **both** the backend and web deployment. Set `MERMAID_VALIDATOR_BASE_URL` on the backend to the explicit origin of that web deployment; it must be reachable from the backend. The backend has no validator-origin default and refuses an unpaired URL or secret, so it cannot send private diagram evidence or the shared secret to the vendor dashboard by accident. `DASHBOARD_BASE_URL` remains the link target for GitHub comments. Diagram generation fails closed when the parser service, shared secret, or deployed Mermaid version is unavailable; the rest of the review still completes. ## Auto-run & re-review From 21db6bc67b310a109630a89a7b0ca208eec935a5 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Mon, 31 Aug 2026 21:41:36 +0000 Subject: [PATCH 2/2] docs: load .env into the shell before go run in self-hosting guide Co-Authored-By: Dhruv --- docs/self-hosting.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/self-hosting.md b/docs/self-hosting.md index fc43796a..6f50d7ca 100644 --- a/docs/self-hosting.md +++ b/docs/self-hosting.md @@ -72,9 +72,10 @@ cd backend && make smee ```bash cd backend -cp .env.example .env # fill in the REQUIRED section -go run ./cmd/migrate # apply DB migrations -go run ./cmd/argus # start the server +cp .env.example .env # fill in the REQUIRED section +set -a; source .env; set +a # the Go binaries read the process env, not .env +go run ./cmd/migrate # apply DB migrations +go run ./cmd/argus # start the server ``` `.env.example` defaults `DASHBOARD_BASE_URL` / `API_BASE_URL` to localhost and @@ -82,7 +83,7 @@ go run ./cmd/argus # start the server the hosted `argus.reviews` origins and the `argus-eye` slug, and your install would post GitHub comments linking to a dashboard you don't run. -Or `docker compose up` from the repo root (Postgres + migrations + server). Compose mounts `backend/secrets/` into the container read-only and expects the GitHub App PEM at `backend/secrets/github-app.pem` — `GITHUB_PRIVATE_KEY_PATH` from `backend/.env` is overridden inside the container. +Or `docker compose up` from the repo root (Postgres + migrations + server) — Compose loads `backend/.env` for you, no export needed. Compose mounts `backend/secrets/` into the container read-only and expects the GitHub App PEM at `backend/secrets/github-app.pem` — `GITHUB_PRIVATE_KEY_PATH` from `backend/.env` is overridden inside the container. Deploying on Fly.io: change the `app` name in `backend/fly.toml`, then `fly deploy` from `backend/`.