SIS CLI
Batch & Campaign Investigation Guide
These public operator recipes scan directories, group files by structure and compare/correlate saved reports. They are distinct from single-sample queries and do not claim exhaustive coverage of every corpus operation.
Capture reports
sis scan intake --glob '*.html' --format jsonl > summaries.jsonl
sis query findings --path intake --glob '*.html' --format jsonl
Directory scan --format jsonl currently emits summary entries, not full reports. Its findings mode emits path/finding envelopes. Neither is an interchangeable input for every correlation/diff reader; query JSONL is also a projection. Some readers skip summary rows rather than fail, so an empty result can mean the wrong capture shape.
Capture full report objects explicitly for the consumers below:
sis scan sample.html --format json > report.json
jq -c . report.json > reports.jsonl
For a directory, this Bash recipe stops on a scan or JSON-conversion failure:
set -o pipefail
for file in intake/*.html; do
[ -f "$file" ] || continue
sis scan "$file" --format json | jq -ce . || exit 1
done > reports.jsonl
Review the selected input population and refuse an unexpectedly empty capture. Other shells should implement the same checked per-file capture contract. Keep input identities, options, build/provider identity and active configuration with the capture. The raw report is a single-file artefact; preserve per-file failures rather than silently converting them to clean or empty records.
Structure hunting on live files
sis corpus cluster intake --glob '*.html' --format json
Cluster reads live files and groups their format-only asset shapes. Equal shapes describe packaging, not identical bytes, identical findings or proof of a shared campaign. See sis docs shape.
Correlate saved reports
sis corpus correlate campaign --input reports.jsonl --out campaigns.json
sis corpus correlate findings --input reports.jsonl --out finding-clusters.json
sis corpus correlate chains --input reports.jsonl --format json
sis corpus correlate iocs --input ioc-reports.jsonl --format json
sis corpus correlate stats --input reports.jsonl --format json
--input is required; it is not a positional argument. For the IOC example, ioc-reports.jsonl is a full-report capture with recorded IOC metadata; the current consumer reads selected URI/stager/launch metadata, not every URL in document text. An ordinary capture can legitimately have no eligible IOCs. These commands consume report JSONL rather than scanning the original files again. Campaign, chain, IOC and finding grouping are different projections. Shared infrastructure or packaging is an investigative lead, not proof that sources share intent or authorship. Inspect representative samples and evidence before acting on a cohort.
Compare two captures
# Produce before.jsonl and after.jsonl using the full-report capture above.
sis corpus diff before.jsonl after.jsonl --format json
sis corpus diff before.jsonl after.jsonl --verdict-only --format json
The first diff compares findings; --verdict-only projects verdict changes. Hold the population, input identities and scan conditions constant to attribute a change to an analyser update. Different configurations/builds or unresolved per-file failures are comparison limits, not evidence of regression or improvement by themselves. Frozen metric reproducibility is a separate contract from replaying a whole analysis run.
Drill into one result
sis query findings --from-report report.json --format json
sis query findings sample.html --format json
sis explain members sample.html --json
Use a single-file report for --from-report, not a whole JSONL capture. The live query and explanation reanalyse the file. Check their resolved posture and any difference from the original run.
Related guides
sis docs scan— capture formats and single-file gatessis docs query— saved versus live query scopesis docs investigate— finding IDs and evidence review