PrioSpot (Prioritize Hotspots) is a language-agnostic hotspot engine that computes C3 (churn + complexity + coverage) and generates interactive SVG treemap reports to help you visualize and prioritize hotspots in your code.
Most teams don't prioritize Tech-debt. If at all they do, they prioritize work by intuition, noisy bug reports, or whoever shouts loudest. That misses hidden risk.
PrioSpot helps you answer:
- Which files are most likely to hurt us next?
- Where should we spend refactoring/testing effort first?
- Which hotspots are risky because of low coverage, high complexity, and frequent churn together?
Why this is useful:
- Focuses engineering effort on high-risk code paths instead of broad, low-impact cleanup
- Makes refactoring prioritization objective and repeatable
- Gives a shared visual language for product, QA, and engineering discussions
- Works across large multi-module repositories with one consolidated view
- JDK 17+
- Gradle 8.10+ (or use wrapper)
plugins {
kotlin("jvm") version "2.0.21"
id("io.specmatic.priospot") version "1.0.0"
}
priospot {
projectName.set("sample-kotlin-service")
projectVersion.set("1.2.0")
churnDays.set(30)
outputDir.set(layout.buildDirectory.dir("reports/priospot"))
}Run:
./gradlew priospotNotes:
- If
sourceRoots,coverageReports, orcomplexityReportsare not configured, the Gradle plugin auto-discovers submodule defaults where present:src/main/kotlin,src/test/kotlinbuild/reports/kover/report.xmlbuild/reports/detekt/detekt.xml
- Missing configured coverage/complexity report files are treated as warnings; unmatched files use defaults:
- coverage defaults to
0/1for non-test sources - coverage defaults to
1/1forsrc/test/**sources - complexity is derived from Kotlin source when report entries are missing; if source-derived complexity is unavailable, defaults to
MAX-CCN=1000
- coverage defaults to
Optional explicit override (when defaults do not fit your build):
priospot {
sourceRoots.set(listOf("src/main/kotlin", "src/test/kotlin"))
coverageReports.set(listOf("build/reports/kover/report.xml"))
complexityReports.set(listOf("build/reports/detekt/detekt.xml"))
coverageTask.set("koverXmlReport")
complexityTask.set("detekt")
}PrioSpot accepts JaCoCo XML reports. If you use the JaCoCo plugin, point PrioSpot to the JaCoCo XML output and (optionally) make priospot depend on jacocoTestReport.
plugins {
kotlin("jvm") version "2.0.21"
jacoco
id("io.specmatic.priospot") version "1.0.0"
}
tasks.jacocoTestReport {
reports {
xml.required.set(true)
html.required.set(false)
csv.required.set(false)
}
}
priospot {
projectName.set("sample-kotlin-service")
sourceRoots.set(listOf("src/main/kotlin", "src/test/kotlin"))
coverageReports.set(listOf("build/reports/jacoco/test/jacocoTestReport.xml"))
complexityReports.set(listOf("build/reports/detekt/detekt.xml"))
coverageTask.set("jacocoTestReport")
complexityTask.set("detekt")
}Run:
./gradlew test jacocoTestReport priospotNotes:
- Auto-discovery currently defaults to Kover (
build/reports/kover/report.xml), so JaCoCo users should setcoverageReportsexplicitly. - In multi-module builds, provide all JaCoCo XML report paths via
coverageReports.
Expected outputs in build/reports/priospot:
priospot.jsonpriospot-interactive-treemap.svgcoverage-interactive-treemap.svgcomplexity-interactive-treemap.svgchurn-interactive-treemap.svg
Download the CLI from either:
- Maven Central: https://search.maven.org/artifact/io.specmatic.priospot/cli
- GitHub Releases: https://github.com/specmatic/priospot/releases
From Maven Central:
java -jar priospot.jar --helpA Docker image is also published with releases. Use the image/tag from the release notes and run it by mounting your repository:
docker run --rm \
-v "$PWD:/usr/src/app" \
specmatic/priospot \
analyze \
--project-name sample \
--source-roots src/main/kotlin \
--coverage-report build/reports/kover/report.xml \
--complexity-report build/reports/detekt/detekt.xml \
--output-json build/reports/priospot/priospot.jsonSupported keys (for host integrations):
projectNameprojectVersionbaseNamespace(optional)sourceRootscoverageReportscomplexityReportschurnDayschurnLog(optional)outputDiremitCompatibilityXml(default false)deterministicTimestamp(optional)coverageTask(optional)complexityTask(optional)defaultCoverageNumerator(optional, default0.0)defaultCoverageDenominator(optional, default1.0)defaultMaxCcn(optional, default1000)
- File box area is proportional to file
NCSS - No in-box labels by default (better density at scale); names are shown on hover tooltips
- Click highlights selected file, full parent package chain, and module boundary
- Right panel shows selected file path, primary metric, and all file metrics
- Checkbox in right panel toggles
Show test classes; when unchecked, treemap re-renders using only non-test files (src/test/**excluded) - Bottom-right legend explains colors for each report type (
priospot,coverage,complexity,churn)
Use the fast sample project outputs:
assets/priospot-interactive-treemap.svgassets/coverage-interactive-treemap.svgassets/complexity-interactive-treemap.svgassets/churn-interactive-treemap.svg
What "problem" looks like:
- Large box (high NCSS) + red/black in PrioSpot
- Red in coverage treemap (low coverage)
- Darker red in complexity/churn treemaps (hard-to-change + frequently changing)
What "good" looks like:
- Large box that stays green/yellow in PrioSpot
- Healthy coverage color for critical large files
- Lower complexity and churn for foundational modules
How to interpret quickly:
- Start with
priospot-interactive-treemap.svg - Click the largest red/black file
- Check details panel metrics
- Cross-check same file in
coverage,complexity, andchurntreemaps - Prioritize files that are large + low coverage + high complexity + high churn
Node wrapper script:
node examples/node-wrapper/run-priospot.mjs analyze --helpCanonical schema is available at:
schema/priospot.schema.json
This section is for contributors and maintainers working on PrioSpot internals.
model: canonicalpriospot.jsonandcoverage.jsondomain modelingest-source: source file inventoryingest-churn: git/baseline churn parser and indicatorsingest-coverage: coverage normalization and mergeingest-complexity: complexity adapters and mergecompute-c3: exact C3 formula implementationreport-svg: interactive treemap SVG generatorengine: orchestration pipeline and outputsgradle-plugin: host integration exposing apriospottaskcli: optionalpriospotCLI (analyze,report)compat-xml: optional compatibilitypanopticode.xmlexporter