# Coverage regression checker

- Human page: https://happytails.ai/en/developer-tools/coverage-regression-checker/
- Markdown: https://happytails.ai/en/developer-tools/coverage-regression-checker.md
- Structured JSON: https://happytails.ai/agents/en/developer-tools/coverage-regression-checker/index.json
- Visibility: public

## Tool capabilities

| Property | Value |
| --- | --- |
| Tool ID | `coverage-regression-checker` |
| Category | developer-tools |
| Implementation | Registered implementation. Registration alone is not a production-quality guarantee. |
| Browser execution | Use the visible action or interactive controls. |
| Browser processing | Browser; see tool notes for network behavior. |
| HTTP API | Not callable through HTTP. |
| Browser-agent interface | run_current_tool |

### Implementation notes

Runs in your browser in a background worker. Compares two coverage reports of up to 2,000,000 characters each and a diff of up to 1,000,000 characters.

### Inputs and settings

Text input: Head coverage report.

Example or placeholder shown in the interface (not a validated fixture):

```text
SF:src/cart.js
DA:3,5
end_of_record
```

Paste the coverage file produced after your change, for example lcov.info or cobertura.xml. Up to 2,000,000 characters. Review the settings before running.

| Setting | Meaning | Control type | Default | Constraints |
| --- | --- | --- | --- | --- |
| `base` | Base coverage report (before the change) | textarea | "TN:\nSF:src/cart.js\nFN:3,addItem\nFNDA:4,addItem\nDA:3,4\nDA:4,4\nDA:5,0\nDA:7,4\nend_of_record\nSF:src/price.js\nDA:1,2\nDA:2,2\nDA:3,0\nend_of_record\n" |  |
| `changes` | Unified diff or changed file list (optional) | textarea | "diff --git a/src/cart.js b/src/cart.js\n--- a/src/cart.js\n+++ b/src/cart.js\n@@ -6,2 +6,4 @@\n }\n export function total(items){\n+  if(!items.length)return 0;\n+  return items.reduce((n,i)=>n+i.price,0);\ndiff --git a/src/price.js b/src/price.js\n--- a/src/price.js\n+++ b/src/price.js\n@@ -3,1 +3,1 @@\n-  return value;\n+  return Math.round(value*100)/100;\n" |  |
| `format` | Report format | select | "auto" | Allowed: auto, lcov, cobertura, jacoco, istanbul, istanbul-summary, go |
| `minPatch` | Minimum patch coverage (%) | number | "80" | min=0 max=100 step=any |
| `maxDrop` | Largest allowed total drop (percentage points) | number | "0" | min=0 max=100 step=any |
| `maxFileDrop` | Largest allowed drop for one file (percentage points) | number | "100" | min=0 max=100 step=any |
| `stripPrefix` | Path prefixes to remove | text | "" |  |

### Browser-agent workflow

1. Open the human page in a browser that supports WebMCP.
2. Discover the interface exposed by that page; use its actual schema.
3. Select files on the page first when the tool requires files.
4. Call `run_current_tool` with valid input and settings.
5. Inspect the returned result or error and the displayed output. Retrieve files from the displayed download links.

Calls do not automatically copy or download results. Browser permissions still apply. Interface availability alone is not proof of successful execution.

### Planning specification

Up to 2,000,000 characters for each coverage report and 1,000,000 characters for the diff. Processing runs locally in a background worker in your browser. Downloads: a JSON report, a CSV of files and a Markdown table.

This describes intended requirements. Use the implementation notes, interface schema and observed output to determine current support.

### Complete machine-readable capability record

```json
{
  "id": "coverage-regression-checker",
  "category": "developer-tools",
  "built": true,
  "requirements": "Up to 2,000,000 characters for each coverage report and 1,000,000 characters for the diff. Processing runs locally in a background worker in your browser. Downloads: a JSON report, a CSV of files and a Markdown table.",
  "implementation": {
    "fields": [
      {
        "key": "base",
        "label": "Base coverage report (before the change)",
        "value": "TN:\nSF:src/cart.js\nFN:3,addItem\nFNDA:4,addItem\nDA:3,4\nDA:4,4\nDA:5,0\nDA:7,4\nend_of_record\nSF:src/price.js\nDA:1,2\nDA:2,2\nDA:3,0\nend_of_record\n",
        "type": "textarea",
        "maxLength": 2000000,
        "help": "LCOV, Cobertura, JaCoCo, Istanbul or Go coverage from the base branch."
      },
      {
        "key": "changes",
        "label": "Unified diff or changed file list (optional)",
        "value": "diff --git a/src/cart.js b/src/cart.js\n--- a/src/cart.js\n+++ b/src/cart.js\n@@ -6,2 +6,4 @@\n }\n export function total(items){\n+  if(!items.length)return 0;\n+  return items.reduce((n,i)=>n+i.price,0);\ndiff --git a/src/price.js b/src/price.js\n--- a/src/price.js\n+++ b/src/price.js\n@@ -3,1 +3,1 @@\n-  return value;\n+  return Math.round(value*100)/100;\n",
        "type": "textarea",
        "maxLength": 1000000,
        "help": "A git diff gives patch coverage. A list of paths, one per line, limits the comparison to those files."
      },
      {
        "key": "format",
        "label": "Report format",
        "value": "auto",
        "type": "select",
        "values": [
          "auto",
          "lcov",
          "cobertura",
          "jacoco",
          "istanbul",
          "istanbul-summary",
          "go"
        ],
        "labels": {
          "auto": "Detect automatically",
          "lcov": "LCOV",
          "cobertura": "Cobertura",
          "jacoco": "JaCoCo",
          "istanbul": "Istanbul",
          "istanbul-summary": "Istanbul summary",
          "go": "Go coverage"
        }
      },
      {
        "key": "minPatch",
        "label": "Minimum patch coverage (%)",
        "value": "80",
        "type": "number",
        "min": 0,
        "max": 100,
        "step": "any"
      },
      {
        "key": "maxDrop",
        "label": "Largest allowed total drop (percentage points)",
        "value": "0",
        "type": "number",
        "min": 0,
        "max": 100,
        "step": "any"
      },
      {
        "key": "maxFileDrop",
        "label": "Largest allowed drop for one file (percentage points)",
        "value": "100",
        "type": "number",
        "min": 0,
        "max": 100,
        "step": "any",
        "help": "100 turns the per-file check off."
      },
      {
        "key": "stripPrefix",
        "label": "Path prefixes to remove",
        "value": "",
        "type": "text",
        "maxLength": 2000,
        "help": "Comma separated, for example /home/ci/project/."
      }
    ],
    "registrationFamily": "report-ingest-analysis-reference",
    "inputMaxLength": 2000000,
    "inputErrorCode": "REPORT_INGEST_ANALYSIS_REFERENCE_TOO_LONG",
    "note": "Runs in your browser in a background worker. Compares two coverage reports of up to 2,000,000 characters each and a diff of up to 1,000,000 characters.",
    "experience": {
      "automatic": false,
      "single": false,
      "inputMaxLength": 2000000,
      "inputMode": "text",
      "label": "Head coverage report",
      "placeholder": "SF:src/cart.js\nDA:3,5\nend_of_record",
      "help": "Paste the coverage file produced after your change, for example lcov.info or cobertura.xml. Up to 2,000,000 characters. Review the settings before running.",
      "action": null
    },
    "mode": "explicit",
    "interactive": false
  },
  "execution": "Browser interface",
  "api": null,
  "browser_agent": {
    "supported": true,
    "name": "run_current_tool",
    "discovery": "WebMCP on the human page in a supporting browser",
    "verification": "See audit/API-AUDIT.md; availability is not verification"
  }
}
```

## Page guide

Compare coverage from before and after a change and see the total change, the coverage of the changed lines and which files dropped. Each threshold gets a clear pass or fail.

### How to use Coverage regression checker

1. Paste the head coverage report from after the change.
2. Paste the base report and, if you have it, the unified diff of the change.
3. Set the minimum patch coverage and the largest allowed drop.
4. Run the check and review the verdicts and per-file deltas.
5. Download the JSON report, CSV or Markdown summary.

How can we improve this tool?

Report a problem or share an idea.

Please leave out private information. Your message and the tool name go to our team via PostHog.

## Useful next steps

- [JSON diff](https://happytails.ai/en/developer-tools/json-diff/) ([Markdown](https://happytails.ai/en/developer-tools/json-diff.md))

- [XML validator](https://happytails.ai/en/developer-tools/xml-validator/) ([Markdown](https://happytails.ai/en/developer-tools/xml-validator.md))

- [Regex tester](https://happytails.ai/en/developer-tools/regex-tester/) ([Markdown](https://happytails.ai/en/developer-tools/regex-tester.md))

## What it compares

Both reports are read into executable lines and hit counts. LCOV, Cobertura, JaCoCo, Istanbul coverage-final and json-summary, and Go coverprofile files are supported and detected automatically. Line coverage is the share of executable lines with at least one hit.

### Patch coverage

With a unified diff, the added lines of each file in the new version are checked against the head report. Lines that are not executable, such as comments, are left out. Paths are matched exactly after removing a/ and b/ prefixes and any prefixes you list, then by a unique path suffix.

### Thresholds

The total drop check compares head and base line coverage in percentage points. Patch coverage passes when it is at least the minimum. A per-file drop check is available and is off at 100. Istanbul json-summary has no line detail, so it supports totals only.
