Coverage Diff
quality.coverage_diff
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
Non-goals
- Does not parse vendor coverage reports
- Does not set a pass or fail bar
- Does not merge overlapping shards
Properties
Capabilities
Cost & billing
Flat rate per invocation
File handling
How we handle your data
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.
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
| before | array | Yes | Before snapshot, 0 through 100001 closed path objects; runtime accepts at most 100000. |
| after | array | Yes | After snapshot, 0 through 100001 closed path objects; runtime accepts at most 100000. |
| pathMode | string | No | EXACT or SLASH_NORMALIZED; omit it for EXACT matching of the path strings as sent. |
Output schema
| Field | Type | Required | Description |
|---|---|---|---|
| pathMode | string | Yes | Path matching mode that was actually applied to both snapshots. |
| global | object | Yes | Closed aggregate line, branch and function deltas across every path in either snapshot. |
| paths | array | Yes | Per-path deltas sorted by path, 0 through 200000 closed rows. |
| added | array | Yes | Normalized paths present only after, sorted lexicographically, 0 through 100000 strings of 1 through 4096 characters. |
| removed | array | Yes | Normalized paths present only before, sorted lexicographically, 0 through 100000 strings of 1 through 4096 characters. |
| regressions | array | Yes | Line-coverage drops sorted by magnitude then path, 0 through 100000 closed {path, metric, beforePercentage, afterPercentage, magnitudePp} objects. |
| beforeCount | integer | Yes | How many distinct before paths were compared. |
| afterCount | integer | Yes | How many distinct after paths were compared. |
API contract
POST /v1/executecurl -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}]}}'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
| Code | HTTP | Retryable | Description |
|---|---|---|---|
| VALIDATION_ERROR | 400 | No | The request payload failed schema validation. |
| UNAUTHORIZED | 401 | No | Missing or invalid API key. |
| SKILL_NOT_ACCESSIBLE | 403 | No | The API key is not granted access to this skill. |
| SKILL_NOT_AVAILABLE_FOR_PLAN | 403 | No | This skill is not included in your current plan. |
| PLAN_ELIGIBILITY_UNAVAILABLE | 503 | Yes | Plan eligibility could not be decided. Retry after backoff. |
| SKILL_NOT_FOUND | 404 | No | The requested skill or version does not exist. |
| TENANT_RATE_LIMITED | 429 | Yes | Request rate limit exceeded. Retry after backoff. |
| QUOTA_EXCEEDED | 429 | Yes | Plan quota exhausted. Retryable once the quota period resets. |
| EXECUTION_TIMEOUT | 504 | Yes | Execution exceeded the allowed time budget. |
| COVERAGE_DIFF_INVALID | 400 | No | The request payload failed this skill's input validation. |
| COVERAGE_DIFF_PATH_COLLISION | 400 | No | The request payload failed this skill's input validation. |
| COVERAGE_DIFF_LIMIT_EXCEEDED | 429 | No | A size, quota, rate, or time limit was exceeded. |
Other limits
| Limit | Value |
|---|---|
| Recommended inline bytes | 32 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)
{
"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
{
"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
}
]
}{
"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
}A unit with total zero reports JSON null percentages, never NaN
{
"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
}
]
}{
"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
}Recommended use cases
- Diff two CI coverage snapshots
- List paths whose line coverage fell
Avoid for
- Parsing a JaCoCo XML file
- Deciding whether coverage is high enough
Related skills
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.