Building a Gitea-First Code Review Tool in Go
1. The Problem: Gitea Has No Code Review Automation
If you self-host Gitea, you already know why: it's lightweight, fast, and doesn't require a GitHub enterprise budget. But there's a gap. GitHub has CodeRabbit, Graphite, and GitHub's own Copilot code review. GitLab has its own analysis. Gitea? Nothing.
You're left with two options:
- Manual review — read every diff yourself, every time
- CI-only checks — linting and tests run in Actions/Act Runner, but nobody looks at the semantic content of changes
Neither catches what a good code review catches: security vulnerabilities introduced in a PR, hardcoded secrets, deprecated patterns, or logic bugs that pass linting.
That's why I built Repository Detective — a Gitea-first code review tool that combines deterministic scanners with optional LLM analysis.
2. Architecture: Deterministic First, LLM Second
The key design decision: deterministic scanners run first, LLM analysis runs second on flagged files only.
This isn't "AI reviews your code." It's "scanners find candidates, then LLM validates and explains them with proof-of-concept."
Why This Order Matters
| Approach | Problem |
|---|---|
| LLM-only | Hallucinations, no verifiable evidence, vibes-based findings |
| Scanner-only | No context, false positives, developer ignores noisy alerts |
| Scanner → LLM | Scanners find real candidates, LLM validates and writes PoC |
Pipeline Stages
Push/PR → Webhook → Diff Extraction
↓
Stage 1: Deterministic Scanners
(Trivy, Grype, golangci-lint, ruff, shellcheck)
↓
Stage 2: LLM Analysis (optional, off by default)
(OpenAI-compatible endpoint, only on flagged files)
↓
Stage 3: Issue Creation
(Gitea issues with severity, file:line, code snippet, PoC)
3. Tech Stack
| Component | Choice | Why |
|---|---|---|
| Language | Go | Single binary, fast, Gitea is Go too |
| Webhooks | Native Gitea webhook | Push and PR events |
| Scanners | Trivy, Grype, golangci-lint, ruff, shellcheck | Best-in-class, open source |
| LLM | Any OpenAI-compatible endpoint | Privacy: runs on your infrastructure |
| Container | Docker + docker-compose | Easy self-hosted deploy |
| License | AGPL-3.0 | Community open source, commercial tiers available |
4. Quick Start
# docker-compose.minimal.yml — included in repo
version: "3.8"
services:
repository-detective:
image: ghcr.io/commstech/repository-detective:latest
ports:
- "8080:8080"
environment:
- GITEA_URL=https://your-gitea-instance.com
- GITEA_TOKEN=your-webhook-secret
- WEBHOOK_SECRET=your-webhook-secret
volumes:
- ./data:/app/data
# 1. Start the container
docker compose up -d
# 2. Add webhook in Gitea repo settings
# URL: http://your-server:8080/webhook
# Content type: application/json
# Secret: your-webhook-secret
# Trigger: Push events, Pull request events
# 3. Push code. Issues appear automatically.
5. What It Catches
Example Finding (created as Gitea issue)
🔍 Repository Detective Finding
Severity: HIGH
File: internal/auth/handler.go
Line: 47
Issue: API token compared with == instead of hmac.Equal
This allows timing side-channel attacks.
Evidence:
if r.Header.Get("Authorization") == expectedToken {
Proof of Concept:
An attacker can measure response time differences
to brute-force the token character by character.
Recommended Fix:
if hmac.Equal([]byte(r.Header.Get("Authorization")),
[]byte(expectedToken)) {
This is the kind of finding that scanners alone miss (it's not a known CVE pattern) and LLM-only tools hallucinate (without scanner context). The combination catches real issues with verifiable evidence.
6. Privacy-First Design
- LLM is off by default. You can run scanner-only mode with zero external API calls.
- When LLM is enabled, it only sends flagged file diffs (not your entire codebase) to the endpoint you configure.
- Self-hosted LLM supported. Point it at your local Ollama, vLLM, or any OpenAI-compatible server. Your code never leaves your infrastructure.
- No telemetry, no phone-home, no analytics. Repository Detective doesn't report back anywhere.
7. Open Core Model
| Tier | Price | Features |
|---|---|---|
| Community | Free (AGPL-3.0) | All scanners, webhook integration, Gitea issues, single repo |
| Pro | $100/instance/month | Multi-repo, custom scanner configs, Slack/Discord notifications, priority fixes |
| Enterprise | Contact us | SSO/OIDC, audit trail, on-prem LLM bundle, custom integrations, SLA |
The community tier is fully functional. No paywalled security features. The paid tiers add convenience and scale.
8. Roadmap
- [x] Gitea webhook integration (push + PR)
- [x] Trivy, Grype, golangci-lint, ruff, shellcheck
- [x] Optional LLM analysis with PoC generation
- [x] Gitea issue creation with severity tagging
- [x] Docker deployment
- [ ] GitHub support (next priority)
- [ ] Slack/Discord/Telegram notifications (Pro tier)
- [ ] Multi-repo dashboard (Pro tier)
- [ ] SSO/OIDC (Enterprise tier)
- [ ] SBOM generation and drift detection
9. Links
- GitHub: https://github.com/CommsTech/Repository-Detective
- Gitea (build repo): https://git.commsnet.org/commstech/Repository-Detective
- License: AGPL-3.0-or-later
-
Docker:
ghcr.io/commstech/repository-detective:latest
10. Feedback Wanted
I'm building this because Gitea users deserve code review tooling too. If you self-host Gitea, I want to know:
- What scanners would you add to the pipeline?
- Does the LLM-optional approach work for your security posture?
- What's missing for you to deploy this today?
Open issues on GitHub or start a discussion. I'm actively developing based on user feedback.
Repository Detective is AGPL-3.0 open source. Self-host your code review.
Top comments (0)