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.
|
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,,
|