Skip to main content

Squillify development is paused indefinitely. Read why, and discover what this experiment achieved. Read the story

MicroSkills Reference

Coverage Diff

quality.coverage_diff

ProductionBounded custom (Class B)Deterministicstrictfastv1.0.0
No network

Overview

You send two coverage snapshots as arrays of closed path counters: lines, branches and functions, each as covered and total integers. pathMode defaults to EXACT; SLASH_NORMALIZED rewrites backslashes to slashes, collapses repeated slashes and strips a trailing slash. The answer is global and per-path deltas, added and removed paths, and line-coverage regressions sorted by magnitude. A percentage is JSON null when its total is zero, never NaN. This does not parse vendor reports or set a pass bar.

Two coverage snapshots need a published integer delta, not a vendor-file parser.

Reliability

Percentages round to six decimals. A percentage is JSON null when its total is zero. COVERAGE_DIFF_INVALID — trigger: a covered count exceeds its total, a blank path, or an unknown pathMode; retryable: no; next: send non-negative counters with covered ≤ total. COVERAGE_DIFF_PATH_COLLISION — trigger: two paths become the same string after pathMode; retryable: no; next: send unique paths under that mode. COVERAGE_DIFF_LIMIT_EXCEEDED — trigger: more than 100000 paths on one side; retryable: no; next: split the snapshots.

Context footprint

Paths and integer counters only; source text is never returned. A successful call costs 1 execution credit.

When to use it

When two already-normalized coverage tables must be compared by path.

When the report is still a JaCoCo or LCOV file, or when a pass bar is required.

Powered by Squillify's own integer coverage-diff arithmetic. No coverage engine is involved.

Scope

Note
Compares two coverage snapshots by path and reports count and percentage-point deltas.

Non-goals

  • Does not parse vendor coverage reports
  • Does not set a pass or fail bar
  • Does not merge overlapping shards

Properties

IdempotentRetry safeStreaming supportedFile input supportedRequires external service

Capabilities

analysis

Cost & billing

Flat rate per invocation

MetercallsBillable onsuccessCost per call1 credit

File handling

Accepts file_refProduces file_refMax input2 MB

How we handle your data

Sensitive processing
What this means

This skill is designed to detect, mask, redact, validate, or otherwise process sensitive data.

Squillify guarantees
  • Runs inside Squillify
  • This skill runs inside Squillify.
  • Payloads are not sent to an external service by this skill.
  • Squillify does not permanently store submitted payloads.
  • Telemetry records metadata only, not submitted content.
  • Submitted payloads are not used for training.
  • Submitted payloads are not reviewed by humans.
  • Targets sensitive data
  • The response does not contain submitted content.
Your responsibility

Squillify does not determine whether submitted content is sensitive. Your application is responsible for deciding what data it is allowed to submit. Your application is responsible for securing the response.

Read the Microskill Data Handling Policy

Input schema

FieldTypeRequiredDescription
beforearrayYesBefore snapshot, 0 through 100001 closed path objects; runtime accepts at most 100000.
afterarrayYesAfter snapshot, 0 through 100001 closed path objects; runtime accepts at most 100000.
pathModestringNoEXACT or SLASH_NORMALIZED; omit it for EXACT matching of the path strings as sent.

Output schema

FieldTypeRequiredDescription
pathModestringYesPath matching mode that was actually applied to both snapshots.
globalobjectYesClosed aggregate line, branch and function deltas across every path in either snapshot.
pathsarrayYesPer-path deltas sorted by path, 0 through 200000 closed rows.
addedarrayYesNormalized paths present only after, sorted lexicographically, 0 through 100000 strings of 1 through 4096 characters.
removedarrayYesNormalized paths present only before, sorted lexicographically, 0 through 100000 strings of 1 through 4096 characters.
regressionsarrayYesLine-coverage drops sorted by magnitude then path, 0 through 100000 closed {path, metric, beforePercentage, afterPercentage, magnitudePp} objects.
beforeCountintegerYesHow many distinct before paths were compared.
afterCountintegerYesHow many distinct after paths were compared.

API contract

POST /v1/execute
curl
curl -sS -X POST "$BASE/v1/execute" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"skillKey":"quality.coverage_diff","input":{"before":[{"path":"src/App.java","linesCovered":8,"linesTotal":10,"branchesCovered":2,"branchesTotal":4,"functionsCovered":1,"functionsTotal":1}],"after":[{"path":"src/App.java","linesCovered":5,"linesTotal":10,"branchesCovered":2,"branchesTotal":4,"functionsCovered":1,"functionsTotal":1}]}}'
Integrations
TypeScript SDK
import { Squillify } from "@squillify/sdk";

const sq = new Squillify({ apiKey: process.env.SQUILLIFY_API_KEY });

const { output } = await sq.execute("quality.coverage_diff", {"before":[{"path":"src/App.java","linesCovered":8,"linesTotal":10,"branchesCovered":2,"branchesTotal":4,"functionsCovered":1,"functionsTotal":1}],"after":[{"path":"src/App.java","linesCovered":5,"linesTotal":10,"branchesCovered":2,"branchesTotal":4,"functionsCovered":1,"functionsTotal":1}]});

Errors

CodeHTTPRetryableDescription
VALIDATION_ERROR400NoThe request payload failed schema validation.
UNAUTHORIZED401NoMissing or invalid API key.
SKILL_NOT_ACCESSIBLE403NoThe API key is not granted access to this skill.
SKILL_NOT_AVAILABLE_FOR_PLAN403NoThis skill is not included in your current plan.
PLAN_ELIGIBILITY_UNAVAILABLE503YesPlan eligibility could not be decided. Retry after backoff.
SKILL_NOT_FOUND404NoThe requested skill or version does not exist.
TENANT_RATE_LIMITED429YesRequest rate limit exceeded. Retry after backoff.
QUOTA_EXCEEDED429YesPlan quota exhausted. Retryable once the quota period resets.
EXECUTION_TIMEOUT504YesExecution exceeded the allowed time budget.
COVERAGE_DIFF_INVALID400NoThe request payload failed this skill's input validation.
COVERAGE_DIFF_PATH_COLLISION400NoThe request payload failed this skill's input validation.
COVERAGE_DIFF_LIMIT_EXCEEDED429NoA size, quota, rate, or time limit was exceeded.

Other limits

LimitValue
Recommended inline bytes32 KiB

Limitations

  • Does not parse vendor coverage reports
  • Does not set a pass or fail bar
  • Does not merge overlapping shards
  • Parsing a JaCoCo XML file
  • Deciding whether coverage is high enough

How to call

POST /v1/execute (requires authentication)

Request bodyjson
{
  "skillKey": "quality.coverage_diff",
  "input": {
    "before": [
      {
        "path": "src/App.java",
        "linesCovered": 8,
        "linesTotal": 10,
        "branchesCovered": 2,
        "branchesTotal": 4,
        "functionsCovered": 1,
        "functionsTotal": 1
      }
    ],
    "after": [
      {
        "path": "src/App.java",
        "linesCovered": 5,
        "linesTotal": 10,
        "branchesCovered": 2,
        "branchesTotal": 4,
        "functionsCovered": 1,
        "functionsTotal": 1
      }
    ]
  }
}

Examples

A ten-line file that loses three covered lines is a regression

Inputjson
{
  "before": [
    {
      "path": "src/App.java",
      "linesCovered": 8,
      "linesTotal": 10,
      "branchesCovered": 2,
      "branchesTotal": 4,
      "functionsCovered": 1,
      "functionsTotal": 1
    }
  ],
  "after": [
    {
      "path": "src/App.java",
      "linesCovered": 5,
      "linesTotal": 10,
      "branchesCovered": 2,
      "branchesTotal": 4,
      "functionsCovered": 1,
      "functionsTotal": 1
    }
  ]
}
Expected outputjson
{
  "pathMode": "EXACT",
  "paths": [
    {
      "path": "src/App.java",
      "change": "CHANGED",
      "lines": {
        "beforeCovered": 8,
        "beforeTotal": 10,
        "afterCovered": 5,
        "afterTotal": 10,
        "deltaCovered": -3,
        "deltaTotal": 0,
        "beforePercentage": 80,
        "afterPercentage": 50,
        "deltaPp": -30
      },
      "branches": {
        "beforeCovered": 2,
        "beforeTotal": 4,
        "afterCovered": 2,
        "afterTotal": 4,
        "deltaCovered": 0,
        "deltaTotal": 0,
        "beforePercentage": 50,
        "afterPercentage": 50,
        "deltaPp": 0
      },
      "functions": {
        "beforeCovered": 1,
        "beforeTotal": 1,
        "afterCovered": 1,
        "afterTotal": 1,
        "deltaCovered": 0,
        "deltaTotal": 0,
        "beforePercentage": 100,
        "afterPercentage": 100,
        "deltaPp": 0
      }
    }
  ],
  "added": [],
  "removed": [],
  "regressions": [
    {
      "path": "src/App.java",
      "metric": "lines",
      "beforePercentage": 80,
      "afterPercentage": 50,
      "magnitudePp": 30
    }
  ],
  "global": {
    "lines": {
      "beforeCovered": 8,
      "beforeTotal": 10,
      "afterCovered": 5,
      "afterTotal": 10,
      "deltaCovered": -3,
      "deltaTotal": 0,
      "beforePercentage": 80,
      "afterPercentage": 50,
      "deltaPp": -30
    },
    "branches": {
      "beforeCovered": 2,
      "beforeTotal": 4,
      "afterCovered": 2,
      "afterTotal": 4,
      "deltaCovered": 0,
      "deltaTotal": 0,
      "beforePercentage": 50,
      "afterPercentage": 50,
      "deltaPp": 0
    },
    "functions": {
      "beforeCovered": 1,
      "beforeTotal": 1,
      "afterCovered": 1,
      "afterTotal": 1,
      "deltaCovered": 0,
      "deltaTotal": 0,
      "beforePercentage": 100,
      "afterPercentage": 100,
      "deltaPp": 0
    }
  },
  "beforeCount": 1,
  "afterCount": 1
}
Tip
Line coverage falls from 80 to 50, so the path is listed as a regression.

A unit with total zero reports JSON null percentages, never NaN

Inputjson
{
  "before": [
    {
      "path": "src/Empty.java",
      "linesCovered": 0,
      "linesTotal": 0,
      "branchesCovered": 0,
      "branchesTotal": 0,
      "functionsCovered": 0,
      "functionsTotal": 0
    }
  ],
  "after": [
    {
      "path": "src/Empty.java",
      "linesCovered": 0,
      "linesTotal": 0,
      "branchesCovered": 0,
      "branchesTotal": 0,
      "functionsCovered": 0,
      "functionsTotal": 0
    }
  ]
}
Expected outputjson
{
  "pathMode": "EXACT",
  "paths": [
    {
      "path": "src/Empty.java",
      "change": "CHANGED",
      "lines": {
        "beforeCovered": 0,
        "beforeTotal": 0,
        "afterCovered": 0,
        "afterTotal": 0,
        "deltaCovered": 0,
        "deltaTotal": 0
      },
      "branches": {
        "beforeCovered": 0,
        "beforeTotal": 0,
        "afterCovered": 0,
        "afterTotal": 0,
        "deltaCovered": 0,
        "deltaTotal": 0
      },
      "functions": {
        "beforeCovered": 0,
        "beforeTotal": 0,
        "afterCovered": 0,
        "afterTotal": 0,
        "deltaCovered": 0,
        "deltaTotal": 0
      }
    }
  ],
  "added": [],
  "removed": [],
  "regressions": [],
  "global": {
    "lines": {
      "beforeCovered": 0,
      "beforeTotal": 0,
      "afterCovered": 0,
      "afterTotal": 0,
      "deltaCovered": 0,
      "deltaTotal": 0
    },
    "branches": {
      "beforeCovered": 0,
      "beforeTotal": 0,
      "afterCovered": 0,
      "afterTotal": 0,
      "deltaCovered": 0,
      "deltaTotal": 0
    },
    "functions": {
      "beforeCovered": 0,
      "beforeTotal": 0,
      "afterCovered": 0,
      "afterTotal": 0,
      "deltaCovered": 0,
      "deltaTotal": 0
    }
  },
  "beforeCount": 1,
  "afterCount": 1
}
Tip
Percentages stay JSON null because the denominators are zero.
  • Diff two CI coverage snapshots
  • List paths whose line coverage fell

Avoid for

  • Parsing a JaCoCo XML file
  • Deciding whether coverage is high enough

Composable with

Safety & privacy

  • Runs without calling any external service.
  • Your payloads are never stored permanently.
  • Telemetry captures metadata only — never your payload contents.
  • We never train models on your payloads.
  • No human reviews your payloads.

Tags

analysisquality