Skip to content

Repository files navigation

BugSwatter

Nightly AI code review that hunts down the shady things hiding in your repos.

Pull-request review usually sees a diff. BugSwatter reviews clusters: changed files together with the unchanged supporting code they depend on, planned against a fresh whole-repository manifest. That wider context can expose defects that live in the relationship between a change and code the pull request did not touch.

There are shady things lurking in your code. Bugs, sharp edges, quiet little mistakes. There always are. BugSwatter is a small, self-hosted app I put together to look for them every night. A primary model reviews bounded repository clusters, and an optional second model challenges the findings before they reach the validated report.

The primary pass can run on a local OpenAI-compatible model, while the validator can stay local or use a stronger cloud model. BugSwatter records what it reviewed, what it deferred, and what failed. It gives the models context, not hands: no shell, no Git access, no MCP adapters, and no ability to edit your code.

See real finding case studies for defects found in BugSwatter, MVNC, and a sanitized commercial-style security product. For the design and its local-first cost model, read Why BugSwatter?.

Contributions are welcome. Found a bug, smoothed a rough edge, or added something useful? Open a pull request.

How it works

BugSwatter is self-hosted and ships as two applications:

  • Informant refreshes a dedicated clone, rebuilds a safe repository manifest, plans related review clusters, sends bounded source to an OpenAI-compatible model, and writes timestamped reports with explicit coverage
  • Marshal is an optional long-running dispatcher that starts Informant from schedules, repository polling, filesystem changes, webhooks, or the built-in dashboard

The primary review can stay on your network through LM Studio, llama.cpp, Ollama, or another OpenAI-compatible endpoint. Informant first supplies a bounded mix of root guidance, root files, configured seeds, changed source, and repository structure, then asks the model to group related files. Invalid planning falls back to deterministic path-based clusters instead of losing required coverage. Informant can also fail over to ordered, already-running models on other endpoints without loading or unloading models and still produces one primary report. A second opinion can use one other local or cloud model to validate findings and assign severity. Advanced configuration can select that one validator from as many as three profiles according to the highest candidate severity in the primary run.

BugSwatter is deliberately not a general-purpose agentic coding harness. The models do not get a shell, MCP servers or adapters, Git access, general filesystem access, or tools that can edit code. Their only model-directed action is asking Informant for a bounded range of numbered lines through its application-owned read_file_lines tool. Informant validates every request and either performs the read itself or refuses it. The model can ask for context and return review text; it cannot execute actions on your machine.

Quick start

Install Git and .NET 10. You can either build from source with the commands below or download the appropriate archive from GitHub Releases, verify it against SHA256SUMS.txt, and extract it into C:\BugSwatter\bin or /opt/bugswatter.

The Windows executables are not code-signed, so Windows may identify them as coming from an unknown publisher or display a SmartScreen warning. Download releases only from this GitHub repository and verify the archive against SHA256SUMS.txt before running it.

Create a directory for one review job:

mkdir C:\BugSwatter\jobs\sample
cd C:\BugSwatter\jobs\sample
C:\BugSwatter\bin\Informant.exe init
notepad informant.json
C:\BugSwatter\bin\Informant.exe verify
C:\BugSwatter\bin\Informant.exe

On Linux, use /opt/bugswatter/Informant and Linux paths instead. Informant init creates a commented starter configuration and the default review prompt. Set the repository URL, branch, a dedicated absolute working-tree path, Git executable path, model endpoint, and model name before running verify. Optional fallbacks must already be loaded and answering at their configured endpoints; BugSwatter does not manage model processes or GPU placement.

The first run uses the full tracked tree as its candidate universe. The default exhaustive strategy deeply reviews every reviewable candidate; adaptive may defer full-file review and records that limitation explicitly. Optional pass budgets stop new primary or second-opinion work gracefully, and adaptive coverage debt can carry a bounded number of deferred paths into later runs. Later changed runs compare the current tip with the last completed-review baseline. Reports are retained for 31 days by default; set reportRetentionDays to -1 to keep them indefinitely.

Why use it

  • More than the diff: review changed files with unchanged supporting context selected from a fresh repository manifest
  • Local-first: keep primary review code on your network
  • Changed-file reviews: after the first run, review only changes since the last successfully completed primary review
  • Repository-aware clusters: group related files and unchanged supporting context without assuming a language or framework
  • Honest coverage: choose exhaustive review or adaptive review with explicit deep-reviewed, changed-content, deferred, excluded, failed, and partial outcomes
  • Bounded unattended work: cap primary and second-opinion pass time without losing completed report sections, and carry selected adaptive coverage debt into later runs
  • Finding memory: assign structural fingerprints, separate new findings from accepted ones, and honor justified inline suppressions without trusting model wording as identity
  • Second opinion: use one validator for every run, or route each complete run to one of as many as three local or cloud model profiles according to its highest primary candidate severity
  • No agentic harness: models can request bounded, read-only line ranges through Informant's single application-owned tool, but cannot write files, execute commands, or invoke Git; no MCP server or adapter is involved
  • Swappable LM Studio models: use modelName * to select exactly one already-loaded model without editing job configuration
  • Multiple triggers: use daily schedules, outbound repository polling, filesystem watching, GitHub webhooks, or Azure DevOps service hooks
  • Unattended operation: run Marshal in the foreground, as a Windows service, or as a systemd service
  • Machine-wide exclusivity: allow one Marshal host and one Informant review or verification operation per machine, including across service accounts and interactive sessions
  • Live review status and cost: the dashboard separates whole-run, current phase/model, local, and frontier usage, and estimates frontier cost when you configure current per-million-token rates
  • Optional GitHub feedback: publish one neutral Check Run with bounded annotations for new findings anchored to changed lines, while keeping the complete finding ledger local
  • No installer or bundled runtime: GitHub Releases provide framework-dependent Windows and Linux archives for machines with .NET 10 installed

Important safety boundaries

The model does not control Git. Informant itself uses application-controlled Git operations to clone the configured repository, detect changes, read baseline versions of deleted files, and refresh its dedicated working tree. Model output is never converted into a command line, and the model cannot choose Git commands or arguments.

Working-tree refresh is intentionally destructive: Informant uses fetch, reset --hard, and clean -fdx to make its dedicated clone match the configured branch. Before doing that, it validates matching ownership records inside and outside the working tree, the canonical path, repository URL, branch, origin remote, .git directory, and reparse-point boundaries. Never point workingTreePath at a checkout where you work.

Informant supplies controller-selected source from the current manifest and exposes one model-directed tool, read_file_lines. The tool can return at most 400 numbered lines per call from a bounded text file inside the repository root. It rejects paths absent from the current manifest, absolute paths, paths outside the root, symbolic links, junctions, mount points, other reparse points, binary files, oversized files, and content that changed after manifest creation. This uses ordinary OpenAI-compatible model tool calling through Informant, not MCP, and gives the model no direct filesystem access.

Marshal's optional dashboard is HTTP-only and has no authentication or authorization. Anyone who can reach it can see operational details, including current file and model names, enqueue reviews, and remove waiting jobs. Bind it to localhost unless you deliberately place it on a trusted internal or VPN network. Never expose it directly to the public internet.

AI output can be incomplete or wrong. Treat reports as leads for human review, not as proof that code is safe. Test BugSwatter against a noncritical repository before relying on unattended operation.

Documentation

See DOCUMENTATION.md for installation, complete configuration references, polling expressions, service deployment, webhooks, email, retention, cost controls, building, and GitHub Releases.

Security limitations and private vulnerability reporting are described in SECURITY.md. Development and pull-request guidance is in CONTRIBUTING.md.

Build from source

Install the .NET 10 SDK, then run:

dotnet restore BugSwatter.slnx
dotnet build BugSwatter.slnx -c Release --no-restore
dotnet test BugSwatter.slnx -c Release --no-build --no-restore

The release packaging script builds both applications for one supported runtime:

./scripts/package-release.ps1 -Runtime win-x64
./scripts/package-release.ps1 -Runtime linux-x64

Disclaimer

Use BugSwatter at your own risk. You choose the AI endpoints, models, repositories, schedules, credentials, and network exposure. Local and cloud models can consume substantial compute or billable tokens, and a cloud second opinion sends selected source code outside your network. Confirm behavior and cost on a small scope before unattended use.

The software is provided "as is", without warranty of any kind, to the maximum extent permitted by law. The authors and contributors accept no liability for costs, losses, missed defects, incorrect findings, security incidents, or other damage arising from its use.

License

BugSwatter is licensed under the Apache License 2.0. Required notices are in NOTICE.

About

Self-hosted nightly AI code review that examines changed files with the unchanged supporting context they depend on

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages