rai-check-core 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. rai_check_core-0.0.1/.gitignore +55 -0
  2. rai_check_core-0.0.1/LICENSE +21 -0
  3. rai_check_core-0.0.1/PKG-INFO +64 -0
  4. rai_check_core-0.0.1/README.md +20 -0
  5. rai_check_core-0.0.1/examples/ci-gate.yml +94 -0
  6. rai_check_core-0.0.1/pyproject.toml +39 -0
  7. rai_check_core-0.0.1/src/rai_audit/core/__init__.py +43 -0
  8. rai_check_core-0.0.1/src/rai_audit/core/ci_formats.py +114 -0
  9. rai_check_core-0.0.1/src/rai_audit/core/cli.py +374 -0
  10. rai_check_core-0.0.1/src/rai_audit/core/config.py +458 -0
  11. rai_check_core-0.0.1/src/rai_audit/core/engine.py +22 -0
  12. rai_check_core-0.0.1/src/rai_audit/core/evidence.py +148 -0
  13. rai_check_core-0.0.1/src/rai_audit/core/export_commands.py +60 -0
  14. rai_check_core-0.0.1/src/rai_audit/core/findings.py +164 -0
  15. rai_check_core-0.0.1/src/rai_audit/core/history.py +317 -0
  16. rai_check_core-0.0.1/src/rai_audit/core/model_card.py +208 -0
  17. rai_check_core-0.0.1/src/rai_audit/core/monitoring.py +170 -0
  18. rai_check_core-0.0.1/src/rai_audit/core/privacy.py +74 -0
  19. rai_check_core-0.0.1/src/rai_audit/core/registry.py +35 -0
  20. rai_check_core-0.0.1/src/rai_audit/core/report.py +355 -0
  21. rai_check_core-0.0.1/src/rai_audit/core/reproducibility.py +173 -0
  22. rai_check_core-0.0.1/src/rai_audit/core/schemas.py +254 -0
  23. rai_check_core-0.0.1/src/rai_audit/core/scoring.py +74 -0
  24. rai_check_core-0.0.1/src/rai_audit/core/standards.py +223 -0
  25. rai_check_core-0.0.1/tests/test_config.py +154 -0
  26. rai_check_core-0.0.1/tests/test_evidence.py +37 -0
  27. rai_check_core-0.0.1/tests/test_findings.py +122 -0
  28. rai_check_core-0.0.1/tests/test_history.py +115 -0
  29. rai_check_core-0.0.1/tests/test_model_card.py +118 -0
  30. rai_check_core-0.0.1/tests/test_monitoring.py +100 -0
  31. rai_check_core-0.0.1/tests/test_schemas.py +61 -0
  32. rai_check_core-0.0.1/tests/test_scoring.py +59 -0
  33. rai_check_core-0.0.1/tests/test_standards.py +91 -0
@@ -0,0 +1,55 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+
8
+ # Virtual environments
9
+ .venv/
10
+ venv/
11
+ env/
12
+
13
+ # Packaging / build
14
+ build/
15
+ dist/
16
+ *.egg-info/
17
+ *.egg
18
+ pip-wheel-metadata/
19
+ *.whl
20
+
21
+ # Test / coverage / type checking
22
+ .pytest_cache/
23
+ .coverage
24
+ .coverage.*
25
+ htmlcov/
26
+ .mypy_cache/
27
+ .ruff_cache/
28
+ .hypothesis/
29
+
30
+ # Audit runtime artifacts
31
+ .rai-check/
32
+ *_audit_report.html
33
+ *_audit_report.md
34
+ *_audit_report.json
35
+ loan_audit_report.*
36
+
37
+ # Environment / secrets
38
+ .env
39
+ .env.*
40
+ !.env.example
41
+
42
+ # IDE / editor
43
+ .vscode/
44
+ .idea/
45
+ *.swp
46
+ *.swo
47
+ *~
48
+
49
+ # OS
50
+ .DS_Store
51
+ Thumbs.db
52
+ Desktop.ini
53
+
54
+ # Typical dev data
55
+ dev-data/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sai Teja Erukude
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,64 @@
1
+ Metadata-Version: 2.5
2
+ Name: rai-check-core
3
+ Version: 0.0.1
4
+ Summary: Shared audit engine, findings, reports, and CLI for the RAI Check Kit
5
+ Author: Sai Teja Erukude
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Sai Teja Erukude
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ License-File: LICENSE
28
+ Keywords: audit,fairness,responsible-ai,trustworthy-ai
29
+ Classifier: Development Status :: 4 - Beta
30
+ Classifier: Intended Audience :: Developers
31
+ Classifier: Intended Audience :: Science/Research
32
+ Classifier: License :: OSI Approved :: MIT License
33
+ Classifier: Programming Language :: Python :: 3
34
+ Classifier: Programming Language :: Python :: 3.10
35
+ Classifier: Programming Language :: Python :: 3.11
36
+ Classifier: Programming Language :: Python :: 3.12
37
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
38
+ Requires-Python: >=3.10
39
+ Requires-Dist: jsonschema>=4.0
40
+ Requires-Dist: pyyaml>=6.0
41
+ Requires-Dist: rich>=13.0
42
+ Requires-Dist: typer>=0.12
43
+ Description-Content-Type: text/markdown
44
+
45
+ # rai-check-core
46
+
47
+ Shared audit findings, evidence manifests, history, and reporting APIs.
48
+
49
+ Configured runs can include `standards-coverage` in `audit.report_formats` to
50
+ write a standalone JSON evidence-coverage artifact. History exports are available
51
+ from the CLI:
52
+
53
+ ```text
54
+ rai-check export standards-coverage audit-run.json
55
+ rai-check export history-dashboard --directory .rai-check/history
56
+ rai-check export eu-post-market --directory .rai-check/history
57
+ ```
58
+
59
+ Standards coverage and EU AI Act-oriented post-market reports summarize recorded
60
+ evidence. They do not make a compliance claim.
61
+
62
+ Configs, audit reports, evidence manifests, agent traces, and LLM suites use
63
+ versioned JSON Schemas. Existing unversioned inputs are migrated to schema version
64
+ `1.0` during loading.
@@ -0,0 +1,20 @@
1
+ # rai-check-core
2
+
3
+ Shared audit findings, evidence manifests, history, and reporting APIs.
4
+
5
+ Configured runs can include `standards-coverage` in `audit.report_formats` to
6
+ write a standalone JSON evidence-coverage artifact. History exports are available
7
+ from the CLI:
8
+
9
+ ```text
10
+ rai-check export standards-coverage audit-run.json
11
+ rai-check export history-dashboard --directory .rai-check/history
12
+ rai-check export eu-post-market --directory .rai-check/history
13
+ ```
14
+
15
+ Standards coverage and EU AI Act-oriented post-market reports summarize recorded
16
+ evidence. They do not make a compliance claim.
17
+
18
+ Configs, audit reports, evidence manifests, agent traces, and LLM suites use
19
+ versioned JSON Schemas. Existing unversioned inputs are migrated to schema version
20
+ `1.0` during loading.
@@ -0,0 +1,94 @@
1
+ # Example: RAI Check Gate in GitHub Actions
2
+ #
3
+ # Copy this file into your repository at .github/workflows/rai-check-gate.yml
4
+ # and adjust the paths and thresholds to match your project.
5
+ #
6
+ # This workflow:
7
+ # 1. Installs rai-check-ml
8
+ # 2. Runs your audit script to produce an audit-run.json
9
+ # 3. Calls `rai-check gate` — exits 1 (blocking deployment) on failure
10
+ # 4. Exports a model card for the audit artifact
11
+ # 5. Uploads the report as a workflow artifact
12
+
13
+ name: RAI Check Gate
14
+
15
+ on:
16
+ push:
17
+ branches: [main]
18
+ pull_request:
19
+
20
+ jobs:
21
+ rai-check:
22
+ name: Responsible AI Audit
23
+ runs-on: ubuntu-latest
24
+
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+
28
+ - uses: actions/setup-python@v5
29
+ with:
30
+ python-version: "3.12"
31
+
32
+ - name: Install rai-check-ml
33
+ run: pip install rai-check-ml
34
+
35
+ # ── Run your audit script ───────────────────────────────────────────────
36
+ # Replace this step with your actual audit script.
37
+ # The script must produce a JSON file via report.to_json("audit-run.json").
38
+ #
39
+ # Minimal example (inline):
40
+ - name: Run audit
41
+ run: |
42
+ python - <<'EOF'
43
+ import numpy as np
44
+ import pandas as pd
45
+ from rai_audit.ml import ClassificationAudit
46
+
47
+ rng = np.random.default_rng(42)
48
+ n = 500
49
+ y_true = rng.integers(0, 2, n)
50
+ y_pred = y_true.copy()
51
+ # Inject synthetic bias: flip 30 % of predictions for group B
52
+ group = pd.DataFrame({"gender": rng.choice(["A", "B"], n)})
53
+ flip_mask = (group["gender"] == "B") & (rng.random(n) < 0.30)
54
+ y_pred[flip_mask] = 1 - y_pred[flip_mask]
55
+
56
+ report = ClassificationAudit(
57
+ y_true=y_true,
58
+ y_pred=y_pred,
59
+ sensitive_features=group,
60
+ project_name="Example Classifier",
61
+ persist=False,
62
+ ).run()
63
+ report.to_json("audit-run.json")
64
+ EOF
65
+
66
+ # ── Gate check ─────────────────────────────────────────────────────────
67
+ # Exit code 1 if any CRITICAL findings exist.
68
+ # Remove --fail-on-critical to allow critical findings through.
69
+ - name: RAI Check gate
70
+ run: |
71
+ rai-check gate audit-run.json \
72
+ --fail-on-critical \
73
+ --output-json gate-result.json
74
+
75
+ # ── Export model card (always, even on gate failure) ───────────────────
76
+ - name: Export model card
77
+ if: always()
78
+ run: |
79
+ rai-check export model-card audit-run.json \
80
+ --model-name "Example Classifier" \
81
+ --model-version "${{ github.sha }}" \
82
+ --output model-card.md
83
+
84
+ # ── Upload artifacts ───────────────────────────────────────────────────
85
+ - name: Upload audit artifacts
86
+ if: always()
87
+ uses: actions/upload-artifact@v4
88
+ with:
89
+ name: rai-check-report-${{ github.run_number }}
90
+ path: |
91
+ audit-run.json
92
+ gate-result.json
93
+ model-card.md
94
+ retention-days: 90
@@ -0,0 +1,39 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "rai-check-core"
7
+ version = "0.0.1"
8
+ description = "Shared audit engine, findings, reports, and CLI for the RAI Check Kit"
9
+ readme = "README.md"
10
+ license = { file = "LICENSE" }
11
+ authors = [{ name = "Sai Teja Erukude" }]
12
+ requires-python = ">=3.10"
13
+ keywords = ["responsible-ai", "audit", "fairness", "trustworthy-ai"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "Intended Audience :: Science/Research",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
24
+ ]
25
+ dependencies = [
26
+ "typer>=0.12",
27
+ "rich>=13.0",
28
+ "pyyaml>=6.0",
29
+ "jsonschema>=4.0",
30
+ ]
31
+
32
+ [project.scripts]
33
+ rai-check = "rai_audit.core.cli:app"
34
+
35
+ [tool.hatch.build.targets.wheel]
36
+ packages = ["src/rai_audit"]
37
+
38
+ [tool.hatch.build.targets.wheel.sources]
39
+ "src" = ""
@@ -0,0 +1,43 @@
1
+ from rai_audit.core.evidence import build_evidence_manifest, load_evidence_manifest
2
+ from rai_audit.core.findings import (
3
+ AuditFinding,
4
+ AuditReport,
5
+ CategoryRisk,
6
+ RemediationEffort,
7
+ RiskLevel,
8
+ Severity,
9
+ )
10
+ from rai_audit.core.history import build_history_summary, write_history_dashboard
11
+ from rai_audit.core.monitoring import build_eu_ai_act_post_market_report
12
+ from rai_audit.core.schemas import (
13
+ SCHEMA_VERSION,
14
+ SchemaDocumentError,
15
+ get_schema,
16
+ migrate_document,
17
+ prepare_document,
18
+ validate_document,
19
+ )
20
+ from rai_audit.core.scoring import compute_risk_matrix
21
+ from rai_audit.core.standards import build_standards_coverage_report
22
+
23
+ __all__ = [
24
+ "AuditFinding",
25
+ "AuditReport",
26
+ "CategoryRisk",
27
+ "RemediationEffort",
28
+ "RiskLevel",
29
+ "Severity",
30
+ "SCHEMA_VERSION",
31
+ "SchemaDocumentError",
32
+ "build_evidence_manifest",
33
+ "build_eu_ai_act_post_market_report",
34
+ "build_history_summary",
35
+ "build_standards_coverage_report",
36
+ "compute_risk_matrix",
37
+ "get_schema",
38
+ "load_evidence_manifest",
39
+ "migrate_document",
40
+ "prepare_document",
41
+ "validate_document",
42
+ "write_history_dashboard",
43
+ ]
@@ -0,0 +1,114 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import xml.etree.ElementTree as ET
5
+ from typing import Any
6
+
7
+ from rai_audit.core.findings import AuditReport, Severity
8
+
9
+ _SARIF_LEVEL = {
10
+ Severity.CRITICAL: "error",
11
+ Severity.HIGH: "error",
12
+ Severity.MEDIUM: "warning",
13
+ Severity.LOW: "note",
14
+ }
15
+
16
+
17
+ def render_sarif(report: AuditReport) -> str:
18
+ """Render active findings as SARIF 2.1.0 for CI and code-scanning systems."""
19
+ active = [
20
+ finding
21
+ for finding in report.findings
22
+ if finding.severity not in {Severity.PASSED, Severity.INFO}
23
+ ]
24
+ rules = {
25
+ finding.check_id: {
26
+ "id": finding.check_id,
27
+ "name": finding.title,
28
+ "shortDescription": {"text": finding.description},
29
+ "properties": {
30
+ "category": finding.category,
31
+ "standards_refs": finding.standards_refs,
32
+ },
33
+ }
34
+ for finding in active
35
+ }
36
+ results = [
37
+ {
38
+ "ruleId": finding.check_id,
39
+ "level": _SARIF_LEVEL.get(finding.severity, "note"),
40
+ "message": {"text": finding.description},
41
+ "properties": {
42
+ "category": finding.category,
43
+ "severity": finding.severity.value,
44
+ "evidence": finding.evidence,
45
+ "recommendation": finding.recommendation,
46
+ "standards_refs": finding.standards_refs,
47
+ },
48
+ }
49
+ for finding in active
50
+ ]
51
+ document: dict[str, Any] = {
52
+ "$schema": "https://json.schemastore.org/sarif-2.1.0.json",
53
+ "version": "2.1.0",
54
+ "runs": [
55
+ {
56
+ "tool": {
57
+ "driver": {
58
+ "name": "rai-check",
59
+ "informationUri": "https://pypi.org/project/rai-check-kit/",
60
+ "rules": list(rules.values()),
61
+ }
62
+ },
63
+ "results": results,
64
+ }
65
+ ],
66
+ }
67
+ return json.dumps(document, indent=2)
68
+
69
+
70
+ def render_junit(report: AuditReport) -> str:
71
+ """Render findings as JUnit XML for CI test-report systems."""
72
+ active = [
73
+ finding
74
+ for finding in report.findings
75
+ if finding.severity not in {Severity.PASSED, Severity.INFO}
76
+ ]
77
+ suite = ET.Element(
78
+ "testsuite",
79
+ {
80
+ "name": report.project_name,
81
+ "tests": str(len(report.findings)),
82
+ "failures": str(len(active)),
83
+ },
84
+ )
85
+ for finding in report.findings:
86
+ case = ET.SubElement(
87
+ suite,
88
+ "testcase",
89
+ {
90
+ "classname": finding.category or "General",
91
+ "name": finding.check_id,
92
+ },
93
+ )
94
+ if finding.severity not in {Severity.PASSED, Severity.INFO}:
95
+ failure = ET.SubElement(
96
+ case,
97
+ "failure",
98
+ {
99
+ "message": finding.title,
100
+ "type": finding.severity.value,
101
+ },
102
+ )
103
+ failure.text = finding.description
104
+ output = ET.SubElement(case, "system-out")
105
+ output.text = json.dumps(
106
+ {
107
+ "evidence": finding.evidence,
108
+ "recommendation": finding.recommendation,
109
+ "standards_refs": finding.standards_refs,
110
+ },
111
+ default=str,
112
+ )
113
+ ET.indent(suite)
114
+ return ET.tostring(suite, encoding="unicode")