Reports & Outputs
Every Gadriel Code scan writes its results into a .security/ directory at the
root of the scanned repository. That directory is the single place to look for
everything the tool produces: the canonical machine-readable findings, the
human-facing HTML report bundle, per-framework compliance reports, the SBOM, and
the operational data store that powers trends and drift.
This page describes each artifact, the schema of the canonical findings.json,
the HTML report bundle, and how to read findings from the command line.
Related pages: Compliance reporting · SBOM · Troubleshooting.
The .security/ directory
A scanned repository accumulates the following layout. Not every file is present on every run — SBOM, compliance, and report bundles are only written by the commands that produce them.
.security/
├── findings.json # Canonical findings (OCSF-style envelope) — see below
├── pillar-scores.json # Per-pillar scores
├── metrics.json # Scan metrics
├── metrics/ # scan-activity.json, learning.json, gadriel-progress.json
├── sbom.spdx.json # SPDX 2.3 SBOM (gadriel code sbom)
├── sbom.cyclonedx.json # CycloneDX 1.5 SBOM (gadriel code sbom)
├── audit-log.jsonl # Append-only reasoning/audit log (NDJSON)
├── reports/ # HTML report bundle (gadriel code report)
│ ├── index.html
│ ├── findings.html
│ ├── compliance.html
│ ├── drift.html
│ ├── trends.html
│ ├── audit.html
│ ├── executive-summary.pdf
│ └── report.json
├── compliance/ # Per-framework reports (gadriel code report --compliance …)
│ ├── <slug>.md / <slug>.typ / <slug>.pdf
│ └── …
├── store/ # RVF operational data store — see below
│ └── *.rvf
└── history/ # Time-series snapshots
└── YYYY-MM-DD/
├── findings.json
├── pillar-scores.json
└── metrics.json
The location of .security/ can be relocated with the security_dir
configuration key. A --ephemeral scan writes to a throwaway temp directory
instead of the repo.
The canonical findings.json
findings.json is the source of truth for a scan. It is an OCSF-style
envelope (OcsfReport) that wraps an array of typed findings together with
scan-level metadata, scores, and coverage information. Every other artifact —
the HTML bundle, the compliance reports, gadriel code findings — is derived
from it, and downstream consumers should read this file rather than scraping
HTML.
Envelope fields
| Field | Type | Meaning |
|---|---|---|
schema_version | string | Upstream OCSF schema version (currently 1.1.0). |
report_id | string | Unique id for this report. |
vendor_name / product_name / product_version | string | Gadriel / Gadriel Preflight / version. |
gadriel_finding_schema_version | string | Gadriel's own finding-schema version (currently 1.2.0) for code-layer reports. |
scan_types_run | string[] | Which scan types executed. |
scan_types_skipped | {type, reason}[] | Scan types that were skipped and why. |
scan_type_counts | map | Finding counts per scan type. |
severity_counts | map | Counts keyed by critical/high/medium/low/info. |
verdict | string | Overall gate verdict. |
overall_score | number | Aggregate score. |
overall_score_derivation | step[] | Per-pillar weight/contribution breakdown. |
pillar_scores | map → number|null | Per-pillar score; null means the pillar had no rules evaluated. |
pillar_rules_evaluated | map → int | Rule counts per pillar. |
sbom_generated / sbom_paths | bool / {spdx?, cyclonedx?} | Whether an SBOM was produced and where. |
graph_stats | object | Nodes, edges, paths analyzed, cycles detected. |
findings | Finding[] | The findings themselves (see below). |
coverage_status | enum | complete or degraded (e.g. OSV data unavailable — see Troubleshooting). |
coverage_advisories | advisory[] | Human-readable notes about degraded coverage. |
osv_synced | bool | Whether the OSV vulnerability snapshot was in place for this scan. |
unanalyzed_languages | map → int | Languages present but not analyzed. |
Finding fields
Each entry in findings[] is a typed Finding. The most commonly used fields:
| Field | Meaning |
|---|---|
id | The finding identifier — equal to the catalog rule id, e.g. CODE-W4-SECRET-023. |
scan_sequence | Per-scan ordinal. When one rule fires at N sites, all N findings share the same id; (id, scan_sequence) is the per-scan unique key. |
rule_id | Deprecated top-level alias carrying the same value as id; may be absent. |
layer | code or runtime. Distinguishes code-layer findings from Preflight runtime findings. |
severity | critical / high / medium / low / info. |
confidence_tier | high / medium / low — how confident the engine is that the finding is real. Combined with severity to produce an effective risk. |
scan_type | sast / sca / secrets / config / container / api / test_coverage / runtime / graph. |
scan_type_code | Short code embedded in the id (e.g. SECRET, L3, SCA). |
pillar | One or more of the 8 pillars (Security, Compliance, Safety, Operational, FinOps, Coherence, Teamwork, Bias). |
code_context | Typed location context: file, line_start, line_end, function, ast_summary, excerpt, redacted, attack_path. |
what_was_tested | What the rule checked for (free-form JSON). |
what_we_analyzed | What was inspected — file/line/function/AST summary, or runtime prompts. |
what_we_measured | Metrics gathered (list of {metric_id, name, value, unit?}). |
failure | Why it failed — for code findings, {reason, risk_score, score_breakdown, amplifiers_applied}. |
remediation | How to fix it: {adr_ref?, effort?, steps[], code_example?, framework_guidance?}. |
finding_origin | Provenance: deterministic, deterministic_ai_corroborated, ai_advisory, or deterministic_ai_contested. |
claude_reasoning | Optional AI narrative (confirmation, explanation, effort estimate, codebase match). |
correlation_id | Groups findings that share a canonical root cause. |
tool_provenance | Whether the finding came from an in-house scanner or a Tier-1 external adapter. |
Field-name note. In prose these subsections are often called
"what was tested / analyzed / measured", but the on-the-wire keys are
what_was_tested, what_we_analyzed, and what_we_measured. Consumers should
match those exact keys.
Finding id format
Code-layer finding ids follow the grammar:
CODE-W<pillar>-<scan_type_code>-<NNN>
W1–W8map to the eight pillars (W1Security,W2Compliance,W3Safety,W4Operational,W5FinOps,W6Coherence,W7Teamwork,W8Bias).<scan_type_code>is one ofL1–L9(SAST, numbered by OWASP Web Top 10 position),AI,ATLAS,GRAPH,PRED,SCA,SECRET,CONFIG,CONTAINER,API.NNNis a three-digit zero-padded sequence, scoped to the pillar × scan-type pair.
Example: CODE-W1-L3-007 is the 7th Security/SAST-injection rule. Runtime
(Preflight) findings use separate grammars (MATH-F*-NNN, ATLAS-NNN,
GOV-NNN) and are distinguished by the CODE- prefix or the layer field.
Secret redaction
Secret findings never write the secret value into findings.json. The value is
replaced with [REDACTED], preserving a short recognizable prefix (up to 12
characters, e.g. sk-ant-api03-, AKIA, ghp_). The full value lives only in
the encrypted .security/secrets-vault.enc.
Reading findings from the CLI
bashgadriel code findings # human-readable table (default)gadriel code findings --format json # machine-readable JSON
gadriel code findings reads .security/findings.json from the current working
directory (it errors if the file is absent).
--format table(default) prints the total count, a "by risk" breakdown along the severity × confidence axis, a count of unverified findings (high/critical severity but low confidence), and then the findings table.--format jsonvalidates the file as anOcsfReportand prints it, additively enriching each finding with flat convenience fields (file,line,message, and alocation {file, line}object) derived from the context. It never overwrites existing keys, and the on-disk file stays canonical OCSF.
The only accepted format values are table and json.
The HTML report bundle
bashgadriel code report
The report command renders a self-contained, offline HTML bundle into
.security/reports/. Point a browser at it, zip it, or attach it to a
compliance package — it works with no network access.
| File | Contents |
|---|---|
index.html | Single-page report with tabs: Home / Findings / Trends / Compliance / Drift / Audit. |
findings.html | Findings-only deep dive. |
compliance.html | Compliance view (auditor-facing). |
drift.html | Drift view (tech-lead-facing). |
trends.html | Longitudinal trends. |
audit.html | Audit-log search (client-side filtering; the only page with non-trivial JS). |
report.json | The full underlying data dump backing the pages. Written only when you pass --json (not part of the default bundle). |
executive-summary.pdf | One-page CISO/executive summary (see below). |
Self-contained and offline by design
The bundle makes no CDN or network requests. Fonts use the system font
stack; CSS is inlined in <style>; data is embedded in
<script type="application/json">; and charts use a Chart.js bundle vendored
into the crate (pinned by SHA-256 checksum), never fetched at runtime. This is
enforced by tests that fail the build if a network client crate is linked in or
if an external URL appears outside an inline data script.
Report flags
| Flag | Purpose |
|---|---|
--format <list> | HTML/compliance output formats. For the HTML bundle the relevant value is html; also accepts pdf, markdown. Default when no format flag is given: pdf,html. |
--sections <list> | Which standalone HTML pages to emit: findings, compliance, drift, trends, audit (home is a tab of index.html, not a standalone file). Default: all. index.html is always written regardless. |
--json | Emit report.json (orthogonal to --format). Opt-in — off by default; report.json is written only when this flag is passed. |
--output <dir> | Output directory for the HTML/JSON bundle (default .security/reports/). |
--no-executive | Skip generating executive-summary.pdf. |
HTML output is selected via --format html (or --format all). There is no
standalone --html flag.
Executive summary PDF
Every gadriel code report run generates executive-summary.pdf by default,
rendered in-process from an embedded Typst template (no external binary
required). Failure to render it is non-fatal — the rest of the bundle still
writes. Opt out with --no-executive.
The report command also drives per-framework compliance output; see
Compliance reporting.
The RVF operational data store
.security/store/*.rvf holds Gadriel's operational data — the longitudinal
state that powers trends, drift, compliance history, and audit search across
scans. These are binary RVF files (not meant to be hand-edited), keyed by a
per-run ULID.
| File | Holds |
|---|---|
scan-runs.rvf | Canonical join hub — one row per scan (timestamps, duration, runner, rule/file/finding counts, cost). Append-only. |
findings-history.rvf | Per-scan finding counts grouped by rule/severity/pillar/scan-type, with delta-vs-previous. FIFO-capped. |
compliance-history.rvf | Per-framework, per-control verdict snapshots, one per run. |
pillar-timeseries.rvf | Eight-pillar score points per run. FIFO-capped. |
coverage.rvf | Files × rules coverage matrix (paths stored hashed only). |
events.rvf | Structured scan event log (companion to the NDJSON audit log). FIFO-capped. |
sbom-cache.rvf | Content-hash-deduplicated SBOMs (blobs stored in a sbom-blobs/ sidecar). |
dependencies-graph.rvf | Resolved dependency adjacency and vulnerable paths. |
fix-outcomes.rvf | Fix lifecycle chain (Proposed → Applied → Verified → Reverted/Rejected/Stale). |
fingerprint.rvf | Per-repo fingerprint. |
audit-embeddings.rvf | HNSW index over the audit log, enabling semantic audit search. |
Inspect the store from the CLI:
bashgadriel code store list # every .rvf: kind, size, mtime (alias: status)gadriel code store verify # integrity: signatures, witness chain, truncation
store verify reports one of: ok, missing_sidecar, rvf_truncated,
witness_chain_broken, signature_invalid, or not_checked per file. Both
subcommands accept --format table|json.
Implementation status. The RVF store is the intended canonical operational
substrate, but as of this writing several stores are still backed by JSON
sidecars rather than fully migrated to RVF. The history/YYYY-MM-DD/
snapshots continue to exist alongside the store; gadriel code store migrate --backfill can seed the newer stores from that legacy history.
Quick reference
| I want… | Command / file |
|---|---|
| The raw, canonical results | .security/findings.json |
| Findings in the terminal | gadriel code findings |
| Findings as JSON for a script | gadriel code findings --format json |
| A browsable, shareable report | gadriel code report → .security/reports/index.html |
| A one-pager for leadership | .security/reports/executive-summary.pdf |
| Compliance reports | gadriel code report --compliance … → Compliance |
| A software bill of materials | gadriel code sbom → SBOM |
| Historical/operational data | gadriel code store list |
