Skip to content
Back to skills

Harness Report Parsing

ASecurity

Parse harness output (Surefire/Failsafe XML, JaCoCo XML, PIT XML, Checkstyle/SpotBugs XML, OpenAPI diff JSON, dependency-check JSON) into a single structured summary. Use when writing `07-validation-report.md` or when a CI run failed and the agent must explain why.

  • 62 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
developmentgojavagitapisecurity

Works with

  • api

Security analysis

A100/100

Scanned November 7, 2026

npx -y skills add loiane/specs-driven-development-spring-angular --skill harness-report-parsing --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Harness Report Parsing?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Harness Report Parsing
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/loiane-harness-report-parsing/badge)](https://www.skillsdirectory.com/skills/loiane-harness-report-parsing)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: harness-report-parsing
description: Parse harness output (Surefire/Failsafe XML, JaCoCo XML, PIT XML, Checkstyle/SpotBugs XML, OpenAPI diff JSON, dependency-check JSON) into a single structured summary. Use when writing `07-validation-report.md` or when a CI run failed and the agent must explain why.
when_to_use:
  - Phase 6 (Validate) — `/validate` command runs the harness and parses every report.
  - Diagnosing a CI failure from log output.
authoritative_references:
  - https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report.xsd
  - https://www.jacoco.org/jacoco/trunk/coverage/report.dtd
---

# Harness report parsing

## Input file map

| Layer | Path | Format |
|---|---|---|
| Spotless | `target/spotless/` (markers) | exit code |
| Checkstyle | `target/checkstyle-result.xml` | XML |
| SpotBugs | `target/spotbugsXml.xml` | XML |
| Error Prone | compiler stderr | text |
| ArchUnit | `target/surefire-reports/.../ArchitectureTest.xml` | Surefire XML |
| ArchUnit | `target/surefire-reports/.../ArchitectureTest.xml` | Surefire XML |
| Surefire (unit) | `target/surefire-reports/TEST-*.xml` | Surefire XML |
| Failsafe (IT) | `target/failsafe-reports/TEST-*.xml` | Surefire XML |
| JaCoCo | `target/site/jacoco/jacoco.xml` | JaCoCo XML |
| PIT | `target/pit-reports/mutations.xml` | PIT XML |
| OpenAPI diff | `target/openapi-diff.json` | JSON |
| Dependency-check | `target/dependency-check-report.json` | JSON |

## Output shape (`harness-summary.json`)

`.github/scripts/harness.sh --report` prints a single JSON document on stdout (build output goes to stderr) and also writes it to `target/harness-summary.json`. The script exits 0 when every gate is `pass` or `skipped`, 1 when any gate fails, and 2 when a prerequisite is missing.

```json
{
  "started_at": "2026-04-18T10:30:00Z",
  "finished_at": "2026-04-18T10:38:42Z",
  "git_sha": "abc1234",
  "stack": { "...": "output of detect-stack.sh" },
  "gates": {
    "build":    { "status": "pass", "exit_code": 0 },
    "unit":     { "status": "pass", "tests": 412, "failures": 0, "errors": 0, "skipped": 2 },
    "it":       { "status": "pass", "tests": 47, "failures": 0, "errors": 0, "skipped": 0 },
    "coverage": { "status": "pass", "line": 0.93, "branch": 0.91 },
    "mutation": { "status": "pass", "exit_code": 0, "kill_rate": 0.84, "killed": 84, "survived": 16, "no_coverage": 0, "total": 100 }
  },
  "overall": "pass"
}
```

- `build` is the result of `mvn verify`, which runs the format, compile, static-analysis, architecture and security layers. When it fails, read those layers' own reports (table above) to say which one broke.
- `mutation` is `skipped` when PIT is not configured or the build failed, and `fail` when PIT exits non-zero or writes no report.
- The contract (`target/openapi-diff.json`) and security (`target/dependency-check-report.json`) layers are not summarised here; parse their reports directly.
- New-code coverage comes from `.github/scripts/check-new-code-coverage.sh` (`target/new-code-coverage.json`), not from this summary.

## Parsing rules

- A **missing report** for a layer the project has configured = `error`, not `pass`.
- A **report with parse errors** = `error`.
- A test marked `skipped` with no `# DisabledReason:` comment in source = `error` (enforced by Checkstyle rule `RegexpSinglelineJava` looking for `@Disabled` without preceding comment).

## Surefire/Failsafe XML quick recipe

```xpath
/testsuite/@tests        -> total
/testsuite/@failures     -> assertion failures
/testsuite/@errors       -> exceptions
/testsuite/@skipped      -> skipped
/testsuite/testcase[skipped]/@name  -> list skipped tests
```

## JaCoCo new-code calculation

1. `git diff --unified=0 $(git merge-base origin/main HEAD) -- 'src/main/java/*.java'` (working tree, so uncommitted changes count) plus untracked files → list of `(file, line-range)`.
2. For each file, read `jacoco.xml` `<class name="...">/<sourcefilename>` matching.
3. Inside `<line nr="N" mi="X" ci="Y" mb="A" cb="B"/>`:
   - `mi` = missed instructions
   - `ci` = covered instructions
   - A line counts as "covered" if `ci > 0`. "Missed" if `mi > 0` and `ci == 0`.
4. New-code coverage = covered ÷ (covered + missed) over diff lines only. Lines with no `<line>` entry (comments, blank lines, imports) are not executable and are ignored. No executable new lines = `pass`.

## PIT mutants in changed packages

```xpath
/mutations/mutation[@status='SURVIVED' and contains(mutatedClass, 'changed.package')]
```

`changed.package` is derived by mapping diff file paths → fully qualified class names.

## Anti-patterns

- Emitting `pass` because the report file is empty (it's not — failures with 0 tests is a misconfiguration).
- Counting `skipped` as `pass`.
- Aggregating across modules without per-module breakdown.
- Hiding errors as warnings.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.