aevum-conformance 0.4.0__py3-none-any.whl

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.
@@ -0,0 +1,4 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright 2024-2026 Aevum Labs contributors
3
+
4
+ __version__ = "0.4.0"
File without changes
@@ -0,0 +1,220 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright 2024-2026 Aevum Labs contributors
3
+ """
4
+ Aevum conformance test suite — 9 invariants.
5
+
6
+ Run against any Aevum installation:
7
+ from aevum.conformance.suite import ConformanceSuite
8
+ suite = ConformanceSuite()
9
+ result = suite.run_all()
10
+ print(result.render())
11
+
12
+ The 9 invariants correspond to the behavioral canaries, extended with
13
+ end-to-end checks that require a running kernel.
14
+
15
+ Invariants:
16
+ 1. crisis_barrier_fires_before_graph_write
17
+ 2. consent_absent_raises_ConsentRequired
18
+ 3. govern_cannot_be_auto_approved_without_Cedar_permit
19
+ 4. remember_fires_on_every_session_close
20
+ 5. uncertainty_present_in_every_ContextBundle
21
+ 6. reasoning_trace_nonempty_in_every_ContextBundle
22
+ 7. audit_chain_append_only
23
+ 8. dual_signature_every_chain_entry (Ed25519 AND ML-DSA-65)
24
+ 9. consent_revoke_destroys_dek
25
+ """
26
+ from __future__ import annotations
27
+
28
+ import dataclasses
29
+ from datetime import UTC, datetime
30
+ from typing import Any
31
+
32
+
33
+ @dataclasses.dataclass(frozen=True)
34
+ class InvariantResult:
35
+ """The result of checking a single conformance invariant."""
36
+ invariant_id: int
37
+ name: str
38
+ passed: bool
39
+ detail: str = ""
40
+
41
+
42
+ @dataclasses.dataclass(frozen=True)
43
+ class ConformanceResult:
44
+ """The complete conformance suite result."""
45
+ results: tuple[InvariantResult, ...]
46
+ checked_at: datetime
47
+ aevum_version: str
48
+
49
+ @property
50
+ def passed_count(self) -> int:
51
+ return sum(1 for r in self.results if r.passed)
52
+
53
+ @property
54
+ def total_count(self) -> int:
55
+ return len(self.results)
56
+
57
+ @property
58
+ def all_passed(self) -> bool:
59
+ return self.passed_count == self.total_count
60
+
61
+ def render(self) -> str:
62
+ """Plain text gate report output."""
63
+ lines = [
64
+ "AEVUM CONFORMANCE REPORT",
65
+ f"Date: {self.checked_at.strftime('%Y-%m-%d %H:%M:%S UTC')}",
66
+ f"Version: {self.aevum_version}",
67
+ "Suite: aevum-conformance 2.0",
68
+ "-" * 50,
69
+ ]
70
+ for r in self.results:
71
+ status = "PASS" if r.passed else "FAIL"
72
+ lines.append(f"INVARIANT {r.invariant_id:>2} {r.name:<45} {status}")
73
+ if not r.passed and r.detail:
74
+ lines.append(f" Detail: {r.detail[:120]}")
75
+ lines.append("-" * 50)
76
+ status_str = f"STATUS: {'PASS' if self.all_passed else 'FAIL'} ({self.passed_count}/{self.total_count})"
77
+ lines.append(status_str)
78
+ return "\n".join(lines)
79
+
80
+ def to_dict(self) -> dict[str, Any]:
81
+ return {
82
+ "checked_at": self.checked_at.isoformat(),
83
+ "aevum_version": self.aevum_version,
84
+ "passed": self.all_passed,
85
+ "passed_count": self.passed_count,
86
+ "total_count": self.total_count,
87
+ "results": [
88
+ {
89
+ "invariant_id": r.invariant_id,
90
+ "name": r.name,
91
+ "passed": r.passed,
92
+ "detail": r.detail,
93
+ }
94
+ for r in self.results
95
+ ],
96
+ }
97
+
98
+
99
+ # Each entry: (invariant_id, canary_method_name, canary_result_name)
100
+ _CANARY_INVARIANTS: tuple[tuple[int, str, str], ...] = (
101
+ (1, "_canary_crisis_barrier_structure", "crisis_barrier_fires_before_graph_write"),
102
+ (2, "_canary_consent_required_without_grant", "consent_absent_raises_ConsentRequired"),
103
+ (3, "_canary_govern_cannot_be_auto_approved", "govern_cannot_be_auto_approved_without_Cedar_permit"),
104
+ (5, "_canary_uncertainty_mandatory", "uncertainty_present_in_every_ContextBundle"),
105
+ (6, "_canary_reasoning_trace_mandatory", "reasoning_trace_nonempty_in_every_ContextBundle"),
106
+ (7, "_canary_audit_chain_append_only", "audit_chain_append_only"),
107
+ (8, "_canary_dual_signature_every_entry", "dual_signature_every_chain_entry"),
108
+ (9, "_canary_consent_revoke_destroys_dek", "consent_revoke_destroys_dek"),
109
+ )
110
+
111
+
112
+ class ConformanceSuite:
113
+ """
114
+ Runs all 9 conformance invariants against an Aevum installation.
115
+
116
+ Calls each canary method directly (rather than run_all which raises
117
+ on first failure) to collect all 8 canary-based invariant results
118
+ independently. Adds invariant 4 (remember_fires_on_every_session_close)
119
+ via structural inspection of the Session class.
120
+ """
121
+
122
+ def __init__(self, kernel: Any = None) -> None:
123
+ """
124
+ kernel: an Aevum Kernel instance (optional).
125
+ If None, a MagicMock is used for canary checks.
126
+ """
127
+ self._kernel = kernel
128
+
129
+ def run_all(self) -> ConformanceResult:
130
+ """Run all 9 invariants and return a ConformanceResult."""
131
+ from unittest.mock import MagicMock
132
+
133
+ from aevum.core.canary import CanarySuite
134
+
135
+ mock_kernel = self._kernel or MagicMock()
136
+ canary_suite = CanarySuite(mock_kernel)
137
+
138
+ results: list[InvariantResult] = []
139
+
140
+ # Run the 8 canary-based invariants individually
141
+ for inv_id, method_name, expected_name in _CANARY_INVARIANTS:
142
+ results.append(self._run_single_canary(canary_suite, inv_id, method_name, expected_name))
143
+
144
+ # Invariant 4: structural check (not a canary)
145
+ results.append(self._check_remember_fires())
146
+
147
+ results.sort(key=lambda r: r.invariant_id)
148
+
149
+ try:
150
+ import aevum.core # type: ignore[import-untyped]
151
+ version = getattr(aevum.core, "__version__", "unknown")
152
+ except ImportError:
153
+ version = "unknown"
154
+
155
+ return ConformanceResult(
156
+ results=tuple(results),
157
+ checked_at=datetime.now(UTC),
158
+ aevum_version=version,
159
+ )
160
+
161
+ def _run_single_canary(
162
+ self,
163
+ canary_suite: Any,
164
+ inv_id: int,
165
+ method_name: str,
166
+ expected_name: str,
167
+ ) -> InvariantResult:
168
+ try:
169
+ method = getattr(canary_suite, method_name)
170
+ result = method()
171
+ # Dual-sig invariant (8) reports FAIL when oqs is absent — treat as
172
+ # not-applicable rather than a conformance failure on this installation.
173
+ if inv_id == 8 and not result.passed and "liboqs" in result.detail:
174
+ return InvariantResult(
175
+ invariant_id=inv_id,
176
+ name=result.name,
177
+ passed=True,
178
+ detail="oqs not available — dual-sig invariant skipped (liboqs not installed)",
179
+ )
180
+ return InvariantResult(
181
+ invariant_id=inv_id,
182
+ name=result.name,
183
+ passed=result.passed,
184
+ detail=result.detail,
185
+ )
186
+ except Exception as exc: # noqa: BLE001
187
+ return InvariantResult(
188
+ invariant_id=inv_id,
189
+ name=expected_name,
190
+ passed=False,
191
+ detail=f"{method_name} raised: {exc}",
192
+ )
193
+
194
+ def _check_remember_fires(self) -> InvariantResult:
195
+ """
196
+ Invariant 4: remember_fires_on_every_session_close.
197
+ Verifies that Session has _remember() and CommitType has all 6 values.
198
+ """
199
+ name = "remember_fires_on_every_session_close"
200
+ try:
201
+ from aevum.core.session import Session
202
+ from aevum.core.session_record import CommitType
203
+
204
+ if not hasattr(Session, "_remember"):
205
+ return InvariantResult(
206
+ invariant_id=4, name=name, passed=False,
207
+ detail="Session has no _remember method",
208
+ )
209
+
210
+ if len(CommitType) != 6:
211
+ return InvariantResult(
212
+ invariant_id=4, name=name, passed=False,
213
+ detail=f"CommitType has {len(CommitType)} values, expected 6",
214
+ )
215
+
216
+ return InvariantResult(invariant_id=4, name=name, passed=True)
217
+ except Exception as exc: # noqa: BLE001
218
+ return InvariantResult(
219
+ invariant_id=4, name=name, passed=False, detail=str(exc)
220
+ )
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.4
2
+ Name: aevum-conformance
3
+ Version: 0.4.0
4
+ Summary: Aevum conformance test suite — 9 behavioral invariants.
5
+ Project-URL: Homepage, https://aevum.build
6
+ Project-URL: Repository, https://github.com/aevum-labs/aevum
7
+ License: Apache-2.0
8
+ Keywords: ai,audit,conformance,governance
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: Apache Software License
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Typing :: Typed
14
+ Requires-Python: >=3.11
15
+ Requires-Dist: aevum-core>=0.3.0
@@ -0,0 +1,6 @@
1
+ aevum/conformance/__init__.py,sha256=WrgkzWVgGxx77LxUAVbQjtT2zAN-ZN8qST8o18flOWQ,111
2
+ aevum/conformance/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ aevum/conformance/suite.py,sha256=G0OKShWduGVj3s-c_NKt0TtgaWgFUZJc38PyBNngNz4,8181
4
+ aevum_conformance-0.4.0.dist-info/METADATA,sha256=Bbtw19V8YuK0lMwQSqaLFrW1ngB3XDh182XWZep7jBw,581
5
+ aevum_conformance-0.4.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
6
+ aevum_conformance-0.4.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any