Rescans and fix verification
How a rescan decides a finding is fixed, what may change a status, and how statuses travel to ServiceNow and back.
A developer fixes three findings and asks for a rescan. Two questions follow, and they are not the same question: are the old findings gone? and did the fix introduce anything new? This page covers how ScanSuite answers both, and how a finding's status moves without anyone editing it by hand.
Absence is not a fix
The obvious design — close anything the rescan did not report — is wrong, and it is worth knowing why before trusting any of what follows. Detection is a model call. A scan that analysed a file and said nothing may mean the defect is gone, or may mean the model missed it this time. Closing a real vulnerability because a scan went quiet is the worst failure this system could have.
So silence is treated as a question, never an answer. When a scan covers a file but no longer reports a finding in it, a separate verification agent opens the current source and decides. A finding is resolved only when that agent can point at the code that fixed it.
Two facts make this safe. A scan only draws conclusions about files it actually analysed — a file that was skipped or failed is not covered, so findings in it are untouched. And only two verdicts close a finding: fixed and file_removed. Everything else leaves it open.
Two ways to rescan
| Mode | What it does |
|---|---|
| Verify Fixes | You select the findings you believe are fixed. ScanSuite resolves them to their files and scans only those, then verifies exactly the findings you selected — never their neighbours. |
| Once / full scan | The whole repository is analysed. Every finding in the repository becomes eligible, which is powerful and blunt: one scan can resolve a great many findings at once. |
Both are started from the SAST scan form; Verify Fixes is also reachable straight from the findings list, so the developer ticks the rows they fixed and presses start without choosing a mode or typing a file pattern.

Prefer Verify Fixes for day-to-day remediation. It is far cheaper — a handful of files instead of a repository — and its conclusions are bounded by what the developer actually asked about. A finding sharing a file with a selected one is not reassessed, so nothing closes by accident.
What a rescan decides
After the scan finishes, every stored finding for that repository falls into exactly one of four buckets. The scan log states the counts:
| Bucket | Meaning |
|---|---|
| Confirmed | The rescan reported it again. It stays open, and its miss counter resets. |
| Covered but not reported | The file was analysed and the finding did not appear. This is the case that goes to verification. |
| Held by an analyst decision | Risk Accepted or False Positive. A scan may never move these — see below. |
| Outside this scan’s coverage | The file was not analysed. The scan says nothing about it either way. |
A finding does not go to verification on its first silent scan in every mode. The threshold depends on how strong the evidence is:
| Mode | Silent scans needed | Why |
|---|---|---|
| Verify Fixes | 1 | You asked about these findings specifically, so one silent scan is an answer. |
| Once / full scan | 1 | The whole repository was analysed, so absence means something. |
| Custom Scope, Incremental, Monitor Changes | 2 | A narrow or diff-derived scope is weaker evidence, so it has to say the same thing twice. |
Verification
Findings that reach the threshold are handed to the fix verification agent one at a time. It reads the current source at the finding's location and returns one of five verdicts:
| Verdict | Effect |
|---|---|
| fixed | Resolved. Requires file:line evidence in the current code, at medium or high confidence. |
| file_removed | Resolved. The file the finding lived in no longer exists. |
| still_present | Stays open, and the miss counter is reset. Detection lost a live defect — that failure is detection’s, and must not walk the finding toward closure one scan at a time. |
| moved | Stays open. A defect relocated by a refactor was not fixed. |
| inconclusive | Stays open. The agent could not establish either way. |
The evidence is stored on the finding and shown in its lifecycle notes, so a closure can be audited later:
Finding test-java-sast-c4d1f672fc16 closed as fixed: fixed (high confidence) |
src/main/java/com/scalesec/vulnado/User.java:39-49 shows fetch(String un) using a
PreparedStatement with the query "select * from users where username = ? limit 1",
followed by stmt.setString(1, un) and stmt.executeQuery().The agent is never shown the stored solution text. That text describes the fix someone was advised to make, and handing the model its own earlier suggestion invites it to recognise the suggestion in the code and call the job done. It gets the defect, not the prescription.
Statuses, and who may change them
| Status | What a rescan may do |
|---|---|
| Open | Assessed on every rescan. May be resolved by verification. |
| In Progress | Assessed on every rescan. May be resolved by verification. |
| Resolved | Still assessed, so a regression is visible: if a rescan detects it again the finding reopens automatically, and the stale closure evidence is cleared. |
| Risk Accepted | Never touched by a scan. |
| False Positive | Never touched by a scan. |
Risk Accepted and False Positive are decisions about a defect everyone agrees exists — a different question from whether the code still contains it. A scanner has an opinion about the code; it does not have an opinion about what your organisation decided to do. So it may not move them, in either direction.
Every automated change records how it happened. A finding closed by verification carries closure_source = scanner and its evidence; one closed by a person carries theirs. You can always tell which is which.

Turning automatic closure on
Scanner-driven closure is off by default. Enable it under Settings → Resolve findings verified as fixed. With it off, everything above still runs and is still logged — misses are counted and reported — but no status changes. That is a deliberately useful state: it lets you watch the verdicts your codebase actually produces before letting them close tickets.
A sensible rollout: leave closure off for a few rescans and read the reconciliation lines in the scan log. If the agent's verdicts match what you know about the code, turn it on and use Verify Fixes first — it only ever touches findings a developer selected, which is a much safer place to watch it work than a whole-repository scan.
Reading the scan log
The rescan narrates its own decisions, naming findings rather than counting them:
Reassessing only the 1 finding(s) this scan was asked to verify, of 1 selected.
Finding reconciliation: 0 confirmed, 1 covered but not reported (1 at or over the
1-miss threshold), 0 held by an analyst decision, 0 outside this scan’s coverage.
Verifying 1 finding(s) that this scan covered but did not report: test-java-sast-c4d1f672fc16
Finding test-java-sast-c4d1f672fc16 closed as fixed: fixed (high confidence) | ...
Fix verification: 1 closed on source-backed evidence, 0 still present, 0 left open.Deduplication is narrated the same way. When a rescan re-detects something already stored, the log says which record it resolved to and on what basis, so you can check that a merge was correct rather than trusting a count.
Sending statuses to ServiceNow, and getting them back
ScanSuite does not connect to ServiceNow. The exchange is files in both directions, which is what makes it work in environments where an outbound integration would never be approved.
- 01Export
From the Vulnerabilities page, choose Export → ServiceNow XLSX. Each row carries the finding’s stable tracking id, so ServiceNow has a key it can hold on to.
- 02Upload
Import the spreadsheet into ServiceNow using your normal process. Nothing about that step is ScanSuite-specific.
- 03Work the tickets
Your ServiceNow workflow assigns and closes them as it always has.
- 04Bring statuses back
The statuses ServiceNow set return to ScanSuite as a file, matched to findings by that same tracking id. Where they disagree with what ScanSuite believes, the difference is surfaced rather than silently overwritten.

The tracking id is what makes the round trip work. It is derived from the finding's identity — its vulnerability class, its file and the repository it belongs to — assigned once and never recomputed, so a finding keeps the same id across rescans and across releases. Two repositories that happen to share a file path are never confused for one another.
The same id appears in the scan log, in the JSON report, in the XLSX export and on the finding in the console. When a developer, a ticket and a scan log all name the same string, an argument about whether they are talking about the same thing cannot start.
Where this fits
Rescanning is the second half of the loop that Vulnerability Management describes: findings are ingested, correlated, validated and owned there, and closed here. For the scanning modes themselves, see Executing the AI-powered scan and Scheduling periodic and incremental scans.
Last reviewed 2026-08-27