diff --git a/AGENTS.md b/AGENTS.md index 1d4c074..e9a59be 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -69,6 +69,15 @@ black aicertify/ - **Reports are user-facing legal artifacts** — when changing report generation, run the quickstart and inspect the output PDF before claiming success. - **Avoid breaking the public API** — anything re-exported from `aicertify/__init__.py` is part of the user-facing contract. Bump the version and note in CHANGELOG.md if you must. +## Diagrams and visual assets + +All README diagrams live in [`diagrams/`](diagrams/) as paired **light and dark SVGs**, embedded via `` for GitHub theme switching. The full design system (palette, type, shape language, naming, contribution flow) is documented in [`diagrams/STYLE.md`](diagrams/STYLE.md). Read it before adding or modifying any diagram. + +- **Edit existing diagrams in place** — they are hand-authored SVGs, not generated. Open the file, change it, validate with `python3 -c "import xml.etree.ElementTree as ET; ET.parse('')"`. +- **Do not reintroduce a matplotlib generator** — the previous `generate_diagrams.py` was deliberately removed. Hand-authored SVGs are the source of truth. +- **New diagrams must ship both `_light.svg` and `_dark.svg` variants.** Use `` markup; verify GitHub theme switching by viewing the rendered README on both light and dark settings. +- **The logo `aicertify/assets/aic.png`** is *not* the README asset — it is bundled into generated PDF reports via [`aicertify/report_generation/report_generator.py`](aicertify/report_generation/report_generator.py). Don't delete it. README assets are the SVGs in `diagrams/`. + ## What NOT to do - Don't pin new dependencies aggressively — many users will install AICertify alongside their own stack; tight pins create conflicts. diff --git a/CHANGELOG.md b/CHANGELOG.md index b304f8a..8bf0bda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -_No unreleased changes._ +### Changed + +- **Visual refresh** — all README diagrams replaced with hand-authored, theme-aware SVGs in [`diagrams/`](diagrams/). Each diagram now ships as a paired `_light.svg` + `_dark.svg` and is embedded via `` so GitHub light- and dark-theme readers each see the variant that matches their canvas. The top-of-README logo is replaced with a hero banner SVG. The previous matplotlib generator (`diagrams/generate_diagrams.py`) and 5 baked-in PNG diagrams have been removed in favour of the hand-authored SVG system documented in [`diagrams/STYLE.md`](diagrams/STYLE.md). +- **OG / social card** — added [`diagrams/og_card.png`](diagrams/og_card.png) (1200×630) for GitHub Settings → Social preview, plus its `_light` / `_dark` SVG sources. +- **AGENTS.md** — added a "Diagrams and visual assets" section pointing future agents at the new style system. ## [0.7.0] — 2026-05-14 (first PyPI release) @@ -17,7 +21,7 @@ This is the first AICertify release on PyPI (`pip install aicertify`). It bundle - **First-party Claude Code skills** under [`skills/`](skills/): `run-compliance-check`, `evaluate-contract`, `explain-regulation`, `draft-policy`. Install with `cp -r skills/* ~/.claude/skills/`. - **AGENTS.md and CLAUDE.md** for AI coding agents (Claude Code, Cursor, Codex, Gemini CLI, Copilot, …). -- **Marketing diagrams** (5 PNG, regenerable via [`diagrams/generate_diagrams.py`](diagrams/generate_diagrams.py)) embedded in the README. +- **Marketing diagrams** — five PNG diagrams generated by a matplotlib script, embedded in the README. _(Superseded in the next release by hand-authored, theme-aware SVGs; see Unreleased.)_ - **Translated READMEs** for Simplified Chinese, Japanese, Korean, and Hindi. - **SECURITY.md** with a private vulnerability-disclosure flow at `security@principledevolution.ai`. - **docs/why-aicertify.md** — long-form positioning doc covering the gap, the shift, the artefact AICertify produces, and the honest scope of what it does not do. diff --git a/README.hi-IN.md b/README.hi-IN.md index 70319df..58ed955 100644 --- a/README.hi-IN.md +++ b/README.hi-IN.md @@ -1,5 +1,8 @@
- AICertify + + + AICertify — Compliance-as-code for AI systems +

AICertify

@@ -32,7 +35,10 @@

- AI ऐप से ऑडिट-तैयार रिपोर्ट तक: AI Application -> AICertify Contract -> OPA Policy Evaluation -> Compliance Report + + + AI ऐप से ऑडिट-तैयार रिपोर्ट तक: AI Application -> AICertify Contract -> OPA Policy Evaluation -> Compliance Report +


@@ -108,10 +114,6 @@ await app.evaluate(regulations=regs, report_format="pdf", output_dir="reports") AICertify उसी आर्टिफैक्ट के लिए बनाया गया है। -

- AICertify बनाम विकल्प: AICertify एकमात्र ओपन-सोर्स, policy-as-code विकल्प है जिसमें नामित रेगुलेटरी फ्रेमवर्क्स, इंडस्ट्री वर्टिकल्स, और बॉक्स से बाहर ऑडिट-तैयार रिपोर्ट्स हैं -

- | | AICertify | Fairlearn / AIF360 | MS RAI Toolbox | Credo AI | |---|---|---|---|---| | ओपन सोर्स | ✅ Apache 2.0 | ✅ MIT | ✅ MIT | ❌ क्लोज़्ड | @@ -127,7 +129,10 @@ AICertify उसी आर्टिफैक्ट के लिए बनाय ## यह कैसे काम करता है

- AICertify आर्किटेक्चर: आपका AI ऐप एक Contract को फीड करता है, जो Evaluators (Fairness, ContentSafety, RiskManagement, Compliance) के माध्यम से 94 Rego पॉलिसीज़ वाले OPA Engine में जाता है, और Report Generator के द्वारा एक ऑडिट डिलिवरेबल तैयार करता है + + + AICertify आर्किटेक्चर: आपका AI ऐप एक Contract को फीड करता है, जो Evaluators (Fairness, ContentSafety, RiskManagement, Compliance) के माध्यम से 94 Rego पॉलिसीज़ वाले OPA Engine में जाता है, और Report Generator के द्वारा एक ऑडिट डिलिवरेबल तैयार करता है +

1. **Contract** — आपके AI एप्लिकेशन का एक JSON विवरण: model, version, कैप्चर की गई interactions, metadata। @@ -142,7 +147,10 @@ AICertify उसी आर्टिफैक्ट के लिए बनाय ## रेगुलेटरी कवरेज

- रेगुलेटरी कवरेज: 15+ फ्रेमवर्क्स और 5 इंडस्ट्रीज़ में 94 पॉलिसीज़ -- EU AI Act, NIST AI RMF, India DPDP, Brazil AI Bill, RTCA DO-365/366, FAA Part 107, EASA SORA, ICAO Doc 10019, Healthcare, Banking and Financial Services, Automotive, Education, Global, Aviation, AIOps, Corporate + + + रेगुलेटरी कवरेज: 15+ फ्रेमवर्क्स और 5 इंडस्ट्रीज़ में 94 पॉलिसीज़ -- EU AI Act, NIST AI RMF, India DPDP, Brazil AI Bill, RTCA DO-365/366, FAA Part 107, EASA SORA, ICAO Doc 10019, Healthcare, Banking and Financial Services, Automotive, Education, Global, Aviation, AIOps, Corporate +

AICertify [gopal](https://github.com/Principled-Evolution/gopal) पॉलिसी लाइब्रेरी के विरुद्ध चलता है — इन फ्रेमवर्क्स में **94 प्रोडक्शन OPA पॉलिसीज़**: @@ -198,7 +206,10 @@ python -m aicertify.cli \ ## सैंपल रिपोर्ट्स

- एक ऑडिट-तैयार रिपोर्ट की संरचना: फ्रेमवर्क नाम, एप्लिकेशन, मॉडल और दिनांक के साथ हेडर; executive summary; policy results table; risk assessment bar chart; remediation guidance; AICertify v0.7.0 का श्रेय देने वाला फुटर + + + एक ऑडिट-तैयार रिपोर्ट की संरचना: फ्रेमवर्क नाम, एप्लिकेशन, मॉडल और दिनांक के साथ हेडर; executive summary; policy results table; risk assessment bar chart; remediation guidance; AICertify v0.7.0 का श्रेय देने वाला फुटर +

`examples/outputs/` डायरेक्टरी में वास्तविक मूल्यांकनों से जनरेट की गई रिपोर्ट्स हैं जिन्हें आप कुछ भी चलाने से पहले देख सकते हैं: diff --git a/README.ja-JP.md b/README.ja-JP.md index b01dabf..3c8f3db 100644 --- a/README.ja-JP.md +++ b/README.ja-JP.md @@ -1,5 +1,8 @@
- AICertify + + + AICertify — Compliance-as-code for AI systems +

AICertify

@@ -32,7 +35,10 @@

- AI アプリケーションから監査対応レポートまで: AI アプリケーション → AICertify 契約 → OPA ポリシー評価 → コンプライアンスレポート + + + AI アプリケーションから監査対応レポートまで: AI アプリケーション → AICertify 契約 → OPA ポリシー評価 → コンプライアンスレポート +


@@ -108,10 +114,6 @@ await app.evaluate(regulations=regs, report_format="pdf", output_dir="reports") AICertify はまさにその成果物のために構築されています。 -

- AICertify と代替ツールの比較: AICertify は、名前の付いた規制フレームワーク、業種別ポリシー、監査対応レポートを標準装備した唯一のオープンソース・ポリシー・アズ・コード型ツールです -

- | | AICertify | Fairlearn / AIF360 | MS RAI Toolbox | Credo AI | |---|---|---|---|---| | オープンソース | ✅ Apache 2.0 | ✅ MIT | ✅ MIT | ❌ クローズド | @@ -127,7 +129,10 @@ AICertify はまさにその成果物のために構築されています。 ## 仕組み

- AICertify のアーキテクチャ: AI アプリが契約を生成し、評価器 (公平性、コンテンツ安全性、リスク管理、コンプライアンス) を経由して 94 個の Rego ポリシーを持つ OPA エンジンに送られ、レポート生成器が監査成果物を出力 + + + AICertify のアーキテクチャ: AI アプリが契約を生成し、評価器 (公平性、コンテンツ安全性、リスク管理、コンプライアンス) を経由して 94 個の Rego ポリシーを持つ OPA エンジンに送られ、レポート生成器が監査成果物を出力 +

1. **契約 (Contract)** — AI アプリケーションを記述した JSON です。モデル、バージョン、収集したやり取り、メタデータを含みます。 @@ -142,7 +147,10 @@ AICertify はまさにその成果物のために構築されています。 ## 規制カバレッジ

- 規制カバレッジ: 15 以上のフレームワークと 5 つの業種にわたる 94 ポリシー -- EU AI Act、NIST AI RMF、インド DPDP、ブラジル AI 法案、RTCA DO-365/366、FAA Part 107、EASA SORA、ICAO Doc 10019、医療、銀行・金融サービス、自動車、教育、グローバル、航空、AIOps、コーポレート + + + 規制カバレッジ: 15 以上のフレームワークと 5 つの業種にわたる 94 ポリシー -- EU AI Act、NIST AI RMF、インド DPDP、ブラジル AI 法案、RTCA DO-365/366、FAA Part 107、EASA SORA、ICAO Doc 10019、医療、銀行・金融サービス、自動車、教育、グローバル、航空、AIOps、コーポレート +

AICertify は [gopal](https://github.com/Principled-Evolution/gopal) ポリシーライブラリ — **本番運用可能な 94 個の OPA ポリシー** — を用いて、以下のフレームワークに対する評価を実行します。 @@ -198,7 +206,10 @@ Python API の全体像は [`examples/quickstart.py`](examples/quickstart.py) ## サンプルレポート

- 監査対応レポートの構成: フレームワーク名・アプリケーション・モデル・日付を含むヘッダー、エグゼクティブサマリー、ポリシー結果テーブル、リスク評価の棒グラフ、是正ガイダンス、AICertify v0.7.0 を示すフッター + + + 監査対応レポートの構成: フレームワーク名・アプリケーション・モデル・日付を含むヘッダー、エグゼクティブサマリー、ポリシー結果テーブル、リスク評価の棒グラフ、是正ガイダンス、AICertify v0.7.0 を示すフッター +

`examples/outputs/` ディレクトリには、実評価から生成されたレポートが含まれており、実行前に内容を確認できます。 diff --git a/README.ko-KR.md b/README.ko-KR.md index 4b80793..070e497 100644 --- a/README.ko-KR.md +++ b/README.ko-KR.md @@ -1,5 +1,8 @@
- AICertify + + + AICertify — Compliance-as-code for AI systems +

AICertify

@@ -32,7 +35,10 @@

- AI 애플리케이션에서 감사 준비 리포트까지: AI 애플리케이션 -> AICertify 계약 -> OPA 정책 평가 -> 컴플라이언스 리포트 + + + AI 애플리케이션에서 감사 준비 리포트까지: AI 애플리케이션 -> AICertify 계약 -> OPA 정책 평가 -> 컴플라이언스 리포트 +


@@ -108,10 +114,6 @@ await app.evaluate(regulations=regs, report_format="pdf", output_dir="reports") AICertify는 바로 그 산출물을 위해 만들어졌습니다. -

- AICertify와 대안 비교: AICertify는 명명된 규제 프레임워크, 산업별 수직 영역, 그리고 기본 제공되는 감사 준비 리포트를 갖춘 유일한 오픈소스 정책 코드화 옵션입니다 -

- | | AICertify | Fairlearn / AIF360 | MS RAI Toolbox | Credo AI | |---|---|---|---|---| | 오픈소스 | ✅ Apache 2.0 | ✅ MIT | ✅ MIT | ❌ 비공개 | @@ -127,7 +129,10 @@ AICertify는 바로 그 산출물을 위해 만들어졌습니다. ## 작동 방식

- AICertify 아키텍처: AI 앱이 계약을 제공하고, 이는 평가기(Fairness, ContentSafety, RiskManagement, Compliance)를 거쳐 94개의 Rego 정책을 포함한 OPA 엔진으로 흐르며, 리포트 생성기를 통해 감사 산출물을 만들어 냅니다 + + + AICertify 아키텍처: AI 앱이 계약을 제공하고, 이는 평가기(Fairness, ContentSafety, RiskManagement, Compliance)를 거쳐 94개의 Rego 정책을 포함한 OPA 엔진으로 흐르며, 리포트 생성기를 통해 감사 산출물을 만들어 냅니다 +

1. **계약(Contract)** — AI 애플리케이션에 대한 JSON 설명: 모델, 버전, 수집된 상호작용, 메타데이터. @@ -142,7 +147,10 @@ AICertify는 바로 그 산출물을 위해 만들어졌습니다. ## 규제 커버리지

- 규제 커버리지: 15개 이상의 프레임워크와 5개 산업에 걸친 94개 정책 -- EU AI Act, NIST AI RMF, India DPDP, Brazil AI Bill, RTCA DO-365/366, FAA Part 107, EASA SORA, ICAO Doc 10019, 의료, 금융, 자동차, 교육, 글로벌, 항공, AIOps, 기업 + + + 규제 커버리지: 15개 이상의 프레임워크와 5개 산업에 걸친 94개 정책 -- EU AI Act, NIST AI RMF, India DPDP, Brazil AI Bill, RTCA DO-365/366, FAA Part 107, EASA SORA, ICAO Doc 10019, 의료, 금융, 자동차, 교육, 글로벌, 항공, AIOps, 기업 +

AICertify는 [gopal](https://github.com/Principled-Evolution/gopal) 정책 라이브러리에서 실행됩니다 — 다음 프레임워크들에 걸친 **94개의 프로덕션 OPA 정책**입니다. @@ -201,7 +209,10 @@ python -m aicertify.cli \ ## 샘플 리포트

- 감사 준비 리포트의 구성: 프레임워크 이름, 애플리케이션, 모델, 날짜를 포함한 헤더, 요약 정리, 정책 결과 표, 리스크 평가 막대 차트, 시정 안내, AICertify v0.7.0 표시 푸터 + + + 감사 준비 리포트의 구성: 프레임워크 이름, 애플리케이션, 모델, 날짜를 포함한 헤더, 요약 정리, 정책 결과 표, 리스크 평가 막대 차트, 시정 안내, AICertify v0.7.0 표시 푸터 +

`examples/outputs/` 디렉터리에는 실제 평가에서 생성된 리포트가 들어 있어, 직접 실행하기 전에 살펴볼 수 있습니다. diff --git a/README.md b/README.md index e64b34f..97466d9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@
- AICertify + + + AICertify — Compliance-as-code for AI systems +

AICertify

@@ -32,7 +35,10 @@

- From AI app to audit-ready report: AI Application -> AICertify Contract -> OPA Policy Evaluation -> Compliance Report + + + From AI app to audit-ready report: AI Application -> AICertify Contract -> OPA Policy Evaluation -> Compliance Report +


@@ -120,10 +126,6 @@ Neither produces the document a regulator actually asks for: *evidence that you AICertify is built for that artifact. -

- AICertify vs alternatives: AICertify is the only open-source, policy-as-code option with named regulatory frameworks, industry verticals, and audit-ready reports out of the box -

- | | AICertify | Fairlearn / AIF360 | MS RAI Toolbox | Credo AI | |---|---|---|---|---| | Open source | ✅ Apache 2.0 | ✅ MIT | ✅ MIT | ❌ Closed | @@ -139,7 +141,10 @@ AICertify is built for that artifact. ## How It Works

- AICertify architecture: Your AI App feeds a Contract, which flows through Evaluators (Fairness, ContentSafety, RiskManagement, Compliance) into the OPA Engine with 94 Rego policies, producing an audit deliverable via the Report Generator + + + AICertify architecture: Your AI App feeds a Contract, which flows through Evaluators (Fairness, ContentSafety, RiskManagement, Compliance) into the OPA Engine with 94 Rego policies, producing an audit deliverable via the Report Generator +

1. **Contract** — A JSON description of your AI application: model, version, captured interactions, metadata. @@ -154,7 +159,10 @@ Because the policies are declarative Rego, they version, diff, and review like a ## Regulatory Coverage

- Regulatory coverage: 94 policies across 15+ frameworks and 5 industries -- EU AI Act, NIST AI RMF, India DPDP, Brazil AI Bill, RTCA DO-365/366, FAA Part 107, EASA SORA, ICAO Doc 10019, Healthcare, Banking and Financial Services, Automotive, Education, Global, Aviation, AIOps, Corporate + + + Regulatory coverage: 94 policies across 15+ frameworks and 5 industries -- EU AI Act, NIST AI RMF, India DPDP, Brazil AI Bill, RTCA DO-365/366, FAA Part 107, EASA SORA, ICAO Doc 10019, Healthcare, Banking and Financial Services, Automotive, Education, Global, Aviation, AIOps, Corporate +

AICertify runs against the [gopal](https://github.com/Principled-Evolution/gopal) policy library — **94 production OPA policies** across these frameworks: @@ -217,7 +225,10 @@ You don't have to install anything to see what AICertify produces. Pre-generated - [examples/outputs/medical_diagnosis/](examples/outputs/medical_diagnosis/) — a clinical-decision-support model evaluated for patient safety

- Anatomy of an audit-ready report: header with framework name, application, model and date; executive summary; policy results table; risk assessment bar chart; remediation guidance; footer attributing AICertify v0.7.0 + + + Anatomy of an audit-ready report: header with framework name, application, model and date; executive summary; policy results table; risk assessment bar chart; remediation guidance; footer attributing AICertify v0.7.0 +

Open the PDFs. That's what your auditor wants. diff --git a/README.zh-CN.md b/README.zh-CN.md index 6ee34b4..44abcba 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,5 +1,8 @@
- AICertify + + + AICertify — Compliance-as-code for AI systems +

AICertify

@@ -32,7 +35,10 @@

- 从 AI 应用到审计就绪的报告:AI 应用 -> AICertify 合约 -> OPA 策略评估 -> 合规报告 + + + 从 AI 应用到审计就绪的报告:AI 应用 -> AICertify 合约 -> OPA 策略评估 -> 合规报告 +


@@ -108,10 +114,6 @@ await app.evaluate(regulations=regs, report_format="pdf", output_dir="reports") AICertify 正是为这份交付物而生。 -

- AICertify 与同类工具对比:AICertify 是唯一开箱即用、采用策略即代码、覆盖具名法规框架与行业垂直领域并生成审计就绪报告的开源选项 -

- | | AICertify | Fairlearn / AIF360 | MS RAI Toolbox | Credo AI | |---|---|---|---|---| | 开源 | ✅ Apache 2.0 | ✅ MIT | ✅ MIT | ❌ 闭源 | @@ -127,7 +129,10 @@ AICertify 正是为这份交付物而生。 ## 工作原理

- AICertify 架构:您的 AI 应用提供合约,合约流经评估器(Fairness、ContentSafety、RiskManagement、Compliance)进入承载 94 条 Rego 策略的 OPA 引擎,并通过报告生成器产出审计交付物 + + + AICertify 架构:您的 AI 应用提供合约,合约流经评估器(Fairness、ContentSafety、RiskManagement、Compliance)进入承载 94 条 Rego 策略的 OPA 引擎,并通过报告生成器产出审计交付物 +

1. **合约(Contract)** —— 用 JSON 描述您的 AI 应用:模型、版本、采集的交互、元数据。 @@ -142,7 +147,10 @@ AICertify 正是为这份交付物而生。 ## 法规覆盖

- 法规覆盖:94 条策略,横跨 15+ 框架与 5 个行业 —— EU AI Act、NIST AI RMF、India DPDP、Brazil AI Bill、RTCA DO-365/366、FAA Part 107、EASA SORA、ICAO Doc 10019、医疗、银行金融服务、汽车、教育、全球、航空、AIOps、企业 + + + 法规覆盖:94 条策略,横跨 15+ 框架与 5 个行业 —— EU AI Act、NIST AI RMF、India DPDP、Brazil AI Bill、RTCA DO-365/366、FAA Part 107、EASA SORA、ICAO Doc 10019、医疗、银行金融服务、汽车、教育、全球、航空、AIOps、企业 +

AICertify 运行于 [gopal](https://github.com/Principled-Evolution/gopal) 策略库之上 —— **94 条生产级 OPA 策略**,覆盖以下框架: @@ -201,7 +209,10 @@ python -m aicertify.cli \ ## 示例报告

- 审计就绪报告的结构:含框架名称、应用、模型与日期的页眉;执行摘要;策略结果表;风险评估柱状图;整改建议;以及标注 AICertify v0.7.0 的页脚 + + + 审计就绪报告的结构:含框架名称、应用、模型与日期的页眉;执行摘要;策略结果表;风险评估柱状图;整改建议;以及标注 AICertify v0.7.0 的页脚 +

`examples/outputs/` 目录中包含来自真实评估的生成报告,您可以在运行前先行查阅: diff --git a/diagrams/STYLE.md b/diagrams/STYLE.md new file mode 100644 index 0000000..5f49dfb --- /dev/null +++ b/diagrams/STYLE.md @@ -0,0 +1,94 @@ +# AICertify diagram style + +A short, opinionated reference so future diagrams (yours, mine, or a contributor's) stay visually coherent with the existing set. If you can read [diagram1_hero_flow_light.svg](diagram1_hero_flow_light.svg) and the matching `_dark.svg`, you have already seen the whole system applied. + +## The principle + +Two colors with intent, flat fills, no animation, no shadows. The polish is in restraint and consistency, not effects. + +## Palette + +| Token | Light | Dark | Used for | +|---|---|---|---| +| **Indigo (primary)** | `#4f46e5` | `#6366f1` | Process, structure, the "happy path" | +| **Indigo (light fill)** | `#eef2ff` | `#312e81` | Card backgrounds for indigo elements | +| **Indigo (text on fill)** | `#4338ca` | `#c7d2fe` | Text inside indigo chips/badges | +| **Amber (accent)** | `#d97706` | `#fbbf24` | The **output** of the flow — audit report, deliverable, industry-specific framework | +| **Amber (light fill)** | `#fffbeb` / `#fef3c7` | `#2a1f06` / `#533404` | Card / chip backgrounds for amber elements | +| **Amber (text on fill)** | `#92400e` / `#b45309` | `#fcd34d` / `#fde68a` | Text inside amber chips | +| **Foreground (text)** | `#0f172a` | `#f0f6fc` | Primary body / heading text | +| **Foreground (muted)** | `#64748b` | `#8b949e` | Secondary captions, labels | +| **Border** | `#e2e8f0` | `#30363d` | Card outlines, dividers | +| **Card surface** | `#ffffff` | `#161b22` | Card backgrounds | +| **Arrow / line** | `#94a3b8` | `#6e7681` | Connectors | + +**Amber is precious.** Reserve it for the deliverable in a flow and for industry-specific (vertical) frameworks. If everything is highlighted, nothing is highlighted. + +## Typography + +- Single stack, declared on every ``: `font-family="system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"`. No webfont hosting, no licensing, picks up the reader's OS font. +- **Headings inside cards**: 13–15px, `font-weight="500"`. +- **Body / captions**: 10–12px, `font-weight="400"`. +- **Stat numerals** (e.g. "94"): 36px, `font-weight="500"`, amber. +- Wordmark on the hero banner / OG card uses `letter-spacing="-0.025em"` for tightness at large sizes. + +## Shape language + +- **Cards / chips**: rounded rectangles. Corner radius `rx="10"` for cards, `rx="12"` (or larger) for chip pills. +- **Card stroke**: `1px` border in the border token, no shadows, no gradients. +- **Arrows**: `1.5px` line in the muted line color, with the marker defined per-file in ``. Don't reuse `id="al"` etc. across files in case both are inlined. +- **Icons inside cards**: `1.5px` stroke in the indigo (or dark variant) color, `stroke-linecap="round"`, `stroke-linejoin="round"`. Compact (~24×24 unit) line icons, no fills unless intentional. + +## Light/dark pattern + +Diagrams ship as **paired files** with matching `_light.svg` and `_dark.svg`. README markup uses ``: + +```html + + + <descriptive alt text> +
+``` + +That gives GitHub-light readers the light variant and GitHub-dark readers the dark variant — same on mobile, on PR previews, and anywhere else `` is honored. + +- Light variants use white card surfaces, slate text. +- Dark variants use `#161b22` cards (GitHub's `--color-canvas-subtle`) and `#30363d` borders so cards sit into the page rather than floating on top of it. +- Don't bake in a background `` filling the viewBox unless the asset is meant to be self-contained (e.g. OG cards). Otherwise let GitHub's page color show through. + +## Files and naming + +``` +diagrams/ +├── STYLE.md (this file) +├── hero_banner_{light,dark}.svg top-of-README banner +├── logo_{light,dark}.svg standalone square mark +├── og_card_{light,dark}.svg 1200×630 social-preview card +├── og_card.png rasterized light variant (1200×630), for GitHub Settings → Social preview +├── diagram1_hero_flow_{light,dark}.svg contract → OPA → report +├── diagram2_architecture_{light,dark}.svg evaluator bus + OPA engine +├── diagram3_regulatory_coverage_{light,dark}.svg stats + four category cards +└── diagram5_report_anatomy_{light,dark}.svg report mockup with callouts +``` + +Diagram 4 (comparison) was deliberately removed — the markdown comparison table in the README is the single source of truth. + +## Adding a new diagram + +1. Sketch the content first in markdown (what does the reader need to understand?). Cut anything that is also said in nearby text. +2. Pick a layout that mirrors an existing diagram if you can — most additions are variations of "flow", "bus", or "stats + cards". +3. Hand-author the SVG. Use the existing files as templates; copy a card definition, swap the content. +4. Validate XML: `python3 -c "import xml.etree.ElementTree as ET; ET.parse('diagrams/_light.svg')"`. Repeat for the dark variant. +5. Embed with the `` snippet above in every README that should reference it (en + 4 translated). +6. **No automation, no matplotlib, no Python generator.** The old `generate_diagrams.py` was retired because hand-authored SVGs are easier to read, edit, and review than rendered raster output. Keep them hand-authored. + +## Rasterizing (only when needed) + +The only raster output we keep in the repo is `og_card.png` — GitHub's Social Preview upload requires PNG/JPG. To regenerate: + +```bash +inkscape --export-type=png --export-width=1200 --export-height=630 \ + --export-filename=diagrams/og_card.png diagrams/og_card_light.svg +``` + +GitHub social preview is uploaded manually at: **Settings → General → Social preview → Edit → Upload an image**. The repo's checked-in `og_card.png` is the source artifact. diff --git a/diagrams/diagram1_hero_flow.png b/diagrams/diagram1_hero_flow.png deleted file mode 100644 index 03760fe..0000000 Binary files a/diagrams/diagram1_hero_flow.png and /dev/null differ diff --git a/diagrams/diagram1_hero_flow_dark.svg b/diagrams/diagram1_hero_flow_dark.svg new file mode 100644 index 0000000..810e600 --- /dev/null +++ b/diagrams/diagram1_hero_flow_dark.svg @@ -0,0 +1,66 @@ + + +How AICertify works +Four-step flow from AI application to audit-ready report. + + + + + + + +01 + + + + + + + +AI application +Real interactions + + + + + + + +02 + + + + +Contract +Inputs + outputs + + + + + + + +03 + + + + +OPA evaluation +Policy as code + + + + + + + +04 + + + + + +Audit report +PDF · MD · JSON + + diff --git a/diagrams/diagram1_hero_flow_light.svg b/diagrams/diagram1_hero_flow_light.svg new file mode 100644 index 0000000..607fda6 --- /dev/null +++ b/diagrams/diagram1_hero_flow_light.svg @@ -0,0 +1,66 @@ + + +How AICertify works +Four-step flow from AI application to audit-ready report. + + + + + + + +01 + + + + + + + +AI application +Real interactions + + + + + + + +02 + + + + +Contract +Inputs + outputs + + + + + + + +03 + + + + +OPA evaluation +Policy as code + + + + + + + +04 + + + + + +Audit report +PDF · MD · JSON + + diff --git a/diagrams/diagram2_architecture.png b/diagrams/diagram2_architecture.png deleted file mode 100644 index cef83ac..0000000 Binary files a/diagrams/diagram2_architecture.png and /dev/null differ diff --git a/diagrams/diagram2_architecture_dark.svg b/diagrams/diagram2_architecture_dark.svg new file mode 100644 index 0000000..bd77b6a --- /dev/null +++ b/diagrams/diagram2_architecture_dark.svg @@ -0,0 +1,93 @@ + + +AICertify architecture +Contract feeds four evaluators, which feed the OPA policy engine, producing an audit report. + + + + + + + + +Contract +JSON definition + + + + + + + + + + + + + + + + + +Fairness +Bias & equity + + + + + + + +Content safety +Toxicity, PII + + + + + + + + +Risk mgmt +NIST controls + + + + + + + + +Compliance +Framework checks + + + + + + + + + + + + + + + +OPA policy engine +94 production Rego policies · gopal library + + + + + + + + + + +Audit report +PDF · MD · JSON · HTML + + diff --git a/diagrams/diagram2_architecture_light.svg b/diagrams/diagram2_architecture_light.svg new file mode 100644 index 0000000..6bee4e3 --- /dev/null +++ b/diagrams/diagram2_architecture_light.svg @@ -0,0 +1,93 @@ + + +AICertify architecture +Contract feeds four evaluators, which feed the OPA policy engine, producing an audit report. + + + + + + + + +Contract +JSON definition + + + + + + + + + + + + + + + + + +Fairness +Bias & equity + + + + + + + +Content safety +Toxicity, PII + + + + + + + + +Risk mgmt +NIST controls + + + + + + + + +Compliance +Framework checks + + + + + + + + + + + + + + + +OPA policy engine +94 production Rego policies · gopal library + + + + + + + + + + +Audit report +PDF · MD · JSON · HTML + + diff --git a/diagrams/diagram3_regulatory_coverage.png b/diagrams/diagram3_regulatory_coverage.png deleted file mode 100644 index 82b344c..0000000 Binary files a/diagrams/diagram3_regulatory_coverage.png and /dev/null differ diff --git a/diagrams/diagram3_regulatory_coverage_dark.svg b/diagrams/diagram3_regulatory_coverage_dark.svg new file mode 100644 index 0000000..012633e --- /dev/null +++ b/diagrams/diagram3_regulatory_coverage_dark.svg @@ -0,0 +1,70 @@ + + +Regulatory coverage +94 production Rego policies across 15+ frameworks and 5 industries. + +94 +Rego policies +15+ +frameworks +5 +industries + + + + + + + + + +International standards + +EU AI Act +NIST AI RMF +India DPDP +Brazil AI Bill + + + + + + + + +Aviation + +ICAO Doc 10019 +FAA Part 107 +EASA SORA +RTCA DO-365/366 + + + + + + + + +Industry verticals + +Healthcare +Banking & finance +Automotive +Education + + + + + + + + +Cross-cutting principles + +Fairness & bias +Content safety +Transparency +Risk management + + diff --git a/diagrams/diagram3_regulatory_coverage_light.svg b/diagrams/diagram3_regulatory_coverage_light.svg new file mode 100644 index 0000000..4b9305c --- /dev/null +++ b/diagrams/diagram3_regulatory_coverage_light.svg @@ -0,0 +1,70 @@ + + +Regulatory coverage +94 production Rego policies across 15+ frameworks and 5 industries. + +94 +Rego policies +15+ +frameworks +5 +industries + + + + + + + + + +International standards + +EU AI Act +NIST AI RMF +India DPDP +Brazil AI Bill + + + + + + + + +Aviation + +ICAO Doc 10019 +FAA Part 107 +EASA SORA +RTCA DO-365/366 + + + + + + + + +Industry verticals + +Healthcare +Banking & finance +Automotive +Education + + + + + + + + +Cross-cutting principles + +Fairness & bias +Content safety +Transparency +Risk management + + diff --git a/diagrams/diagram4_comparison.png b/diagrams/diagram4_comparison.png deleted file mode 100644 index 8cdad65..0000000 Binary files a/diagrams/diagram4_comparison.png and /dev/null differ diff --git a/diagrams/diagram5_report_anatomy.png b/diagrams/diagram5_report_anatomy.png deleted file mode 100644 index bb55b47..0000000 Binary files a/diagrams/diagram5_report_anatomy.png and /dev/null differ diff --git a/diagrams/diagram5_report_anatomy_dark.svg b/diagrams/diagram5_report_anatomy_dark.svg new file mode 100644 index 0000000..81b6696 --- /dev/null +++ b/diagrams/diagram5_report_anatomy_dark.svg @@ -0,0 +1,76 @@ + + +Anatomy of an audit-ready report +Stylized AICertify report showing header, executive summary, policy results, risk assessment, and remediation sections. + + + + +EU AI Act compliance +customer-support-bot · 2026-05-14 + +Executive summary + + + + + +Policy results + + + + + + + + + + + + +Risk assessment + + + + + + + + + +Remediation + + + + + + + + +AICertify v0.7.0 · run #a4f3 · Apache 2.0 + + + +Header +Framework, model, date + + + +Executive summary +Outcome at a glance + + + +Policy results +Per-rule pass status + + + +Risk assessment +Severity by category + + + +Remediation +Required follow-ups + diff --git a/diagrams/diagram5_report_anatomy_light.svg b/diagrams/diagram5_report_anatomy_light.svg new file mode 100644 index 0000000..fd8cd1c --- /dev/null +++ b/diagrams/diagram5_report_anatomy_light.svg @@ -0,0 +1,76 @@ + + +Anatomy of an audit-ready report +Stylized AICertify report showing header, executive summary, policy results, risk assessment, and remediation sections. + + + + +EU AI Act compliance +customer-support-bot · 2026-05-14 + +Executive summary + + + + + +Policy results + + + + + + + + + + + + +Risk assessment + + + + + + + + + +Remediation + + + + + + + + +AICertify v0.7.0 · run #a4f3 · Apache 2.0 + + + +Header +Framework, model, date + + + +Executive summary +Outcome at a glance + + + +Policy results +Per-rule pass status + + + +Risk assessment +Severity by category + + + +Remediation +Required follow-ups + diff --git a/diagrams/generate_diagrams.py b/diagrams/generate_diagrams.py deleted file mode 100644 index 27920a3..0000000 --- a/diagrams/generate_diagrams.py +++ /dev/null @@ -1,1028 +0,0 @@ -"""Generate marketing diagrams for the AICertify README. - -Run from repo root: python diagrams/generate_diagrams.py -Outputs 5 PNGs (1600x900, ~retina-2x) into the diagrams/ directory. -""" - -from __future__ import annotations - -import os -from pathlib import Path - -import matplotlib.pyplot as plt -from matplotlib.patches import FancyBboxPatch, FancyArrowPatch, Rectangle - -# ---------- shared style ---------- -PURPLE = "#7D4698" -PURPLE_DARK = "#5C2E76" -BLUE = "#1971c2" -GREEN = "#2f9e44" -ORANGE = "#e8590c" -TEXT = "#212529" -MUTED = "#495057" -LIGHT_BG = "#f1f3f5" -LIGHTER_BG = "#f8f9fa" -BORDER = "#dee2e6" -WHITE = "#ffffff" -RED = "#c92a2a" - -# Figure size: 16x9 inches at 100 dpi -> 1600x900px (retina-friendly) -FIGSIZE = (16, 9) -DPI = 100 - -# Typography -TITLE_SIZE = 30 -SUBTITLE_SIZE = 18 -BODY_SIZE = 16 -SMALL_SIZE = 13 - -HERE = Path(__file__).resolve().parent - - -# ---------- helpers ---------- -def new_fig(): - """Create a clean 16:9 figure with white background.""" - fig, ax = plt.subplots(figsize=FIGSIZE, dpi=DPI) - fig.patch.set_facecolor(WHITE) - ax.set_facecolor(WHITE) - ax.set_xlim(0, 100) - ax.set_ylim(0, 56.25) # keeps a 16:9 aspect in data coords - ax.set_xticks([]) - ax.set_yticks([]) - for spine in ax.spines.values(): - spine.set_visible(False) - return fig, ax - - -def title(ax, text, y=52, color=TEXT, size=TITLE_SIZE, weight="bold"): - ax.text( - 50, - y, - text, - ha="center", - va="center", - fontsize=size, - fontweight=weight, - color=color, - ) - - -def subtitle(ax, text, y=47, color=MUTED, size=SUBTITLE_SIZE): - ax.text(50, y, text, ha="center", va="center", fontsize=size, color=color) - - -def draw_box( - ax, - x, - y, - w, - h, - facecolor=WHITE, - edgecolor=PURPLE, - linewidth=2.2, - rounding=0.4, - shadow=False, -): - """Draw a rounded rectangle centered on (x, y) with width w, height h.""" - if shadow: - # offset shadow - shadow_box = FancyBboxPatch( - (x - w / 2 + 0.25, y - h / 2 - 0.35), - w, - h, - boxstyle=f"round,pad=0.02,rounding_size={rounding}", - linewidth=0, - facecolor="#000000", - alpha=0.08, - zorder=1, - ) - ax.add_patch(shadow_box) - box = FancyBboxPatch( - (x - w / 2, y - h / 2), - w, - h, - boxstyle=f"round,pad=0.02,rounding_size={rounding}", - linewidth=linewidth, - edgecolor=edgecolor, - facecolor=facecolor, - zorder=2, - ) - ax.add_patch(box) - return box - - -def labeled_box( - ax, - cx, - cy, - w, - h, - title_text, - subtitle_text=None, - facecolor=WHITE, - edgecolor=PURPLE, - title_color=None, - subtitle_color=None, - title_size=BODY_SIZE + 2, - subtitle_size=SMALL_SIZE, - shadow=True, -): - draw_box( - ax, - cx, - cy, - w, - h, - facecolor=facecolor, - edgecolor=edgecolor, - shadow=shadow, - ) - tc = ( - title_color - if title_color - else (WHITE if facecolor in (PURPLE, PURPLE_DARK) else TEXT) - ) - sc = ( - subtitle_color - if subtitle_color - else (WHITE if facecolor in (PURPLE, PURPLE_DARK) else MUTED) - ) - if subtitle_text: - title_lines = title_text.count("\n") + 1 - sub_lines = subtitle_text.count("\n") + 1 - # vertical spacing roughly proportional to font size (1 unit ~ 14pt) - title_line_h = title_size / 14.0 - sub_line_h = subtitle_size / 14.0 - gap = 0.8 - total_h = title_lines * title_line_h + gap + sub_lines * sub_line_h - # top of text block - top = cy + total_h / 2 - # title block center - title_cy = top - (title_lines * title_line_h) / 2 - sub_cy = ( - title_cy - - (title_lines * title_line_h) / 2 - - gap - - (sub_lines * sub_line_h) / 2 - ) - ax.text( - cx, - title_cy, - title_text, - ha="center", - va="center", - fontsize=title_size, - fontweight="bold", - color=tc, - zorder=3, - linespacing=1.0, - ) - ax.text( - cx, - sub_cy, - subtitle_text, - ha="center", - va="center", - fontsize=subtitle_size, - color=sc, - zorder=3, - linespacing=1.1, - ) - else: - ax.text( - cx, - cy, - title_text, - ha="center", - va="center", - fontsize=title_size, - fontweight="bold", - color=tc, - zorder=3, - ) - - -def draw_arrow(ax, x1, y1, x2, y2, color=PURPLE, lw=2.8, mutation_scale=28): - arr = FancyArrowPatch( - (x1, y1), - (x2, y2), - arrowstyle="-|>", - mutation_scale=mutation_scale, - linewidth=lw, - color=color, - zorder=2, - ) - ax.add_patch(arr) - - -def save_fig(fig, name): - out = HERE / name - fig.savefig(out, dpi=DPI, bbox_inches="tight", facecolor=WHITE, pad_inches=0.25) - plt.close(fig) - size_kb = os.path.getsize(out) / 1024 - print(f" wrote {name} ({size_kb:.1f} KB)") - - -# ---------- diagram 1: hero flow ---------- -def diagram1_hero_flow(): - fig, ax = new_fig() - title(ax, "From AI app to audit-ready report") - subtitle( - ax, - "One contract. One command. One report your auditor accepts.", - ) - - steps = [ - ("AI\nApplication", "model + interactions\n+ metadata", BLUE), - ("AICertify\nContract", "captured\nas JSON", PURPLE), - ("OPA Policy\nEvaluation", "EU AI Act, NIST\n+ 13 more", GREEN), - ("Compliance\nReport", "PDF, Markdown,\nJSON, HTML", ORANGE), - ] - - box_w = 19 - box_h = 18 - y = 26 - # 4 boxes spaced with clear gaps for arrows - centers = [12, 37.33, 62.66, 88] - - for i, (cx, (t, s, color)) in enumerate(zip(centers, steps)): - # numbered circle on top of each box - circle = plt.Circle( - (cx - box_w / 2 + 1.8, y + box_h / 2 - 1.2), - 1.3, - color=color, - zorder=4, - ) - ax.add_patch(circle) - ax.text( - cx - box_w / 2 + 1.8, - y + box_h / 2 - 1.2, - str(i + 1), - ha="center", - va="center", - color=WHITE, - fontsize=14, - fontweight="bold", - zorder=5, - ) - labeled_box( - ax, - cx, - y, - box_w, - box_h, - t, - s, - facecolor=WHITE, - edgecolor=color, - title_size=18, - subtitle_size=13, - shadow=True, - ) - - # arrows - for i in range(3): - x_from = centers[i] + box_w / 2 + 0.2 - x_to = centers[i + 1] - box_w / 2 - 0.2 - draw_arrow(ax, x_from, y, x_to, y, color=MUTED, lw=2.5, mutation_scale=24) - - # footer tag - ax.text( - 50, - 7, - "Open source - Apache 2.0 | Built on Open Policy Agent | 94 Rego policies", - ha="center", - va="center", - fontsize=14, - color=MUTED, - ) - - save_fig(fig, "diagram1_hero_flow.png") - - -# ---------- diagram 2: architecture ---------- -def diagram2_architecture(): - fig, ax = new_fig() - title(ax, "How AICertify works", y=53) - subtitle( - ax, - "Pluggable evaluators feed OPA. OPA produces the report.", - y=48.5, - ) - - # LEFT: your AI app - labeled_box( - ax, - 10, - 24, - 14, - 11, - "Your AI App", - "any LLM, agent,\nor pipeline", - facecolor=BLUE, - edgecolor=BLUE, - title_color=WHITE, - subtitle_color=WHITE, - title_size=16, - subtitle_size=11, - shadow=True, - ) - - # CENTER stack - cx = 50 - box_w = 44 - box_h = 7.2 - rows = [ - ( - 38.5, - "Contract", - "model_name | version | interactions | metadata", - PURPLE, - ), - ( - 29, - "Evaluators", - "Fairness | ContentSafety | RiskManagement | Compliance", - PURPLE, - ), - ( - 19.5, - "OPA Engine + Rego Policies", - "94 policies sourced from the gopal library", - PURPLE_DARK, - ), - ( - 10, - "Report Generator", - "ReportLab PDF | Markdown | JSON | HTML", - PURPLE, - ), - ] - - for y, t, s, color in rows: - labeled_box( - ax, - cx, - y, - box_w, - box_h, - t, - s, - facecolor=color, - edgecolor=color, - title_color=WHITE, - subtitle_color="#e9d5f0", - title_size=17, - subtitle_size=12, - shadow=True, - ) - - # arrows down the stack - for i in range(len(rows) - 1): - y_from = rows[i][0] - box_h / 2 - 0.05 - y_to = rows[i + 1][0] + box_h / 2 + 0.05 - draw_arrow(ax, cx, y_from, cx, y_to, color=MUTED, lw=2.4, mutation_scale=22) - - # arrow from left box into center stack (top) - draw_arrow(ax, 10 + 14 / 2 + 0.2, 24, cx - box_w / 2 - 0.2, rows[0][0], color=MUTED) - - # RIGHT: audit deliverable - labeled_box( - ax, - 90, - 24, - 14, - 11, - "Audit\nDeliverable", - "dated, signed,\nreproducible", - facecolor=ORANGE, - edgecolor=ORANGE, - title_color=WHITE, - subtitle_color=WHITE, - title_size=16, - subtitle_size=11, - shadow=True, - ) - # arrow from bottom of stack out to the right box - draw_arrow( - ax, - cx + box_w / 2 + 0.2, - rows[-1][0], - 90 - 14 / 2 - 0.2, - 24, - color=MUTED, - ) - - save_fig(fig, "diagram2_architecture.png") - - -# ---------- diagram 3: regulatory coverage ---------- -def diagram3_regulatory_coverage(): - fig, ax = new_fig() - title(ax, "Regulatory coverage - 15+ frameworks", y=53) - ax.text( - 50, - 47.5, - "94 policies | 15+ frameworks | 5 industries", - ha="center", - va="center", - fontsize=22, - fontweight="bold", - color=PURPLE, - ) - - # row category labels - row_labels = [ - "International", - "Aviation Safety", - "Industry", - "Cross-cutting", - ] - - cells = [ - # row 1: International - [ - ("EU AI Act", "29"), - ("NIST AI RMF", "5"), - ("India DPDP", "1"), - ("Brazil AI Bill", "1"), - ], - # row 2: Aviation Safety - [ - ("RTCA DO-365/366", "2"), - ("FAA Part 107", "2"), - ("EASA SORA", "2"), - ("ICAO Doc 10019", "1"), - ], - # row 3: Industry - [ - ("Healthcare", "2"), - ("Banking & FS", "2"), - ("Automotive", "1"), - ("Education", "12"), - ], - # row 4: Cross-cutting - [ - ("Global", "9"), - ("Aviation Vertical", "17"), - ("AIOps", "1"), - ("Corporate", "2"), - ], - ] - - # grid layout area: rows centered at y values, columns centered at x values - col_x = [22, 41, 60, 79] - row_y = [37, 28, 19, 10] - cell_w = 16.5 - cell_h = 7.4 - - # row labels on the far left - for ry, label in zip(row_y, row_labels): - ax.text( - 6.5, - ry, - label, - ha="center", - va="center", - fontsize=13, - fontweight="bold", - color=MUTED, - rotation=0, - ) - - for r_i, row in enumerate(cells): - for c_i, (name, count) in enumerate(row): - cx = col_x[c_i] - cy = row_y[r_i] - draw_box( - ax, - cx, - cy, - cell_w, - cell_h, - facecolor=PURPLE, - edgecolor=PURPLE_DARK, - linewidth=1.5, - rounding=0.3, - shadow=True, - ) - # framework name - ax.text( - cx, - cy + 1.1, - name, - ha="center", - va="center", - fontsize=14, - fontweight="bold", - color=WHITE, - zorder=3, - ) - # policy count pill - ax.text( - cx, - cy - 1.5, - f"{count} {'policy' if count == '1' else 'policies'}", - ha="center", - va="center", - fontsize=12, - color="#e9d5f0", - zorder=3, - ) - - save_fig(fig, "diagram3_regulatory_coverage.png") - - -# ---------- diagram 4: comparison ---------- -def diagram4_comparison(): - fig, ax = new_fig() - title(ax, "AICertify vs alternatives", y=53.5) - subtitle( - ax, - "The only open-source, policy-as-code option with named regulatory coverage.", - y=48.8, - ) - - columns = [ - "Feature", - "AICertify", - "Fairlearn", - "AI Fairness 360", - "MS RAI Toolbox", - "Credo AI", - ] - rows = [ - ( - "Open source (Apache 2.0)", - ["YES", "YES (MIT)", "YES (MIT)", "YES (MIT)", "NO"], - ), - ("On-prem capable", ["YES", "YES", "YES", "YES", "NO"]), - ("Policy-as-code (OPA / Rego)", ["YES", "NO", "NO", "NO", "NO"]), - ("Named regulatory frameworks (15+)", ["YES", "NO", "NO", "NO", "PARTIAL"]), - ("Industry verticals out of box", ["YES", "NO", "NO", "NO", "PARTIAL"]), - ("Audit-ready report output", ["YES", "NO", "NO", "PARTIAL", "YES"]), - ("Custom policies via `.rego`", ["YES", "NO", "NO", "NO", "PAID"]), - ] - - # Layout: columns - col_x = [18, 39, 52, 65, 78, 91] - col_w = [26, 11, 13, 13, 13, 11] - header_y = 42 - row_h = 4.2 - first_row_y = 38 - - # column header strip - for cx, cw, name in zip(col_x, col_w, columns): - is_aic = name == "AICertify" - ax.add_patch( - Rectangle( - (cx - cw / 2, header_y - row_h / 2), - cw, - row_h, - facecolor=PURPLE if is_aic else "#343a40", - edgecolor="none", - zorder=2, - ) - ) - ax.text( - cx, - header_y, - name, - ha="center", - va="center", - fontsize=14 if is_aic else 12, - fontweight="bold", - color=WHITE, - zorder=3, - ) - - # highlight strip for AICertify column behind rows - aic_x = col_x[1] - aic_w = col_w[1] - rows_total_h = row_h * len(rows) - ax.add_patch( - Rectangle( - (aic_x - aic_w / 2, first_row_y - row_h * (len(rows) - 1) - row_h / 2), - aic_w, - rows_total_h, - facecolor="#f3e8f7", - edgecolor="none", - zorder=1, - ) - ) - - def cell_marker(value): - if value == "YES": - return ("Yes", GREEN, "bold") - if value == "NO": - return ("No", RED, "bold") - if value == "PARTIAL": - return ("Partial", ORANGE, "bold") - if value == "PAID": - return ("Paid", ORANGE, "bold") - if value.startswith("YES "): - return (value.replace("YES ", "Yes "), GREEN, "bold") - return (value, TEXT, "normal") - - for r_i, (feature, vals) in enumerate(rows): - y = first_row_y - r_i * row_h - # alternating row band - if r_i % 2 == 0: - ax.add_patch( - Rectangle( - (col_x[0] - col_w[0] / 2, y - row_h / 2), - sum(col_w) - + (col_x[-1] + col_w[-1] / 2 - (col_x[0] - col_w[0] / 2)) - - sum(col_w), - row_h, - facecolor=LIGHTER_BG, - edgecolor="none", - zorder=0, - ) - ) - # feature label (left col) - ax.text( - col_x[0] - col_w[0] / 2 + 1, - y, - feature, - ha="left", - va="center", - fontsize=13, - color=TEXT, - zorder=3, - ) - # value cells - for c_i, v in enumerate(vals): - label, color, weight = cell_marker(v) - ax.text( - col_x[c_i + 1], - y, - label, - ha="center", - va="center", - fontsize=13, - color=color, - fontweight=weight, - zorder=3, - ) - - # bottom border - ax.plot( - [col_x[0] - col_w[0] / 2, col_x[-1] + col_w[-1] / 2], - [ - first_row_y - len(rows) * row_h + row_h / 2, - first_row_y - len(rows) * row_h + row_h / 2, - ], - color=BORDER, - lw=1.5, - zorder=2, - ) - - # footer - ax.text( - 50, - 4, - "Source: public docs and source repos as of 2025. AICertify is community-maintained.", - ha="center", - va="center", - fontsize=11, - color=MUTED, - style="italic", - ) - - save_fig(fig, "diagram4_comparison.png") - - -# ---------- diagram 5: report anatomy ---------- -def diagram5_report_anatomy(): - fig, ax = new_fig() - title(ax, "Anatomy of an audit-ready report", y=53.5) - subtitle( - ax, - "What the generated PDF actually contains.", - y=48.8, - ) - - # The "document" page - page_x, page_y = 50, 23.5 - page_w, page_h = 70, 41 - - # shadow - shadow_rect = Rectangle( - (page_x - page_w / 2 + 0.5, page_y - page_h / 2 - 0.6), - page_w, - page_h, - facecolor="#000000", - alpha=0.10, - edgecolor="none", - zorder=1, - ) - ax.add_patch(shadow_rect) - # page background - ax.add_patch( - Rectangle( - (page_x - page_w / 2, page_y - page_h / 2), - page_w, - page_h, - facecolor=WHITE, - edgecolor=BORDER, - linewidth=1.5, - zorder=2, - ) - ) - - left = page_x - page_w / 2 + 2.5 - right = page_x + page_w / 2 - 2.5 - top = page_y + page_h / 2 - - # Header band - ax.add_patch( - Rectangle( - (page_x - page_w / 2, top - 5.5), - page_w, - 5.5, - facecolor=PURPLE, - edgecolor="none", - zorder=3, - ) - ) - ax.text( - left, - top - 2.0, - "EU AI Act Compliance Report", - ha="left", - va="center", - fontsize=17, - fontweight="bold", - color=WHITE, - zorder=4, - ) - ax.text( - left, - top - 4.0, - "customer-support-bot | gpt-4o | 2026-05-14", - ha="left", - va="center", - fontsize=12, - color="#e9d5f0", - zorder=4, - ) - # PASS stamp on header - ax.add_patch( - FancyBboxPatch( - (right - 9, top - 4.6), - 8, - 3.4, - boxstyle="round,pad=0.02,rounding_size=0.4", - facecolor=GREEN, - edgecolor=GREEN, - zorder=4, - ) - ) - ax.text( - right - 5, - top - 2.9, - "PASS", - ha="center", - va="center", - fontsize=15, - fontweight="bold", - color=WHITE, - zorder=5, - ) - - # Section 1: Executive Summary - sec_y = top - 8.5 - ax.text( - left, - sec_y, - "1. Executive Summary", - ha="left", - va="center", - fontsize=14, - fontweight="bold", - color=PURPLE, - zorder=4, - ) - for i, line in enumerate( - [ - "27 of 29 EU AI Act policies passed. 2 advisory findings.", - "Risk classification: limited risk (Article 52 transparency).", - ] - ): - ax.text( - left, - sec_y - 2 - i * 1.7, - line, - ha="left", - va="center", - fontsize=11.5, - color=TEXT, - zorder=4, - ) - - # Section 2: Policy Results table - sec_y2 = sec_y - 7.5 - ax.text( - left, - sec_y2, - "2. Policy Results", - ha="left", - va="center", - fontsize=14, - fontweight="bold", - color=PURPLE, - zorder=4, - ) - - tbl_top = sec_y2 - 2 - # header row - ax.add_patch( - Rectangle( - (left, tbl_top - 1.4), - right - left - 22, - 1.4, - facecolor=LIGHT_BG, - edgecolor=BORDER, - zorder=3, - ) - ) - headers = ["Policy", "Status", "Evidence"] - hxs = [left + 0.5, left + 22, left + 30] - for hx, h in zip(hxs, headers): - ax.text( - hx, - tbl_top - 0.7, - h, - ha="left", - va="center", - fontsize=11, - fontweight="bold", - color=MUTED, - zorder=4, - ) - - rows = [ - ("Art. 5 Prohibited practices", "Pass", "0/127 interactions flagged"), - ("Art. 10 Data governance", "Pass", "training set documented"), - ("Art. 13 Transparency", "Pass", "user notice present"), - ("Art. 14 Human oversight", "Advisory", "review queue partial"), - ] - for i, (p, status, ev) in enumerate(rows): - y = tbl_top - 1.4 - 1.4 - i * 1.5 - color = GREEN if status == "Pass" else ORANGE - ax.text( - left + 0.5, - y, - p, - ha="left", - va="center", - fontsize=10.5, - color=TEXT, - zorder=4, - ) - ax.text( - left + 22, - y, - status, - ha="left", - va="center", - fontsize=10.5, - fontweight="bold", - color=color, - zorder=4, - ) - ax.text( - left + 30, - y, - ev, - ha="left", - va="center", - fontsize=10.5, - color=MUTED, - zorder=4, - ) - - # Section 3: Risk Assessment with mini bar chart - sec_y3 = sec_y2 - 12.5 - ax.text( - left, - sec_y3, - "3. Risk Assessment", - ha="left", - va="center", - fontsize=14, - fontweight="bold", - color=PURPLE, - zorder=4, - ) - bar_labels = ["Fair", "Safe", "Priv", "Robust"] - bar_vals = [0.92, 0.88, 0.95, 0.71] - bar_colors = [GREEN, GREEN, GREEN, ORANGE] - bx_start = left + 0.5 - bar_w = 3.6 - gap = 1.6 - base_y = sec_y3 - 6.2 - max_h = 4.5 - for i, (lbl, v, c) in enumerate(zip(bar_labels, bar_vals, bar_colors)): - bx = bx_start + i * (bar_w + gap) - ax.add_patch( - Rectangle( - (bx, base_y), - bar_w, - v * max_h, - facecolor=c, - edgecolor="none", - zorder=4, - ) - ) - ax.text( - bx + bar_w / 2, - base_y - 0.7, - lbl, - ha="center", - va="top", - fontsize=10, - color=MUTED, - zorder=4, - ) - ax.text( - bx + bar_w / 2, - base_y + v * max_h + 0.3, - f"{int(v * 100)}", - ha="center", - va="bottom", - fontsize=9.5, - color=TEXT, - zorder=4, - ) - - # Section 4: Remediation Guidance (right side, next to chart) - ax.text( - left + 24, - sec_y3, - "4. Remediation Guidance", - ha="left", - va="center", - fontsize=14, - fontweight="bold", - color=PURPLE, - zorder=4, - ) - for i, line in enumerate( - [ - "- Expand human-in-loop for low-confidence replies", - "- Add adversarial test set for robustness", - "- Document data-source provenance", - ] - ): - ax.text( - left + 24, - sec_y3 - 2 - i * 1.6, - line, - ha="left", - va="center", - fontsize=11, - color=TEXT, - zorder=4, - ) - - # Footer band - foot_y = page_y - page_h / 2 - ax.add_patch( - Rectangle( - (page_x - page_w / 2, foot_y), - page_w, - 2.0, - facecolor=LIGHTER_BG, - edgecolor="none", - zorder=3, - ) - ) - ax.text( - page_x, - foot_y + 1.0, - "Generated by AICertify v0.7.0 | Apache 2.0 | reproducible from contract.json", - ha="center", - va="center", - fontsize=10.5, - color=MUTED, - zorder=4, - ) - - save_fig(fig, "diagram5_report_anatomy.png") - - -# ---------- entrypoint ---------- -def main(): - print(f"Generating diagrams into {HERE}") - diagram1_hero_flow() - diagram2_architecture() - diagram3_regulatory_coverage() - diagram4_comparison() - diagram5_report_anatomy() - print("done.") - - -if __name__ == "__main__": - main() diff --git a/diagrams/hero_banner_dark.svg b/diagrams/hero_banner_dark.svg new file mode 100644 index 0000000..ffbcae4 --- /dev/null +++ b/diagrams/hero_banner_dark.svg @@ -0,0 +1,23 @@ + + +AICertify +AICertify hero banner with logo, wordmark, tagline, and framework badges. + + +AICertify +Compliance-as-code for AI systems +One contract. One command. Audit-ready reports. + + + +EU AI Act + + + +NIST AI RMF + + + +ICAO Doc 10019 + + diff --git a/diagrams/hero_banner_light.svg b/diagrams/hero_banner_light.svg new file mode 100644 index 0000000..4d694b2 --- /dev/null +++ b/diagrams/hero_banner_light.svg @@ -0,0 +1,23 @@ + + +AICertify +AICertify hero banner with logo, wordmark, tagline, and framework badges. + + +AICertify +Compliance-as-code for AI systems +One contract. One command. Audit-ready reports. + + + +EU AI Act + + + +NIST AI RMF + + + +ICAO Doc 10019 + + diff --git a/diagrams/logo_dark.svg b/diagrams/logo_dark.svg new file mode 100644 index 0000000..5fed7c6 --- /dev/null +++ b/diagrams/logo_dark.svg @@ -0,0 +1,7 @@ + + +AICertify +AICertify mark — flat-top hexagon with a checkmark. + + + diff --git a/diagrams/logo_light.svg b/diagrams/logo_light.svg new file mode 100644 index 0000000..4c208ee --- /dev/null +++ b/diagrams/logo_light.svg @@ -0,0 +1,7 @@ + + +AICertify +AICertify mark — flat-top hexagon with a checkmark. + + + diff --git a/diagrams/og_card.png b/diagrams/og_card.png new file mode 100644 index 0000000..b8cb9a3 Binary files /dev/null and b/diagrams/og_card.png differ diff --git a/diagrams/og_card_dark.svg b/diagrams/og_card_dark.svg new file mode 100644 index 0000000..6fb331f --- /dev/null +++ b/diagrams/og_card_dark.svg @@ -0,0 +1,38 @@ + + +AICertify — Compliance-as-code for AI systems +AICertify social card with logo, wordmark, tagline, framework chips, and project URL. + + + + + + + + +AICertify + +Compliance-as-code for AI systems +One contract · One command · Audit-ready reports + + + +EU AI Act + + + +NIST AI RMF + + + +ICAO Doc 10019 + + + ++13 more + + + +github.com/Principled-Evolution/aicertify +94 Rego policies · Apache 2.0 + diff --git a/diagrams/og_card_light.svg b/diagrams/og_card_light.svg new file mode 100644 index 0000000..2c41bb8 --- /dev/null +++ b/diagrams/og_card_light.svg @@ -0,0 +1,38 @@ + + +AICertify — Compliance-as-code for AI systems +AICertify social card with logo, wordmark, tagline, framework chips, and project URL. + + + + + + + + +AICertify + +Compliance-as-code for AI systems +One contract · One command · Audit-ready reports + + + +EU AI Act + + + +NIST AI RMF + + + +ICAO Doc 10019 + + + ++13 more + + + +github.com/Principled-Evolution/aicertify +94 Rego policies · Apache 2.0 +