Read/write the state sidecar for mix mob.security_scan.log.
The state file is a small JSON document that records the last-known set of findings and when each was first seen. Diff computation between runs depends on it.
Default location: .security_scan/state.json at the project root.
Should be checked into git so a fresh CI run knows what the
prior baseline was — without it, every scheduled run reports every
finding as 'new' and the changelog becomes useless.
Schema
{
"version": 1,
"last_run_at": "2026-05-07T05:30:00Z",
"findings": [
{
"key": "EEF-CVE-2026-32689|phoenix|1.8.5",
"id": "EEF-CVE-2026-32689",
"severity": "high",
"package": "phoenix",
"version": "1.8.5",
"fixed_in": "1.7.22",
"title": "...",
"url": "...",
"source": "osv_scanner",
"layer": "hex_deps",
"first_seen_at": "2026-05-07T05:30:00Z"
}
]
}
Summary
Types
Finding-as-stored: same fields as Finding plus key + first_seen_at.
Dedup key derived from id|package|version.
Loaded state map.
Functions
Empty initial state for first-time scans.
Build the next state from the current report and a Diff (which
carries first_seen_at for findings that already existed).
Load state from a JSON file. Returns empty/0 if the file is missing.
Encode + write the given state to disk. Creates parent dirs as needed.
Types
@type entry() :: %{ key: key(), id: String.t() | nil, severity: atom(), package: String.t() | nil, version: String.t() | nil, fixed_in: String.t() | nil, title: String.t() | nil, url: String.t() | nil, source: atom() | nil, layer: atom() | nil, first_seen_at: DateTime.t() | String.t() }
Finding-as-stored: same fields as Finding plus key + first_seen_at.
@type key() :: String.t()
Dedup key derived from id|package|version.
@type state() :: %{ version: integer(), last_run_at: DateTime.t() | nil, findings: [entry()] }
Loaded state map.
Functions
@spec empty() :: state()
Empty initial state for first-time scans.
@spec from_report( MobDev.SecurityScan.Report.t(), MobDev.SecurityScan.Diff.t(), DateTime.t() ) :: state()
Build the next state from the current report and a Diff (which
carries first_seen_at for findings that already existed).
Load state from a JSON file. Returns empty/0 if the file is missing.
Encode + write the given state to disk. Creates parent dirs as needed.