EU AI Act Article 9 Risk Management System — open-source CLI
Project description
RiskForge
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 37 guided questions across 8 EU AI Act risk dimensions. RiskForge produces a SHA-256-signed Risk Management File (JSON + PDF) suitable for inclusion in your Annex IV technical documentation pack — ready for your legal team and your downstream compliance toolchain. (Not a substitute for notified-body conformity assessment.)
Built by AI Exponent LLC. Apache 2.0. Runs entirely offline after pip install.
Quick Start
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 (~30 minutes)
riskforge assess <system-id> \
--assessor-name "Alice Chen" \
--assessor-role "AI Governance Lead"
# 3. (Optional) Derive Article 9(6)–(8) test requirements per identified risk
riskforge tests generate <system-id>
# 4. Check completeness before export
riskforge validate <system-id>
# 5. Export your Article 9 Risk Management File
riskforge export <system-id> --format pdf --output rmf.pdf
riskforge export <system-id> --format json --output rmf.json
Why RiskForge
EU 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 |
¹ Indicative market figures gathered from public Big-4 governance-engagement quotes and 2024–2026 enterprise GRC pricing pages. Not a benchmark study; your mileage will vary by scope, jurisdiction, and incumbent advisor.
Architecture
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.
AI Exponent compliance toolchain — planned integration
RiskForge is designed to integrate with the broader AI Exponent toolchain. Today, only RiskForge and rag-benchmarking are available on PyPI. The other nodes below are on the public roadmap and will integrate via plain JSON files when they ship.
graph LR
RAG["rag-benchmarking<br/>(accuracy evidence)<br/><i>shipped</i>"]
TF["TraceForge<br/>(data governance)<br/><i>roadmap</i>"]
RF["RiskForge<br/>(Art. 9 RMS)<br/><i>shipped</i>"]
TD["TransparencyDeck<br/>(Art. 13 docs)<br/><i>roadmap</i>"]
CB["ConformityBot<br/>(Art. 43 cert)<br/><i>roadmap</i>"]
CCO["Compliance Officer<br/>(PDF)"]
RAG -->|"benchmark_report.json"| RF
TF -.->|"trace_report.json (planned)"| RF
RF -->|"rmf.pdf"| CCO
RF -.->|"rmf.json (planned)"| TD
RF -.->|"rmf.json (planned)"| CB
style RF fill:#c9a84c,color:#000,stroke:#c9a84c
style RAG fill:#1e3a5f,color:#fff
style TF fill:#6b7685,color:#fff,stroke-dasharray:5
style TD fill:#6b7685,color:#fff,stroke-dasharray:5
style CB fill:#6b7685,color:#fff,stroke-dasharray:5
style CCO fill:#2d5a2d,color:#fff
All current connections are plain JSON files on disk. RiskForge never calls external APIs.
EU AI Act Article 9 Coverage
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 · 37 questions"]
A9_2b["Art. 9(2)(b)<br/>Estimate misuse risks"] --> PAT["Risk patterns<br/>6 Annex III scenarios"]
A9_4["Art. 9(4)<br/>Risk measures"] --> MIT["Mitigation docs<br/>Vague-detection"]
A9_6_8["Art. 9(6)–(8)<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_6_8 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.
Validation Gates
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 |
Features
| 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 | 6 pre-built risk patterns for common Annex III use cases (credit scoring, hiring, facial recognition, medical imaging, content moderation, criminal risk assessment) — community contributions extend the library |
| 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 |
Contributing
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: settled
Add 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 + format
Privacy
RiskForge makes zero outbound network connections in CLI mode, enforced in CI with pytest-socket --disable-socket.
RiskForge v1.0.0 | 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]).
Releases
| Version | Highlights |
|---|---|
| v1.0.0 | First Production/Stable release. Click 8.3 regression fixed; LICENSE realigned to canonical SPDX; PRD amended to ship reality (37 questions, 6 patterns); coverage floor 24→55. |
| v0.1.4 | CI fixes: lint version compat, format alignment, --sys-version rename |
| v0.1.3 | Superseded by v0.1.4 (ruff format alignment) |
| 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 |
License
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
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file riskforge-1.0.0.tar.gz.
File metadata
- Download URL: riskforge-1.0.0.tar.gz
- Upload date:
- Size: 187.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1bce85fef4d0485d27dc0da8e1a518d0afacb934d4fc15d58cd4742d904cee33
|
|
| MD5 |
cc0489fb7b27b98cc6b7cb8e609539e5
|
|
| BLAKE2b-256 |
48965a5a5e66daaff8b8b1fd666ca636e410dbb5b91aa74520039570b97772e6
|
Provenance
The following attestation bundles were made for riskforge-1.0.0.tar.gz:
Publisher:
release.yml on aiexponenthq/riskforge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
riskforge-1.0.0.tar.gz -
Subject digest:
1bce85fef4d0485d27dc0da8e1a518d0afacb934d4fc15d58cd4742d904cee33 - Sigstore transparency entry: 1496738756
- Sigstore integration time:
-
Permalink:
aiexponenthq/riskforge@0e4b9794b9ce6c6a64fd5d5833ded321ceb51660 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/aiexponenthq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0e4b9794b9ce6c6a64fd5d5833ded321ceb51660 -
Trigger Event:
push
-
Statement type:
File details
Details for the file riskforge-1.0.0-py3-none-any.whl.
File metadata
- Download URL: riskforge-1.0.0-py3-none-any.whl
- Upload date:
- Size: 84.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
15985a757265aae8c74458d012402fbe1e3b63fbdfaafbd2c3fb4c248b21afec
|
|
| MD5 |
e8dfa94238a5bb833395b2647a75476d
|
|
| BLAKE2b-256 |
654af1dcd63a92d6128e492e817604fc4f3c70ae07c8aa7651c0a8820c76ef0d
|
Provenance
The following attestation bundles were made for riskforge-1.0.0-py3-none-any.whl:
Publisher:
release.yml on aiexponenthq/riskforge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
riskforge-1.0.0-py3-none-any.whl -
Subject digest:
15985a757265aae8c74458d012402fbe1e3b63fbdfaafbd2c3fb4c248b21afec - Sigstore transparency entry: 1496738999
- Sigstore integration time:
-
Permalink:
aiexponenthq/riskforge@0e4b9794b9ce6c6a64fd5d5833ded321ceb51660 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/aiexponenthq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0e4b9794b9ce6c6a64fd5d5833ded321ceb51660 -
Trigger Event:
push
-
Statement type: