# NoiseGate

**Filter the noise from bug bounty reports.**

A program-aware AI triage assistant that evaluates report quality, scope alignment, and impact — so researchers submit better reports and triagers focus on real vulnerabilities.

## Features

- **Three-verdict system** — PASS / WARN / FAIL maps directly to downstream actions for both researchers and triagers
- **Program-aware** — import any bug bounty program from a URL or local file; NoiseGate extracts scope, ineligible findings, and rules using an LLM
- **Structured output** — every verdict includes per-check reasoning (scope, eligibility, quality, impact)
- **Multi-provider** — Anthropic, OpenAI, Gemini, or local Ollama via a single `--model` flag
- **Scriptable** — `--json` output + exit codes (`0`=PASS, `1`=WARN, `2`=FAIL, `3`=error) for automation and pipelines
- **No PoC, no FAIL** — a real finding with a weak writeup gets WARN, not FAIL; the finding is preserved

### Verdicts

| Verdict | Meaning | Researcher action | Triager action |
|---------|---------|-------------------|----------------|
| **PASS** | In scope, real impact, clear writeup | Submit it | Triage it |
| **WARN** | Real finding, incomplete writeup | Fix the report | Ask for more info |
| **FAIL** | Out of scope, no real impact, non-qualifying | Don't submit | Close it |

## Installation

Requires Python 3.12+.

```bash
pip install noisegate                    # Anthropic (default)
pip install "noisegate[openai]"          # + OpenAI
pip install "noisegate[google]"          # + Gemini
```

Or from source:
```bash
git clone https://github.com/sgmurphy/noisegate.git
cd noisegate
pip install -e ".[dev]"
playwright install chromium
```

## Quickstart

**1. Configure your LLM provider:**
```bash
noisegate llm
```

**2. Import a bug bounty program:**
```bash
noisegate program add acme --url https://hackerone.com/acme
```

**3. Triage a report against the program:**
```bash
noisegate triage report.md
```

## Usage

### Triage a report

```bash
# Uses the default program
noisegate triage report.md

# Override the program for this run
noisegate triage report.md --program acme

# Machine-readable JSON (for CI/scripts)
noisegate triage report.md --json

# Use a specific model
noisegate triage report.md --model openai:gpt-4o
noisegate triage report.md --model google-gla:gemini-2.0-flash
noisegate triage report.md --model ollama:llama3
```

**Exit codes:** `0`=PASS, `1`=WARN, `2`=FAIL, `3`=error

### Multi-provider support

NoiseGate uses [pydantic-ai](https://github.com/pydantic/pydantic-ai) for LLM abstraction.
Pass `--model <provider>:<model-id>` to switch providers:

| Provider | Model string | API key env var |
|----------|-------------|-----------------|
| Anthropic (default) | `anthropic:claude-sonnet-4-6` | `ANTHROPIC_API_KEY` |
| OpenAI | `openai:gpt-4o` | `OPENAI_API_KEY` |
| Gemini | `google-gla:gemini-2.0-flash` | `GOOGLE_API_KEY` |
| Ollama (local) | `ollama:llama3` | *(none)* |

### JSON output

```json
{
  "checks": [
    {
      "check_id": "asset_in_scope",
      "passed": true,
      "reason": "The reported target matches the in-scope asset *.example.com."
    },
    {
      "check_id": "finding_ineligible",
      "passed": true,
      "reason": "The finding type is not listed as ineligible."
    },
    {
      "check_id": "required_sections_present",
      "passed": false,
      "reason": "No proof-of-concept is included, which the program requires."
    }
  ],
  "summary": "The report targets an in-scope asset with real impact, but is missing a required proof-of-concept.",
  "verdict": "WARN",
  "model_used": "anthropic:claude-sonnet-4-6",
  "prompt_tokens": 1234,
  "completion_tokens": 567
}
```
