Compliance Reporting
Gadriel Code maps its findings onto recognized security and AI-governance frameworks and produces per-framework compliance reports. The reports state, for each control, whether the evidence gathered from your source code supports a PASS, a PARTIAL, a FAIL, or whether the control simply cannot be judged from source and needs manual review.
This page documents the supported frameworks, how to generate reports, how findings map to controls, what each control state means, and — importantly — how coverage honestly varies from framework to framework.
Related pages: Reports & outputs · SBOM · Troubleshooting.
Supported frameworks
Ten frameworks are supported. Use the slug in the --compliance flag.
| Slug | Framework |
|---|---|
eu-ai-act | EU AI Act |
nist-ai-rmf | NIST AI Risk Management Framework |
soc2 | SOC 2 Type II |
hipaa | HIPAA |
pci-dss | PCI-DSS |
owasp-llm-top10 | OWASP LLM Top 10 |
owasp-agentic | OWASP Agentic AI Top 10 |
iso-42001 | ISO/IEC 42001 (AI Management System) |
cmmc-level-1 | CMMC Level 1 (Foundational) |
cyber-insurance-readiness | Cyber Insurance Readiness Checklist |
Several common aliases are accepted (e.g. nist, soc-2, pci, owasp-llm,
iso42001, cmmc, cyber-insurance), but the slugs above are canonical.
Cyber Insurance Readiness is deliberately a Gadriel-authored readiness checklist, not a compliance standard, and carries a disclaimer: it does not guarantee insurability, approval, premium, coverage, or claim payment.
Generating reports
bash# One frameworkgadriel code report --compliance soc2# Several frameworksgadriel code report --compliance soc2,pci-dss,hipaa# All tengadriel code report --compliance all# Choose output formatsgadriel code report --compliance all --format pdf,markdown,html
| Flag | Meaning |
|---|---|
--compliance <list> | A single slug, a comma-separated list, or all. |
--all-frameworks | Shorthand for every framework. |
--format <list> | Comma-separated output formats: pdf, markdown (alias md), html. Convenience aliases: both = pdf,markdown; all = pdf,markdown,html. Default (no format flag): pdf,html. |
--output-dir <path> | Override the compliance output directory (default .security/compliance/). |
--fail-on <verdict|render-only> | verdict (default) makes the exit code reflect the rollup; render-only always exits 0 for any verdict. |
The command reads .security/findings.json, so run a scan first.
There are also legacy --pdf and --markdown boolean flags. They are
mutually exclusive with --format (passing both is an error); prefer
--format.
Output location
Per-framework files are written into .security/compliance/, one set per
framework, named by slug:
| File | When |
|---|---|
.security/compliance/<slug>.md | markdown/md format selected |
.security/compliance/<slug>.typ | pdf selected (Typst source, kept for transparency and manual re-render) |
.security/compliance/<slug>.pdf | pdf selected (compiled in-process; best-effort — a compile failure keeps the .typ and warns) |
For example, gadriel code report --compliance all --format all writes ten sets
of {.md, .typ, .pdf}. The same command run also refreshes the HTML bundle in
.security/reports/ (including the compliance view) and appends a row to the
compliance-history.rvf store. See Reports & outputs.
Exit codes
When --fail-on verdict (the default), the report command exits:
| Code | Meaning |
|---|---|
0 | PASS |
1 | PARTIAL |
2 | FAIL |
3 | Fatal (missing .security/, missing findings.json, unknown framework slug) |
--fail-on render-only collapses 1 and 2 to 0 (only true render failures fail).
See the exit-code reference.
How findings map to controls
Each rule in the Gadriel Vulnerability Library (GVL) carries a
compliance_mapping — a set of framework keys, each naming the control that
rule provides evidence for. The available keys are:
owasp_llm, owasp_web, cwe, eu_ai_act, nist_ai_rmf, iso_42001,
soc2, pci_dss, hipaa.
Each key holds a single control id, for example:
yamlcompliance_mapping:eu_ai_act: Article_9nist_ai_rmf: GOVERN-1.1soc2: CC6.1cwe: CWE-20
A finding produced by that rule inherits the mapping, and the aggregator ties it to the corresponding control in three tiers (first non-empty tier wins per control):
- Direct — the finding carries an explicit
compliance_mappingentry for that framework's control. - Pattern match — the control declares
rule_id_patternsthat match the finding's id. (This tier feeds the evidence table shown in the report but does not currently drive the verdict.) - Pillar fallback — the finding's pillar overlaps the control's declared pillars (only when the control opts in).
Structural gap for three frameworks. ComplianceMapping has no
cmmc, cyber_insurance, or owasp_agentic key. Direct (Tier-1) mapping is
therefore impossible for CMMC Level 1, Cyber Insurance Readiness, and
OWASP Agentic — those frameworks rely on manual-only controls and the
pattern/pillar tiers.
What a control's state means
| State | Meaning |
|---|---|
| PASS | The control's pass_when predicate was satisfied and no failing/partial predicate matched. |
| PARTIAL | A partial_when predicate matched (and no fail_when did), or no predicate matched and the conservative default applied ("evidence not collected"). Gadriel never silently promotes an unevidenced control to PASS. |
| FAIL | A fail_when predicate matched. |
| NOT ASSESSABLE (manual review) | The control is marked manual_only — it cannot be judged from source code and requires a human. |
A single control is evaluated as follows:
- If the control is
manual_only, it short-circuits to NOT ASSESSABLE before any predicate runs, and carries the control's own narrative as its note. - Otherwise predicates are evaluated with strict precedence —
fail_when>partial_when>pass_when, first match wins. - If nothing matches, the control defaults to PARTIAL with the reason "evidence not collected".
Framework rollup. A framework's overall verdict is PASS / PARTIAL / FAIL: any FAIL makes the framework FAIL; else any PARTIAL makes it PARTIAL; else PASS. NOT ASSESSABLE controls are neutral — they are excluded from the rollup and never counted as a deficiency. A framework whose only non-PASS controls are manual-only will roll up to PASS.
Coverage varies by framework — read this
Automated coverage is genuinely uneven across frameworks. Some frameworks are
almost fully automatable from source; others are mostly or entirely
manual-assessment. The table below reflects how many controls each framework
defines and how many are manual_only (i.e. NOT ASSESSABLE by design).
| Framework | Controls | Manual-only | Machine-assessable |
|---|---|---|---|
eu-ai-act | 9 | 0 | 9 |
owasp-llm-top10 | 10 | 0 | 10 |
soc2 | 12 | 2 | 10 |
pci-dss | 12 | 2 | 10 |
nist-ai-rmf | 12 | 4 | 8 |
cmmc-level-1 | 17 | 9 | 8 |
hipaa | 14 | 7 | 7 |
cyber-insurance-readiness | 12 | 10 | 2 |
owasp-agentic | 10 | 10 | 0 (fully manual) |
iso-42001 | 19 | 19 | 0 (fully manual) |
Additional honesty notes:
- SOC 2 / HIPAA / PCI-DSS corpus annotation is still thin. The framework keys exist and the vacuous-PASS bug that once let these frameworks pass controls without evidence has been fixed — so unevidenced controls now correctly show as "not yet evidenced" (PARTIAL) rather than silently PASS. However, direct rule-to-control annotation for these three is still largely pending, so many of their controls report PARTIAL until the corpus catches up.
- ISO/IEC 42001 is all-manual in v1. Existing
iso_42001data in the corpus is largely mislabeled ISO 27001 content and is deliberately not used to drive verdicts. - OWASP Agentic and ISO 42001 emit zero automated verdicts today — every control is manual review.
- CMMC Level 1 (~8/17 predicated) and Cyber Insurance Readiness (2/12 predicated) are mostly manual.
The practical takeaway: a PASS is meaningful evidence, a FAIL is a real deficiency, PARTIAL means "not yet evidenced from source," and NOT ASSESSABLE means "bring a human." Always read a framework's report alongside the coverage figures above rather than treating an overall PASS as a certification.
