aprender-cbtop 0.63.0

Compute Block Top - Real-time load testing and hardware monitoring TUI
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
//! Types, enums, and data models for the double-blind verification framework.

use std::collections::HashMap;
use std::time::SystemTime;

/// Role in the double-blind verification process
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Role {
    /// Developer - implements features, makes claims
    Dev,
    /// Quality Assurance - verifies claims black-box
    Qa,
    /// System - makes release decisions
    System,
}

impl Role {
    /// Get role name
    pub fn name(&self) -> &'static str {
        match self {
            Role::Dev => "Developer",
            Role::Qa => "QA",
            Role::System => "System",
        }
    }

    /// Check if role can make claims
    pub fn can_claim(&self) -> bool {
        matches!(self, Role::Dev)
    }

    /// Check if role can verify
    pub fn can_verify(&self) -> bool {
        matches!(self, Role::Qa)
    }

    /// Check if role can approve releases
    pub fn can_approve(&self) -> bool {
        matches!(self, Role::System)
    }
}

/// Verification result
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VerificationResult {
    /// Claim was successfully falsified (QA found a bug)
    Falsified,
    /// Unable to falsify the claim (QA failed to find bugs)
    Unfalsified,
    /// Verification was inconclusive
    Inconclusive,
}

impl VerificationResult {
    /// Check if release should be approved based on this result
    pub fn should_approve(&self) -> bool {
        matches!(self, VerificationResult::Unfalsified)
    }
}

/// A falsification criterion (F-criteria)
#[derive(Debug, Clone)]
pub struct FalsificationCriterion {
    /// Criterion ID (e.g., "F1001")
    pub id: String,
    /// Description of what to test
    pub description: String,
    /// Pass condition
    pub pass_condition: String,
}

impl FalsificationCriterion {
    /// Create a new criterion
    pub fn new(id: &str, description: &str, pass_condition: &str) -> Self {
        Self {
            id: id.to_string(),
            description: description.to_string(),
            pass_condition: pass_condition.to_string(),
        }
    }

    /// Compute hash of criterion for integrity verification
    pub fn hash(&self) -> u64 {
        // Simple hash combining id, description, and pass_condition
        let mut hash: u64 = 0;
        for byte in self.id.bytes() {
            hash = hash.wrapping_mul(31).wrapping_add(u64::from(byte));
        }
        for byte in self.description.bytes() {
            hash = hash.wrapping_mul(31).wrapping_add(u64::from(byte));
        }
        for byte in self.pass_condition.bytes() {
            hash = hash.wrapping_mul(31).wrapping_add(u64::from(byte));
        }
        hash
    }
}

/// Developer's claim that falsification passed
#[derive(Debug, Clone)]
pub struct FalsificationClaim {
    /// Claim ID
    pub id: String,
    /// Feature or component being claimed
    pub feature: String,
    /// F-criteria that were tested
    pub criteria: Vec<FalsificationCriterion>,
    /// Hash of all criteria for integrity
    pub criteria_hash: u64,
    /// Timestamp of claim
    pub timestamp: SystemTime,
    /// Developer making the claim
    pub claimant: String,
    /// Version of the software
    pub version: String,
    /// Evidence supporting the claim (test results, logs)
    pub evidence: Vec<String>,
}

impl FalsificationClaim {
    /// Create a new claim
    pub fn new(id: &str, feature: &str, claimant: &str, version: &str) -> Self {
        Self {
            id: id.to_string(),
            feature: feature.to_string(),
            criteria: Vec::new(),
            criteria_hash: 0,
            timestamp: SystemTime::now(),
            claimant: claimant.to_string(),
            version: version.to_string(),
            evidence: Vec::new(),
        }
    }

    /// Add a criterion to the claim
    pub fn add_criterion(&mut self, criterion: FalsificationCriterion) {
        self.criteria.push(criterion);
        self.update_hash();
    }

    /// Add evidence to the claim
    pub fn add_evidence(&mut self, evidence: &str) {
        self.evidence.push(evidence.to_string());
    }

    /// Update the criteria hash
    fn update_hash(&mut self) {
        let mut hash: u64 = 0;
        for criterion in &self.criteria {
            hash = hash.wrapping_add(criterion.hash());
        }
        self.criteria_hash = hash;
    }

    /// Verify the criteria hash matches
    pub fn verify_hash(&self) -> bool {
        let mut expected: u64 = 0;
        for criterion in &self.criteria {
            expected = expected.wrapping_add(criterion.hash());
        }
        expected == self.criteria_hash
    }

    /// Check if claim is valid (has required fields)
    pub fn is_valid(&self) -> bool {
        !self.id.is_empty()
            && !self.feature.is_empty()
            && !self.claimant.is_empty()
            && !self.version.is_empty()
            && !self.criteria.is_empty()
            && self.verify_hash()
    }
}

/// Black-box artifact for QA (no source code)
#[derive(Debug, Clone)]
pub struct BlackBoxArtifact {
    /// Artifact ID
    pub id: String,
    /// Binary hash (SHA256 hex)
    pub binary_hash: String,
    /// F-criteria to test against
    pub criteria: Vec<FalsificationCriterion>,
    /// Criteria hash for integrity
    pub criteria_hash: u64,
    /// Version being tested
    pub version: String,
    /// Deadline for verification
    pub deadline: Option<SystemTime>,
}

impl BlackBoxArtifact {
    /// Create from a claim (strips source-related info)
    pub fn from_claim(claim: &FalsificationClaim, binary_hash: &str) -> Self {
        Self {
            id: format!("BB-{}", claim.id),
            binary_hash: binary_hash.to_string(),
            criteria: claim.criteria.clone(),
            criteria_hash: claim.criteria_hash,
            version: claim.version.clone(),
            deadline: None,
        }
    }

    /// Set verification deadline
    pub fn with_deadline(mut self, deadline: SystemTime) -> Self {
        self.deadline = Some(deadline);
        self
    }

    /// Check if deadline has passed
    pub fn is_expired(&self) -> bool {
        if let Some(deadline) = self.deadline {
            SystemTime::now() > deadline
        } else {
            false
        }
    }

    /// Verify criteria hash matches claim
    pub fn verify_criteria_integrity(&self, claim: &FalsificationClaim) -> bool {
        self.criteria_hash == claim.criteria_hash
    }
}

/// A single verification attempt by QA
#[derive(Debug, Clone)]
pub struct VerificationAttempt {
    /// Attempt ID
    pub id: String,
    /// Artifact being tested
    pub artifact_id: String,
    /// QA engineer making the attempt
    pub verifier: String,
    /// Result of verification
    pub result: VerificationResult,
    /// Timestamp
    pub timestamp: SystemTime,
    /// Evidence collected (logs, traces)
    pub evidence: Vec<String>,
    /// Individual criterion results
    pub criterion_results: HashMap<String, bool>,
}

impl VerificationAttempt {
    /// Create a new attempt
    pub fn new(id: &str, artifact_id: &str, verifier: &str) -> Self {
        Self {
            id: id.to_string(),
            artifact_id: artifact_id.to_string(),
            verifier: verifier.to_string(),
            result: VerificationResult::Inconclusive,
            timestamp: SystemTime::now(),
            evidence: Vec::new(),
            criterion_results: HashMap::new(),
        }
    }

    /// Record result for a criterion
    pub fn record_criterion(&mut self, criterion_id: &str, passed: bool) {
        self.criterion_results
            .insert(criterion_id.to_string(), passed);
    }

    /// Add evidence
    pub fn add_evidence(&mut self, evidence: &str) {
        self.evidence.push(evidence.to_string());
    }

    /// Finalize the attempt with result
    pub fn finalize(&mut self, result: VerificationResult) {
        self.result = result;
        self.timestamp = SystemTime::now();
    }

    /// Check if any criterion was falsified
    pub fn has_falsification(&self) -> bool {
        self.criterion_results.values().any(|&passed| !passed)
    }

    /// Get count of passed criteria
    pub fn passed_count(&self) -> usize {
        self.criterion_results.values().filter(|&&p| p).count()
    }

    /// Get count of failed criteria
    pub fn failed_count(&self) -> usize {
        self.criterion_results.values().filter(|&&p| !p).count()
    }
}

/// Scorecard component with weight
#[derive(Debug, Clone)]
pub struct ScorecardComponent {
    /// Component name
    pub name: String,
    /// Weight (0.0 to 1.0, must sum to 1.0 across all components)
    pub weight: f64,
    /// Score (0 to 100)
    pub score: u32,
}

impl ScorecardComponent {
    /// Create a new component
    pub fn new(name: &str, weight: f64, score: u32) -> Self {
        Self {
            name: name.to_string(),
            weight,
            score: score.min(100),
        }
    }

    /// Calculate weighted score
    pub fn weighted_score(&self) -> f64 {
        self.weight * f64::from(self.score)
    }
}

/// Falsification Scorecard v2 per section 36.3
#[derive(Debug, Clone)]
pub struct ScorecardV2 {
    /// Components with weights
    pub components: Vec<ScorecardComponent>,
    /// Version (v1 or v2)
    pub version: u8,
}

impl Default for ScorecardV2 {
    fn default() -> Self {
        Self::new()
    }
}

impl ScorecardV2 {
    /// Create a new v2 scorecard with default components
    pub fn new() -> Self {
        Self {
            components: vec![
                ScorecardComponent::new("Core Correctness", 0.30, 0),
                ScorecardComponent::new("Performance", 0.30, 0),
                ScorecardComponent::new("Resilience", 0.20, 0),
                ScorecardComponent::new("Usability", 0.20, 0),
            ],
            version: 2,
        }
    }

    /// Set score for a component by name
    pub fn set_score(&mut self, name: &str, score: u32) -> bool {
        for component in &mut self.components {
            if component.name == name {
                component.score = score.min(100);
                return true;
            }
        }
        false
    }

    /// Calculate total weighted score
    pub fn total_score(&self) -> f64 {
        self.components.iter().map(|c| c.weighted_score()).sum()
    }

    /// Check if weights sum to 1.0
    pub fn weights_valid(&self) -> bool {
        let sum: f64 = self.components.iter().map(|c| c.weight).sum();
        (sum - 1.0).abs() < 1e-10
    }

    /// Check if scorecard passes (>= 70)
    pub fn passes(&self) -> bool {
        self.total_score() >= 70.0
    }

    /// Get grade based on score
    pub fn grade(&self) -> &'static str {
        let score = self.total_score();
        if score >= 90.0 {
            "A"
        } else if score >= 80.0 {
            "B"
        } else if score >= 70.0 {
            "C"
        } else if score >= 60.0 {
            "D"
        } else {
            "F"
        }
    }
}

/// Release decision
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ReleaseDecision {
    /// Approved for release
    Approved { reason: String },
    /// Rejected
    Rejected { reason: String },
    /// Pending more verification
    Pending { reason: String },
}

impl ReleaseDecision {
    /// Check if approved
    pub fn is_approved(&self) -> bool {
        matches!(self, ReleaseDecision::Approved { .. })
    }

    /// Get reason
    pub fn reason(&self) -> &str {
        match self {
            ReleaseDecision::Approved { reason }
            | ReleaseDecision::Rejected { reason }
            | ReleaseDecision::Pending { reason } => reason,
        }
    }
}

/// Audit trail entry
#[derive(Debug, Clone)]
pub struct AuditEntry {
    /// Entry ID
    pub id: String,
    /// Timestamp
    pub timestamp: SystemTime,
    /// Role performing action
    pub role: Role,
    /// Actor name
    pub actor: String,
    /// Action description
    pub action: String,
    /// Related artifact IDs
    pub artifacts: Vec<String>,
}

impl AuditEntry {
    /// Create a new audit entry
    pub fn new(id: &str, role: Role, actor: &str, action: &str) -> Self {
        Self {
            id: id.to_string(),
            timestamp: SystemTime::now(),
            role,
            actor: actor.to_string(),
            action: action.to_string(),
            artifacts: Vec::new(),
        }
    }

    /// Add related artifact
    pub fn with_artifact(mut self, artifact_id: &str) -> Self {
        self.artifacts.push(artifact_id.to_string());
        self
    }
}

/// Session state
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SessionState {
    /// Awaiting claims from Dev
    AwaitingClaims,
    /// Claims received, awaiting verification
    AwaitingVerification,
    /// Verification complete, awaiting decision
    AwaitingDecision,
    /// Session completed
    Completed,
}

/// Summary report of verification session
#[derive(Debug, Clone)]
pub struct VerificationReport {
    /// Session ID
    pub session_id: String,
    /// Total claims submitted
    pub total_claims: usize,
    /// Total artifacts generated
    pub total_artifacts: usize,
    /// Total verification attempts
    pub total_attempts: usize,
    /// Number of falsified claims
    pub falsified_count: usize,
    /// Number of unfalsified claims
    pub unfalsified_count: usize,
    /// Number of inconclusive attempts
    pub inconclusive_count: usize,
    /// Scorecard total
    pub scorecard_total: f64,
    /// Scorecard grade
    pub scorecard_grade: String,
    /// Audit trail entries
    pub audit_entries: usize,
}

impl VerificationReport {
    /// Check if report indicates success
    pub fn is_success(&self) -> bool {
        self.falsified_count == 0 && self.scorecard_total >= 70.0
    }
}