superlocalmemory 3.8.13 → 4.0.0

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 (212) hide show
  1. package/ATTRIBUTION.md +4 -4
  2. package/CHANGELOG.md +113 -121
  3. package/README.md +65 -63
  4. package/docs/pi-dev-integration.md +1 -1
  5. package/package.json +6 -1
  6. package/plugin/.claude-plugin/plugin.json +1 -1
  7. package/plugin/CLAUDE.md +3 -3
  8. package/plugin/agents/slm-governance-advisor.md +1 -1
  9. package/plugin/agents/slm-loop-runner.md +1 -1
  10. package/plugin/agents/slm-memory-advisor.md +1 -1
  11. package/plugin/agents/slm-optimize-advisor.md +1 -1
  12. package/plugin/requirements.txt +1 -1
  13. package/plugin/skills/slm-cache/SKILL.md +1 -1
  14. package/plugin/skills/slm-compress/SKILL.md +1 -1
  15. package/plugin/skills/slm-governance/SKILL.md +1 -1
  16. package/plugin/skills/slm-graph/SKILL.md +1 -1
  17. package/plugin/skills/slm-loop/SKILL.md +1 -1
  18. package/plugin/skills/slm-mesh/SKILL.md +1 -1
  19. package/plugin/skills/slm-profile/SKILL.md +1 -1
  20. package/plugin/skills/slm-recall/SKILL.md +1 -1
  21. package/plugin/skills/slm-remember/SKILL.md +1 -1
  22. package/plugin/skills/slm-scope/SKILL.md +1 -1
  23. package/plugin/skills/slm-session/SKILL.md +1 -1
  24. package/plugin/skills/slm-status/SKILL.md +1 -1
  25. package/plugin-src/rules/AGENTS.md +1 -1
  26. package/plugin-src/skills/slm-cache/SKILL.md +1 -1
  27. package/plugin-src/skills/slm-compress/SKILL.md +1 -1
  28. package/plugin-src/skills/slm-governance/SKILL.md +248 -0
  29. package/plugin-src/skills/slm-graph/SKILL.md +1 -1
  30. package/plugin-src/skills/slm-loop/SKILL.md +99 -0
  31. package/plugin-src/skills/slm-mesh/SKILL.md +282 -0
  32. package/plugin-src/skills/slm-profile/SKILL.md +148 -0
  33. package/plugin-src/skills/slm-recall/SKILL.md +1 -1
  34. package/plugin-src/skills/slm-remember/SKILL.md +1 -1
  35. package/plugin-src/skills/slm-scope/SKILL.md +176 -0
  36. package/plugin-src/skills/slm-session/SKILL.md +1 -1
  37. package/plugin-src/skills/slm-status/SKILL.md +1 -1
  38. package/pyproject.toml +11 -4
  39. package/src/superlocalmemory/__init__.py +1 -1
  40. package/src/superlocalmemory/cli/commands.py +125 -11
  41. package/src/superlocalmemory/cli/daemon.py +5 -1
  42. package/src/superlocalmemory/cli/main.py +35 -2
  43. package/src/superlocalmemory/cli/ops_cmd.py +281 -0
  44. package/src/superlocalmemory/cli/setup_wizard.py +1 -1
  45. package/src/superlocalmemory/compliance/audit.py +65 -0
  46. package/src/superlocalmemory/compliance/eu_ai_act.py +27 -57
  47. package/src/superlocalmemory/compliance/gdpr.py +416 -20
  48. package/src/superlocalmemory/compliance/retention.py +74 -22
  49. package/src/superlocalmemory/compliance/scheduler.py +78 -9
  50. package/src/superlocalmemory/core/actor_context.py +166 -0
  51. package/src/superlocalmemory/core/admission.py +549 -0
  52. package/src/superlocalmemory/core/backend_orchestrator.py +23 -10
  53. package/src/superlocalmemory/core/config.py +202 -24
  54. package/src/superlocalmemory/core/consolidation_engine.py +13 -13
  55. package/src/superlocalmemory/core/context_cache.py +28 -0
  56. package/src/superlocalmemory/core/embeddings.py +64 -2
  57. package/src/superlocalmemory/core/engine.py +7 -2
  58. package/src/superlocalmemory/core/engine_ingestion.py +65 -3
  59. package/src/superlocalmemory/core/engine_wiring.py +36 -9
  60. package/src/superlocalmemory/core/ingest_policy.py +38 -0
  61. package/src/superlocalmemory/core/maintenance.py +255 -0
  62. package/src/superlocalmemory/core/modes.py +40 -13
  63. package/src/superlocalmemory/core/mutations.py +437 -44
  64. package/src/superlocalmemory/core/operation_policy.py +92 -0
  65. package/src/superlocalmemory/core/operation_policy_registry.py +542 -0
  66. package/src/superlocalmemory/core/operation_request.py +127 -0
  67. package/src/superlocalmemory/core/ops_remediation.py +542 -0
  68. package/src/superlocalmemory/core/recall_pipeline.py +7 -0
  69. package/src/superlocalmemory/core/remember_runtime.py +202 -4
  70. package/src/superlocalmemory/core/remote_mode.py +20 -5
  71. package/src/superlocalmemory/core/store_pipeline.py +150 -0
  72. package/src/superlocalmemory/core/topic_signature.py +19 -4
  73. package/src/superlocalmemory/core/transactions/__init__.py +78 -0
  74. package/src/superlocalmemory/core/transactions/concrete_owners.py +597 -0
  75. package/src/superlocalmemory/core/transactions/erasure.py +825 -0
  76. package/src/superlocalmemory/core/transactions/manifest.py +255 -0
  77. package/src/superlocalmemory/core/transactions/manifest_key.py +155 -0
  78. package/src/superlocalmemory/core/transactions/obligations.py +272 -0
  79. package/src/superlocalmemory/core/transactions/owners.py +114 -0
  80. package/src/superlocalmemory/core/transactions/reconciler.py +285 -0
  81. package/src/superlocalmemory/core/transactions/service.py +330 -0
  82. package/src/superlocalmemory/core/worker_pool.py +33 -5
  83. package/src/superlocalmemory/encoding/cognitive_consolidator.py +70 -28
  84. package/src/superlocalmemory/encoding/emotional.py +75 -14
  85. package/src/superlocalmemory/encoding/scene_builder.py +115 -13
  86. package/src/superlocalmemory/encoding/temporal_parser.py +4 -0
  87. package/src/superlocalmemory/evolution/blind_verifier.py +11 -4
  88. package/src/superlocalmemory/evolution/evolution_store.py +244 -4
  89. package/src/superlocalmemory/evolution/llm_dispatch.py +40 -0
  90. package/src/superlocalmemory/evolution/model_selection.py +18 -3
  91. package/src/superlocalmemory/evolution/mutation_generator.py +3 -0
  92. package/src/superlocalmemory/evolution/skill_activator.py +270 -0
  93. package/src/superlocalmemory/evolution/skill_evolver.py +281 -59
  94. package/src/superlocalmemory/evolution/types.py +30 -8
  95. package/src/superlocalmemory/graph/cozo_backend.py +17 -9
  96. package/src/superlocalmemory/hooks/auto_invoker.py +2 -1
  97. package/src/superlocalmemory/hooks/auto_recall.py +64 -30
  98. package/src/superlocalmemory/hooks/codex_assets.py +14 -1
  99. package/src/superlocalmemory/infra/backup.py +434 -7
  100. package/src/superlocalmemory/infra/process_reaper.py +18 -0
  101. package/src/superlocalmemory/infra/self_heal.py +401 -0
  102. package/src/superlocalmemory/learning/feedback.py +52 -9
  103. package/src/superlocalmemory/loops/engine.py +10 -0
  104. package/src/superlocalmemory/mcp/_daemon_proxy.py +3 -0
  105. package/src/superlocalmemory/mcp/http_transport.py +30 -331
  106. package/src/superlocalmemory/mcp/profiles.py +5 -0
  107. package/src/superlocalmemory/mcp/resources.py +8 -0
  108. package/src/superlocalmemory/mcp/server.py +51 -4
  109. package/src/superlocalmemory/mcp/shared.py +19 -0
  110. package/src/superlocalmemory/mcp/tools_active.py +25 -4
  111. package/src/superlocalmemory/mcp/tools_code_graph.py +26 -18
  112. package/src/superlocalmemory/mcp/tools_context.py +50 -8
  113. package/src/superlocalmemory/mcp/tools_core.py +69 -21
  114. package/src/superlocalmemory/mcp/tools_evolution.py +9 -2
  115. package/src/superlocalmemory/mcp/tools_learning.py +21 -10
  116. package/src/superlocalmemory/mcp/tools_loops.py +29 -18
  117. package/src/superlocalmemory/mcp/tools_mesh.py +8 -0
  118. package/src/superlocalmemory/mcp/tools_ops.py +115 -0
  119. package/src/superlocalmemory/mcp/tools_optimize.py +4 -0
  120. package/src/superlocalmemory/mcp/tools_v28.py +10 -3
  121. package/src/superlocalmemory/mcp/tools_v3.py +34 -14
  122. package/src/superlocalmemory/mcp/tools_v33.py +18 -33
  123. package/src/superlocalmemory/mesh/broker.py +124 -46
  124. package/src/superlocalmemory/mesh/broker_security.py +470 -0
  125. package/src/superlocalmemory/mesh/discovery.py +365 -0
  126. package/src/superlocalmemory/mesh/lock_protocol.py +313 -0
  127. package/src/superlocalmemory/mesh/node_identity.py +97 -0
  128. package/src/superlocalmemory/mesh/outbox_remote.py +429 -0
  129. package/src/superlocalmemory/mesh/remote_sync.py +511 -28
  130. package/src/superlocalmemory/mesh/state_sync.py +286 -0
  131. package/src/superlocalmemory/optimize/config/store.py +45 -0
  132. package/src/superlocalmemory/parameterization/cross_project.py +12 -0
  133. package/src/superlocalmemory/parameterization/prompt_injector.py +13 -11
  134. package/src/superlocalmemory/parameterization/prompt_lifecycle.py +8 -2
  135. package/src/superlocalmemory/parameterization/workflow_miner.py +17 -0
  136. package/src/superlocalmemory/retrieval/ann_index.py +5 -0
  137. package/src/superlocalmemory/retrieval/bm25_channel.py +49 -2
  138. package/src/superlocalmemory/retrieval/engine.py +19 -4
  139. package/src/superlocalmemory/retrieval/fusion.py +4 -1
  140. package/src/superlocalmemory/retrieval/hopfield_channel.py +9 -3
  141. package/src/superlocalmemory/retrieval/remote_reranker.py +47 -22
  142. package/src/superlocalmemory/retrieval/reranker.py +32 -1
  143. package/src/superlocalmemory/retrieval/temporal_channel.py +16 -3
  144. package/src/superlocalmemory/retrieval/temporal_utils.py +107 -0
  145. package/src/superlocalmemory/retrieval/temporal_validity_filter.py +155 -42
  146. package/src/superlocalmemory/retrieval/vector_store.py +214 -8
  147. package/src/superlocalmemory/server/api.py +5 -5
  148. package/src/superlocalmemory/server/egress_policy.py +258 -0
  149. package/src/superlocalmemory/server/rbac_enforce.py +32 -0
  150. package/src/superlocalmemory/server/route_mutations.py +20 -0
  151. package/src/superlocalmemory/server/routes/compliance.py +153 -7
  152. package/src/superlocalmemory/server/routes/data_io.py +43 -2
  153. package/src/superlocalmemory/server/routes/events.py +15 -0
  154. package/src/superlocalmemory/server/routes/memories.py +56 -3
  155. package/src/superlocalmemory/server/routes/mesh.py +82 -1
  156. package/src/superlocalmemory/server/routes/mesh_lock.py +54 -0
  157. package/src/superlocalmemory/server/routes/mesh_state.py +63 -0
  158. package/src/superlocalmemory/server/routes/v3_api.py +50 -27
  159. package/src/superlocalmemory/server/routes/ws.py +86 -0
  160. package/src/superlocalmemory/server/ui.py +6 -6
  161. package/src/superlocalmemory/server/unified_daemon.py +942 -119
  162. package/src/superlocalmemory/storage/_migration_internals.py +568 -0
  163. package/src/superlocalmemory/storage/_schema_version.py +110 -0
  164. package/src/superlocalmemory/storage/database.py +329 -24
  165. package/src/superlocalmemory/storage/embedding_migrator.py +246 -51
  166. package/src/superlocalmemory/storage/erasure_fence.py +45 -0
  167. package/src/superlocalmemory/storage/generation_fence.py +63 -0
  168. package/src/superlocalmemory/storage/migration_runner.py +140 -417
  169. package/src/superlocalmemory/storage/migrations/M009_model_lineage.py +40 -0
  170. package/src/superlocalmemory/storage/migrations/M033_projection_transactions.py +148 -0
  171. package/src/superlocalmemory/storage/migrations/M034_obligation_integrity.py +58 -0
  172. package/src/superlocalmemory/storage/migrations/M035_erasure_receipts.py +113 -0
  173. package/src/superlocalmemory/storage/migrations/M036_vector_row_map.py +107 -0
  174. package/src/superlocalmemory/storage/migrations/M037_manifest_hmac_version.py +162 -0
  175. package/src/superlocalmemory/storage/migrations/{M033_learning_feedback_channel.py → M038_learning_feedback_channel.py} +3 -3
  176. package/src/superlocalmemory/storage/migrations/M039_scene_fact_members.py +137 -0
  177. package/src/superlocalmemory/storage/migrations/__init__.py +4 -2
  178. package/src/superlocalmemory/storage/schema.py +67 -0
  179. package/src/superlocalmemory/storage/write_coordinator.py +125 -0
  180. package/src/superlocalmemory/trust/scorer.py +28 -4
  181. package/src/superlocalmemory/ui/index.html +14 -3
  182. package/src/superlocalmemory/ui/js/auto-settings.js +12 -1
  183. package/src/superlocalmemory/ui/js/brain.js +6 -4
  184. package/src/superlocalmemory/ui/js/compliance.js +66 -12
  185. package/src/superlocalmemory/ui/js/dashboard.js +13 -3
  186. package/src/superlocalmemory/ui/js/feedback.js +8 -2
  187. package/src/superlocalmemory/ui/js/lifecycle.js +7 -1
  188. package/src/superlocalmemory/ui/js/modal.js +272 -5
  189. package/src/superlocalmemory/ui/js/od-backup.js +9 -2
  190. package/src/superlocalmemory/ui/js/od-compliance-ext.js +301 -0
  191. package/src/superlocalmemory/ui/js/od-operations.js +154 -23
  192. package/src/superlocalmemory/ui/js/od-ops-health.js +417 -0
  193. package/src/superlocalmemory/ui/js/od-optimize.js +35 -21
  194. package/src/superlocalmemory/ui/js/od-team.js +9 -2
  195. package/src/superlocalmemory/ui/js/optimize.js +13 -16
  196. package/src/superlocalmemory/ui/js/profiles.js +7 -3
  197. package/src/superlocalmemory/ui/js/settings.js +7 -1
  198. package/src/superlocalmemory/vector/lancedb_backend.py +19 -9
  199. package/src/superlocalmemory/attribution/mathematical_dna.py +0 -235
  200. package/src/superlocalmemory/cli/post_install.py +0 -114
  201. package/src/superlocalmemory/core/clock_monitor.py +0 -45
  202. package/src/superlocalmemory/core/db_pool.py +0 -80
  203. package/src/superlocalmemory/core/error_catalog.py +0 -113
  204. package/src/superlocalmemory/core/loop_watchdog.py +0 -56
  205. package/src/superlocalmemory/core/priority_queue.py +0 -61
  206. package/src/superlocalmemory/core/pruning_engine.py +0 -216
  207. package/src/superlocalmemory/core/queue_dispatcher.py +0 -73
  208. package/src/superlocalmemory/core/slmignore.py +0 -125
  209. package/src/superlocalmemory/infra/heartbeat_monitor.py +0 -140
  210. package/src/superlocalmemory/infra/webhook_dispatcher.py +0 -247
  211. package/src/superlocalmemory/learning/quantization_scheduler.py +0 -320
  212. package/src/superlocalmemory/storage/access_control.py +0 -182
@@ -74,6 +74,12 @@ class AuditChain:
74
74
  def __init__(self, db_path: Optional[Union[str, Path]] = None) -> None:
75
75
  self._db_path = str(db_path) if db_path else ":memory:"
76
76
  self._is_memory = self._db_path == ":memory:"
77
+ # External truncation anchor: a sidecar file holding the current chain
78
+ # length and head hash. The in-chain hash links detect mutation of a
79
+ # retained prefix, but not truncation of a suffix (or the whole chain);
80
+ # comparing against this externally-persisted (count, head) closes that
81
+ # gap. Not used for in-memory chains.
82
+ self._anchor_path = None if self._is_memory else (self._db_path + ".anchor")
77
83
  self._lock = threading.Lock()
78
84
  # For in-memory DBs, keep a persistent connection (each connect()
79
85
  # to ":memory:" creates a separate empty database).
@@ -136,6 +142,37 @@ class AuditChain:
136
142
  ).fetchone()
137
143
  return row["event_hash"] if row else _GENESIS_HASH
138
144
 
145
+ def _write_anchor(self, count: int, head: str) -> None:
146
+ """Persist the external (count, head) truncation anchor."""
147
+ if not self._anchor_path:
148
+ return
149
+ try:
150
+ payload = json.dumps({"count": int(count), "head": head}, sort_keys=True)
151
+ with open(self._anchor_path, "w", encoding="utf-8") as fh:
152
+ fh.write(payload)
153
+ try:
154
+ from superlocalmemory.core.security_primitives import harden_db_perms
155
+ harden_db_perms(self._anchor_path)
156
+ except Exception: # noqa: BLE001
157
+ pass
158
+ except Exception as exc: # noqa: BLE001
159
+ logger.warning("audit anchor write failed: %s", exc)
160
+
161
+ def _read_anchor(self) -> Optional[dict[str, Any]]:
162
+ """Read the external truncation anchor, or None if absent/unreadable."""
163
+ if not self._anchor_path:
164
+ return None
165
+ try:
166
+ with open(self._anchor_path, encoding="utf-8") as fh:
167
+ data = json.loads(fh.read())
168
+ if isinstance(data, dict) and "count" in data and "head" in data:
169
+ return data
170
+ except FileNotFoundError:
171
+ return None
172
+ except Exception as exc: # noqa: BLE001
173
+ logger.warning("audit anchor read failed: %s", exc)
174
+ return None
175
+
139
176
  # ------------------------------------------------------------------
140
177
  # Public API
141
178
  # ------------------------------------------------------------------
@@ -182,6 +219,14 @@ class AuditChain:
182
219
  ),
183
220
  )
184
221
  conn.commit()
222
+ # Update the external truncation anchor (chain length + head).
223
+ try:
224
+ cnt = conn.execute(
225
+ "SELECT COUNT(*) FROM audit_chain"
226
+ ).fetchone()[0]
227
+ self._write_anchor(int(cnt), event_hash)
228
+ except Exception as exc: # noqa: BLE001
229
+ logger.warning("audit anchor update skipped: %s", exc)
185
230
  return event_hash
186
231
  finally:
187
232
  self._release_conn(conn)
@@ -260,9 +305,29 @@ class AuditChain:
260
305
  finally:
261
306
  self._release_conn(conn)
262
307
 
308
+ anchor = self._read_anchor()
309
+ anchored_count = int(anchor.get("count", 0)) if anchor is not None else None
310
+
263
311
  if not rows:
312
+ # An empty chain is valid only if no external anchor claims prior
313
+ # entries; otherwise the whole chain was truncated.
314
+ if anchored_count is not None and anchored_count > 0:
315
+ logger.warning(
316
+ "Audit chain truncation detected: anchor expects %d entries, "
317
+ "found 0", anchored_count,
318
+ )
319
+ return False
264
320
  return True
265
321
 
322
+ # External truncation check: the retained prefix is verified below, but
323
+ # a suffix (or full) truncation leaves fewer rows than the anchor recorded.
324
+ if anchored_count is not None and len(rows) < anchored_count:
325
+ logger.warning(
326
+ "Audit chain truncation detected: anchor expects %d entries, "
327
+ "found %d", anchored_count, len(rows),
328
+ )
329
+ return False
330
+
266
331
  expected_prev = _GENESIS_HASH
267
332
  for row in rows:
268
333
  row_dict = dict(row)
@@ -2,11 +2,11 @@
2
2
  # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
- """SuperLocalMemory V3 — EU AI Act Compliance Verification.
5
+ """EU AI Act technical deployment-posture reporting.
6
6
 
7
- Verifies that each operating mode meets EU AI Act requirements.
8
- Mode A and B: FULL compliance (zero cloud, zero generative AI / local only).
9
- Mode C: NOT compliant (cloud LLM processing).
7
+ An operating mode can establish technical facts such as locality and use of
8
+ generative AI. It cannot determine the Act's risk classification or certify
9
+ legal compliance without the system's intended purpose and deployment context.
10
10
 
11
11
  Part of Qualixar | Author: Varun Pratap Bhardwaj
12
12
  """
@@ -28,29 +28,19 @@ class ComplianceReport:
28
28
  """EU AI Act compliance assessment for a specific mode."""
29
29
 
30
30
  mode: Mode
31
- compliant: bool
32
- risk_category: str # "minimal" / "limited" / "high" / "unacceptable"
31
+ compliant: bool | None
32
+ risk_category: str
33
33
  data_stays_local: bool
34
34
  uses_generative_ai: bool
35
- transparency_met: bool
36
- human_oversight: bool
35
+ transparency_met: bool | None
36
+ human_oversight: bool | None
37
+ deployment_context_required: bool
37
38
  findings: list[str]
38
39
  timestamp: str
39
40
 
40
41
 
41
42
  class EUAIActChecker:
42
- """Verify EU AI Act compliance for each operating mode.
43
-
44
- EU AI Act (effective Aug 2025) classifies AI systems by risk:
45
- - Minimal risk: No obligations (most AI systems)
46
- - Limited risk: Transparency obligations
47
- - High risk: Strict requirements (biometric, critical infra)
48
- - Unacceptable: Banned
49
-
50
- Memory systems are generally "minimal risk" UNLESS they process
51
- personal data via cloud AI services (then "limited risk" with
52
- transparency obligations).
53
- """
43
+ """Report mode-level technical posture without giving legal certification."""
54
44
 
55
45
  def check_compliance(self, mode: Mode) -> ComplianceReport:
56
46
  """Generate compliance report for a mode."""
@@ -75,43 +65,26 @@ class EUAIActChecker:
75
65
  "transparency: users must be informed AI generates content."
76
66
  )
77
67
 
78
- # Transparency
79
- transparency = True # We always disclose AI usage
80
- findings.append("Transparency requirement MET: system identifies as AI-assisted.")
81
-
82
- # Human oversight
83
- human_oversight = True # User controls all memory operations
84
- findings.append("Human oversight MET: user controls store/recall/delete.")
85
-
86
- # Risk classification
87
- if not uses_gen_ai:
88
- risk = "minimal"
89
- findings.append("Minimal risk: no generative AI, local processing only.")
90
- elif local_gen_ai:
91
- risk = "minimal"
92
- findings.append("Minimal risk: generative AI is local-only (Ollama).")
93
- else:
94
- risk = "limited"
95
- findings.append(
96
- "Limited risk: cloud generative AI requires transparency "
97
- "disclosure and DPA with cloud provider."
98
- )
99
-
100
- compliant = caps.eu_ai_act_compliant
101
- if not compliant:
102
- findings.append(
103
- "Mode C is NOT EU AI Act compliant by design. "
104
- "Use Mode A or B for EU-compliant deployments."
105
- )
68
+ if local_gen_ai:
69
+ findings.append("Generative AI processing is configured to remain local.")
70
+ findings.append(
71
+ "Legal classification is undetermined: intended purpose, affected persons, "
72
+ "sector, deployment context, and operator controls must be assessed."
73
+ )
74
+ findings.append(
75
+ "Transparency and human-oversight obligations require deployment evidence; "
76
+ "the operating mode alone cannot mark them as met."
77
+ )
106
78
 
107
79
  return ComplianceReport(
108
80
  mode=mode,
109
- compliant=compliant,
110
- risk_category=risk,
81
+ compliant=None,
82
+ risk_category="undetermined",
111
83
  data_stays_local=data_local,
112
84
  uses_generative_ai=uses_gen_ai,
113
- transparency_met=transparency,
114
- human_oversight=human_oversight,
85
+ transparency_met=None,
86
+ human_oversight=None,
87
+ deployment_context_required=True,
115
88
  findings=findings,
116
89
  timestamp=datetime.now(UTC).isoformat(),
117
90
  )
@@ -124,8 +97,5 @@ class EUAIActChecker:
124
97
  }
125
98
 
126
99
  def get_compliant_modes(self) -> list[Mode]:
127
- """Return list of EU AI Act compliant modes."""
128
- return [
129
- mode for mode in Mode
130
- if get_capabilities(mode).eu_ai_act_compliant
131
- ]
100
+ """Return no certified modes; mode alone is insufficient evidence."""
101
+ return []