EU AI Act Article 9 risk management, as a developer workflow.
RiskForge is an open-source CLI that turns EU AI Act Article 9 compliance from a consultant invoice into a 30-minute developer workflow.
Answer 50+ guided questions about your AI system. RiskForge produces a SHA-256-signed Risk Management File (JSON + PDF) that satisfies Annex IV documentation requirements — ready for your legal team and your downstream compliance toolchain.
Built by AI Exponent LLC. Apache 2.0. Runs entirely offline after pip install.
pip install riskforge# 1. Register your AI system
riskforge init \
--name "Loan Scoring Model" \
--sys-version "2.1" \
--purpose "Automated credit scoring for retail loan applications." \
--provider "Acme Financial Services" \
--category essential_services# 2. Run the guided 8-dimension risk assessment (~25 minutes)
riskforge assess <system-id> \
--assessor-name "Alice Chen" \
--assessor-role "AI Governance Lead"# 3. Check completeness before export
riskforge validate <system-id>
# 4. Export your Article 9 Risk Management File
riskforge export <system-id> --format pdf --output rmf.pdf
riskforge export <system-id> --format json --output rmf.jsonEU AI Act Article 9 requires providers of high-risk AI systems to maintain a documented risk management system throughout the system's lifecycle.
The current alternatives:
| Option | Cost | Time | Repeatable |
|---|---|---|---|
| Big 4 consulting | €80K–€350K per system | Weeks | No |
| Enterprise GRC platforms | $60K–$200K/year | Months | Partial |
| Spreadsheets | Free | Days | No |
| RiskForge | Free | ~30 min | Yes |
RiskForge has four strictly-decoupled layers with CI-enforced import boundaries:
graph TD
CLI["CLI (Typer)<br/>riskforge init / assess / validate / export / verify"]
Engine["Engine Layer<br/>AuditEngine · RiskEngine · ValidateEngine<br/>AssessEngine · ExportEngine · TestDerivationEngine"]
Storage["Storage (FileStore)<br/>YAML + JSONL · chmod 600/700 · async · pluggable ABC"]
Adapters["Integration Adapters<br/>RAGBenchmarkingAdapter · TraceForgeAdapter<br/>Discovered via Python entry_points"]
CLI -->|"calls engine functions"| Engine
Engine -->|"reads/writes via StorageBackend ABC"| Storage
Engine -->|"adapter pattern — no hard imports"| Adapters
style CLI fill:#1e3a5f,color:#fff
style Engine fill:#1e3a5f,color:#fff
style Storage fill:#1e3a5f,color:#fff
style Adapters fill:#1e3a5f,color:#fff
State on disk:
your-project/
├── riskforge.yaml ← project manifest
├── .riskforge/
│ ├── audit.jsonl ← append-only hash-chained audit log
│ └── .nodelete ← deletion sentinel
└── systems/<system-id>/
├── system.yaml
├── register.yaml
└── exports/
└── rmf-*.json
Plain YAML + JSONL — readable by regulators without RiskForge installed, diff-able in GitHub PRs.
RiskForge is the structural centre of the AiExponent compound moat. Every upstream tool feeds it; every downstream tool consumes it.
graph LR
RAG["rag-benchmarking<br/>(accuracy evidence)"]
TF["TraceForge<br/>(data governance)"]
RF["RiskForge<br/>(Art. 9 RMS)"]
TD["TransparencyDeck<br/>(Art. 13 docs)"]
CB["ConformityBot<br/>(Art. 43 cert)"]
CCO["Compliance Officer<br/>(PDF)"]
RAG -->|"benchmark_report.json"| RF
TF -->|"trace_report.json"| RF
RF -->|"rmf.json"| TD
RF -->|"rmf.json"| CB
RF -->|"rmf.pdf"| CCO
style RF fill:#c9a84c,color:#000,stroke:#c9a84c
style RAG fill:#1e3a5f,color:#fff
style TF fill:#1e3a5f,color:#fff
style TD fill:#1e3a5f,color:#fff
style CB fill:#1e3a5f,color:#fff
style CCO fill:#2d5a2d,color:#fff
All connections are file-based. RiskForge never calls external APIs.
graph LR
A9_1["Art. 9(1)<br/>Establish RMS"] --> REG["Register lifecycle<br/>Version history<br/>Audit log"]
A9_2a["Art. 9(2)(a)<br/>Identify risks"] --> QB["Guided question bank<br/>8 dimensions · 50+ questions"]
A9_2b["Art. 9(2)(b)<br/>Estimate misuse risks"] --> PAT["Risk patterns<br/>20 Annex III scenarios"]
A9_4["Art. 9(4)<br/>Risk measures"] --> MIT["Mitigation docs<br/>Vague-detection"]
A9_7["Art. 9(7)<br/>Testing requirements"] --> TEST["riskforge tests generate<br/>Per-risk metric hints"]
A9_9["Art. 9(9)<br/>Vulnerable groups"] --> VG["Dedicated questions<br/>Mandatory flag"]
A9_10["Art. 9(10)<br/>Documentation"] --> AUD["Append-only JSONL<br/>SHA-256 hash chain"]
style A9_1 fill:#1e3a5f,color:#fff
style A9_2a fill:#1e3a5f,color:#fff
style A9_2b fill:#1e3a5f,color:#fff
style A9_4 fill:#1e3a5f,color:#fff
style A9_7 fill:#1e3a5f,color:#fff
style A9_9 fill:#1e3a5f,color:#fff
style A9_10 fill:#1e3a5f,color:#fff
Cross-maps to: NIST AI RMF (GOVERN/MAP/MEASURE/MANAGE) · ISO/IEC 42001 (Clauses 6.1, 8.4, A.6–A.9) · Colorado AI Act SB 24-205 · Texas HB 1709
Disclaimer: RiskForge produces documented evidence for Article 9 compliance. It does not substitute for qualified legal counsel or notified body conformity assessment.
Before every export, riskforge validate runs 8 gates:
| Gate | Check |
|---|---|
| G1 | All 8 risk dimensions have at least one entry |
| G2 | Article 6(2) Annex III self-classification documented |
| G3 | All high-scoring risks mitigated or accepted with rationale |
| G4 | Knowledge gaps have test requirements |
| G5 | System metadata complete |
| G6 | Assessor identity recorded |
| G7 | Risk score distribution plausible (warns if all scores are low) |
| G8 | No vague mitigation language detected |
| Feature | Detail |
|---|---|
| Offline-first | Zero outbound calls after pip install — enforced by pytest-socket CI gate |
| Hash-chained audit | Every mutation appended to audit.jsonl; riskforge verify exits code 2 on tampering |
| Schema-validated exports | Every JSON export validated against rmf.schema.json before writing |
| PDF export | WeasyPrint + Jinja2 — no LibreOffice or wkhtmltopdf required |
| Pattern matching | 20 pre-built risk patterns for Annex III use cases (credit scoring, hiring, facial recognition…) |
| Plugin extensible | Add question banks, exporters, adapters via pip install — no config edit required |
| Git-friendly state | YAML + JSONL files — human-readable, diff-able, merge-conflict-resolvable |
The easiest contribution requires zero Python — edit a YAML file and open a PR.
Add a question to an existing dimension:
# src/riskforge/_data/question_bank/privacy.yaml
- id: PRIV-007
text: "Does the system process special category data under GDPR Article 9?"
guidance: "Special category data includes health, biometric, racial, or political data."
annex_iii_categories: [essential_services, employment]
default_likelihood_hint: 3
default_severity_hint: 5
article_refs: ["Art.9(2)(a)", "Art.10(3)"]
nist_rmf_ref: "MAP 1.5"
iso42001_ref: "Clause A.7"
regulatory_status: settledAdd a risk pattern — edit src/riskforge/_data/patterns/patterns.yaml.
Fix a bug or add a feature — see CONTRIBUTING.md.
git clone https://github.com/aiexponenthq/riskforge
cd riskforge
make dev-setup # pip install -e ".[dev]" + pre-commit install
make test # 57 tests, all must pass
make lint # ruff check + formatRiskForge makes zero outbound network connections in CLI mode, enforced in CI with pytest-socket --disable-socket.
RiskForge v0.1.4 | Apache 2.0 | Zero telemetry | aiexponent.com
Your AI system's risk data never leaves your machine unless you explicitly deploy the optional API server (pip install riskforge[server]).
| Version | Highlights |
|---|---|
| v0.1.4 | CI fixes: lint version compat, format alignment, --sys-version rename |
| v0.1.2 | OSS hardening: LICENSE, CONTRIBUTING, SECURITY, issue templates, full integration tests |
| v0.1.1 | riskforge assess fully implemented; PDF exporter fix; audit chain integrity fixes |
| v0.1.0 | Initial release |
Apache 2.0 — free to use, modify, and distribute.
Built by AI Exponent LLC — hello@aiexponent.com
Part of the AiExponent open-source AI governance toolchain: license-compliance-checker · rag-benchmarking · RiskForge
