mima-governance 0.3.0__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 (46) hide show
  1. mima_governance-0.3.0/.gitignore +105 -0
  2. mima_governance-0.3.0/PKG-INFO +203 -0
  3. mima_governance-0.3.0/README.md +169 -0
  4. mima_governance-0.3.0/TASKS.md +263 -0
  5. mima_governance-0.3.0/mima_governance/__init__.py +34 -0
  6. mima_governance-0.3.0/mima_governance/__main__.py +4 -0
  7. mima_governance-0.3.0/mima_governance/_base.py +591 -0
  8. mima_governance-0.3.0/mima_governance/approvals.py +260 -0
  9. mima_governance-0.3.0/mima_governance/approvals_cmd.py +279 -0
  10. mima_governance-0.3.0/mima_governance/async_client.py +464 -0
  11. mima_governance-0.3.0/mima_governance/cli.py +3438 -0
  12. mima_governance-0.3.0/mima_governance/client.py +567 -0
  13. mima_governance-0.3.0/mima_governance/config.py +58 -0
  14. mima_governance-0.3.0/mima_governance/daemon.py +459 -0
  15. mima_governance-0.3.0/mima_governance/gates.py +385 -0
  16. mima_governance-0.3.0/mima_governance/guard.py +401 -0
  17. mima_governance-0.3.0/mima_governance/integrations/__init__.py +29 -0
  18. mima_governance-0.3.0/mima_governance/integrations/autogen_middleware.py +121 -0
  19. mima_governance-0.3.0/mima_governance/integrations/deepeval_adapter.py +253 -0
  20. mima_governance-0.3.0/mima_governance/integrations/langchain_callback.py +109 -0
  21. mima_governance-0.3.0/mima_governance/integrations/langfuse_adapter.py +131 -0
  22. mima_governance-0.3.0/mima_governance/integrations/llamaindex_handler.py +85 -0
  23. mima_governance-0.3.0/mima_governance/policy.py +651 -0
  24. mima_governance-0.3.0/mima_governance/testing.py +253 -0
  25. mima_governance-0.3.0/mima_governance/types.py +70 -0
  26. mima_governance-0.3.0/mima_governance/webhooks_cmd.py +248 -0
  27. mima_governance-0.3.0/pyproject.toml +38 -0
  28. mima_governance-0.3.0/tasks/plan.md +222 -0
  29. mima_governance-0.3.0/tasks/todo.md +56 -0
  30. mima_governance-0.3.0/tests/conftest.py +14 -0
  31. mima_governance-0.3.0/tests/test_approvals.py +563 -0
  32. mima_governance-0.3.0/tests/test_async_client.py +404 -0
  33. mima_governance-0.3.0/tests/test_cli_suite.py +335 -0
  34. mima_governance-0.3.0/tests/test_client.py +194 -0
  35. mima_governance-0.3.0/tests/test_eval_adapters.py +396 -0
  36. mima_governance-0.3.0/tests/test_gates.py +313 -0
  37. mima_governance-0.3.0/tests/test_grc.py +551 -0
  38. mima_governance-0.3.0/tests/test_guard_daemon.py +610 -0
  39. mima_governance-0.3.0/tests/test_guard_otel.py +232 -0
  40. mima_governance-0.3.0/tests/test_integrations.py +400 -0
  41. mima_governance-0.3.0/tests/test_live_server.py +201 -0
  42. mima_governance-0.3.0/tests/test_new_features.py +706 -0
  43. mima_governance-0.3.0/tests/test_policy.py +525 -0
  44. mima_governance-0.3.0/tests/test_push.py +411 -0
  45. mima_governance-0.3.0/tests/test_signing.py +238 -0
  46. mima_governance-0.3.0/tests/test_testing_framework.py +170 -0
@@ -0,0 +1,105 @@
1
+ # --- Mima Production Guardrails ---
2
+
3
+ # 🛑 Environment & Secrets
4
+ .env
5
+ .env.local
6
+ .env.*.local
7
+ .mcp.json
8
+ certs/
9
+ *.pem
10
+ *.key
11
+
12
+ # 🛑 OS & Editor Gunk
13
+ .DS_Store
14
+ Thumbs.db
15
+ .vscode/
16
+ .idea/
17
+ *.swp
18
+ *.swo
19
+
20
+ # 🛑 Logs & Process IDs (Transient Data)
21
+ *.log
22
+ # Exception: FlexLM test fixture logs are checked in as test data
23
+ !tests/datasets/*.log
24
+ # Exception: agent-ui stub assets (rust-embed requires the folder to exist at compile time)
25
+ !apps/agent-ui/dist/
26
+ !apps/agent-ui/dist/index.html
27
+ !apps/agent-ui/dist/bundle.js
28
+ *.pid
29
+ agent_output.json
30
+ executed_tools*.txt
31
+ registry_tools*.txt
32
+ executor_tools*.txt
33
+
34
+ # 🛑 Dependency Management
35
+ node_modules/
36
+ /jspm_packages
37
+ /.pnp
38
+ .pnp.js
39
+ vendor/
40
+
41
+ # 🛑 Build & Binaries
42
+ bin/
43
+ release/
44
+ obj/
45
+ out/
46
+ dist/
47
+ build/
48
+ *.exe
49
+ *.dll
50
+ *.so
51
+ *.dylib
52
+ *.mat
53
+ matlab
54
+
55
+ # 🛑 Next.js / Frontend
56
+ /.next/
57
+ /out/
58
+ .vercel
59
+ .turbo
60
+
61
+ # 🛑 Go
62
+ pkg/
63
+ # Allow agent packaging assets (systemd unit, env template, debian scripts, WiX sources)
64
+ !apps/agent/pkg/
65
+ !apps/agent/wix/
66
+ go.work.sum
67
+
68
+ # 🛑 Rust
69
+ target/
70
+ **/*.rs.bk
71
+
72
+ # 🛑 Workspace & Tempoary
73
+ uploads/
74
+ tests_backup/
75
+ tmp/
76
+ apps/mima-calc/pkg/
77
+
78
+ # Terraform downloaded providers/modules
79
+ **/.terraform/
80
+ .terraform/
81
+ .aider*
82
+
83
+ # Content pipeline — sensitive runtime files
84
+ # reply-queue.json contains post IDs (direct handles to post on Mima's behalf)
85
+ # and raw comment text. Never commit to the repo.
86
+ tasks/reply-queue.json
87
+ tasks/pipeline-report.html
88
+
89
+ tasks/topics.json
90
+ apps/website/src/content/knowledge/_distribute-log.json
91
+ apps/website/src/content/knowledge/_manifest.json
92
+
93
+ # Python tooling artifacts
94
+ .pytest_cache/
95
+ .deepeval/
96
+ __pycache__/
97
+ *.pyc
98
+
99
+ # Python virtual environments
100
+ venv/
101
+ .venv/
102
+
103
+ # E2E test artifacts
104
+ apps/governance-dashboard/e2e-report/
105
+ apps/governance-dashboard/test-results/
@@ -0,0 +1,203 @@
1
+ Metadata-Version: 2.4
2
+ Name: mima-governance
3
+ Version: 0.3.0
4
+ Summary: Mima AI Governance SDK — runtime attestation, GRC evidence, and compliance testing for AI systems
5
+ Project-URL: Documentation, https://docs.mima.ai/sdk
6
+ Project-URL: Repository, https://github.com/mima-ai/mima-governance-python
7
+ Author-email: Mima <sdk@mima.ai>
8
+ License-Expression: MIT
9
+ Keywords: ai,attestation,compliance,eu-ai-act,governance
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
13
+ Classifier: Topic :: Security
14
+ Requires-Python: >=3.9
15
+ Requires-Dist: httpx>=0.24
16
+ Requires-Dist: pynacl>=1.5
17
+ Provides-Extra: autogen
18
+ Requires-Dist: pyautogen>=0.2; extra == 'autogen'
19
+ Provides-Extra: dev
20
+ Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
21
+ Requires-Dist: pytest-mock>=3.10; extra == 'dev'
22
+ Requires-Dist: pytest>=7; extra == 'dev'
23
+ Requires-Dist: pyyaml>=6; extra == 'dev'
24
+ Requires-Dist: respx>=0.20; extra == 'dev'
25
+ Provides-Extra: langchain
26
+ Requires-Dist: langchain-core>=0.1; extra == 'langchain'
27
+ Provides-Extra: llamaindex
28
+ Requires-Dist: llama-index-core>=0.10; extra == 'llamaindex'
29
+ Provides-Extra: otel
30
+ Requires-Dist: opentelemetry-api>=1.20; extra == 'otel'
31
+ Provides-Extra: policy
32
+ Requires-Dist: pyyaml>=6; extra == 'policy'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # mima-governance
36
+
37
+ Attest AI executions, push GRC evidence records, and run governance policy tests — one call maps to EU AI Act, ISO 42001, SOC 2, and NIST AI RMF simultaneously.
38
+
39
+ ## Four frameworks, one attestation call
40
+
41
+ | Framework | What it covers |
42
+ |---|---|
43
+ | EU AI Act | Art. 9–15 (risk management through accuracy), Art. 17 (quality management system), Art. 26 (deployer obligations), Art. 72–73 (post-market monitoring, incident reporting) |
44
+ | ISO 42001 | AI management system controls — A.6.x risk treatment, A.9.x performance evaluation |
45
+ | SOC 2 | CC3.x risk assessment, CC5.x control activities, CC7.x–CC8.x change and incident management |
46
+ | NIST AI RMF | GOVERN, MAP, MEASURE, MANAGE functions |
47
+
48
+ One `@mima.attest()` call earns controls across whichever frameworks apply — no per-regulation wiring, no separate pipelines. `human_oversight` earns `EUAIA_ART14`, `EUAIA_ART13`, `ISO42001_A.6.6`, and `NIST_AIRF_GOV_1` in a single write. Your readiness score updates across all four.
49
+
50
+ **What mima does not cover:** EU AI Act Art. 1–5 (scope and prohibited practices — legal determinations), Art. 51–56 (GPAI obligations — foundation model providers only, not application builders), and Art. 57–101 (regulatory apparatus, conformity assessment, EU database registration). Those require lawyers, structural decisions, or third-party conformity bodies — not SDK calls. mima covers the articles that require *technical evidence from code*.
51
+
52
+ ## No account needed to start
53
+
54
+ ```bash
55
+ pip install mima-governance
56
+ mima init . # scan codebase, generate tests/test_governance.py
57
+ mima test tests/test_governance.py # run immediately — no API key, no network
58
+ ```
59
+
60
+ `mima scan` and `mima test` are fully local. A Mima account unlocks `mima push` (evidence records), `mima status` (readiness scores), and the compliance dashboard.
61
+
62
+ ## Install
63
+
64
+ ```bash
65
+ pip install mima-governance
66
+ ```
67
+
68
+ ## Quick Start — SDK attestation
69
+
70
+ ```python
71
+ from mima_governance import MimaGovernance
72
+
73
+ mima = MimaGovernance(
74
+ api_key="mima_ext_...",
75
+ system_name="my-ai-pipeline",
76
+ )
77
+ # workspace_id is resolved automatically from the API key.
78
+
79
+ # Decorator — wraps a function; every call writes a GRC evidence record
80
+ # and maps to applicable controls across EU AI Act, ISO 42001, SOC 2, NIST AI RMF
81
+ @mima.attest(tool_name="generate_report")
82
+ def generate_report(data):
83
+ return call_llm(data)
84
+ ```
85
+
86
+ Each `@mima.attest()` call writes a row to `v2.grc_evidence_records` with `source = 'sdk'`. The cross-framework control mapping is automatic — the same record that evidences `EUAIA_ART13` also earns `ISO42001_A.6.2` and the relevant NIST AI RMF function. That compounding is what makes mima different from a per-regulation tool.
87
+
88
+ ## Framework Integrations
89
+
90
+ ### LangChain
91
+
92
+ ```python
93
+ from mima_governance.integrations import MimaLangChainCallback
94
+
95
+ chain = my_chain.with_config(callbacks=[MimaLangChainCallback(mima)])
96
+ # Every LLM call, tool invocation, and chain step is auto-attested
97
+ ```
98
+
99
+ ### LlamaIndex
100
+
101
+ ```python
102
+ from mima_governance.integrations import MimaLlamaIndexHandler
103
+ import llama_index.core
104
+
105
+ llama_index.core.global_handler = MimaLlamaIndexHandler(mima)
106
+ ```
107
+
108
+ ## Sync vs Batch
109
+
110
+ ```python
111
+ # Sync (default) — immediate push, blocks ~50ms
112
+ @mima.attest(tool_name="credit_decision")
113
+ def decide(app): ...
114
+
115
+ # Batch — buffered, flushed every 30s or 100 items
116
+ @mima.attest(tool_name="classify_email", mode="batch")
117
+ def classify(email): ...
118
+ ```
119
+
120
+ ## Ed25519 Signing
121
+
122
+ Records are stored as append-only rows in Postgres. Workspace admins can purge records via the dashboard. To detect deletion or tampering in a signed chain, use Ed25519 signing:
123
+
124
+ ```python
125
+ from nacl.signing import SigningKey
126
+
127
+ key = SigningKey.generate()
128
+
129
+ mima = MimaGovernance(
130
+ api_key="...",
131
+ system_name="...",
132
+ signing_key=key.encode(), # 32-byte seed
133
+ )
134
+ # Attestations are cryptographically signed → trust_tier: "verified"
135
+ # A deleted or modified record breaks the chain and is detectable
136
+ ```
137
+
138
+ Keep the private key outside the Mima account (local HSM or secrets manager). The signature is stored alongside the record; Mima cannot forge or reconstruct it.
139
+
140
+ ## Delegation Chain
141
+
142
+ ```python
143
+ from mima_governance import MimaGovernance, AuthorisedBy
144
+
145
+ mima = MimaGovernance(
146
+ ...,
147
+ authorised_by=AuthorisedBy(
148
+ identity="analyst@corp.com",
149
+ role="credit-analyst",
150
+ session_id="sso_abc123",
151
+ ),
152
+ )
153
+ # Every attestation records WHO authorised the agent to act
154
+ ```
155
+
156
+ ## How inferred evidence works
157
+
158
+ The Mima platform runs a nightly job (03:45 UTC) that reads AI system classifications already in the estate — from cloud integrations and CMDB data you have already connected — and converts them into evidence records with `source = 'estate_auto'`. No network scanning. No discovery beyond what's already in your connected estate.
159
+
160
+ **What inferred evidence is:** the AI risk classification process (tier determination, prohibited-use check) is itself a real risk assessment. It honestly evidences `EUAIA_ART9`, `EUAIA_ART11`, and related controls.
161
+
162
+ **What it is not:** proof that anyone evaluated model accuracy, governed training data, or operated a human oversight mechanism. The bridge explicitly does not generate `model_evaluation`, `training_data_governance`, or `human_oversight` records — auto-generating those would produce false evidence.
163
+
164
+ Inferred records are marked "indicative only" in the dashboard until a workspace admin validates the control list. SDK-attested records (`source = 'sdk'`) carry higher weight and are required for formal audit submissions.
165
+
166
+ ## Scan limitations
167
+
168
+ `mima scan` uses AST-based analysis (with a tokenizer fallback for files that can't be parsed). It correctly detects:
169
+
170
+ - **Direct usage:** `openai.chat.completions.create()`
171
+ - **Aliased imports:** `from openai import OpenAI; client = OpenAI(); client.chat.completions.create()`
172
+ - **Constructor-assigned handles:** `client = OpenAI()` → `client.chat.completions.create()`
173
+ - **Function-scope attestation:** `@mima.attest()` covers every AI call in the decorated function body, not just the nearest lines
174
+
175
+ It does **not** detect:
176
+
177
+ - **Wrapper abstractions:** `my_llm.generate()` where `my_llm` is not a direct AI constructor assignment
178
+ - **Runtime-constructed calls** or non-Python code
179
+
180
+ When `mima scan` reports zero unattested calls, the AST scanner found none in reachable call sites — not that none exist. Use `--strict` as a CI gate; complement with code review for deep wrapper abstractions it cannot reach.
181
+
182
+ ## Readiness score — how it's calculated
183
+
184
+ `overall_pct` is the **minimum** across all frameworks with defined controls (weakest-link). If SOC 2 is at 80% and EU AI Act is at 30%, `overall_pct` is 30. A certification chain is only as strong as its weakest framework; averaging would overstate readiness.
185
+
186
+ Per-framework `score_pct` = `controls_covered / controls_required × 100`.
187
+
188
+ ## Credential storage
189
+
190
+ `mima login` saves your API key to `~/.mima/config.json` with `0o600` permissions (owner read/write only). The file is plaintext — keep your home directory encrypted (FileVault on macOS, LUKS on Linux) if this is a shared or managed machine.
191
+
192
+ For CI/CD, use environment variables instead of the config file:
193
+
194
+ ```bash
195
+ export MIMA_API_KEY=mima_ext_...
196
+ export MIMA_WORKSPACE_ID=ws-...
197
+ mima push change_event \
198
+ --by ci-bot@company.com \
199
+ --description "Deploy v1.2.3" \
200
+ --environment production \
201
+ --system api-service \
202
+ --no-delta # skip readiness fetch in CI
203
+ ```
@@ -0,0 +1,169 @@
1
+ # mima-governance
2
+
3
+ Attest AI executions, push GRC evidence records, and run governance policy tests — one call maps to EU AI Act, ISO 42001, SOC 2, and NIST AI RMF simultaneously.
4
+
5
+ ## Four frameworks, one attestation call
6
+
7
+ | Framework | What it covers |
8
+ |---|---|
9
+ | EU AI Act | Art. 9–15 (risk management through accuracy), Art. 17 (quality management system), Art. 26 (deployer obligations), Art. 72–73 (post-market monitoring, incident reporting) |
10
+ | ISO 42001 | AI management system controls — A.6.x risk treatment, A.9.x performance evaluation |
11
+ | SOC 2 | CC3.x risk assessment, CC5.x control activities, CC7.x–CC8.x change and incident management |
12
+ | NIST AI RMF | GOVERN, MAP, MEASURE, MANAGE functions |
13
+
14
+ One `@mima.attest()` call earns controls across whichever frameworks apply — no per-regulation wiring, no separate pipelines. `human_oversight` earns `EUAIA_ART14`, `EUAIA_ART13`, `ISO42001_A.6.6`, and `NIST_AIRF_GOV_1` in a single write. Your readiness score updates across all four.
15
+
16
+ **What mima does not cover:** EU AI Act Art. 1–5 (scope and prohibited practices — legal determinations), Art. 51–56 (GPAI obligations — foundation model providers only, not application builders), and Art. 57–101 (regulatory apparatus, conformity assessment, EU database registration). Those require lawyers, structural decisions, or third-party conformity bodies — not SDK calls. mima covers the articles that require *technical evidence from code*.
17
+
18
+ ## No account needed to start
19
+
20
+ ```bash
21
+ pip install mima-governance
22
+ mima init . # scan codebase, generate tests/test_governance.py
23
+ mima test tests/test_governance.py # run immediately — no API key, no network
24
+ ```
25
+
26
+ `mima scan` and `mima test` are fully local. A Mima account unlocks `mima push` (evidence records), `mima status` (readiness scores), and the compliance dashboard.
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ pip install mima-governance
32
+ ```
33
+
34
+ ## Quick Start — SDK attestation
35
+
36
+ ```python
37
+ from mima_governance import MimaGovernance
38
+
39
+ mima = MimaGovernance(
40
+ api_key="mima_ext_...",
41
+ system_name="my-ai-pipeline",
42
+ )
43
+ # workspace_id is resolved automatically from the API key.
44
+
45
+ # Decorator — wraps a function; every call writes a GRC evidence record
46
+ # and maps to applicable controls across EU AI Act, ISO 42001, SOC 2, NIST AI RMF
47
+ @mima.attest(tool_name="generate_report")
48
+ def generate_report(data):
49
+ return call_llm(data)
50
+ ```
51
+
52
+ Each `@mima.attest()` call writes a row to `v2.grc_evidence_records` with `source = 'sdk'`. The cross-framework control mapping is automatic — the same record that evidences `EUAIA_ART13` also earns `ISO42001_A.6.2` and the relevant NIST AI RMF function. That compounding is what makes mima different from a per-regulation tool.
53
+
54
+ ## Framework Integrations
55
+
56
+ ### LangChain
57
+
58
+ ```python
59
+ from mima_governance.integrations import MimaLangChainCallback
60
+
61
+ chain = my_chain.with_config(callbacks=[MimaLangChainCallback(mima)])
62
+ # Every LLM call, tool invocation, and chain step is auto-attested
63
+ ```
64
+
65
+ ### LlamaIndex
66
+
67
+ ```python
68
+ from mima_governance.integrations import MimaLlamaIndexHandler
69
+ import llama_index.core
70
+
71
+ llama_index.core.global_handler = MimaLlamaIndexHandler(mima)
72
+ ```
73
+
74
+ ## Sync vs Batch
75
+
76
+ ```python
77
+ # Sync (default) — immediate push, blocks ~50ms
78
+ @mima.attest(tool_name="credit_decision")
79
+ def decide(app): ...
80
+
81
+ # Batch — buffered, flushed every 30s or 100 items
82
+ @mima.attest(tool_name="classify_email", mode="batch")
83
+ def classify(email): ...
84
+ ```
85
+
86
+ ## Ed25519 Signing
87
+
88
+ Records are stored as append-only rows in Postgres. Workspace admins can purge records via the dashboard. To detect deletion or tampering in a signed chain, use Ed25519 signing:
89
+
90
+ ```python
91
+ from nacl.signing import SigningKey
92
+
93
+ key = SigningKey.generate()
94
+
95
+ mima = MimaGovernance(
96
+ api_key="...",
97
+ system_name="...",
98
+ signing_key=key.encode(), # 32-byte seed
99
+ )
100
+ # Attestations are cryptographically signed → trust_tier: "verified"
101
+ # A deleted or modified record breaks the chain and is detectable
102
+ ```
103
+
104
+ Keep the private key outside the Mima account (local HSM or secrets manager). The signature is stored alongside the record; Mima cannot forge or reconstruct it.
105
+
106
+ ## Delegation Chain
107
+
108
+ ```python
109
+ from mima_governance import MimaGovernance, AuthorisedBy
110
+
111
+ mima = MimaGovernance(
112
+ ...,
113
+ authorised_by=AuthorisedBy(
114
+ identity="analyst@corp.com",
115
+ role="credit-analyst",
116
+ session_id="sso_abc123",
117
+ ),
118
+ )
119
+ # Every attestation records WHO authorised the agent to act
120
+ ```
121
+
122
+ ## How inferred evidence works
123
+
124
+ The Mima platform runs a nightly job (03:45 UTC) that reads AI system classifications already in the estate — from cloud integrations and CMDB data you have already connected — and converts them into evidence records with `source = 'estate_auto'`. No network scanning. No discovery beyond what's already in your connected estate.
125
+
126
+ **What inferred evidence is:** the AI risk classification process (tier determination, prohibited-use check) is itself a real risk assessment. It honestly evidences `EUAIA_ART9`, `EUAIA_ART11`, and related controls.
127
+
128
+ **What it is not:** proof that anyone evaluated model accuracy, governed training data, or operated a human oversight mechanism. The bridge explicitly does not generate `model_evaluation`, `training_data_governance`, or `human_oversight` records — auto-generating those would produce false evidence.
129
+
130
+ Inferred records are marked "indicative only" in the dashboard until a workspace admin validates the control list. SDK-attested records (`source = 'sdk'`) carry higher weight and are required for formal audit submissions.
131
+
132
+ ## Scan limitations
133
+
134
+ `mima scan` uses AST-based analysis (with a tokenizer fallback for files that can't be parsed). It correctly detects:
135
+
136
+ - **Direct usage:** `openai.chat.completions.create()`
137
+ - **Aliased imports:** `from openai import OpenAI; client = OpenAI(); client.chat.completions.create()`
138
+ - **Constructor-assigned handles:** `client = OpenAI()` → `client.chat.completions.create()`
139
+ - **Function-scope attestation:** `@mima.attest()` covers every AI call in the decorated function body, not just the nearest lines
140
+
141
+ It does **not** detect:
142
+
143
+ - **Wrapper abstractions:** `my_llm.generate()` where `my_llm` is not a direct AI constructor assignment
144
+ - **Runtime-constructed calls** or non-Python code
145
+
146
+ When `mima scan` reports zero unattested calls, the AST scanner found none in reachable call sites — not that none exist. Use `--strict` as a CI gate; complement with code review for deep wrapper abstractions it cannot reach.
147
+
148
+ ## Readiness score — how it's calculated
149
+
150
+ `overall_pct` is the **minimum** across all frameworks with defined controls (weakest-link). If SOC 2 is at 80% and EU AI Act is at 30%, `overall_pct` is 30. A certification chain is only as strong as its weakest framework; averaging would overstate readiness.
151
+
152
+ Per-framework `score_pct` = `controls_covered / controls_required × 100`.
153
+
154
+ ## Credential storage
155
+
156
+ `mima login` saves your API key to `~/.mima/config.json` with `0o600` permissions (owner read/write only). The file is plaintext — keep your home directory encrypted (FileVault on macOS, LUKS on Linux) if this is a shared or managed machine.
157
+
158
+ For CI/CD, use environment variables instead of the config file:
159
+
160
+ ```bash
161
+ export MIMA_API_KEY=mima_ext_...
162
+ export MIMA_WORKSPACE_ID=ws-...
163
+ mima push change_event \
164
+ --by ci-bot@company.com \
165
+ --description "Deploy v1.2.3" \
166
+ --environment production \
167
+ --system api-service \
168
+ --no-delta # skip readiness fetch in CI
169
+ ```