vyre_conform/pipeline/certify/
accessors.rs1use std::collections::BTreeMap;
4
5use super::{
6 Certificate, CertificateLevels, CertificateStrength, ConformanceLevel, CoverageMetrics,
7 EngineResult, EngineStatus, OpOutcome, OpResult, TrackReport, Violation,
8};
9use crate::spec::law::LawViolation;
10use crate::spec::types::ParityFailure;
11
12impl Violation {
13 #[must_use]
15 #[inline]
16 pub(crate) fn new(
17 op_id: String,
18 law: String,
19 backend: String,
20 reference_output: Vec<u8>,
21 backend_output: Vec<u8>,
22 message: String,
23 ) -> Self {
24 Self {
25 op_id,
26 law,
27 backend,
28 reference_output,
29 backend_output,
30 message,
31 }
32 }
33
34 #[must_use]
36 #[inline]
37 pub fn op_id(&self) -> &str {
38 &self.op_id
39 }
40
41 #[must_use]
43 #[inline]
44 pub fn law(&self) -> &str {
45 &self.law
46 }
47
48 #[must_use]
50 #[inline]
51 pub fn backend(&self) -> &str {
52 &self.backend
53 }
54
55 #[must_use]
57 #[inline]
58 pub fn reference_output(&self) -> &[u8] {
59 &self.reference_output
60 }
61
62 #[must_use]
64 #[inline]
65 pub fn backend_output(&self) -> &[u8] {
66 &self.backend_output
67 }
68
69 #[must_use]
71 #[inline]
72 pub fn message(&self) -> &str {
73 &self.message
74 }
75}
76
77impl Certificate {
78 #[must_use]
79 #[inline]
80 pub(crate) fn new(
81 backend_name: String,
82 backend_version: String,
83 spec_version: u32,
84 level: CertificateLevels,
85 timestamp: String,
86 monotonic_sequence: u64,
87 strength: CertificateStrength,
88 witness_count: u64,
89 witness_count_by_op: BTreeMap<String, u64>,
90 proof_status: String,
91 integer_track: TrackReport,
92 float_track: Option<TrackReport>,
93 approximate_track: Option<TrackReport>,
94 ops: Vec<OpResult>,
95 unsupported_ops: Vec<String>,
96 engines: Vec<EngineResult>,
97 registry_hash: [u8; 32],
98 coverage: CoverageMetrics,
99 ) -> Self {
100 let certificate_hash = certificate_hash_for(
101 &backend_name,
102 &backend_version,
103 spec_version,
104 ×tamp,
105 monotonic_sequence,
106 ®istry_hash,
107 );
108 Self {
109 backend_name,
110 backend_version,
111 spec_version,
112 level,
113 timestamp,
114 monotonic_sequence,
115 certificate_hash,
116 strength,
117 witness_count,
118 witness_count_by_op,
119 proof_status,
120 integer_track,
121 float_track,
122 approximate_track,
123 ops,
124 unsupported_ops,
125 engines,
126 registry_hash,
127 coverage,
128 }
129 }
130
131 #[must_use]
133 #[inline]
134 pub fn id(&self) -> &[u8; 32] {
135 &self.certificate_hash
136 }
137
138 #[must_use]
140 #[inline]
141 pub fn backend_id(&self) -> &str {
142 &self.backend_name
143 }
144
145 #[must_use]
147 #[inline]
148 pub fn spec_hash(&self) -> &[u8; 32] {
149 &self.registry_hash
150 }
151
152 #[must_use]
154 #[inline]
155 pub fn cert_hash(&self) -> &[u8; 32] {
156 &self.certificate_hash
157 }
158
159 #[must_use]
161 #[inline]
162 pub fn backend_name(&self) -> &str {
163 &self.backend_name
164 }
165
166 #[must_use]
168 #[inline]
169 pub fn backend_version(&self) -> &str {
170 &self.backend_version
171 }
172
173 #[must_use]
175 #[inline]
176 pub fn spec_version(&self) -> u32 {
177 self.spec_version
178 }
179
180 #[must_use]
182 #[inline]
183 pub fn level(&self) -> CertificateLevels {
184 self.level
185 }
186
187 #[must_use]
189 #[inline]
190 pub fn timestamp(&self) -> &str {
191 &self.timestamp
192 }
193
194 #[must_use]
196 #[inline]
197 pub fn monotonic_sequence(&self) -> u64 {
198 self.monotonic_sequence
199 }
200
201 #[must_use]
203 #[inline]
204 pub fn certificate_hash(&self) -> &[u8; 32] {
205 &self.certificate_hash
206 }
207
208 #[must_use]
210 #[inline]
211 pub fn strength(&self) -> CertificateStrength {
212 self.strength
213 }
214
215 #[must_use]
217 #[inline]
218 pub fn witness_count(&self) -> u64 {
219 self.witness_count
220 }
221
222 #[must_use]
224 #[inline]
225 pub fn witness_count_by_op(&self) -> &BTreeMap<String, u64> {
226 &self.witness_count_by_op
227 }
228
229 #[must_use]
231 #[inline]
232 pub fn proof_status(&self) -> &str {
233 &self.proof_status
234 }
235
236 #[must_use]
238 #[inline]
239 pub fn integer_track(&self) -> &TrackReport {
240 &self.integer_track
241 }
242
243 #[must_use]
245 #[inline]
246 pub fn float_track(&self) -> &Option<TrackReport> {
247 &self.float_track
248 }
249
250 #[must_use]
252 #[inline]
253 pub fn approximate_track(&self) -> &Option<TrackReport> {
254 &self.approximate_track
255 }
256
257 #[must_use]
259 #[inline]
260 pub fn ops(&self) -> &[OpResult] {
261 &self.ops
262 }
263
264 #[must_use]
266 #[inline]
267 pub fn unsupported_ops(&self) -> &[String] {
268 &self.unsupported_ops
269 }
270
271 #[must_use]
273 #[inline]
274 pub fn engines(&self) -> &[EngineResult] {
275 &self.engines
276 }
277
278 #[must_use]
280 #[inline]
281 pub fn registry_hash(&self) -> &[u8; 32] {
282 &self.registry_hash
283 }
284
285 #[must_use]
287 #[inline]
288 pub fn coverage(&self) -> &CoverageMetrics {
289 &self.coverage
290 }
291}
292
293impl OpResult {
294 #[must_use]
296 #[inline]
297 pub fn id(&self) -> &str {
298 &self.id
299 }
300
301 #[must_use]
303 #[inline]
304 pub fn archetype(&self) -> &str {
305 &self.archetype
306 }
307
308 #[must_use]
310 #[inline]
311 pub fn outcome(&self) -> OpOutcome {
312 self.outcome
313 }
314
315 #[must_use]
317 #[inline]
318 pub fn parity_passed(&self) -> bool {
319 self.parity_passed
320 }
321
322 #[must_use]
324 #[inline]
325 pub fn laws_verified(&self) -> &[String] {
326 &self.laws_verified
327 }
328
329 #[must_use]
331 #[inline]
332 pub fn laws_failed(&self) -> &[LawViolation] {
333 &self.laws_failed
334 }
335
336 #[must_use]
338 #[inline]
339 pub fn parity_failures(&self) -> &[ParityFailure] {
340 &self.parity_failures
341 }
342
343 #[must_use]
345 #[inline]
346 pub fn cases_tested(&self) -> u64 {
347 self.cases_tested
348 }
349
350 #[must_use]
352 #[inline]
353 pub fn witness_count(&self) -> u64 {
354 self.witness_count
355 }
356}
357
358impl TrackReport {
359 #[must_use]
361 #[inline]
362 pub fn level(&self) -> Option<ConformanceLevel> {
363 self.level
364 }
365
366 #[must_use]
368 #[inline]
369 pub fn ops(&self) -> &[OpResult] {
370 &self.ops
371 }
372
373 #[must_use]
375 #[inline]
376 pub fn unsupported_ops(&self) -> &[String] {
377 &self.unsupported_ops
378 }
379
380 #[must_use]
382 #[inline]
383 pub fn coverage(&self) -> &CoverageMetrics {
384 &self.coverage
385 }
386}
387
388impl EngineResult {
389 #[must_use]
391 #[inline]
392 pub fn id(&self) -> &str {
393 &self.id
394 }
395
396 #[must_use]
398 #[inline]
399 pub fn status(&self) -> EngineStatus {
400 self.status
401 }
402
403 #[must_use]
405 #[inline]
406 pub fn invariants_verified(&self) -> &[String] {
407 &self.invariants_verified
408 }
409
410 #[must_use]
412 #[inline]
413 pub fn invariants_failed(&self) -> &[String] {
414 &self.invariants_failed
415 }
416
417 #[must_use]
419 #[inline]
420 pub fn cases_tested(&self) -> u64 {
421 self.cases_tested
422 }
423}
424
425fn certificate_hash_for(
426 backend_name: &str,
427 backend_version: &str,
428 spec_version: u32,
429 timestamp: &str,
430 monotonic_sequence: u64,
431 registry_hash: &[u8; 32],
432) -> [u8; 32] {
433 let mut hasher = blake3::Hasher::new();
434 hasher.update(b"vyre-conform.certificate.v1");
435 hash_bytes(&mut hasher, backend_name.as_bytes());
436 hash_bytes(&mut hasher, backend_version.as_bytes());
437 hasher.update(&spec_version.to_le_bytes());
438 hash_bytes(&mut hasher, timestamp.as_bytes());
439 hasher.update(&monotonic_sequence.to_le_bytes());
440 hasher.update(registry_hash);
441 *hasher.finalize().as_bytes()
442}
443
444fn hash_bytes(hasher: &mut blake3::Hasher, bytes: &[u8]) {
445 hasher.update(&(bytes.len() as u64).to_le_bytes());
446 hasher.update(bytes);
447}