Skip to content

Understand results and scores

Scores help you order your work. When deciding what to do, always consider the observed version, signal source, and repository context alongside the score.

Guide home.

Partial manifest scan behavior verified on October 6, 2026.

Applications and source-scoped results were verified on October 10, 2026. Overview defaults to Production. Findings, Update queue and Inventory use the same application/environment scopes and exact source provenance. Manage applications defines sharing, posture history, local exclusions and the three-day source grace period.

Source-based current posture requires complete coverage. An incomplete new scan is retained as evidence and cannot publish a partial healthy score. A repository that only exceeds the manifest or depth safety ceiling is still complete coverage: Perpensa publishes the manifests it kept and shows an information note. The historical repository workflows described later retain their own partial scan records; those records do not become current application coverage.

A finding links an observed dependency to a vulnerability advisory. Its identifier may be a CVE or an identifier from another source; other identifiers of the same advisory are kept with it.

An update proposes moving from one version to another. It may address several findings or represent a version update with no associated finding. The absence of an update does not make a finding disappear.

Perpensa does not open pull requests or apply updates. Changing the dependency in your repository, deploying it, and the finding disappearing after a new scan are separate steps to verify.

Base images in a repository or application shows Dockerfile references, file/line/stage, and endoflife.date support evidence. An ARG default is a scanned value that CI can override. These checks do not inspect image packages or find image CVEs, and they do not change vulnerability risk scores.

The repository panel appears below the findings summary, before Stack & manifests and Recent scans. Each image shows its reference without the digest, branch, severity when relevant, and security-support dates for its recognized cycles. Open Details to see the complete reference, including its digest, Dockerfile locations, stages, ARG caveats, checks and source links. Unknown and stale support information remains visible while these details are closed.

  • High: reference security support has ended. Base image priorities in the update queue groups affected uses by product and release cycle, such as Debian 11. Expand it to see images, repositories, refs and locations: Python and Node images based on Bullseye share the Debian 11 entry.
  • Medium: active support ended while reference security support remains, or security support ends within 180 UTC calendar days, inclusive. A moving latest tag is also medium. These signals stay on repository/application pages.
  • Low: a floating version or release alias without a digest.
  • Info: no SHA-256 digest or EOL not verified. Missing a digest does not increase priority or alert counts; its explanation remains in the detail.

The same support verification is available on all plans. Application pages retain their existing plan requirements. Unknown private images, cycles or distribution versions remain unverified; a runtime’s support date does not prove that every package in its image is maintained. Debian uses the LTS end; Ubuntu uses reference Maintenance & Security Support. Commercial ELTS and ESM / Ubuntu Pro coverage is not presumed.

Each recognized cycle links to its source and shows the product and version cycle. Security support ends YYYY-MM-DD is the security-support end date for that cycle, not the date the evidence was retrieved. If no such date is available, it shows Security support end date unknown; an active-support end date is not substituted.

If support information cannot be refreshed, earlier evidence keeps its known support end date and is marked stale. Without usable evidence, the page says EOL not verified. Run a scan to refresh this information; opening the page does not refresh it. An unavailable support source does not prevent the vulnerability check from completing.

Display Meaning Key limitation
Severity (critical, high, medium, low, info) Category representing severity It does not determine the final queue order on its own
CVSS Technical severity score out of 10 The displayed value is not always an official value extracted from the advisory
EPSS Estimated probability of a CVE being exploited in the next 30 days, displayed as a percentage It is not the probability that your own system will be compromised
CISA KEV Indicates inclusion in the catalog of vulnerabilities known to be exploited No badge does not guarantee no exploitation
Public exploit Exploitation signal available in the data This signal comes from KEV, not from an independent inventory of all public exploits
Reachability Signal about whether vulnerable code can be reached unknown means this has not been established
Risk score Composite score out of 100; a higher number increases the base priority It is neither a percentage of real-world risk nor a certification
Effective priority, AI badge Priority used after a priority adjustment A recommendation still requires human review

General definitions of CVSS and EPSS are published by FIRST. The KEV catalog is maintained by CISA.

Advisory sources and identifiers (OSV, GHSA, CVE, ENISA EUVD)

Section titled “Advisory sources and identifiers (OSV, GHSA, CVE, ENISA EUVD)”

Perpensa matches installed package versions against OSV, which aggregates ecosystem advisories including the GitHub Advisory Database (GHSA-*), ecosystem trackers (PYSEC-*, RUSTSEC-*, GO-*), and CVE (CVE-*) records. When an upstream advisory includes an identifier or reference from the ENISA European Union Vulnerability Database (EUVD) (EUVD-YYYY-NNNN), Perpensa keeps the EUVD-* identifier among the finding’s identifiers; which identifier is shown and linked depends on the primary identifier and the available aliases. An EUVD link points directly to https://euvd.enisa.europa.eu/vulnerability/EUVD-YYYY-NNNN, like the cve.org and GitHub Advisories links, for European compliance workflows (such as NIS2 and the Cyber Resilience Act). Exploitation signals from FIRST EPSS and CISA KEV are enriched across all CVE-* identifiers attached to the advisory or its aliases.

Vulnerability advisories include EPSS and KEV when available. Opening a details page does not immediately refresh every signal. Check the scan date and source advisory before acting; the scan date is not the advisory’s publication date.

If a source is unavailable, earlier values may be retained. Without a usable value, EPSS may remain zero and KEV false. That stored false is not a verified absence: triage Monitor still requires a successful KEV catalog lookup. EPSS is also rounded to a whole percentage on the finding details page: a small positive value may appear as 0%. Do not interpret this display as “no possibility of exploitation.” The source or retrieval date may not be shown for every value. Check the source advisory when you need to verify a value.

A displayed CVSS value of 7.0 can be a default rather than the CVE’s official score. Severity is a separate indicator. Verify the source advisory before reporting a displayed CVSS score as official.

Reachability remains unknown by default in the current scan. A direct dependency does not prove that vulnerable code is called. reachable and unreachable require an explicit signal; example data in documentation is not an analysis of your application.

Finally, No fix yet means the details page has no usable fixed version to display. It proves neither that no fix exists nor that any newer version fixes the issue. First seen is the first recorded observation, not the CVE’s publication date.

The risk score is the sum of the contributions below, rounded to an integer and clamped between 0 and 100. Each contribution is weight × factor value. Finding details show the risk value and Signals; update details show Risk score.

Factor Weight Factor value out of 100 in the current calculation
Base severity 35% Critical 95; high 75; medium 55; low 30; info 10
EPSS 20% Probability between 0 and 1, scaled to 100 and rounded
KEV / public exploit 15% KEV 100; otherwise public exploit 85; otherwise 10
Reachability 15% Reachable 90; unknown 75; unreachable 20
Direct dependency 5% Direct 100; transitive 20
Blast radius 5% Supplied value, or 60 by default
Update lag 5% Fix age / 90 days × 100, rounded and capped at 100; default age of 14 days

A direct dependency is declared by the project; a transitive dependency is brought in by another dependency. Unknown reachability deliberately keeps a high contribution: uncertainty should not make risk appear negligible.

The current finding scoring flow uses these defaults for blast radius and age. The labels Org-wide dependents and Days since fix published therefore do not guarantee an actual calculation of your scope or the fix’s age. Similarly, CVSS-normalized refers here to the severity category table above, not to multiplying CVSS directly by ten.

For a direct dependency with high severity, 20% EPSS, no exploit signal, unknown reachability, and default values:

Severity 0.35 × 75 = 26.25
EPSS 0.20 × 20 = 4.00
Exploit 0.15 × 10 = 1.50
Reachability 0.15 × 75 = 11.25
Direct 0.05 ×100 = 5.00
Blast radius 0.05 × 60 = 3.00
Update lag 0.05 × 16 = 0.80
Total = 51.80 → score 52/100

A score of 52 does not mean “a 52% chance of being attacked.” With the other factors unchanged, a KEV signal replaces the exploit contribution of 1.50 with 15.00: the score becomes 65. This is a teaching example, not an observation of a real CVE.

Update queue and Findings show a rules-based recommendation with the rule’s reason. It is available on Starter, Pro and Team without an AI key. Open the details for the full explanation and unknown signals; list tags also expose the reason.

Recommendation Meaning
Fix now Confirmed or assumed production with CISA KEV or EPSS at least 10%. Without a verified corrective version, examine immediate mitigation.
Plan Schedule review/remediation, including KEV or EPSS at least 10% on dev/test-only dependencies. Missing inputs can also require review.
Monitor Defer by the rule: dev/test with no KEV and known EPSS below 10%; or low production severity with EPSS below 1%; or medium transitive production finding with no known fix and EPSS below 1%.

Monitor does not accept or resolve a finding. Use the separate local Accept risk decision to exclude it from one application environment. No recommendation changes your repository or performs another action.

Only confirmed dev scope or an exclusively non-production application environment reduces production urgency. Otherwise the reason states Production assumed, context unknown. Optional or unknown scope is not proof of dev-only usage. Application declarations are available on every plan. An explicit application environment supplies its own Production/non-production context.

KEV takes precedence over ordinary backlog rules and a disputed CVE. Explicit VEX not_affected or a rejected CVE are policy exceptions, but VEX and CVE status are currently unknown in live results. They are never inferred from reachability or free text. Historical EPSS zero cannot establish a backlog rule because the signal may have been unavailable. Triage uses the severity band when numeric CVSS is unverified and reports that limitation in details.

The default Priority order puts Fix now before Plan before Monitor, then uses the existing numeric rank and base risk within each category. The displayed risk score and breakdown keep their meaning. Alerts and digests retain their existing numeric ordering and selection.

This section was updated on October 6, 2026 for the Perpensa Rank indicator.

Rules set the category. Perpensa Rank refines the order. Pro and Team include triage for all open findings in active inventories, shared by application sources and actual environment profiles. Starter uses rules only. Fix now → Plan → Monitor always takes precedence.

The finding rank starts at the risk score plus declared context, bounded to 0–100, then receives a refinement between −30 and +30, again bounded to 0–100. The stored risk score stays unchanged. An update takes the highest finding rank in its most urgent category; context is not added a second time.

Perpensa AI accepts a result only when its strongest level has at least 70% probability weight. This weight is not an accuracy guarantee. Unknown facts never justify a lower rank. Once a result is accepted, verified ended base-image support sets a floor of +5 when active support has ended, or +15 when security support has ended. The floor is inside the −30 to +30 adjustment and applies even when the accepted adjustment would otherwise be lower or zero. An accepted result can stay at 0 when that support has not ended, so the number may not move. A result that is not accepted keeps adjustment 0 and stays ranked by rules. The floor does not apply to it.

An advisory can record an impact class, such as cross-site scripting or a sandbox escape, together with the conditions that source recorded. The finding shows that class as a fact, including when no class is established. If sources disagree, every reported class stays visible. Disagreement, and a class that is not established, do not lower the rank. No impact class outranks another by itself. On Pro and Team, Perpensa Rank can weigh those recorded facts inside the existing refinement. The risk score stays the same, and Fix now still comes before Plan and Monitor.

Reviews are reused while their facts and review settings stay unchanged. When data changes, rules set the order while the new review is in progress. On Pro and Team, a message such as Perpensa AI is still reviewing 2 findings. Rules set the order meanwhile. shows how many findings are still being reviewed. Each finding is counted once, even if it has several contexts under review. The message disappears when no findings are being reviewed. Reviews delayed by budgets or temporary errors resume automatically without a rescan.

The Perpensa Rank badge appears beside the priority in Findings, Update queue, update details and Overview when a current refinement is accepted on Pro or Team. Its tooltip says Ranked by Perpensa AI: rules set the category (Fix now / Plan / Monitor), and Perpensa Rank refines the order within it. An accepted refinement can leave the rank unchanged. The badge does not promise that the priority is correct.

The badge is absent on Starter, while Perpensa AI review is in progress, when Perpensa AI reviewed the item and kept this order, and for outdated decisions. An update can show the badge while other linked findings are still processing: an accepted finding must contribute to the highest rank in the update’s most urgent category. An accepted finding in another category or below that highest rank is insufficient.

Settings → AI copilot → LLM explanations and Q&A controls prose only. Turning it off preserves included triage. Choose Explain priority or ask about a finding/update to request prose. Your configured personal key is selected first; otherwise the explicitly configured service key is used. Failure of the selected key returns a rules-based explanation without switching keys.

Free-text questions go as entered only to the selected explanation provider, never to the scoring engine. Do not include information you do not want sent. Perpensa does not keep your questions or answers after the session. Provider retention depends on its terms. Replies cite available public sources, recognize missing facts, and never change state or execute actions.

Public watches groups analyze an upstream product; their row count is not the raw finding count. Base-image EOL rows and digest ranking keep their existing contracts.

  • “No findings means no risk”: first check inventory, sources, coverage, reference, scan status, and filters.
  • “A lower score requires no action”: consider your exposure, policies, and the information in the advisory.
  • “The alert disappeared, so it is fixed”: suppression may remove an entry from the queue without changing the version in use.

Next: Remediate a vulnerability and verify the fix.

Perpensa discovers dependency files from the repository tree, then keeps the ones it can analyze.

  • Each file is ranked as 100 minus its depth, plus a bonus for lockfiles. A lockfile several directories down can therefore rank ahead of a root package.json. Public watches add a further preference for a file at the repository root. In the same directory, the lockfile wins and the direct manifest beside it is not scanned (package-lock.json over package.json, and the same idea for Composer, Go, Maven, pip, and NuGet).
  • Dependency and test directories are skipped: node_modules, vendor, testdata, __fixtures__, and fixtures.
  • Three safety ceilings apply: 256 manifests, depth 10, and 20,000 tree entries or 200 tree pages (whichever comes first, after root and top-level directory coverage). Reaching any of these ceilings still publishes the manifests that were kept. The application and the repository scan show an information note that the scan covered the main manifests up to that ceiling. The source is not marked failed, and the published findings, queue, and inventory stay current. A ceiling that kept no manifest does not publish: previous results stay in place.
  • On GitLab, when the server keeps rate-limiting the repository read after the root and top-level directories were read, Perpensa publishes the manifests read so far with a separate information note: “GitLab rate-limited the repository read”. Deeper manifests not reached in that scan are left out of it. If the same repository keeps getting this note, the GitLab token’s rate limit is too low for the repository’s size. A rate limit before the root and top-level directories are read, or one that left no manifest, does not publish: the scan waits and retries, and previous results stay in place.
  • On GitLab, when part of the repository listing keeps failing (timeouts or server errors that persist after retries) after the root and top-level directories were read, Perpensa publishes the manifests read so far with a separate information note: “GitLab kept failing to return part of the repository listing”. Deeper manifests not reached in that scan are left out of it. A failure before the root and top-level directories are read, or one that left no manifest, does not publish, and previous results stay in place.
  • A truncated listing, an unavailable tree, or a file that could not be read is a real read failure. Those scans stay incomplete and do not replace a healthy result. The same applies when analysis of a kept manifest fails (files_inaccessible, manifests_uncovered, and the other blocking gaps), even if a ceiling was also reached.

A Partial scan means at least one manifest was scanned while another could not be read or understood. Open the scan details to see the affected paths. Results from readable manifests are updated. Previous packages and findings from the unreadable paths remain, so those paths still need a successful scan. A safety ceiling (256 manifests, depth 10, or 20,000 tree entries / 200 tree pages) is not a partial scan: those results publish, with the information note described above. Public watches have a separate budget of 100 useful dependency files. The 101st useful file stays uncovered. That scan is Partial and keeps the previous rows for the files it did not read. That budget is separate from the 256-manifest ceiling. Unpinned Python requirements are one example: Perpensa cannot check exact versions from them. If every required manifest fails, the scan fails and keeps the previous data.

A valid empty npm lockfile is different: it confirms that its path has no installed dependencies. Its old packages can be removed after the normal scan checks. A partial scan does not confirm full coverage of the tracked ref.

The latest attempt and latest successful result have separate dates. After a failed attempt, displayed results still come from the dated successful scan. After Partial, findings on uncovered paths may come from even earlier scans; the partial scan date does not make every finding current. The last complete scan date is shown only when it is known for that reference.

Waiting for GitHub means requests are temporarily limited. Perpensa queues an automatic retry around the displayed local time; it may be postponed again. It does not publish a new successful result while waiting. A failure with no previous success has no results to display. Use Copy details for support for a repeated failure, then contact support from Help.

If OSV is disabled or cannot cover the inventory, the scan reports incomplete advisory matching. Existing findings remain until a complete real scan can reconcile them. Docker images are excluded from OSV package matching; their support lifecycle signals use their own source.

The General settings name and slug are read-only. Subscription changes use the configured billing flow. An AI suggestion to create a ticket reports that ticket creation is unavailable; create it directly in your issue tracker.

On Overview, Why this rank? opens the selected update’s explanation in its application and environment. Fix now uses stacked rows on small screens. Perpensa Rank badges show a star and an indigo border when an accepted ranking refinement is available. Their tooltip reads Ranked by Perpensa AI and explains how the refinement relates to Fix now, Plan and Monitor.