Delta Report¶
The -diff flag compares two MethodAtlas scan outputs (CSV files) and reports which test methods were added, removed, or modified between the two runs. It is the primary mechanism for change-tracking, audit evidence, and CI gating on security-test coverage.
A delta report answers the regulator's recurring question: did the security-test surface of this release change relative to the previous one, and if so, where? The CSV emitted by a single scan is a snapshot; the delta turns two snapshots into a change log, which is what most compliance frameworks actually require for a release-to-release audit.
A delta is also the cheapest way to enforce a non-regression rule in CI.
Rather than scanning twice from scratch and comparing in some external
tool, you run a single methodatlas -diff before.csv after.csv, post-
process the textual output with a one-line shell pattern (see CI gating),
and either fail the build or annotate the pull request inline.
When to use this mode¶
There are four recurring situations where -diff is the right answer:
- You want to prove to an auditor that security-test coverage did not regress between two releases.
- You want to gate a CI pipeline on whether any security-relevant test was removed or reclassified.
- You want a change log of which security tests were added during a sprint or on a pull request.
- You want to detect source edits to existing security tests (requires both scans to use
-content-hash).
For the first three scenarios a regular scan with no extra flags is sufficient on both sides. The fourth — detecting whether a test body was rewritten while keeping its name and signature — is the only one that requires content hashing on both inputs; without it the delta will still detect added or removed methods but cannot tell whether an existing test was silently weakened.
How the comparison works¶
sequenceDiagram
participant A as Before scan<br/>(e.g. v1.2-scan.csv)
participant D as Delta engine<br/>(MethodAtlas -diff)
participant B as After scan<br/>(e.g. v1.3-scan.csv)
A->>D: load all rows<br/>(fqcn + method = key)
B->>D: load all rows<br/>(fqcn + method = key)
D->>D: key in A only → mark as REMOVED (-)
D->>D: key in B only → mark as ADDED (+)
D->>D: key in both → compare shared fields<br/>loc, tags, display_name, content_hash, security, ai_tags
D->>D: fields differ → mark as MODIFIED (~)
D-->>D: emit summary with counts
The two CSV files are compared using the (fqcn, method) pair as the key. Fields that are present in both files are compared; fields absent from either file (because the two scans used different flag sets) are skipped silently.
Basic usage¶
Both files must be CSV outputs produced by MethodAtlas. All other flags are
ignored when -diff is present.
Example output¶
MethodAtlas delta report
before: scan-2026-04-10.csv (scanned: 2026-04-10T09:00:00Z · 45 methods · 5 security-relevant)
after: scan-2026-04-24.csv (scanned: 2026-04-24T14:30:00Z · 47 methods · 7 security-relevant)
+ com.acme.auth.Oauth2FlowTest test_authCode
+ com.acme.auth.Oauth2FlowTest test_tokenRefresh
- com.acme.auth.LegacyAuthTest test_basicAuth
~ com.acme.crypto.AesGcmTest roundTrip_encryptDecrypt [source; security: false → true]
2 added · 1 removed · 1 modified · 42 unchanged
security-relevant: 5 → 7 (+2)
Change-type indicators¶
| Symbol | Meaning |
|---|---|
+ |
Method is new in the after scan — added since the before run |
- |
Method is absent from the after scan — removed or renamed since the before run |
~ |
Method is present in both scans but one or more fields changed |
What fields are compared¶
For each method present in both scans:
| Field | Compared when |
|---|---|
loc |
Always (lines of code in the method declaration) |
tags |
Always (JUnit @Tag annotations; order-independent) |
display_name |
Both files contain the display_name column; detects @DisplayName annotations added, removed, or renamed |
source |
Both files were produced with -content-hash; a difference means the enclosing class source was edited |
security |
Both files were produced with -ai; a flip of ai_security_relevant |
ai_tags |
Both files were produced with -ai; the AI taxonomy tag set changed |
Fields absent from either file (produced with different flag sets) are silently
skipped. You can compare a scan with -content-hash against one without it — only
the fields common to both files are compared.
Change detail notation¶
A ~ (modified) line means the method is present in both the before and after scan, but at least one field changed. The bracketed summary after the method name lists every field that changed and, where possible, the old and new values.
Reading the example from above:
This means: the content_hash changed (the source was edited — indicated by source) and the AI security classification changed from false to true. Both changes happened in the same method between the two scans.
The full set of possible bracket tokens:
| Token | Meaning |
|---|---|
source |
content_hash differs — the class source was edited since the before scan |
loc: 5 → 8 |
Lines of code in the method declaration changed (5 in before, 8 in after) |
tags |
The JUnit @Tag set changed (tags were added, removed, or renamed) |
display_name |
The @DisplayName annotation was added, removed, or its text changed |
security: false → true |
AI classification flipped from not-security-relevant to security-relevant |
security: true → false |
AI classification flipped from security-relevant to not-security-relevant (regression) |
ai_tags |
The AI taxonomy tag set changed (e.g. auth was added or removed) |
Multiple tokens are separated by semicolons. A method may appear with several changed fields at once.
Why the delta report matters in the SDLC¶
Sprint close / PR review¶
Run MethodAtlas at the start and end of a sprint (or on the base branch and the feature branch), then diff the two outputs to answer "did this sprint / this PR add, remove, or reclassify security-relevant tests?":
git stash
./methodatlas -ai -content-hash -emit-metadata src/test/java > before.csv
git stash pop
./methodatlas -ai -content-hash -emit-metadata src/test/java > after.csv
./methodatlas -diff before.csv after.csv
Regulatory evidence¶
Many security standards (PCI DSS, ISO 27001, SOC 2) require evidence that security controls are tested and that the test coverage does not regress between releases. A delta report generated at each release boundary provides a machine-readable change log of the security-test layer:
+lines prove new security tests were added alongside new features-lines must be reviewed and justified (was the test replaced or deleted?)~lines withsecurity: true → falserequire particular scrutiny — a test that was previously considered security-relevant was reclassified
Store the delta output alongside the scan CSV in your artifact repository or compliance folder.
CI gating — detecting regressions¶
A simple shell gate that fails the build if any security-relevant test is removed or reclassified away from security:
./methodatlas -diff before.csv after.csv > delta.txt
cat delta.txt
# Fail if any security-relevant test was removed
if grep -qE "^- " delta.txt; then
echo "ERROR: test methods were removed — review delta.txt"
exit 1
fi
# Fail if a security-relevant method was reclassified to non-security
if grep -qE "security: true → false" delta.txt; then
echo "ERROR: security classification regressed — review delta.txt"
exit 1
fi
Nightly scan with archiving¶
A typical CI setup stores one scan output per day and computes the delta on each run:
# .github/workflows/security-delta.yml (excerpt)
- name: Run today's scan
run: |
./methodatlas -ai -content-hash -emit-metadata \
-ai-api-key-env ANTHROPIC_API_KEY \
src/test/java > scans/$(date +%F).csv
- name: Compute delta from yesterday
run: |
YESTERDAY=$(date -d "yesterday" +%F)
if [ -f "scans/$YESTERDAY.csv" ]; then
./methodatlas -diff "scans/$YESTERDAY.csv" scans/$(date +%F).csv \
| tee delta-$(date +%F).txt
else
echo "No previous scan found; skipping delta"
fi
- name: Archive scan and delta
uses: actions/upload-artifact@v4
with:
name: security-scan-$(date +%F)
path: |
scans/$(date +%F).csv
delta-$(date +%F).txt
Combining with scan options¶
The -diff mode only consumes CSV files — it does not run a scan itself. To
produce the input files you can use any combination of scan options. For the most
informative delta, include both -content-hash (detects source edits) and -ai
(detects classification changes) in both scan runs:
# First scan (e.g. at release tag v1.2)
./methodatlas -ai -content-hash -emit-metadata \
-ai-provider anthropic \
-ai-api-key-env ANTHROPIC_API_KEY \
src/test/java > v1.2-scan.csv
# Second scan (e.g. at release tag v1.3)
./methodatlas -ai -content-hash -emit-metadata \
-ai-provider anthropic \
-ai-api-key-env ANTHROPIC_API_KEY \
src/test/java > v1.3-scan.csv
# Delta report
./methodatlas -diff v1.2-scan.csv v1.3-scan.csv
If you omit -content-hash, source changes cannot be detected; if you omit
-ai, only structural changes (method added, removed, LOC changed) will appear
in the delta.
Limitations¶
The delta engine is deliberately conservative: it reports facts it can prove from two CSV files and does not infer intent. Three limits follow from that design choice.
- Rename tracking — when a class or method is renamed, it appears as one
REMOVEDentry and oneADDEDentry. MethodAtlas does not attempt to infer renames from content-hash similarity, because content-similarity inference produces false positives that would weaken the audit signal. If your release process renames classes routinely, post-process the delta with a similarity matcher of your own. - Plain / SARIF inputs — only CSV files produced by MethodAtlas are accepted. Plain-text and SARIF outputs cannot be diffed, because they omit fields (such as the per-method content hash and the AI taxonomy tag set) that the comparison depends on.
- Exit code — the command always exits with code
0. Use shell post-processing (see the CI gating example above) to gate on specific change types. The reason for the design is that different teams care about different change types: a test-engineering team may treat anyREMOVEDas a regression, while a refactoring team may accept removals provided nosecurity: true → falsereclassification is present.
Reproducibility and audit retention¶
Because the inputs to -diff are plain CSV files, a delta is fully
reproducible: archive the two scan CSVs alongside the delta report and
any auditor can re-run the comparison years later without needing the
original codebase or even the MethodAtlas binary that produced them. In
regulated environments this property — being able to verify a historic
claim about test coverage from durable artefacts — is the reason the
delta report exists in the first place. See the Audit trail
chapter for the recommended retention layout.
See CLI reference — -diff for the flag description.