JSON output¶
--json writes the report to stdout; --output-json <file> writes it to a
file; --server POSTs it (see Shipping reports to a server). A JSON schema for validation
lives at docs/json-schema.json.
Structure¶
{
"timestamp": "2026-05-30T09:12:50",
"hostname": "...",
"version": "0.0.3",
"config_file": "policy.json",
"overall_status": "passed",
"data_consistent": true,
"file_check": { "...": "..." },
"process_check": { "...": "..." },
"port_check": { "...": "..." },
"filesystem_check": { "...": "..." },
"memory": {
"total_kb": 16316248, "available_kb": 9912344, "available_pct": 60,
"slab_kb": 524288, "slab_unreclaimable_kb": 262144,
"slab": { "allocator": "slub", "slabinfo_mode": "0400", "caches": 137,
"reported_kb": 520100, "freelist_hardened": true,
"freelist_random": true, "slub_debug": false,
"top_caches": [ { "name": "dentry", "kb": 61440, "objs": 320000, "objsize": 192 } ] },
"consistency": { "...": "..." }
},
"trace": {
"backend": "ebpf", "window_ms": 1000, "total": 48211,
"rate_per_sec": 48211, "dropped": 0, "truncated": false,
"processes_observed": 37,
"arguments": true,
"processes": [ { "pid": 812, "name": "nginx", "total": 9120,
"rate_per_sec": 9120, "classes": ["network"],
"syscalls": [ { "name": "epoll_wait", "count": 3011 } ],
"details": [ { "call": "connect",
"args": "addr=10.0.0.9:5432",
"count": 12 } ] } ]
},
"device": { "os": "Debian GNU/Linux 12", "kernel": "6.1.0", "machine_id": "..." },
"stun": { "reachable": true, "public": "[2001:db8::1]:54321", "rtt_ms": 21 },
"risk": { "score": 0, "grade": "A" },
"violations": [ ],
"violation_count": 0,
"summary": "All checks passed"
}
Metadata —
timestamp(ISO 8601),hostname,version,config_file, andtoken(when--tokenis given — identifies the source to a collector; see Shipping reports to a server).Per-domain results —
*_checkobjects carry counts (scanned / matched / unexpected), astatus(passed/failed/skipped/error) and a cross-sourceconsistencyblock.overall_status — the aggregate pass/fail, mirrored by the process exit code.
data_consistent — true when no cross-source mismatches were seen during collection (each domain reads twice and diffs).
memory — kernel memory posture: the
/proc/meminfototals, the SLAB/SLUB allocator state (flavor,/proc/slabinfopermissions, cache count, the largest caches, freelist hardening —nullwhen no kernel config was readable) and the meminfo-vs-slabinfoconsistencyblock. Any*_kbfield the kernel did not report is omitted. See Threat detection.trace — the syscall behavior sample, present when
--traceran. It gives thebackendthat operated (ornoneand anote), the window, the totals, and a profile for each process with its behaviorclassesand its loudestsyscalls. With--trace-argsthe block contains"arguments": true, and each process also getsdetails: the decoded arguments (paths, peer addresses, protection bits) with acount. Delta ships a maximum of 20 processes, 8 syscalls for each process and 10 details for each process.truncatedstates that Delta reached a limit. See Syscall behavior tracing.device — device identity (OS, kernel, machine-id), when determinable.
stun — NAT reachability beacon (
reachable/public/rtt_ms), present when--stunis given. See Shipping reports to a server.risk — aggregate posture:
score(0–100, severity-weighted) andgrade(A–F). See Threat detection.
Violations¶
Every policy failure appends a violation:
Field |
Meaning |
|---|---|
|
|
|
|
|
human-readable explanation |
|
the affected item (e.g. |
|
the policy value vs. what was observed (optional) |
|
MITRE ATT&CK technique id (e.g. |
Monitor stream¶
In monitor mode (Continuous monitoring) --json emits one compact NDJSON object per
cycle instead of a full report:
{"cycle":2,"timestamp":"...","checks_passed":true,"baseline":false,
"added":["port:4444/tcp/LISTEN"],"removed":[],
"anomalies":["conn_established=412 (z=+5.3)"],
"stun":{"reachable":true,"public":"[2001:db8::1]:54321","rtt_ms":21}}
checks_passed reflects the policy; added / removed are the temporal
drift in feature-key form.